From ef3bfe84a83df26a93d0f939baf7f342a71146e1 Mon Sep 17 00:00:00 2001 From: Jacob Tobiasz Date: Tue, 10 Sep 2024 19:35:56 +0200 Subject: [PATCH] Refactoring creating a transaction and add handling a credit card transactions --- config/services/payum/action.php | 26 ++- config/services/payum/factory.php | 11 + config/services/tpay.php | 30 +++ src/Form/Type/TpayPaymentDetailsType.php | 11 + .../Api/AbstractCreateTransactionAction.php | 46 +++++ .../Api/CreateCardTransactionAction.php | 68 +++++++ .../CreateRedirectBasedTransactionAction.php | 67 ++++++ .../Action/Api/CreateTransactionAction.php | 90 --------- src/Payum/Action/Api/PayWithCardAction.php | 43 ++++ src/Payum/Action/CaptureAction.php | 7 +- .../Factory/Token/NotifyTokenFactory.php | 30 +++ .../Token/NotifyTokenFactoryInterface.php | 13 ++ src/Payum/Request/Api/PayWithCard.php | 11 + .../CreateCardPaymentPayloadFactory.php | 27 +++ ...eateCardPaymentPayloadFactoryInterface.php | 15 ++ ...eateRedirectBasedPaymentPayloadFactory.php | 53 +++++ ...ectBasedPaymentPayloadFactoryInterface.php | 15 ++ templates/shop/cart/complete/_card.html.twig | 48 ++--- .../Api/CreateCardTransactionActionTest.php | 178 ++++++++++++++++ ...eateRedirectBasedTransactionActionTest.php | 191 ++++++++++++++++++ .../Api/CreateTransactionActionTest.php | 151 -------------- .../Action/Api/PayWithCardActionTest.php | 149 ++++++++++++++ tests/Unit/Payum/Action/CaptureActionTest.php | 7 +- .../Unit/Payum/Action/GetStatusActionTest.php | 2 + .../Factory/Token/NotifyTokenFactoryTest.php | 64 ++++++ .../CreateCardPaymentPayloadFactoryTest.php | 46 +++++ ...RedirectBasedPaymentPayloadFactoryTest.php | 142 +++++++++++++ 27 files changed, 1259 insertions(+), 282 deletions(-) create mode 100644 config/services/tpay.php create mode 100644 src/Payum/Action/Api/AbstractCreateTransactionAction.php create mode 100644 src/Payum/Action/Api/CreateCardTransactionAction.php create mode 100644 src/Payum/Action/Api/CreateRedirectBasedTransactionAction.php delete mode 100644 src/Payum/Action/Api/CreateTransactionAction.php create mode 100644 src/Payum/Action/Api/PayWithCardAction.php create mode 100644 src/Payum/Factory/Token/NotifyTokenFactory.php create mode 100644 src/Payum/Factory/Token/NotifyTokenFactoryInterface.php create mode 100644 src/Payum/Request/Api/PayWithCard.php create mode 100644 src/Tpay/Factory/CreateCardPaymentPayloadFactory.php create mode 100644 src/Tpay/Factory/CreateCardPaymentPayloadFactoryInterface.php create mode 100644 src/Tpay/Factory/CreateRedirectBasedPaymentPayloadFactory.php create mode 100644 src/Tpay/Factory/CreateRedirectBasedPaymentPayloadFactoryInterface.php create mode 100644 tests/Unit/Payum/Action/Api/CreateCardTransactionActionTest.php create mode 100644 tests/Unit/Payum/Action/Api/CreateRedirectBasedTransactionActionTest.php delete mode 100644 tests/Unit/Payum/Action/Api/CreateTransactionActionTest.php create mode 100644 tests/Unit/Payum/Action/Api/PayWithCardActionTest.php create mode 100644 tests/Unit/Payum/Factory/Token/NotifyTokenFactoryTest.php create mode 100644 tests/Unit/Tpay/Factory/CreateCardPaymentPayloadFactoryTest.php create mode 100644 tests/Unit/Tpay/Factory/CreateRedirectBasedPaymentPayloadFactoryTest.php diff --git a/config/services/payum/action.php b/config/services/payum/action.php index def41c28..49e433d6 100644 --- a/config/services/payum/action.php +++ b/config/services/payum/action.php @@ -4,8 +4,10 @@ namespace Symfony\Component\DependencyInjection\Loader\Configurator; -use CommerceWeavers\SyliusTpayPlugin\Payum\Action\Api\CreateTransactionAction; +use CommerceWeavers\SyliusTpayPlugin\Payum\Action\Api\CreateCardTransactionAction; +use CommerceWeavers\SyliusTpayPlugin\Payum\Action\Api\CreateRedirectBasedTransactionAction; use CommerceWeavers\SyliusTpayPlugin\Payum\Action\Api\NotifyAction; +use CommerceWeavers\SyliusTpayPlugin\Payum\Action\Api\PayWithCardAction; use CommerceWeavers\SyliusTpayPlugin\Payum\Action\CaptureAction; use CommerceWeavers\SyliusTpayPlugin\Payum\Action\GetStatusAction; use CommerceWeavers\SyliusTpayPlugin\Payum\Action\RefundAction; @@ -24,20 +26,32 @@ ->tag('payum.action', ['factory' => TpayGatewayFactory::NAME, 'alias' => 'cw.tpay.capture']) ; - $services->set(CreateTransactionAction::class) + $services->set(CreateCardTransactionAction::class) ->args([ service('router'), - param('commerce_weavers_tpay.payum.create_transaction.success_route'), - param('commerce_weavers_tpay.payum.create_transaction.error_route'), - param('commerce_weavers_tpay.payum.create_transaction.notify_route'), + service('commerce_weavers_tpay.tpay.factory.create_card_payment_payload'), + service('commerce_weavers_tpay.payum.factory.token.notify'), ]) - ->tag('payum.action', ['factory' => TpayGatewayFactory::NAME, 'alias' => 'cw.tpay.create_transaction']) + ->tag('payum.action', ['factory' => TpayGatewayFactory::NAME, 'alias' => 'cw.tpay.create_card_transaction']) + ; + + $services->set(CreateRedirectBasedTransactionAction::class) + ->args([ + service('router'), + service('commerce_weavers_tpay.tpay.factory.create_redirect_based_payment_payload'), + service('commerce_weavers_tpay.payum.factory.token.notify'), + ]) + ->tag('payum.action', ['factory' => TpayGatewayFactory::NAME, 'alias' => 'cw.tpay.create_redirect_based_transaction']) ; $services->set(NotifyAction::class) ->tag('payum.action', ['factory' => TpayGatewayFactory::NAME, 'alias' => 'cw.tpay.notify']) ; + $services->set(PayWithCardAction::class) + ->tag('payum.action', ['factory' => TpayGatewayFactory::NAME, 'alias' => 'cw.tpay.pay_with_card']) + ; + $services->set(GetStatusAction::class) ->tag('payum.action', ['factory' => TpayGatewayFactory::NAME, 'alias' => 'cw.tpay.get_status']) ; diff --git a/config/services/payum/factory.php b/config/services/payum/factory.php index bc2bb30e..14d23d5f 100644 --- a/config/services/payum/factory.php +++ b/config/services/payum/factory.php @@ -8,6 +8,8 @@ use CommerceWeavers\SyliusTpayPlugin\Payum\Factory\CreateTransactionFactoryInterface; use CommerceWeavers\SyliusTpayPlugin\Payum\Factory\NotifyFactory; use CommerceWeavers\SyliusTpayPlugin\Payum\Factory\NotifyFactoryInterface; +use CommerceWeavers\SyliusTpayPlugin\Payum\Factory\Token\NotifyTokenFactory; +use CommerceWeavers\SyliusTpayPlugin\Payum\Factory\Token\NotifyTokenFactoryInterface; use CommerceWeavers\SyliusTpayPlugin\Payum\Factory\TpayGatewayFactory; use Payum\Core\Bridge\Symfony\Builder\GatewayFactoryBuilder; @@ -28,4 +30,13 @@ $services->set('commerce_weavers.tpay.payum.factory.create_transaction', CreateTransactionFactory::class) ->alias(CreateTransactionFactoryInterface::class, 'commerce_weavers.tpay.payum.factory.create_transaction') ; + + $services->set('commerce_weavers_tpay.payum.factory.token.notify', NotifyTokenFactory::class) + ->args([ + service('payum'), + service('router'), + param('commerce_weavers_tpay.payum.create_transaction.notify_route'), + ]) + ->alias(NotifyTokenFactoryInterface::class, 'commerce_weavers_tpay.payum.factory.token.notify') + ; }; diff --git a/config/services/tpay.php b/config/services/tpay.php new file mode 100644 index 00000000..964cca6b --- /dev/null +++ b/config/services/tpay.php @@ -0,0 +1,30 @@ +services(); + + $services->set('commerce_weavers_tpay.tpay.factory.create_card_payment_payload', CreateCardPaymentPayloadFactory::class) + ->args([ + service('commerce_weavers_tpay.tpay.factory.create_redirect_based_payment_payload'), + ]) + ->alias(CreateCardPaymentPayloadFactoryInterface::class, 'commerce_weavers_tpay.factory.create_card_payment_payload') + ; + + $services->set('commerce_weavers_tpay.tpay.factory.create_redirect_based_payment_payload', CreateRedirectBasedPaymentPayloadFactory::class) + ->args([ + service('router'), + param('commerce_weavers_tpay.payum.create_transaction.success_route'), + param('commerce_weavers_tpay.payum.create_transaction.error_route'), + ]) + ->alias(CreateRedirectBasedPaymentPayloadFactoryInterface::class, 'commerce_weavers_tpay.factory.create_redirect_based_payment_payload') + ; +}; diff --git a/src/Form/Type/TpayPaymentDetailsType.php b/src/Form/Type/TpayPaymentDetailsType.php index b2cbc9ac..ff57ca1a 100644 --- a/src/Form/Type/TpayPaymentDetailsType.php +++ b/src/Form/Type/TpayPaymentDetailsType.php @@ -6,6 +6,8 @@ use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; +use Symfony\Component\Form\FormEvent; +use Symfony\Component\Form\FormEvents; final class TpayPaymentDetailsType extends AbstractType { @@ -21,5 +23,14 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'property_path' => '[card]' ] ); + + $builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) { + $data = $event->getData() ?? []; + $form = $event->getForm(); + + if (!isset($data['card'])) { + $form->remove('card'); + } + }); } } diff --git a/src/Payum/Action/Api/AbstractCreateTransactionAction.php b/src/Payum/Action/Api/AbstractCreateTransactionAction.php new file mode 100644 index 00000000..87b3c19a --- /dev/null +++ b/src/Payum/Action/Api/AbstractCreateTransactionAction.php @@ -0,0 +1,46 @@ +getDetails(); + + $order = $payment->getOrder(); + Assert::notNull($order); + $localeCode = $order->getLocaleCode(); + Assert::notNull($localeCode); + + $response = $this->api->transactions()->createTransaction($payload); + + $details['tpay']['transaction_id'] = $response['transactionId']; + $details['tpay']['transaction_payment_url'] = $response['transactionPaymentUrl']; + + $payment->setDetails($details); + } + + protected function getLocaleCodeFrom(PaymentInterface $payment): string + { + return $payment->getOrder()->getLocaleCode() ?? throw new \InvalidArgumentException('Cannot determine locale code for a given payment'); + } +} diff --git a/src/Payum/Action/Api/CreateCardTransactionAction.php b/src/Payum/Action/Api/CreateCardTransactionAction.php new file mode 100644 index 00000000..f65e2984 --- /dev/null +++ b/src/Payum/Action/Api/CreateCardTransactionAction.php @@ -0,0 +1,68 @@ +getModel(); + $token = $request->getToken(); + Assert::notNull($token); + + $localeCode = $this->getLocaleCodeFrom($model); + $notifyToken = $this->notifyTokenFactory->create($model, $token->getGatewayName(), $localeCode); + + $this->createTransaction( + $model, + $this->createCardPaymentPayloadFactory->createFrom($model, $notifyToken->getTargetUrl(), $localeCode), + ); + + $this->gateway->execute(new PayWithCard($token)); + } + + public function supports($request): bool + { + $model = $request->getModel(); + + if (!$request instanceof CreateTransaction) { + return false; + } + + if (!$model instanceof PaymentInterface) { + return false; + } + + $details = $model->getDetails(); + + return isset($details['tpay']['card']); + } +} diff --git a/src/Payum/Action/Api/CreateRedirectBasedTransactionAction.php b/src/Payum/Action/Api/CreateRedirectBasedTransactionAction.php new file mode 100644 index 00000000..af05afc9 --- /dev/null +++ b/src/Payum/Action/Api/CreateRedirectBasedTransactionAction.php @@ -0,0 +1,67 @@ +getModel(); + $token = $request->getToken(); + Assert::notNull($token); + + $localeCode = $this->getLocaleCodeFrom($model); + $notifyToken = $this->notifyTokenFactory->create($model, $token->getGatewayName(), $localeCode); + + $this->createTransaction( + $model, + $this->createRedirectBasedPaymentPayloadFactory->createFrom($model, $notifyToken->getTargetUrl(), $localeCode), + ); + + $details = $model->getDetails(); + + throw new HttpRedirect($details['tpay']['transaction_payment_url']); + } + + public function supports($request): bool + { + $model = $request->getModel(); + + if (!$request instanceof CreateTransaction) { + return false; + } + + if (!$model instanceof PaymentInterface) { + return false; + } + + $details = $model->getDetails(); + + return !isset($details['tpay']['card']) && !isset($details['tpay']['blik']); + } +} diff --git a/src/Payum/Action/Api/CreateTransactionAction.php b/src/Payum/Action/Api/CreateTransactionAction.php deleted file mode 100644 index e47ddada..00000000 --- a/src/Payum/Action/Api/CreateTransactionAction.php +++ /dev/null @@ -1,90 +0,0 @@ -getModel(); - $details = $model->getDetails(); - $token = $request->getToken(); - Assert::notNull($token); - - $order = $model->getOrder(); - Assert::notNull($order); - $localeCode = $order->getLocaleCode(); - Assert::notNull($localeCode); - $customer = $order->getCustomer(); - Assert::notNull($customer); - $billingAddress = $order->getBillingAddress(); - Assert::notNull($billingAddress); - $amount = $model->getAmount(); - Assert::notNull($amount); - - $notifyToken = $this->createNotifyToken($model, $token, $localeCode); - - $response = $this->api->transactions()->createTransaction([ - 'amount' => number_format($amount / 100, 2, thousands_separator: ''), - 'description' => sprintf('zamówienie #%s', $order->getNumber()), // TODO: Introduce translations - 'payer' => [ - 'email' => $customer->getEmail(), - 'name' => $billingAddress->getFullName(), - ], - 'callbacks' => [ - 'payerUrls' => [ - 'success' => $this->router->generate($this->successRoute, ['_locale' => $localeCode], UrlGeneratorInterface::ABSOLUTE_URL), - 'error' => $this->router->generate($this->errorRoute, ['_locale' => $localeCode], UrlGeneratorInterface::ABSOLUTE_URL), - ], - 'notification' => [ - 'url' => $notifyToken->getTargetUrl(), - ], - ], - ]); - - $details['tpay']['transaction_id'] = $response['transactionId']; - $details['tpay']['transaction_payment_url'] = $response['transactionPaymentUrl']; - - $model->setDetails($details); - } - - private function createNotifyToken(PaymentInterface $payment, TokenInterface $token, string $localeCode): TokenInterface - { - return $this->tokenFactory->createToken( - $token->getGatewayName(), - $payment, - $this->router->generate($this->notifyRoute, ['_locale' => $localeCode], UrlGeneratorInterface::ABSOLUTE_URL), - ); - } - - public function supports($request): bool - { - return $request instanceof CreateTransaction && $request->getModel() instanceof PaymentInterface; - } -} diff --git a/src/Payum/Action/Api/PayWithCardAction.php b/src/Payum/Action/Api/PayWithCardAction.php new file mode 100644 index 00000000..5b5a4831 --- /dev/null +++ b/src/Payum/Action/Api/PayWithCardAction.php @@ -0,0 +1,43 @@ +getModel(); + $details = $model->getDetails(); + + $response = $this->api->transactions()->createPaymentByTransactionId([ + 'groupId' => 103, + 'cardPaymentData' => [ + 'card' => $details['tpay']['card'], + ], + ], $details['tpay']['transaction_id']); + + $details['tpay']['transaction_payment_url'] = $response['transactionPaymentUrl']; + unset($details['tpay']['card']); + + $model->setDetails($details); + + if ($response['status'] === 'pending') { + throw new HttpRedirect($details['tpay']['transaction_payment_url']); + } + } + + public function supports($request): bool + { + return $request instanceof PayWithCard && $request->getModel() instanceof PaymentInterface; + } +} diff --git a/src/Payum/Action/CaptureAction.php b/src/Payum/Action/CaptureAction.php index 7cb1d5bc..5de2227b 100644 --- a/src/Payum/Action/CaptureAction.php +++ b/src/Payum/Action/CaptureAction.php @@ -26,16 +26,11 @@ public function __construct( */ public function execute($request): void { - /** @var PaymentInterface $model */ - $model = $request->getModel(); - $this->gateway->execute( $this->createTransactionFactory->createNewWithModel($request->getToken()), ); - $paymentDetails = $model->getDetails(); - - throw new HttpRedirect($paymentDetails['tpay']['transaction_payment_url']); + throw new HttpRedirect($request->getToken()->getAfterUrl()); } public function supports($request): bool diff --git a/src/Payum/Factory/Token/NotifyTokenFactory.php b/src/Payum/Factory/Token/NotifyTokenFactory.php new file mode 100644 index 00000000..ba8b67db --- /dev/null +++ b/src/Payum/Factory/Token/NotifyTokenFactory.php @@ -0,0 +1,30 @@ +payum->getTokenFactory()->createToken( + $gatewayName, + $payment, + $this->router->generate($this->notifyRouteName, ['_locale' => $localeCode], UrlGeneratorInterface::ABSOLUTE_URL), + ); + } +} diff --git a/src/Payum/Factory/Token/NotifyTokenFactoryInterface.php b/src/Payum/Factory/Token/NotifyTokenFactoryInterface.php new file mode 100644 index 00000000..857ce330 --- /dev/null +++ b/src/Payum/Factory/Token/NotifyTokenFactoryInterface.php @@ -0,0 +1,13 @@ +createRedirectBasedPaymentPayloadFactory->createFrom($payment, $notifyUrl, $localeCode); + + $payload['pay']['groupId'] = 103; + + return $payload; + } +} diff --git a/src/Tpay/Factory/CreateCardPaymentPayloadFactoryInterface.php b/src/Tpay/Factory/CreateCardPaymentPayloadFactoryInterface.php new file mode 100644 index 00000000..94aa39f5 --- /dev/null +++ b/src/Tpay/Factory/CreateCardPaymentPayloadFactoryInterface.php @@ -0,0 +1,15 @@ + + */ + public function createFrom(PaymentInterface $payment, string $notifyUrl, string $localeCode): array; +} diff --git a/src/Tpay/Factory/CreateRedirectBasedPaymentPayloadFactory.php b/src/Tpay/Factory/CreateRedirectBasedPaymentPayloadFactory.php new file mode 100644 index 00000000..92396ca4 --- /dev/null +++ b/src/Tpay/Factory/CreateRedirectBasedPaymentPayloadFactory.php @@ -0,0 +1,53 @@ +getOrder(); + Assert::notNull($order); + $customer = $order->getCustomer(); + Assert::notNull($customer); + $billingAddress = $order->getBillingAddress(); + Assert::notNull($billingAddress); + $amount = $payment->getAmount(); + Assert::notNull($amount); + + return [ + 'amount' => number_format($amount / 100, 2, thousands_separator: ''), + 'description' => sprintf('zamówienie #%s', $order->getNumber()), // TODO: Introduce translations + 'payer' => [ + 'email' => $customer->getEmail(), + 'name' => $billingAddress->getFullName(), + ], + 'callbacks' => [ + 'payerUrls' => [ + 'success' => $this->router->generate($this->successRoute, ['_locale' => $localeCode], UrlGeneratorInterface::ABSOLUTE_URL), + 'error' => $this->router->generate($this->errorRoute, ['_locale' => $localeCode], UrlGeneratorInterface::ABSOLUTE_URL), + ], + 'notification' => [ + 'url' => $notifyUrl, + ], + ], + ]; + } +} diff --git a/src/Tpay/Factory/CreateRedirectBasedPaymentPayloadFactoryInterface.php b/src/Tpay/Factory/CreateRedirectBasedPaymentPayloadFactoryInterface.php new file mode 100644 index 00000000..c5ef041e --- /dev/null +++ b/src/Tpay/Factory/CreateRedirectBasedPaymentPayloadFactoryInterface.php @@ -0,0 +1,15 @@ + + */ + public function createFrom(PaymentInterface $payment, string $notifyUrl, string $localeCode): array; +} diff --git a/templates/shop/cart/complete/_card.html.twig b/templates/shop/cart/complete/_card.html.twig index 6531917a..f25a7e40 100644 --- a/templates/shop/cart/complete/_card.html.twig +++ b/templates/shop/cart/complete/_card.html.twig @@ -1,31 +1,33 @@ -
-
- {% set payment = order.lastPayment('cart') %} +{% set payment = order.lastPayment('cart') %} -
- -
-
- {{ form_row(form.tpay.card.holder_name) }} -
-
- {{ form_row(form.tpay.card.number) }} -
-
-
- {{ form_row(form.tpay.card.cvv) }} +{% if payment.method.gatewayConfig.config.type == 'card' %} +
+
+
+ +
+
+ {{ form_row(form.tpay.card.holder_name) }} +
+
+ {{ form_row(form.tpay.card.number) }}
-
-
- {{ form_row(form.tpay.card.expiration_date_month) }} - {{ form_row(form.tpay.card.expiration_date_year) }} +
+
+ {{ form_row(form.tpay.card.cvv) }} +
+
+
+ {{ form_row(form.tpay.card.expiration_date_month) }} + {{ form_row(form.tpay.card.expiration_date_year) }} +
-
- {{ form_row(form.tpay.card.card) }} + {{ form_row(form.tpay.card.card) }} - + +
-
+{% endif %} diff --git a/tests/Unit/Payum/Action/Api/CreateCardTransactionActionTest.php b/tests/Unit/Payum/Action/Api/CreateCardTransactionActionTest.php new file mode 100644 index 00000000..84f1de8a --- /dev/null +++ b/tests/Unit/Payum/Action/Api/CreateCardTransactionActionTest.php @@ -0,0 +1,178 @@ +api = $this->prophesize(TpayApi::class); + $this->router = $this->prophesize(RouterInterface::class); + $this->createCardPaymentPayloadFactory = $this->prophesize(CreateCardPaymentPayloadFactoryInterface::class); + $this->tokenFactory = $this->prophesize(GenericTokenFactoryInterface::class); + $this->notifyTokenFactory = $this->prophesize(NotifyTokenFactoryInterface::class); + $this->gateway = $this->prophesize(GatewayInterface::class); + } + + public function test_it_supports_create_transaction_requests_with_a_valid_payment_model(): void + { + $payment = $this->prophesize(PaymentInterface::class); + $payment->getDetails()->willReturn(['tpay' => ['card' => 'hashed_card']]); + + $request = $this->prophesize(CreateTransaction::class); + $request->getModel()->willReturn($payment); + + $isSupported = $this->createTestSubject()->supports($request->reveal()); + + $this->assertTrue($isSupported); + } + + + public function test_it_does_not_support_non_create_transaction_requests(): void + { + $payment = $this->prophesize(PaymentInterface::class); + $payment->getDetails()->willReturn([]); + + $request = $this->prophesize(Capture::class); + $request->getModel()->willReturn($payment); + + $isSupported = $this->createTestSubject()->supports($request->reveal()); + + $this->assertFalse($isSupported); + } + + public function test_it_does_not_support_requests_with_non_payment_model(): void + { + $nonPaymentModel = new \stdClass(); + + $request = $this->prophesize(CreateTransaction::class); + $request->getModel()->willReturn($nonPaymentModel); + + $isSupported = $this->createTestSubject()->supports($request->reveal()); + + $this->assertFalse($isSupported); + } + + public function test_it_does_not_support_requests_with_payment_model_not_containing_tpay_card(): void + { + $payment = $this->prophesize(PaymentInterface::class); + $payment->getDetails()->willReturn(['tpay' => ['blik' => '123456']]); + + $request = $this->prophesize(CreateTransaction::class); + $request->getModel()->willReturn($payment); + + $isSupported = $this->createTestSubject()->supports($request->reveal()); + + $this->assertFalse($isSupported); + } + + public function test_it_creates_a_payment_and_requests_paying_it_with_a_provided_card(): void + { + $order = $this->prophesize(OrderInterface::class); + $order->getLocaleCode()->willReturn('pl_PL'); + + $payment = $this->prophesize(PaymentInterface::class); + $payment->getOrder()->willReturn($order); + $payment->getDetails()->willReturn([]); + + $token = $this->prophesize(TokenInterface::class); + $token->getGatewayName()->willReturn('tpay'); + + $request = $this->prophesize(CreateTransaction::class); + $request->getModel()->willReturn($payment); + $request->getToken()->willReturn($token); + + $notifyToken = $this->prophesize(TokenInterface::class); + $notifyToken->getTargetUrl()->willReturn('https://cw.org/notify'); + + $transactions = $this->prophesize(TransactionsApi::class); + $transactions->createTransaction(['factored' => 'payload'])->willReturn([ + 'transactionId' => 'tr4ns4ct!0n_id', + 'transactionPaymentUrl' => 'https://tpay.org/pay', + ]); + + $this->api->transactions()->willReturn($transactions); + + $payment->setDetails([ + 'tpay' => [ + 'transaction_id' => 'tr4ns4ct!0n_id', + 'transaction_payment_url' => 'https://tpay.org/pay', + ], + ])->shouldBeCalled(); + + $this->notifyTokenFactory->create($payment, 'tpay', 'pl_PL')->willReturn($notifyToken); + + $this->createCardPaymentPayloadFactory + ->createFrom($payment, 'https://cw.org/notify', 'pl_PL') + ->willReturn(['factored' => 'payload']) + ; + + $this->gateway->execute(Argument::that(function (PayWithCard $request) use ($token): bool { + return $request->getToken() === $token->reveal(); + }))->shouldBeCalled(); + + $this->createTestSubject()->execute($request->reveal()); + } + + public function test_it_throws_an_exception_if_a_token_is_null(): void + { + $this->expectException(InvalidArgumentException::class); + + $request = $this->prophesize(CreateTransaction::class); + $request->getModel()->willReturn($this->prophesize(PaymentInterface::class)->reveal()); + $request->getToken()->willReturn(null); + + $this->createTestSubject()->execute($request->reveal()); + } + + private function createTestSubject(): CreateCardTransactionAction + { + $action = new CreateCardTransactionAction( + $this->router->reveal(), + $this->createCardPaymentPayloadFactory->reveal(), + $this->notifyTokenFactory->reveal(), + ); + + $action->setApi($this->api->reveal()); + $action->setGenericTokenFactory($this->tokenFactory->reveal()); + $action->setGateway($this->gateway->reveal()); + + return $action; + } +} diff --git a/tests/Unit/Payum/Action/Api/CreateRedirectBasedTransactionActionTest.php b/tests/Unit/Payum/Action/Api/CreateRedirectBasedTransactionActionTest.php new file mode 100644 index 00000000..21035d1e --- /dev/null +++ b/tests/Unit/Payum/Action/Api/CreateRedirectBasedTransactionActionTest.php @@ -0,0 +1,191 @@ +api = $this->prophesize(TpayApi::class); + $this->router = $this->prophesize(RouterInterface::class); + $this->createRedirectBasedPaymentPayloadFactory = $this->prophesize(CreateRedirectBasedPaymentPayloadFactoryInterface::class); + $this->tokenFactory = $this->prophesize(GenericTokenFactoryInterface::class); + $this->notifyTokenFactory = $this->prophesize(NotifyTokenFactoryInterface::class); + } + + public function test_it_supports_create_transaction_requests_with_a_valid_payment_model(): void + { + $payment = $this->prophesize(PaymentInterface::class); + $payment->getDetails()->willReturn([]); + + $request = $this->prophesize(CreateTransaction::class); + $request->getModel()->willReturn($payment); + + $isSupported = $this->createTestSubject()->supports($request->reveal()); + + $this->assertTrue($isSupported); + } + + + public function test_it_does_not_support_non_create_transaction_requests(): void + { + $payment = $this->prophesize(PaymentInterface::class); + $payment->getDetails()->willReturn([]); + + $request = $this->prophesize(Capture::class); + $request->getModel()->willReturn($payment); + + $isSupported = $this->createTestSubject()->supports($request->reveal()); + + $this->assertFalse($isSupported); + } + + public function test_it_does_not_support_requests_with_non_payment_model(): void + { + $nonPaymentModel = new \stdClass(); + + $request = $this->prophesize(CreateTransaction::class); + $request->getModel()->willReturn($nonPaymentModel); + + $isSupported = $this->createTestSubject()->supports($request->reveal()); + + $this->assertFalse($isSupported); + } + + public function test_it_does_not_support_requests_with_payment_model_containing_tpay_card(): void + { + $payment = $this->prophesize(PaymentInterface::class); + $payment->getDetails()->willReturn(['tpay' => ['card' => 'some_value']]); + + $request = $this->prophesize(CreateTransaction::class); + $request->getModel()->willReturn($payment); + + $isSupported = $this->createTestSubject()->supports($request->reveal()); + + $this->assertFalse($isSupported); + } + + public function test_it_does_not_support_requests_with_payment_model_containing_tpay_blik(): void + { + $payment = $this->prophesize(PaymentInterface::class); + $payment->getDetails()->willReturn(['tpay' => ['blik' => 'some_value']]); + + $request = $this->prophesize(CreateTransaction::class); + $request->getModel()->willReturn($payment); + + $isSupported = $this->createTestSubject()->supports($request->reveal()); + + $this->assertFalse($isSupported); + } + + public function test_it_creates_a_payment_and_redirects_to_a_payment_page(): void + { + $this->expectException(HttpRedirect::class); + + $order = $this->prophesize(OrderInterface::class); + $order->getLocaleCode()->willReturn('pl_PL'); + + $payment = $this->prophesize(PaymentInterface::class); + $payment->getOrder()->willReturn($order); + $payment->getDetails()->willReturn( + [], + [ + 'tpay' => [ + 'transaction_id' => 'tr4ns4ct!0n_id', + 'transaction_payment_url' => 'https://tpay.org/pay', + ], + ], + ); + + $token = $this->prophesize(TokenInterface::class); + $token->getGatewayName()->willReturn('tpay'); + + $request = $this->prophesize(CreateTransaction::class); + $request->getModel()->willReturn($payment); + $request->getToken()->willReturn($token); + + $notifyToken = $this->prophesize(TokenInterface::class); + $notifyToken->getTargetUrl()->willReturn('https://cw.org/notify'); + + $transactions = $this->prophesize(TransactionsApi::class); + $transactions->createTransaction(['factored' => 'payload'])->willReturn([ + 'transactionId' => 'tr4ns4ct!0n_id', + 'transactionPaymentUrl' => 'https://tpay.org/pay', + ]); + + $this->api->transactions()->willReturn($transactions); + + $payment->setDetails([ + 'tpay' => [ + 'transaction_id' => 'tr4ns4ct!0n_id', + 'transaction_payment_url' => 'https://tpay.org/pay', + ], + ])->shouldBeCalled(); + + $this->notifyTokenFactory->create($payment, 'tpay', 'pl_PL')->willReturn($notifyToken); + + $this->createRedirectBasedPaymentPayloadFactory + ->createFrom($payment, 'https://cw.org/notify', 'pl_PL') + ->willReturn(['factored' => 'payload']) + ; + + $this->createTestSubject()->execute($request->reveal()); + } + + public function test_it_throws_an_exception_if_a_token_is_null(): void + { + $this->expectException(InvalidArgumentException::class); + + $request = $this->prophesize(CreateTransaction::class); + $request->getModel()->willReturn($this->prophesize(PaymentInterface::class)->reveal()); + $request->getToken()->willReturn(null); + + $this->createTestSubject()->execute($request->reveal()); + } + + private function createTestSubject(): CreateRedirectBasedTransactionAction + { + $action = new CreateRedirectBasedTransactionAction( + $this->router->reveal(), + $this->createRedirectBasedPaymentPayloadFactory->reveal(), + $this->notifyTokenFactory->reveal(), + ); + + $action->setApi($this->api->reveal()); + $action->setGenericTokenFactory($this->tokenFactory->reveal()); + + return $action; + } +} diff --git a/tests/Unit/Payum/Action/Api/CreateTransactionActionTest.php b/tests/Unit/Payum/Action/Api/CreateTransactionActionTest.php deleted file mode 100644 index 994e5d48..00000000 --- a/tests/Unit/Payum/Action/Api/CreateTransactionActionTest.php +++ /dev/null @@ -1,151 +0,0 @@ -request = $this->prophesize(CreateTransaction::class); - $this->model = $this->prophesize(PaymentInterface::class); - $this->api = $this->prophesize(TpayApi::class); - $this->router = $this->prophesize(RouterInterface::class); - $this->tokenFactory = $this->prophesize(GenericTokenFactoryInterface::class); - - $this->request->getModel()->willReturn($this->model->reveal()); - } - - public function it_supports_only_create_transaction_requests(): void - { - $action = $this->createTestSubject(); - - $this->assertFalse($action->supports(new Sync($this->model->reveal()))); - $this->assertTrue($action->supports(new CreateTransaction('https://cw.org', $this->model->reveal()))); - } - - public function test_it_supports_only_payment_interface_based_models(): void - { - $action = $this->createTestSubject(); - - $this->assertFalse($action->supports(new CreateTransaction(new \stdClass()))); - $this->assertTrue($action->supports(new CreateTransaction($this->model->reveal()))); - } - - public function test_it_creates_transaction(): void - { - $createTransactionToken = $this->prophesize(TokenInterface::class); - $createTransactionToken->getGatewayName()->willReturn('tpay'); - - $this->request->getToken()->willReturn($createTransactionToken); - - $customer = $this->prophesize(CustomerInterface::class); - $customer->getEmail()->willReturn('maks@skalski.com'); - - $billingAddress = $this->prophesize(AddressInterface::class); - $billingAddress->getFullName()->willReturn('Maksymilian Skalski'); - - $order = $this->prophesize(OrderInterface::class); - $order->getLocaleCode()->willReturn('en_US'); - $order->getCustomer()->willReturn($customer); - $order->getBillingAddress()->willReturn($billingAddress); - $order->getNumber()->willReturn('00000001'); - - $this->model->getAmount()->willReturn(1234); - $this->model->getOrder()->willReturn($order); - $this->model->getDetails()->willReturn([]); - $this->model->setDetails([ - 'tpay' => [ - 'transaction_id' => '1234abcd', - 'transaction_payment_url' => 'https://tpay.pay', - ], - ])->shouldBeCalled(); - - $this->tokenFactory->createToken( - 'tpay', - $this->model, - 'https://cw.org/notify', - )->willReturn($token = $this->prophesize(TokenInterface::class)); - $token->getTargetUrl()->willReturn('https://cw.org/notify'); - - $this->router - ->generate('sylius_shop_order_thank_you', ['_locale' => 'en_US'], UrlGeneratorInterface::ABSOLUTE_URL) - ->willReturn('https://cw.org/thank-you') - ; - $this->router - ->generate('commerce_weavers_tpay_payment_notification', ['_locale' => 'en_US'], UrlGeneratorInterface::ABSOLUTE_URL) - ->willReturn('https://cw.org/notify') - ; - - $transactionsApi = $this->prophesize(TransactionsApi::class); - $transactionsApi->createTransaction([ - 'amount' => 12.34, - 'description' => 'zamówienie #00000001', - 'payer' => [ - 'email' => 'maks@skalski.com', - 'name' => 'Maksymilian Skalski', - ], - 'callbacks' => [ - 'payerUrls' => [ - 'success' => 'https://cw.org/thank-you', - 'error' => 'https://cw.org/thank-you', - ], - 'notification' => [ - 'url' => 'https://cw.org/notify' - ], - ], - ])->shouldBeCalled()->willReturn([ - 'transactionId' => '1234abcd', - 'transactionPaymentUrl' => 'https://tpay.pay', - ]); - - $this->api->transactions()->willReturn($transactionsApi); - - $this->createTestSubject()->execute($this->request->reveal()); - } - - private function createTestSubject(): CreateTransactionAction - { - $action = new CreateTransactionAction( - $this->router->reveal(), - 'sylius_shop_order_thank_you', - 'sylius_shop_order_thank_you', - 'commerce_weavers_tpay_payment_notification', - ); - - $action->setApi($this->api->reveal()); - $action->setGenericTokenFactory($this->tokenFactory->reveal()); - - return $action; - } -} diff --git a/tests/Unit/Payum/Action/Api/PayWithCardActionTest.php b/tests/Unit/Payum/Action/Api/PayWithCardActionTest.php new file mode 100644 index 00000000..862075cf --- /dev/null +++ b/tests/Unit/Payum/Action/Api/PayWithCardActionTest.php @@ -0,0 +1,149 @@ +api = $this->prophesize(TpayApi::class); + } + + public function test_it_supports_pay_with_card_request_with_a_payment_model(): void + { + $request = $this->prophesize(PayWithCard::class); + $request->getModel()->willReturn($this->prophesize(PaymentInterface::class)->reveal()); + + $isSupported = $this->createTestSubject()->supports($request->reveal()); + + $this->assertTrue($isSupported); + } + + public function test_it_does_not_supports_other_request(): void + { + $request = $this->prophesize(\stdClass::class); + $isSupported = $this->createTestSubject()->supports($request->reveal()); + + $this->assertFalse($isSupported); + } + + public function test_it_does_not_supports_pay_with_card_request_with_non_payment_model(): void + { + $request = $this->prophesize(PayWithCard::class); + $request->getModel()->willReturn($this->prophesize(\stdClass::class)->reveal()); + + $isSupported = $this->createTestSubject()->supports($request->reveal()); + + $this->assertFalse($isSupported); + } + + + public function test_it_executes_pay_with_card_request_successfully(): void + { + $request = $this->prophesize(PayWithCard::class); + $paymentModel = $this->prophesize(PaymentInterface::class); + $details = [ + 'tpay' => [ + 'card' => 'test-card', + 'transaction_id' => 12345, + ], + ]; + + $response = [ + 'transactionPaymentUrl' => 'http://example.com', + 'status' => 'completed', + ]; + + $request->getModel()->willReturn($paymentModel->reveal()); + $paymentModel->getDetails()->willReturn($details); + + $transactions = $this->prophesize(TransactionsApi::class); + $transactions->createPaymentByTransactionId([ + 'groupId' => 103, + 'cardPaymentData' => [ + 'card' => $details['tpay']['card'], + ], + ], $details['tpay']['transaction_id'])->willReturn($response); + + $this->api->transactions()->willReturn($transactions); + + $paymentModel->setDetails([ + 'tpay' => [ + 'transaction_id' => 12345, + 'transaction_payment_url' => 'http://example.com', + ], + ])->shouldBeCalled(); + + $subject = $this->createTestSubject(); + + $subject->execute($request->reveal()); + } + + public function test_it_throws_http_redirect_for_pending_status(): void + { + $this->expectException(HttpRedirect::class); + + $request = $this->prophesize(PayWithCard::class); + $paymentModel = $this->prophesize(PaymentInterface::class); + $details = [ + 'tpay' => [ + 'card' => 'test-card', + 'transaction_id' => 12345, + ], + ]; + + $response = [ + 'transactionPaymentUrl' => 'http://example.com', + 'status' => 'pending', + ]; + + $request->getModel()->willReturn($paymentModel->reveal()); + $paymentModel->getDetails()->willReturn($details); + + $transactions = $this->prophesize(TransactionsApi::class); + $transactions->createPaymentByTransactionId([ + 'groupId' => 103, + 'cardPaymentData' => [ + 'card' => $details['tpay']['card'], + ], + ], $details['tpay']['transaction_id'])->willReturn($response); + + $this->api->transactions()->willReturn($transactions); + + $paymentModel->setDetails([ + 'tpay' => [ + 'transaction_id' => 12345, + 'transaction_payment_url' => 'http://example.com', + ], + ])->shouldBeCalled(); + + $subject = $this->createTestSubject(); + + $subject->execute($request->reveal()); + } + + private function createTestSubject(): PayWithCardAction + { + $action = new PayWithCardAction(); + + $action->setApi($this->api->reveal()); + + return $action; + } +} diff --git a/tests/Unit/Payum/Action/CaptureActionTest.php b/tests/Unit/Payum/Action/CaptureActionTest.php index 67171e84..7a48c4cc 100644 --- a/tests/Unit/Payum/Action/CaptureActionTest.php +++ b/tests/Unit/Payum/Action/CaptureActionTest.php @@ -55,7 +55,7 @@ public function test_it_supports_only_payment_interface_based_models(): void $this->assertTrue($action->supports(new Capture($this->model->reveal()))); } - public function test_it_throws_http_redirect_with_using_transaction_payment_url(): void + public function test_it_throws_http_redirect_with_token_after_url(): void { $this->expectException(HttpRedirect::class); @@ -65,11 +65,6 @@ public function test_it_throws_http_redirect_with_using_transaction_payment_url( $this->request->getToken()->willReturn($token); $this->createTransactionFactory->createNewWithModel($token)->willReturn($createTransaction = $this->prophesize(CreateTransaction::class)); $this->gateway->execute($createTransaction)->shouldBeCalled(); - $this->model->getDetails()->shouldBeCalled()->willReturn([ - 'tpay' => [ - 'transaction_payment_url' => 'https://tpay.pay', - ], - ]); $this->createTestSubject()->execute($this->request->reveal()); } diff --git a/tests/Unit/Payum/Action/GetStatusActionTest.php b/tests/Unit/Payum/Action/GetStatusActionTest.php index 61424e3d..180f6d3d 100644 --- a/tests/Unit/Payum/Action/GetStatusActionTest.php +++ b/tests/Unit/Payum/Action/GetStatusActionTest.php @@ -18,6 +18,8 @@ final class GetStatusActionTest extends TestCase { use ProphecyTrait; + private Notify|ObjectProphecy $request; + private PaymentInterface|ObjectProphecy $model; private GatewayInterface|ObjectProphecy $gateway; diff --git a/tests/Unit/Payum/Factory/Token/NotifyTokenFactoryTest.php b/tests/Unit/Payum/Factory/Token/NotifyTokenFactoryTest.php new file mode 100644 index 00000000..1d510ca8 --- /dev/null +++ b/tests/Unit/Payum/Factory/Token/NotifyTokenFactoryTest.php @@ -0,0 +1,64 @@ +payum = $this->prophesize(Payum::class); + $this->tokenFactory = $this->prophesize(TokenFactoryInterface::class); + $this->router = $this->prophesize(RouterInterface::class); + + $this->payum->getTokenFactory()->willReturn($this->tokenFactory); + } + + public function test_it_returns_created_notify_token(): void + { + $payment = $this->prophesize(PaymentInterface::class); + + $this->router + ->generate('cw_notify', ['_locale' => 'pl_PL'], UrlGeneratorInterface::ABSOLUTE_URL) + ->willReturn('https://cw.org/notify') + ; + + $this->tokenFactory->createToken( + 'tpay', + $payment, + 'https://cw.org/notify', + )->shouldBeCalled()->willReturn($this->prophesize(TokenInterface::class)); + + $this->createTestSubject()->create($payment->reveal(), 'tpay', 'pl_PL'); + } + + private function createTestSubject(): NotifyTokenFactoryInterface + { + return new NotifyTokenFactory( + $this->payum->reveal(), + $this->router->reveal(), + 'cw_notify', + ); + } +} diff --git a/tests/Unit/Tpay/Factory/CreateCardPaymentPayloadFactoryTest.php b/tests/Unit/Tpay/Factory/CreateCardPaymentPayloadFactoryTest.php new file mode 100644 index 00000000..f5e40b79 --- /dev/null +++ b/tests/Unit/Tpay/Factory/CreateCardPaymentPayloadFactoryTest.php @@ -0,0 +1,46 @@ +createRedirectBasedPaymentPayloadFactory = $this->prophesize(CreateRedirectBasedPaymentPayloadFactoryInterface::class); + } + + public function test_it_adds_card_related_data_to_a_basic_create_payment_payload_output(): void + { + $payment = $this->prophesize(PaymentInterface::class); + + $this->createRedirectBasedPaymentPayloadFactory->createFrom($payment, 'https://cw.org/notify', 'pl_PL')->willReturn(['some' => 'data']); + + $payload = $this->createTestSubject()->createFrom($payment->reveal(), 'https://cw.org/notify', 'pl_PL'); + + $this->assertSame([ + 'some' => 'data', + 'pay' => [ + 'groupId' => 103, + ], + ], $payload); + } + + private function createTestSubject(): CreateCardPaymentPayloadFactoryInterface + { + return new CreateCardPaymentPayloadFactory($this->createRedirectBasedPaymentPayloadFactory->reveal()); + } +} diff --git a/tests/Unit/Tpay/Factory/CreateRedirectBasedPaymentPayloadFactoryTest.php b/tests/Unit/Tpay/Factory/CreateRedirectBasedPaymentPayloadFactoryTest.php new file mode 100644 index 00000000..3df4b13a --- /dev/null +++ b/tests/Unit/Tpay/Factory/CreateRedirectBasedPaymentPayloadFactoryTest.php @@ -0,0 +1,142 @@ +router = $this->prophesize(RouterInterface::class); + } + + public function test_it_returns_a_payload_for_a_redirect_based_payment(): void + { + $billingAddress = $this->prophesize(AddressInterface::class); + $billingAddress->getFullName()->willReturn('Don Matteo'); + + $customer = $this->prophesize(CustomerInterface::class); + $customer->getEmail()->willReturn('don.matteo@sandomierz.org'); + + $order = $this->prophesize(OrderInterface::class); + $order->getCustomer()->willReturn($customer); + $order->getBillingAddress()->willReturn($billingAddress); + $order->getNumber()->willReturn('000000001'); + + $payment = $this->prophesize(PaymentInterface::class); + $payment->getOrder()->willReturn($order); + $payment->getAmount()->willReturn(1050); + + $this->router + ->generate('cw_success', ['_locale' => 'pl_PL'], UrlGeneratorInterface::ABSOLUTE_URL) + ->willReturn('https://cw.org/success') + ; + $this->router + ->generate('cw_error', ['_locale' => 'pl_PL'], UrlGeneratorInterface::ABSOLUTE_URL) + ->willReturn('https://cw.org/error') + ; + + $payload = $this->createTestSubject()->createFrom($payment->reveal(), 'https://cw.org/notify', 'pl_PL'); + + $this->assertSame([ + 'amount' => '10.50', + 'description' => 'zamówienie #000000001', + 'payer' => [ + 'email' => 'don.matteo@sandomierz.org', + 'name' => 'Don Matteo', + ], + 'callbacks' => [ + 'payerUrls' => [ + 'success' => 'https://cw.org/success', + 'error' => 'https://cw.org/error', + ], + 'notification' => [ + 'url' => 'https://cw.org/notify', + ], + ], + ], $payload); + } + + public function test_it_throws_an_exception_if_the_order_is_null(): void + { + $this->expectException(InvalidArgumentException::class); + + $payment = $this->prophesize(PaymentInterface::class); + + $this->createTestSubject()->createFrom($payment->reveal(), 'https://cw.org/notify', 'pl_PL'); + } + + + public function test_it_throws_an_exception_if_the_customer_is_null(): void + { + $this->expectException(InvalidArgumentException::class); + + $order = $this->prophesize(OrderInterface::class); + $order->getCustomer()->willReturn(null); + + $payment = $this->prophesize(PaymentInterface::class); + $payment->getOrder()->willReturn($order); + + $this->createTestSubject()->createFrom($payment->reveal(), 'https://cw.org/notify', 'pl_PL'); + } + + public function test_it_throws_an_exception_if_the_billing_address_is_null(): void + { + $this->expectException(InvalidArgumentException::class); + + $customer = $this->prophesize(CustomerInterface::class); + + $order = $this->prophesize(OrderInterface::class); + $order->getCustomer()->willReturn($customer); + $order->getBillingAddress()->willReturn(null); + + $payment = $this->prophesize(PaymentInterface::class); + $payment->getOrder()->willReturn($order); + + $this->createTestSubject()->createFrom($payment->reveal(), 'https://cw.org/notify', 'pl_PL'); + } + + public function test_it_throws_an_exception_if_the_amount_is_null(): void + { + $this->expectException(InvalidArgumentException::class); + + $billingAddress = $this->prophesize(AddressInterface::class); + $customer = $this->prophesize(CustomerInterface::class); + $order = $this->prophesize(OrderInterface::class); + $order->getCustomer()->willReturn($customer); + $order->getBillingAddress()->willReturn($billingAddress); + + $payment = $this->prophesize(PaymentInterface::class); + $payment->getOrder()->willReturn($order); + $payment->getAmount()->willReturn(null); + + $this->createTestSubject()->createFrom($payment->reveal(), 'https://cw.org/notify', 'pl_PL'); + } + + private function createTestSubject(): CreateRedirectBasedPaymentPayloadFactoryInterface + { + return new CreateRedirectBasedPaymentPayloadFactory( + $this->router->reveal(), + 'cw_success', + 'cw_error', + ); + } +}