From e8ade803a9b6fadd888511e1b3b698a8f25d8672 Mon Sep 17 00:00:00 2001 From: Jacob Tobiasz Date: Tue, 10 Sep 2024 14:47:03 +0200 Subject: [PATCH] wip --- config/services/payum/action.php | 22 ++++- .../Api/AbstractCreateTransactionAction.php | 58 ++++++++++++ .../Api/CreateCardTransactionAction.php | 66 ++++++++++++++ .../CreateRedirectBasedTransactionAction.php | 66 ++++++++++++++ .../Action/Api/CreateTransactionAction.php | 90 ------------------- src/Payum/Action/Api/PayWithCardAction.php | 42 +++++++++ src/Payum/Action/CaptureAction.php | 4 +- src/Payum/Request/Api/PayWithCard.php | 11 +++ .../CreateCardPaymentPayloadFactory.php | 25 ++++++ ...eateCardPaymentPayloadFactoryInterface.php | 15 ++++ ...RedirectBasedCardPaymentPayloadFactory.php | 53 +++++++++++ ...ectBasedPaymentPayloadFactoryInterface.php | 15 ++++ .../Api/CreateTransactionActionTest.php | 6 +- 13 files changed, 374 insertions(+), 99 deletions(-) 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/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/CreateRedirectBasedCardPaymentPayloadFactory.php create mode 100644 src/Tpay/Factory/CreateRedirectBasedPaymentPayloadFactoryInterface.php diff --git a/config/services/payum/action.php b/config/services/payum/action.php index def41c28..0c7300bd 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,34 @@ ->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'), ]) - ->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'), + 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'), + ]) + ->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/src/Payum/Action/Api/AbstractCreateTransactionAction.php b/src/Payum/Action/Api/AbstractCreateTransactionAction.php new file mode 100644 index 00000000..623496b7 --- /dev/null +++ b/src/Payum/Action/Api/AbstractCreateTransactionAction.php @@ -0,0 +1,58 @@ +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'); + } + + protected 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), + ); + } +} diff --git a/src/Payum/Action/Api/CreateCardTransactionAction.php b/src/Payum/Action/Api/CreateCardTransactionAction.php new file mode 100644 index 00000000..e5ce40fd --- /dev/null +++ b/src/Payum/Action/Api/CreateCardTransactionAction.php @@ -0,0 +1,66 @@ +notifyRoute); + } + + /** + * @param CreateTransaction $request + */ + public function execute($request): void + { + /** @var PaymentInterface $model */ + $model = $request->getModel(); + $token = $request->getToken(); + Assert::notNull($token); + + $localeCode = $this->getLocaleCodeFrom($model); + $notifyToken = $this->createNotifyToken($model, $token, $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..81a49565 --- /dev/null +++ b/src/Payum/Action/Api/CreateRedirectBasedTransactionAction.php @@ -0,0 +1,66 @@ +getModel(); + $token = $request->getToken(); + Assert::notNull($token); + + $localeCode = $this->getLocaleCodeFrom($model); + $notifyToken = $this->createNotifyToken($model, $token, $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..613414a2 --- /dev/null +++ b/src/Payum/Action/Api/PayWithCardAction.php @@ -0,0 +1,42 @@ +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']; + + $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..110d8b33 100644 --- a/src/Payum/Action/CaptureAction.php +++ b/src/Payum/Action/CaptureAction.php @@ -33,9 +33,7 @@ public function execute($request): void $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/Request/Api/PayWithCard.php b/src/Payum/Request/Api/PayWithCard.php new file mode 100644 index 00000000..cc991d65 --- /dev/null +++ b/src/Payum/Request/Api/PayWithCard.php @@ -0,0 +1,11 @@ +createRedirectBasedPaymentPayloadFactory->createFrom($payment, $notifyUrl, $localeCode); + + + } +} 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/CreateRedirectBasedCardPaymentPayloadFactory.php b/src/Tpay/Factory/CreateRedirectBasedCardPaymentPayloadFactory.php new file mode 100644 index 00000000..591d02f0 --- /dev/null +++ b/src/Tpay/Factory/CreateRedirectBasedCardPaymentPayloadFactory.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/tests/Unit/Payum/Action/Api/CreateTransactionActionTest.php b/tests/Unit/Payum/Action/Api/CreateTransactionActionTest.php index 994e5d48..49e8e8db 100644 --- a/tests/Unit/Payum/Action/Api/CreateTransactionActionTest.php +++ b/tests/Unit/Payum/Action/Api/CreateTransactionActionTest.php @@ -4,7 +4,7 @@ namespace Tests\CommerceWeavers\SyliusTpayPlugin\Unit\Payum\Action\Api; -use CommerceWeavers\SyliusTpayPlugin\Payum\Action\Api\CreateTransactionAction; +use CommerceWeavers\SyliusTpayPlugin\Payum\Action\Api\CreateRedirectBasedTransactionAction; use CommerceWeavers\SyliusTpayPlugin\Payum\Request\Api\CreateTransaction; use Payum\Core\Request\Sync; use Payum\Core\Security\GenericTokenFactoryInterface; @@ -134,9 +134,9 @@ public function test_it_creates_transaction(): void $this->createTestSubject()->execute($this->request->reveal()); } - private function createTestSubject(): CreateTransactionAction + private function createTestSubject(): CreateRedirectBasedTransactionAction { - $action = new CreateTransactionAction( + $action = new CreateRedirectBasedTransactionAction( $this->router->reveal(), 'sylius_shop_order_thank_you', 'sylius_shop_order_thank_you',