diff --git a/src/Payum/Server/Api/ApiControllerProvider.php b/src/Payum/Server/Api/ApiControllerProvider.php index fbd63a6..5c673bc 100644 --- a/src/Payum/Server/Api/ApiControllerProvider.php +++ b/src/Payum/Server/Api/ApiControllerProvider.php @@ -1,20 +1,14 @@ payum = $payum; $this->formFactory = $formFactory; $this->formToJsonConverter = $formToJsonConverter; $this->paymentToJsonConverter = $paymentToJsonConverter; $this->urlGenerator = $urlGenerator; + $this->gatewayConfigStorage = $gatewayConfigStorage; } /** @@ -87,42 +94,20 @@ public function createAction($content, Request $request) /** @var Payment $payment */ $payment = $form->getData(); $payment->setId(Random::generateToken()); - - $storage = $this->payum->getStorage($payment); - $storage->update($payment); - $payment->setNumber($payment->getNumber() ?: date('Ymd-'.mt_rand(10000, 99999))); - $storage->update($payment); - - // TODO - $payment->setValue('links', 'done', 'http://dev.payum-server.com/client/index.html'); - - $payment->setValue('links', 'self', $this->urlGenerator->generate('payment_get', ['id' => $payment->getId()], true)); - - $token = $this->payum->getTokenFactory()->createAuthorizeToken($payment->getGatewayName(), $payment, $payment->getValue('links', 'done'), [ - 'payum_token' => null, - 'payment' => $payment->getId(), - ]); - $payment->setValue('links', 'authorize', $token->getTargetUrl()); - - $token = $this->payum->getTokenFactory()->createCaptureToken($payment->getGatewayName(), $payment, $payment->getValue('links', 'done'), [ - 'payum_token' => null, - 'payment' => $payment->getId(), - ]); - $payment->setValue('links', 'capture', $token->getTargetUrl()); - - $token = $this->payum->getTokenFactory()->createNotifyToken($payment->getGatewayName(), $payment); - $payment->setValue('links', 'notify', $token->getTargetUrl()); + if ($payment->getGatewayConfig()->getGatewayName()) { + $payment->setGatewayConfig($this->gatewayConfigStorage->find($payment->getGatewayConfig()->getGatewayName())); + } - $storage->update($payment); + $this->payum->getStorage($payment)->update($payment); return new JsonResponse( array( 'payment' => $this->paymentToJsonConverter->convert($payment), ), 201, - array('Location' => $payment->getValue('links', 'self')) + array('Location' => $this->urlGenerator->generate('payment_get', ['id' => $payment->getId()], true)) ); } @@ -148,8 +133,11 @@ public function updateAction($content, Request $request) /** @var Payment $payment */ $payment = $form->getData(); - $storage = $this->payum->getStorage($payment); - $storage->update($payment); + if ($payment->getGatewayConfig()->getGatewayName()) { + $payment->setGatewayConfig($this->gatewayConfigStorage->find($payment->getGatewayConfig()->getGatewayName())); + } + + $this->payum->getStorage($payment)->update($payment); return new JsonResponse(array( 'payment' => $this->paymentToJsonConverter->convert($payment), diff --git a/src/Payum/Server/Api/View/PaymentToJsonConverter.php b/src/Payum/Server/Api/View/PaymentToJsonConverter.php index 63fd705..17140a5 100644 --- a/src/Payum/Server/Api/View/PaymentToJsonConverter.php +++ b/src/Payum/Server/Api/View/PaymentToJsonConverter.php @@ -2,7 +2,6 @@ namespace Payum\Server\Api\View; use Payum\Core\Registry\GatewayRegistryInterface; -use Payum\Core\Request\GetHumanStatus; use Payum\Server\Model\Payment; class PaymentToJsonConverter @@ -12,12 +11,19 @@ class PaymentToJsonConverter */ private $registry; + /** + * @var GatewayConfigToJsonConverter + */ + private $gatewayConfigToJsonConverter; + /** * @param GatewayRegistryInterface $registry + * @param GatewayConfigToJsonConverter $gatewayConfigToJsonConverter */ - public function __construct(GatewayRegistryInterface $registry) + public function __construct(GatewayRegistryInterface $registry, GatewayConfigToJsonConverter $gatewayConfigToJsonConverter) { $this->registry = $registry; + $this->gatewayConfigToJsonConverter = $gatewayConfigToJsonConverter; } /** @@ -27,10 +33,9 @@ public function __construct(GatewayRegistryInterface $registry) */ public function convert(Payment $payment) { - $normalizedPayment = [ + return [ 'id' => $payment->getId(), 'status' => $payment->getStatus(), - 'gatewayName' => $payment->getGatewayName(), 'number' => $payment->getNumber(), 'totalAmount' => $payment->getTotalAmount(), 'currencyCode' => $payment->getCurrencyCode(), @@ -38,15 +43,7 @@ public function convert(Payment $payment) 'clientId' => $payment->getClientId(), 'description' => $payment->getDescription(), 'details' => $payment->getDetails(), - '_links' => [], + 'gateway' => $this->gatewayConfigToJsonConverter->convert($payment->getGatewayConfig()), ]; - - foreach (['self', 'done', 'capture', 'authorize', 'notify'] as $name) { - if ($link = $payment->getValue('links', $name)) { - $normalizedPayment['_links'][$name] = ['href' => $link]; - } - } - - return $normalizedPayment; } } diff --git a/src/Payum/Server/Form/Type/CreatePaymentGatewayConfigType.php b/src/Payum/Server/Form/Type/CreatePaymentGatewayConfigType.php new file mode 100644 index 0000000..9548ad8 --- /dev/null +++ b/src/Payum/Server/Form/Type/CreatePaymentGatewayConfigType.php @@ -0,0 +1,42 @@ +add('gatewayName', 'payum_gateways_choice', [ + 'required' => false, + 'empty_value' => '', + ]) + ; + } + + /** + * {@inheritDoc} + */ + public function setDefaultOptions(OptionsResolverInterface $resolver) + { + $resolver->setDefaults(array( + 'data_class' => GatewayConfig::class, + 'allow_extra_fields' => true, + )); + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return 'create_payment_gateway_config'; + } +} \ No newline at end of file diff --git a/src/Payum/Server/Form/Type/CreatePaymentType.php b/src/Payum/Server/Form/Type/CreatePaymentType.php index 81fedf7..9b45347 100644 --- a/src/Payum/Server/Form/Type/CreatePaymentType.php +++ b/src/Payum/Server/Form/Type/CreatePaymentType.php @@ -19,10 +19,7 @@ class CreatePaymentType extends AbstractType public function buildForm(FormBuilderInterface $builder, array $options) { $builder - ->add('gatewayName', 'payum_gateways_choice', [ - 'required' => false, - 'empty_value' => '', - ]) + ->add('gatewayConfig', 'create_payment_gateway_config') ->add('totalAmount', 'number', array( 'label' => 'Amount', 'constraints' => array(new NotBlank(), new Type(['type' => 'numeric'])) diff --git a/src/Payum/Server/Model/Payment.php b/src/Payum/Server/Model/Payment.php index 6a1970a..f0f791a 100644 --- a/src/Payum/Server/Model/Payment.php +++ b/src/Payum/Server/Model/Payment.php @@ -180,30 +180,34 @@ public function setCreditCard(CreditCardInterface $creditCard) } /** - * @return string + * @return Payer */ - public function getGatewayName() + public function getPayer() { - return $this->getSelfValue('gatewayName'); + if (false == $this->getValue('self', 'payer')) { + $this->setObject('self', 'payer', new Payer()); + } + + return $this->getObject('self', 'payer', Payer::class); } /** - * @param string $gatewayName + * @return GatewayConfig */ - public function setGatewayName($gatewayName) + public function getGatewayConfig() { - $this->setSelfValue('gatewayName', $gatewayName); + if (false == $this->getValue('self', 'gatewayConfig')) { + $this->setObject('self', 'gatewayConfig', new GatewayConfig()); + } + + return $this->getObject('self', 'gatewayConfig', GatewayConfig::class); } /** - * @return Payer + * @param GatewayConfig $gatewayConfig */ - public function getPayer() + public function setGatewayConfig(GatewayConfig $gatewayConfig) { - if (false == $this->getValue('self', 'payer')) { - $this->setObject('self', 'payer', new Payer()); - } - - return $this->getObject('self', 'payer', Payer::class); + $this->setObject('self', 'gatewayConfig', $gatewayConfig); } -} \ No newline at end of file +} diff --git a/src/Payum/Server/Model/SecurityToken.php b/src/Payum/Server/Model/SecurityToken.php index b2bcf89..c1c48b8 100644 --- a/src/Payum/Server/Model/SecurityToken.php +++ b/src/Payum/Server/Model/SecurityToken.php @@ -119,7 +119,7 @@ public function getGatewayName() { $payment = $this->getPayment(); - return $payment ? $payment->getGatewayName() : null; + return $payment ? $payment->getGatewayConfig()->getGatewayName() : null; } /** diff --git a/src/Payum/Server/ServiceProvider.php b/src/Payum/Server/ServiceProvider.php index 2935411..d219911 100644 --- a/src/Payum/Server/ServiceProvider.php +++ b/src/Payum/Server/ServiceProvider.php @@ -5,22 +5,19 @@ use Doctrine\MongoDB\Database; use Payum\Core\Bridge\Symfony\Reply\HttpResponse; use Payum\Core\Bridge\Twig\TwigFactory; -use Payum\Core\Exception\LogicException; use Payum\Core\Model\GatewayConfigInterface; use Payum\Core\Payum; use Payum\Core\PayumBuilder; use Payum\Core\Reply\ReplyInterface; -use Payum\Core\Security\TokenInterface; use Payum\Core\Storage\StorageInterface; use Payum\Server\Action\AuthorizePaymentAction; use Payum\Server\Action\CapturePaymentAction; use Payum\Server\Action\ExecuteSameRequestWithPaymentDetailsAction; use Payum\Server\Action\ObtainMissingDetailsAction; use Payum\Server\Action\ObtainMissingDetailsForBe2BillAction; -use Payum\Server\Controller\AuthorizeController; -use Payum\Server\Controller\CaptureController; use Payum\Server\Extension\UpdatePaymentStatusExtension; use Payum\Server\Form\Type\ChooseGatewayType; +use Payum\Server\Form\Type\CreatePaymentGatewayConfigType; use Payum\Server\Form\Type\CreatePaymentType; use Payum\Server\Form\Type\CreateTokenType; use Payum\Server\Form\Type\UpdatePaymentType; @@ -35,7 +32,6 @@ use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\Validator\Constraints\NotBlank; class ServiceProvider implements ServiceProviderInterface { @@ -102,6 +98,7 @@ public function register(SilexApplication $app) $app['form.types'] = $app->share($app->extend('form.types', function ($types) use ($app) { $types[] = new CreatePaymentType(); $types[] = new UpdatePaymentType(); + $types[] = new CreatePaymentGatewayConfigType(); $types[] = new CreateTokenType(); $types[] = new ChooseGatewayType(); @@ -156,12 +153,16 @@ public function register(SilexApplication $app) /** @var FormFactoryInterface $formFactory */ $formFactory = $app['form.factory']; - $form = $formFactory->createNamed('', 'choose_gateway', $payment, [ + $form = $formFactory->createNamed('', 'choose_gateway', [ 'action' => $token->getTargetUrl(), ]); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { + /** @var StorageInterface $gatewayConfigStorage */ + $gatewayConfigStorage = $app['payum.gateway_config_storage']; + $payment->setGatewayConfig($gatewayConfigStorage->find($form->getData()['gatewayName'])); + $payum->getStorage($payment)->update($payment); } else { /** @var \Twig_Environment $twig */ diff --git a/tests/Payum/Server/Tests/Functional/Api/Controller/PaymentControllerTest.php b/tests/Payum/Server/Tests/Functional/Api/Controller/PaymentControllerTest.php index 19f6ce7..001942b 100644 --- a/tests/Payum/Server/Tests/Functional/Api/Controller/PaymentControllerTest.php +++ b/tests/Payum/Server/Tests/Functional/Api/Controller/PaymentControllerTest.php @@ -1,7 +1,8 @@ assertEquals(123, $content->payment->totalAmount); } + /** + * @test + */ + public function shouldUpdateGatewayConfigOnPaymentUpdate() + { + /** @var StorageInterface $gatewayConfigStorage */ + $gatewayConfigStorage = $this->app['payum.gateway_config_storage']; + + /** @var GatewayConfig $gatewayConfig */ + $gatewayConfig = $gatewayConfigStorage->create(); + $gatewayConfig->setFactoryName('offline'); + $gatewayConfig->setGatewayName('firstOffline'); + $gatewayConfig->setConfig(['foo' => 'foo']); + $gatewayConfigStorage->update($gatewayConfig); + + $payment = new Payment(); + $payment->setId(uniqid()); + $payment->setTotalAmount(123); + $payment->setClientEmail('theClientEmail@example.com'); + + $storage = $this->app['payum']->getStorage($payment); + $storage->update($payment); + + //guard + $this->getClient()->putJson('/payments/'.$payment->getId(), [ + 'totalAmount' => 123, + 'currencyCode' => 'USD', + 'clientEmail' => 'theOtherClientEmail@example.com', + 'clientId' => 'theClientId', + 'gatewayConfig' => [ + 'gatewayName' => 'firstOffline', + ], + ]); + + $this->assertClientResponseStatus(200); + $this->assertClientResponseContentJson(); + + $content = $this->getClientResponseJsonContent(); + + $this->assertObjectHasAttribute('payment', $content); + $this->assertObjectHasAttribute('gateway', $content->payment); + + $this->assertObjectHasAttribute('gatewayName', $content->payment->gateway); + $this->assertEquals('firstOffline', $content->payment->gateway->gatewayName); + + $this->assertObjectHasAttribute('factoryName', $content->payment->gateway); + $this->assertEquals('offline', $content->payment->gateway->factoryName); + + $this->assertObjectHasAttribute('config', $content->payment->gateway); + $this->assertEquals(['foo' => 'f**'], (array) $content->payment->gateway->config); + } + /** * @test */ @@ -119,36 +172,46 @@ public function shouldAllowCreatePayment() $this->assertStringStartsWith('http://localhost/payments/', $this->getClient()->getResponse()->headers->get('Location')); } -// /** -// * @test -// */ -// public function shouldAllowGetPaymentLinks() -// { -// $this->getClient()->postJson('/payments', [ -// 'totalAmount' => 123, -// 'currencyCode' => 'USD', -// 'clientEmail' => 'foo@example.com', -// 'clientId' => 'theClientId', -// 'gatewayName' => 'stripe_js', -// 'afterUrl' => 'http://example.com', -// ]); -// -// $this->assertClientResponseStatus(201); -// $this->assertClientResponseContentJson(); -// -// //guard -// $this->assertTrue($this->getClient()->getResponse()->headers->has('Location')); -// -// $this->getClient()->request('GET', $this->getClient()->getResponse()->headers->get('Location')); -// -// $this->assertClientResponseStatus(200); -// $this->assertClientResponseContentJson(); -// -// $content = $this->getClientResponseJsonContent(); -// -// $this->assertObjectHasAttribute('payment', $content); -// -// $this->assertObjectHasAttribute('_links', $content->payment); -// $this->assertObjectHasAttribute('self', $content->payment->_links); -// } + /** + * @test + */ + public function shouldUpdateGatewayConfigOnPaymentCreate() + { + /** @var StorageInterface $gatewayConfigStorage */ + $gatewayConfigStorage = $this->app['payum.gateway_config_storage']; + + /** @var GatewayConfig $gatewayConfig */ + $gatewayConfig = $gatewayConfigStorage->create(); + $gatewayConfig->setFactoryName('offline'); + $gatewayConfig->setGatewayName('firstOffline'); + $gatewayConfig->setConfig(['foo' => 'foo']); + $gatewayConfigStorage->update($gatewayConfig); + + $this->getClient()->postJson('/payments/', [ + 'totalAmount' => 123, + 'currencyCode' => 'USD', + 'clientEmail' => 'foo@example.com', + 'clientId' => 'theClientId', + 'gatewayConfig' => [ + 'gatewayName' => 'firstOffline', + ], + ]); + + $this->assertClientResponseStatus(201); + $this->assertClientResponseContentJson(); + + $content = $this->getClientResponseJsonContent(); + + $this->assertObjectHasAttribute('payment', $content); + $this->assertObjectHasAttribute('gateway', $content->payment); + + $this->assertObjectHasAttribute('gatewayName', $content->payment->gateway); + $this->assertEquals('firstOffline', $content->payment->gateway->gatewayName); + + $this->assertObjectHasAttribute('factoryName', $content->payment->gateway); + $this->assertEquals('offline', $content->payment->gateway->factoryName); + + $this->assertObjectHasAttribute('config', $content->payment->gateway); + $this->assertEquals(['foo' => 'f**'], (array) $content->payment->gateway->config); + } } diff --git a/tests/Payum/Server/Tests/Functional/Api/Controller/PaymentMetaControllerTest.php b/tests/Payum/Server/Tests/Functional/Api/Controller/PaymentMetaControllerTest.php index 9d769a8..aa58309 100644 --- a/tests/Payum/Server/Tests/Functional/Api/Controller/PaymentMetaControllerTest.php +++ b/tests/Payum/Server/Tests/Functional/Api/Controller/PaymentMetaControllerTest.php @@ -11,7 +11,7 @@ class PaymentMetaControllerTest extends ClientTestCase /** * @test */ - public function shouldAllowGetPayment() + public function shouldAllowGetPaymentMeta() { $this->getClient()->request('GET', '/payments/meta'); @@ -24,8 +24,36 @@ public function shouldAllowGetPayment() $this->assertObjectHasAttribute('totalAmount', $content->meta); $this->assertObjectHasAttribute('currencyCode', $content->meta); - $this->assertObjectHasAttribute('gatewayName', $content->meta); $this->assertObjectHasAttribute('clientEmail', $content->meta); $this->assertObjectHasAttribute('clientId', $content->meta); } + + /** + * @test + */ + public function shouldAllowGetPaymentGatewayConfigMeta() + { + $this->getClient()->request('GET', '/payments/meta'); + + $this->assertClientResponseStatus(200); + $this->assertClientResponseContentJson(); + + $content = $this->getClientResponseJsonContent(); + + $this->assertObjectHasAttribute('meta', $content); + + $this->assertObjectHasAttribute('gatewayConfig', $content->meta); + + $gatewayConfigMeta = $content->meta->gatewayConfig; + $this->assertObjectHasAttribute('type', $gatewayConfigMeta); + $this->assertEquals('form', $gatewayConfigMeta->type); + + $this->assertObjectHasAttribute('children', $gatewayConfigMeta); + $this->assertObjectHasAttribute('gatewayName', $gatewayConfigMeta->children); + + $this->assertObjectHasAttribute('type', $gatewayConfigMeta->children->gatewayName); + $this->assertEquals('choice', $gatewayConfigMeta->children->gatewayName->type); + } + + } diff --git a/tests/Payum/Server/Tests/Functional/Api/Controller/TokenControllerTest.php b/tests/Payum/Server/Tests/Functional/Api/Controller/TokenControllerTest.php index c8a96be..d9aaee3 100644 --- a/tests/Payum/Server/Tests/Functional/Api/Controller/TokenControllerTest.php +++ b/tests/Payum/Server/Tests/Functional/Api/Controller/TokenControllerTest.php @@ -47,7 +47,7 @@ public function testShouldAllowCreateCaptureToken() /** @var Payment $payment */ $payment = $store->create(); - $payment->setGatewayName('offline'); + $payment->getGatewayConfig()->setGatewayName('offline'); $payment->setId(uniqid()); $store->update($payment); @@ -96,7 +96,7 @@ public function testShouldAllowCreateAuthorizeToken() /** @var Payment $payment */ $payment = $store->create(); - $payment->setGatewayName('offline'); + $payment->getGatewayConfig()->setGatewayName('offline'); $payment->setId(uniqid()); $store->update($payment); diff --git a/tests/Payum/Server/Tests/Functional/Controller/AuthorizeControllerTest.php b/tests/Payum/Server/Tests/Functional/Controller/AuthorizeControllerTest.php index 8e3c34c..55a21e1 100644 --- a/tests/Payum/Server/Tests/Functional/Controller/AuthorizeControllerTest.php +++ b/tests/Payum/Server/Tests/Functional/Controller/AuthorizeControllerTest.php @@ -39,7 +39,7 @@ public function testShouldAllowChooseGateway() /** @var Payment $payment */ $payment = $store->create(); - $payment->setGatewayName(null); + $payment->getGatewayConfig()->setGatewayName(null); $payment->setId(uniqid()); $store->update($payment); diff --git a/tests/Payum/Server/Tests/Functional/Controller/CaptureControllerTest.php b/tests/Payum/Server/Tests/Functional/Controller/CaptureControllerTest.php index 5b1b53f..dd3cd1a 100644 --- a/tests/Payum/Server/Tests/Functional/Controller/CaptureControllerTest.php +++ b/tests/Payum/Server/Tests/Functional/Controller/CaptureControllerTest.php @@ -39,12 +39,12 @@ public function testShouldAllowChooseGateway() /** @var Payment $payment */ $payment = $store->create(); - $payment->setGatewayName(null); + $payment->getGatewayConfig()->setGatewayName(null); $payment->setId(uniqid()); $store->update($payment); - $token = $payum->getTokenFactory()->createCaptureToken('', $payment, 'http://localhost'); + $token = $payum->getTokenFactory()->createCaptureToken('itDoesNotMatter', $payment, 'http://localhost'); $crawler = $this->getClient()->request('GET', $token->getTargetUrl()); @@ -87,7 +87,7 @@ public function testShouldObtainMissingDetails() /** @var Payment $payment */ $payment = $store->create(); - $payment->setGatewayName('be2bill'); + $payment->getGatewayConfig()->setGatewayName('be2bill'); $payment->setId(uniqid()); $store->update($payment); diff --git a/tests/Payum/Server/Tests/Functional/Model/PaymentTest.php b/tests/Payum/Server/Tests/Functional/Model/PaymentTest.php index 05a1f96..325bd81 100644 --- a/tests/Payum/Server/Tests/Functional/Model/PaymentTest.php +++ b/tests/Payum/Server/Tests/Functional/Model/PaymentTest.php @@ -30,7 +30,7 @@ public function testShouldAllowPersistPaymentToMongo() $payment->setCurrencyCode('USD'); $payment->setDescription('theDesc'); $payment->setNumber('theNumber'); - $payment->setGatewayName('theGatewayName'); + $payment->getGatewayConfig()->setGatewayName('theGatewayName'); $storage->update($payment); @@ -45,6 +45,7 @@ public function testShouldAllowPersistPaymentToMongo() $this->assertEquals('theClientEmail', $foundPayment->getClientEmail()); $this->assertEquals('theClientId', $foundPayment->getClientId()); + $this->assertEquals('theGatewayName', $foundPayment->getGatewayConfig()->getGatewayName()); } public function testShouldAllowStorePaymentsDetails() diff --git a/tests/Payum/Server/Tests/Functional/Model/SecurityTokenTest.php b/tests/Payum/Server/Tests/Functional/Model/SecurityTokenTest.php index f636380..021d444 100644 --- a/tests/Payum/Server/Tests/Functional/Model/SecurityTokenTest.php +++ b/tests/Payum/Server/Tests/Functional/Model/SecurityTokenTest.php @@ -86,7 +86,7 @@ public function testShouldGetsGatewayNameFromUnderlyingPaymentModel() $payment = $paymentStorage->create(); $payment->setId(uniqid()); - $payment->setGatewayName('theGatewayName'); + $payment->getGatewayConfig()->setGatewayName('theGatewayName'); $paymentStorage->update($payment);