diff --git a/README.md b/README.md index cab9258..6b13b9b 100644 --- a/README.md +++ b/README.md @@ -62,5 +62,5 @@ $gateway->execute($captureRequest); ### Missing features -* `OrderRequest` params `recurring`, `mcpData`, `threeDsAuthentication`, `credit` +* `OrderRequest` params `recurring`, `mcpData`, `credit` * ... diff --git a/src/Action/CaptureAction.php b/src/Action/CaptureAction.php index 8bab9b8..387c5d8 100644 --- a/src/Action/CaptureAction.php +++ b/src/Action/CaptureAction.php @@ -153,7 +153,8 @@ private function prepareOrderRequest(Capture $request, TokenInterface $token, Mo $model->additionalDescription(), $model->visibleDescription(), $model->statementDescription(), - $model->cardOnFile() + $model->cardOnFile(), + threeDsAuthentication: $model->threeDsAuthentication(), ); } diff --git a/src/Enum/ChallengeRequestedType.php b/src/Enum/ChallengeRequestedType.php new file mode 100644 index 0000000..0ef5c60 --- /dev/null +++ b/src/Enum/ChallengeRequestedType.php @@ -0,0 +1,12 @@ +value; } + public function threeDsAuthentication(): ?ThreeDsAuthentication + { + if (!isset($this[ModelFields::THREE_DS_AUTHENTICATION])) { + return null; + } + + return new ThreeDsAuthentication( + ChallengeRequestedType::from($this[ModelFields::THREE_DS_AUTHENTICATION][ModelFields::CHALLENGE_REQUESTED]) + ); + } + public function setPayUResponse(Response\OrderCreatedResponse $orderCreatedResponse): void { $this[ModelFields::PAYU_RESPONSE] = $orderCreatedResponse->toArray(); diff --git a/src/ValueObject/Request/Order/ThreeDsAuthentication.php b/src/ValueObject/Request/Order/ThreeDsAuthentication.php new file mode 100644 index 0000000..5a8e2be --- /dev/null +++ b/src/ValueObject/Request/Order/ThreeDsAuthentication.php @@ -0,0 +1,25 @@ + + */ + public function toArray(): array + { + return [ + 'challangeRequested' => $this->challengeRequested->value, + ]; + } +} diff --git a/src/ValueObject/Request/OrderRequest.php b/src/ValueObject/Request/OrderRequest.php index b9c9c07..ff51273 100644 --- a/src/ValueObject/Request/OrderRequest.php +++ b/src/ValueObject/Request/OrderRequest.php @@ -10,6 +10,7 @@ use Answear\Payum\PayU\ValueObject\Buyer; use Answear\Payum\PayU\ValueObject\Product; use Answear\Payum\PayU\ValueObject\Request\Order\PayMethod; +use Answear\Payum\PayU\ValueObject\Request\Order\ThreeDsAuthentication; use Webmozart\Assert\Assert; class OrderRequest @@ -38,6 +39,7 @@ public function __construct( public readonly ?string $statementDescription = null, public ?CardOnFileEnum $cardOnFile = null, public ?string $recurring = null, + public ?ThreeDsAuthentication $threeDsAuthentication = null, ) { Assert::notEmpty($this->products); Assert::allIsInstanceOf($this->products, Product::class); @@ -64,6 +66,7 @@ public function toArray(string $merchantPosId): array 'buyer' => $this->buyer?->toArray(), 'products' => array_map(static fn(Product $product) => $product->toArray(), $this->products), 'payMethods' => null === $this->payMethod ? null : ['payMethod' => $this->payMethod->toArray()], + 'threeDsAuthentication' => $this->threeDsAuthentication?->toArray(), 'cardOnFile' => $this->cardOnFile?->value, 'recurring' => $this->recurring, ]; diff --git a/tests/Integration/Action/CaptureActionTest.php b/tests/Integration/Action/CaptureActionTest.php index 6a14e09..8ead342 100644 --- a/tests/Integration/Action/CaptureActionTest.php +++ b/tests/Integration/Action/CaptureActionTest.php @@ -5,6 +5,8 @@ namespace Answear\Payum\PayU\Tests\Integration\Action; use Answear\Payum\PayU\Action\CaptureAction; +use Answear\Payum\PayU\Enum\ChallengeRequestedType; +use Answear\Payum\PayU\Enum\ModelFields; use Answear\Payum\PayU\Enum\PayMethodType; use Answear\Payum\PayU\Exception\PayUException; use Answear\Payum\PayU\Model\Model; @@ -56,6 +58,35 @@ public function captureTest(): void self::assertTrue($redirected); } + /** + * @test + */ + public function captureTestWithThreeDSAuthentication(): void + { + $details = FileTestUtil::decodeJsonFromFile(__DIR__ . '/data/details.json'); + $details[ModelFields::THREE_DS_AUTHENTICATION][ModelFields::CHALLENGE_REQUESTED] = ChallengeRequestedType::Mandate->value; + + $captureAction = $this->getCaptureAction( + expectedCreateRequest: FileTestUtil::decodeJsonFromFile(__DIR__ . '/data/expectedOrderRequestWithThreeDSAuthentication.json'), + details: $details + ); + + $captureToken = new Token(); + $capture = new Capture($captureToken); + $capture->setModel(new \Answear\Payum\PayU\Tests\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 */ diff --git a/tests/Integration/Action/data/expectedOrderRequest.json b/tests/Integration/Action/data/expectedOrderRequest.json index 795f442..c368dae 100644 --- a/tests/Integration/Action/data/expectedOrderRequest.json +++ b/tests/Integration/Action/data/expectedOrderRequest.json @@ -32,6 +32,7 @@ } ], "payMethods": null, + "threeDsAuthentication": null, "cardOnFile": null, "recurring": null } diff --git a/tests/Integration/Action/data/expectedOrderRequestWithPayMethod.json b/tests/Integration/Action/data/expectedOrderRequestWithPayMethod.json index 2f84f9e..6a4ec02 100644 --- a/tests/Integration/Action/data/expectedOrderRequestWithPayMethod.json +++ b/tests/Integration/Action/data/expectedOrderRequestWithPayMethod.json @@ -39,6 +39,7 @@ "specificData": null } }, + "threeDsAuthentication": null, "cardOnFile": null, "recurring": null } diff --git a/tests/Integration/Action/data/expectedOrderRequestWithThreeDSAuthentication.json b/tests/Integration/Action/data/expectedOrderRequestWithThreeDSAuthentication.json new file mode 100644 index 0000000..a3d3987 --- /dev/null +++ b/tests/Integration/Action/data/expectedOrderRequestWithThreeDSAuthentication.json @@ -0,0 +1,40 @@ +{ + "extOrderId": "221214-0026UJ-CZ", + "notifyUrl": "http:\/\/notify.url", + "customerIp": "10.0.13.152", + "merchantPosId": "posId", + "validityTime": 259200, + "description": "Platnost za objedn\u00e1vku \u010d.: 221214-0026UJ-CZ", + "additionalDescription": null, + "visibleDescription": null, + "statementDescription": null, + "currencyCode": "CZK", + "totalAmount": 95500, + "continueUrl": null, + "buyer": { + "email": "test@email-fake.domain", + "firstName": "Testy", + "lastName": "Mjzykdwmh", + "phone": "+420733999019", + "customerId": null, + "extCustomerId": null, + "nin": null, + "language": "cs", + "delivery": null + }, + "products": [ + { + "name": "Platnost za objedn\u00e1vku \u010d.: 221214-0026UJ-CZ", + "unitPrice": 95500, + "quantity": 1, + "virtual": null, + "listingDate": null + } + ], + "payMethods": null, + "threeDsAuthentication": { + "challangeRequested": "MANDATE" + }, + "cardOnFile": null, + "recurring": null +}