php symfony paypal payment-gateway payum

php - Configurando Payum Bundle con Symfony2 dando error



paypal payment-gateway (1)

Finalmente logré terminarlo.

Necesitaba 4 archivos

  1. PaymentController
  2. Pedidos (Entidad)
  3. PaymentToken (entidad)
  4. Pedidos (Modelo)

Este es mi PaymentController parece

<?php namespace ClickTeck/featuresBundle/Controller; use ClickTeck/featuresBundle/Entity/Orders; use Symfony/Bundle/FrameworkBundle/Controller/Controller; use Payum/Paypal/ExpressCheckout/Nvp/Api; use Payum/Core/Registry/RegistryInterface; use Payum/Core/Request/GetHumanStatus; use Payum/Core/Security/GenericTokenFactoryInterface; use Symfony/Component/HttpFoundation/Request; use Symfony/Component/HttpFoundation/JsonResponse; use Sensio/Bundle/FrameworkExtraBundle/Configuration as Extra; class PaymentController extends Controller { public function preparePaypalExpressCheckoutPaymentAction(Request $request) { $paymentName = ''paypal''; $eBook = array( ''author'' => ''Jules Verne'', ''name'' => ''The Mysterious Island'', ''description'' => ''The Mysterious Island is a novel by Jules Verne, published in 1874.'', ''price'' => 8.64, ''currency_symbol'' => ''$'', ''currency'' => ''USD'', ''clientId'' => ''222'', ''clientemail'' => ''[email protected]'' ); $storage = $this->get(''payum'')->getStorage(''ClickTeck/featuresBundle/Entity/Orders''); /** @var $paymentDetails Orders */ $paymentDetails = $storage->create(); $paymentDetails->setNumber(uniqid()); $paymentDetails->setCurrencyCode($eBook[''currency'']); $paymentDetails->setTotalAmount($eBook[''price'']); $paymentDetails->setDescription($eBook[''description'']); $paymentDetails->setClientId($eBook[''clientId'']); $paymentDetails->setClientEmail($eBook[''clientemail'']); $paymentDetails[''PAYMENTREQUEST_0_CURRENCYCODE''] = $eBook[''currency'']; $paymentDetails[''PAYMENTREQUEST_0_AMT''] = $eBook[''price'']; $paymentDetails[''NOSHIPPING''] = Api::NOSHIPPING_NOT_DISPLAY_ADDRESS; $paymentDetails[''REQCONFIRMSHIPPING''] = Api::REQCONFIRMSHIPPING_NOT_REQUIRED; $paymentDetails[''L_PAYMENTREQUEST_0_ITEMCATEGORY0''] = Api::PAYMENTREQUEST_ITERMCATEGORY_DIGITAL; $paymentDetails[''L_PAYMENTREQUEST_0_AMT0''] = $eBook[''price'']; $paymentDetails[''L_PAYMENTREQUEST_0_NAME0''] = $eBook[''author''].''. ''.$eBook[''name'']; $paymentDetails[''L_PAYMENTREQUEST_0_DESC0''] = $eBook[''description'']; $storage->update($paymentDetails); $captureToken = $this->getTokenFactory()->createCaptureToken( $paymentName, $paymentDetails, ''payment_done'' ); $paymentDetails[''INVNUM''] = $paymentDetails->getId(); $storage->update($paymentDetails); return $this->redirect($captureToken->getTargetUrl()); } public function doneAction(Request $request) { $token = $this->get(''payum.security.http_request_verifier'')->verify($request); $payment = $this->get(''payum'')->getPayment($token->getPaymentName()); // you can invalidate the token. The url could not be requested any more. // $this->get(''payum.security.http_request_verifier'')->invalidate($token); // Once you have token you can get the model from the storage directly. //$identity = $token->getDetails(); //$order = $payum->getStorage($identity->getClass())->find($identity); // or Payum can fetch the model for you while executing a request (Preferred). $payment->execute($status = new GetHumanStatus($token)); $order = $status->getFirstModel(); // you have order and payment status // so you can do whatever you want for example you can just print status and payment details. return new JsonResponse(array( ''status'' => $status->getValue(), ''response'' => array( ''order'' => $order->getTotalAmount(), ''currency_code'' => $order->getCurrencyCode(), ''details'' => $order->getDetails(), ), )); } /** * @return RegistryInterface */ protected function getPayum() { return $this->get(''payum''); } /** * @return GenericTokenFactoryInterface */ protected function getTokenFactory() { return $this->get(''payum.security.token_factory''); } }

Esta es mi Entidad de Orders

<?php namespace ClickTeck/featuresBundle/Entity; use Doctrine/ORM/Mapping as ORM; use ClickTeck/featuresBundle/Model/Orders as BasePaymentDetails; /** * Orders */ class Orders extends BasePaymentDetails { /** * @var integer */ protected $id; private $number; private $description; private $client_email; private $client_id; private $total_amount; private $currency_code; protected $details; /** * Get id * * @return integer */ public function getId() { return $this->id; } /** * Set number * * @param integer $number * @return Orders */ public function setNumber($number) { $this->number = $number; return $this; } /** * Get number * * @return integer */ public function getNumber() { return $this->number; } /** * Set description * * @param string $description * @return Orders */ public function setDescription($description) { $this->description = $description; return $this; } /** * Get description * * @return string */ public function getDescription() { return $this->description; } /** * Set client_email * * @param string $clientEmail * @return Orders */ public function setClientEmail($clientEmail) { $this->client_email = $clientEmail; return $this; } /** * Get client_email * * @return string */ public function getClientEmail() { return $this->client_email; } /** * Set client_id * * @param string $clientId * @return Orders */ public function setClientId($clientId) { $this->client_id = $clientId; return $this; } /** * Get client_id * * @return string */ public function getClientId() { return $this->client_id; } /** * Set total_amount * * @param float $totalAmount * @return Orders */ public function setTotalAmount($totalAmount) { $this->total_amount = $totalAmount; return $this; } /** * Get total_amount * * @return float */ public function getTotalAmount() { return $this->total_amount; } /** * Set currency_code * * @param string $currencyCode * @return Orders */ public function setCurrencyCode($currencyCode) { $this->currency_code = $currencyCode; return $this; } /** * Get currency_code * * @return string */ public function getCurrencyCode() { return $this->currency_code; } /** * Set details * * @param string $details * @return Orders */ public function setDetails($details) { $this->details = $details; return $this; } /** * Get details * * @return string */ public function getDetails() { return $this->details; } }

Esta es mi entidad PaymentToken

<?php namespace ClickTeck/featuresBundle/Entity; use Doctrine/ORM/Mapping as ORM; use Payum/Core/Model/Token; /** * PaymentToken */ class PaymentToken extends Token { }

Este es mi modelo de Orders

<?php namespace ClickTeck/featuresBundle/Model; use Payum/Core/Model/ArrayObject; class Orders extends ArrayObject { protected $id; /** * @return int */ public function getId() { return $this->id; } }

  1. Ahora cuando llamo a la acción preparePaypalExpressCheckoutPaymentAction por ruta
  2. Me redireccionan para hacer el pago
  3. Puedo ver la respuesta en doneAction

Biblioteca muy ordenada. Me tomó un tiempo resolverlo y estoy contento de que funcione ahora. Estoy seguro de que tengo mucho más para aprender sobre Payum y espero que alguien pueda confirmar si esta es la manera correcta :)

Estoy trabajando con Symfony 2.6 y estoy intentando configurar PayumBundle (paypal express checkout) y estoy obteniendo un error

InvalidConfigurationException in BaseNode.php line 313: Invalid configuration for path "payum.security.token_storage": The storage entry must be a valid model class. It is set Acme/featuresBundle/Entity/PaymentToken

Estoy siguiendo los pasos mencionados en documetation allí

Así es como se ve mi config.yml

doctrine: orm: auto_generate_proxy_classes: "%kernel.debug%" entity_managers: default: auto_mapping: true mappings: payum: is_bundle: false type: xml dir: %kernel.root_dir%/../vendor/payum/core/Payum/Core/Bridge/Doctrine/Resources/mapping prefix: Payum/Core/Model payum: security: token_storage: Acme/featuresBundle/Entity/PaymentToken: { doctrine: orm } storages: Acme/featuresBundle/Entity/PaymentDetails: { doctrine: orm } contexts: paypal: paypal_express_checkout_nvp: username: ''asdasd'' password: ''adsasd'' signature: ''asdasdasd'' sandbox: true

Este es mi Entity PaymentToken

namespace Acme/featuresBundle/Entity; use Doctrine/ORM/Mapping as ORM; use Payum/Core/Model/Token; /** * @ORM/Table * @ORM/Entity */ class PaymentToken extends Token { }

Y esto es Entity PaymentDetails

namespace Acme/featuresBundle/Entity; use Doctrine/ORM/Mapping as ORM; use Payum/Core/Model/Order as BaseOrder; /** * @ORM/Table * @ORM/Entity */ class PaymentDetails extends BaseOrder { /** * @ORM/Column(name="id", type="integer") * @ORM/Id * @ORM/GeneratedValue(strategy="IDENTITY") * * @var integer $id */ protected $id; }

He revisado una gran cantidad de documentación en línea y otras publicaciones como esta, pero no entiendo por qué recibo este error.

The storage entry must be a valid model class. It is set Acme/featuresBundle/Entity/PaymentToken

Ni siquiera puedo acceder al controlador, así que algo me dice que es la configuración config.yml de Payum que no está configurada correctamente. He revisado la documentación una y otra vez y no puedo encontrar qué estoy haciendo mal.

Realmente agradeceré cualquier ayuda para pasar este error.