From 63a4e1a37d1ac4d42ce40d0ad1a45465f8dcfc21 Mon Sep 17 00:00:00 2001 From: Lukasz Falda Date: Mon, 6 Nov 2023 10:23:01 +0100 Subject: [PATCH] Pay method on Payment --- core/Model/Payment.php | 4 + src/Action/CaptureAction.php | 3 +- src/Action/ConvertPaymentAction.php | 11 +++ src/Enum/ModelFields.php | 2 + src/Enum/PayMethodType.php | 1 + src/Model/Model.php | 22 ++++++ .../Integration/Action/CaptureActionTest.php | 73 +++++++++++++++++-- .../Integration/Action/ConvertActionTest.php | 17 +++++ .../Action/data/detailsWithPayMethod.json | 29 ++++++++ tests/Payment.php | 12 +++ 10 files changed, 168 insertions(+), 6 deletions(-) create mode 100644 tests/Integration/Action/data/detailsWithPayMethod.json diff --git a/core/Model/Payment.php b/core/Model/Payment.php index cbe8af7..9c6c6df 100644 --- a/core/Model/Payment.php +++ b/core/Model/Payment.php @@ -4,6 +4,8 @@ namespace Answear\Payum\Model; +use Answear\Payum\PayU\ValueObject\Request\Order\PayMethod; + abstract class Payment extends \Payum\Core\Model\Payment { abstract public function getGatewayName(): string; @@ -17,4 +19,6 @@ abstract public function getConfigKey(): ?string; abstract public function getPaidFor(): PaidForInterface; abstract public function getLanguage(): ?string; + + abstract public function getPayMethod(): ?PayMethod; } diff --git a/src/Action/CaptureAction.php b/src/Action/CaptureAction.php index b9478a7..69a13e5 100644 --- a/src/Action/CaptureAction.php +++ b/src/Action/CaptureAction.php @@ -117,6 +117,7 @@ private function updatePayment( } } + $model->filterSensitiveData(); $payment->setDetails($model); $status = new GetHumanStatus($token); @@ -165,7 +166,7 @@ private function setRecurringStandardPayment(OrderRequest $orderRequest, Model $ $orderRequest->setRequiring($model->recurring(), new PayMethod(PayMethodType::CardToken, $cardToken['value'])); } - private function findPreferredToken(array $tokens, ?string $creditCardMaskedNumber = null): ?array + private function findPreferredToken(array $tokens, string $creditCardMaskedNumber = null): ?array { $tokens = array_filter( $tokens, diff --git a/src/Action/ConvertPaymentAction.php b/src/Action/ConvertPaymentAction.php index e65e2e3..e814df7 100644 --- a/src/Action/ConvertPaymentAction.php +++ b/src/Action/ConvertPaymentAction.php @@ -68,6 +68,17 @@ public function execute($request): void ); $details->setBuyer($buyer); + + $payMethod = $payment->getPayMethod(); + if (null !== $payMethod) { + $details->replace( + [ + ModelFields::PAY_METHODS => [ + ModelFields::PAY_METHOD => $payMethod->toArray(), + ], + ] + ); + } } if (RecurringEnum::First === $details->recurring() && !empty($payment->getCreditCard()?->getToken())) { diff --git a/src/Enum/ModelFields.php b/src/Enum/ModelFields.php index 401512a..279c1f5 100644 --- a/src/Enum/ModelFields.php +++ b/src/Enum/ModelFields.php @@ -25,6 +25,8 @@ enum ModelFields public const PAY_METHOD = 'payMethod'; public const PAY_METHOD_TYPE = 'type'; public const PAY_METHOD_VALUE = 'value'; + public const PAY_METHOD_AUTHORIZATION_CODE = 'authorizationCode'; + public const PAY_METHOD_SPECIFIC_DATA = 'specificData'; public const PRODUCT_LISTING_DATE = 'listingDate'; public const PRODUCT_VIRTUAL = 'virtual'; public const PRODUCT_QUANTITY = 'quantity'; diff --git a/src/Enum/PayMethodType.php b/src/Enum/PayMethodType.php index dc8c9a0..8267abb 100644 --- a/src/Enum/PayMethodType.php +++ b/src/Enum/PayMethodType.php @@ -10,4 +10,5 @@ enum PayMethodType: string case CardToken = 'CARD_TOKEN'; case Installments = 'INSTALLMENTS'; case PaymentWall = 'PAYMENT_WALL'; + case BlikAuthorizationCode = 'BLIK_AUTHORIZATION_CODE'; } diff --git a/src/Model/Model.php b/src/Model/Model.php index 42e9033..68f6ab6 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -104,6 +104,28 @@ public function payMethod(): ?PayMethod return new PayMethod( $type instanceof PayMethodType ? $type : PayMethodType::tryFrom($type), $this[ModelFields::PAY_METHODS][ModelFields::PAY_METHOD][ModelFields::PAY_METHOD_VALUE], + $this[ModelFields::PAY_METHODS][ModelFields::PAY_METHOD][ModelFields::PAY_METHOD_AUTHORIZATION_CODE] ?? null, + $this[ModelFields::PAY_METHODS][ModelFields::PAY_METHOD][ModelFields::PAY_METHOD_SPECIFIC_DATA] ?? null, + ); + } + + public function filterSensitiveData(): void + { + if (!isset($this[ModelFields::PAY_METHODS])) { + return; + } + + $this->replace( + [ + ModelFields::PAY_METHODS => [ + ModelFields::PAY_METHOD => [ + ModelFields::PAY_METHOD_TYPE => $this[ModelFields::PAY_METHODS][ModelFields::PAY_METHOD][ModelFields::PAY_METHOD_TYPE], + ModelFields::PAY_METHOD_VALUE => '???', + ModelFields::PAY_METHOD_AUTHORIZATION_CODE => '???', + ModelFields::PAY_METHOD_SPECIFIC_DATA => $this[ModelFields::PAY_METHODS][ModelFields::PAY_METHOD][ModelFields::PAY_METHOD_SPECIFIC_DATA] ?? null, + ], + ], + ] ); } diff --git a/tests/Integration/Action/CaptureActionTest.php b/tests/Integration/Action/CaptureActionTest.php index 5766dbc..b8e6ccf 100644 --- a/tests/Integration/Action/CaptureActionTest.php +++ b/tests/Integration/Action/CaptureActionTest.php @@ -5,11 +5,14 @@ namespace Answear\Payum\PayU\Tests\Integration\Action; use Answear\Payum\PayU\Action\CaptureAction; +use Answear\Payum\PayU\Enum\PayMethodType; use Answear\Payum\PayU\Exception\PayUException; use Answear\Payum\PayU\Model\Model; use Answear\Payum\PayU\Request\OrderRequestService; use Answear\Payum\PayU\Request\PayMethodsRequestService; use Answear\Payum\PayU\Tests\Util\FileTestUtil; +use Answear\Payum\PayU\ValueObject\Request\Order\PayMethod; +use Answear\Payum\PayU\ValueObject\Request\OrderRequest; use Answear\Payum\PayU\ValueObject\Response\OrderCreated\OrderCreatedStatus; use Answear\Payum\PayU\ValueObject\Response\OrderCreated\StatusCode; use Answear\Payum\PayU\ValueObject\Response\OrderCreatedResponse; @@ -51,6 +54,61 @@ public function captureTest(): void self::assertTrue($redirected); } + /** + * @test + */ + public function captureWithPayMethodTest(): void + { + $response = new OrderCreatedResponse( + new OrderCreatedStatus( + StatusCode::Success, + 'Żądanie zostało wykonane poprawnie.' + ), + 'http://redirect-after-create-payment.url', + 'WZHF5FFDRJ140731GUEST000P01', + 'vjis3d90tsozmuj0rjgs3i' + ); + + $expectedPayMethod = new PayMethod( + PayMethodType::Pbl, + 'ap', + 'authorization-code' + ); + + $orderRequestService = $this->createMock(OrderRequestService::class); + $orderRequestService->method('create') + ->with( + self::callback(function (OrderRequest $orderRequest) use ($expectedPayMethod) { + self::assertNotNull($orderRequest->payMethod); + self::assertSame($expectedPayMethod->toArray(), $orderRequest->payMethod->toArray()); + + return true; + }) + ) + ->willReturn($response); + + $details = FileTestUtil::decodeJsonFromFile(__DIR__ . '/data/detailsWithPayMethod.json'); + + $captureAction = $this->getCaptureAction(details: $details, orderRequestService: $orderRequestService); + + $captureToken = new Token(); + $capture = new Capture($captureToken); + $payment = new \Answear\Payum\PayU\Tests\Payment(); + $payment->storePayMethod($expectedPayMethod); + $capture->setModel($payment); + $capture->setModel($details); + + $redirected = false; + try { + $captureAction->execute($capture); + } catch (HttpRedirect $httpRedirect) { + $redirected = true; + self::assertSame('http://redirect-after-create-payment.url', $httpRedirect->getUrl()); + } + + self::assertTrue($redirected); + } + /** * @test */ @@ -155,8 +213,11 @@ public function captureWithOrderIdFailsTest(): void $captureAction->execute($capture); } - private function getCaptureAction(?OrderCreatedResponse $response = null, ?array $details = null): CaptureAction - { + private function getCaptureAction( + OrderCreatedResponse $response = null, + array $details = null, + OrderRequestService $orderRequestService = null + ): CaptureAction { $response = $response ?? new OrderCreatedResponse( new OrderCreatedStatus( StatusCode::Success, @@ -167,9 +228,11 @@ private function getCaptureAction(?OrderCreatedResponse $response = null, ?array 'vjis3d90tsozmuj0rjgs3i' ); - $orderRequestService = $this->createMock(OrderRequestService::class); - $orderRequestService->method('create') - ->willReturn($response); + if (null === $orderRequestService) { + $orderRequestService = $this->createMock(OrderRequestService::class); + $orderRequestService->method('create') + ->willReturn($response); + } $captureAction = new CaptureAction( $orderRequestService, diff --git a/tests/Integration/Action/ConvertActionTest.php b/tests/Integration/Action/ConvertActionTest.php index 7486c8b..c9cc350 100644 --- a/tests/Integration/Action/ConvertActionTest.php +++ b/tests/Integration/Action/ConvertActionTest.php @@ -6,8 +6,10 @@ use Answear\Payum\Model\PaidForInterface; use Answear\Payum\PayU\Action\ConvertPaymentAction; +use Answear\Payum\PayU\Enum\PayMethodType; use Answear\Payum\PayU\Service\UserIpService; use Answear\Payum\PayU\Tests\Payment; +use Answear\Payum\PayU\ValueObject\Request\Order\PayMethod; use Payum\Core\Model\CreditCard; use Payum\Core\Request\Convert; use PHPUnit\Framework\TestCase; @@ -101,6 +103,13 @@ public function convertWithFullDataTest(): void $payment->setLanguage('pl'); $payment->setConfigKey('pos2'); $payment->setPaidFor($paidFor); + $payment->storePayMethod( + new PayMethod( + PayMethodType::Pbl, + 'ap', + 'authorization-code' + ) + ); $convert = new Convert($payment, 'array'); $convertAction->execute($convert); @@ -128,6 +137,14 @@ public function convertWithFullDataTest(): void 'language' => 'pl', 'delivery' => null, ], + 'payMethods' => [ + 'payMethod' => [ + 'type' => 'PBL', + 'value' => 'ap', + 'authorizationCode' => 'authorization-code', + 'specificData' => null, + ], + ], 'status' => 'NEW', ], $convert->getResult() diff --git a/tests/Integration/Action/data/detailsWithPayMethod.json b/tests/Integration/Action/data/detailsWithPayMethod.json new file mode 100644 index 0000000..a65b078 --- /dev/null +++ b/tests/Integration/Action/data/detailsWithPayMethod.json @@ -0,0 +1,29 @@ +{ + "totalAmount": 95500, + "firstName": "Testy", + "lastName": "Mjzykdwmh", + "description": "Platnost za objedn\u00e1vku \u010d.: 221214-0026UJ-CZ", + "currencyCode": "CZK", + "language": "cs", + "validityTime": 259200, + "buyer": { + "email": "test@email-fake.domain", + "firstName": "Testy", + "lastName": "Mjzykdwmh", + "phone": "+420733999019", + "language": "cs" + }, + "payMethods": { + "payMethod": { + "type": "PBL", + "value": "ap", + "authorizationCode": "authorization-code", + "specificData": null + } + }, + "extOrderId": "221214-0026UJ-CZ", + "client_email": "test@email-fake.domain", + "client_id": "124077", + "customerIp": "10.0.13.152", + "creditCardMaskedNumber": null +} diff --git a/tests/Payment.php b/tests/Payment.php index a5d9d5f..513b3ff 100644 --- a/tests/Payment.php +++ b/tests/Payment.php @@ -5,6 +5,7 @@ namespace Answear\Payum\PayU\Tests; use Answear\Payum\Model\PaidForInterface; +use Answear\Payum\PayU\ValueObject\Request\Order\PayMethod; class Payment extends \Answear\Payum\Model\Payment { @@ -13,6 +14,7 @@ class Payment extends \Answear\Payum\Model\Payment private string $configKey; private PaidForInterface $paidFor; private string $language; + private ?PayMethod $payMethod = null; public function getGatewayName(): string { @@ -63,4 +65,14 @@ public function setLanguage(string $language): void { $this->language = $language; } + + public function getPayMethod(): ?PayMethod + { + return $this->payMethod; + } + + public function storePayMethod(PayMethod $payMethod): void + { + $this->payMethod = $payMethod; + } }