From 57ea1b5acce5bdb293e674597bd57a8ed3b4f590 Mon Sep 17 00:00:00 2001 From: juhopekkavuorela Date: Fri, 30 Jun 2023 13:15:17 +0300 Subject: [PATCH 01/32] Add method for pay and add card -endpoint --- src/Client.php | 18 ++++++ src/Response/AddCardPaymentResponse.php | 79 +++++++++++++++++++++++++ tests/ClientTest.php | 7 +++ 3 files changed, 104 insertions(+) create mode 100644 src/Response/AddCardPaymentResponse.php diff --git a/src/Client.php b/src/Client.php index 9a43845..663f80c 100644 --- a/src/Client.php +++ b/src/Client.php @@ -38,6 +38,7 @@ use Paytrail\SDK\Exception\ValidationException; use Paytrail\SDK\Exception\RequestException; use Paytrail\SDK\Exception\ClientException; +use Paytrail\SDK\Response\AddCardPaymentResponse; /** * Class Client @@ -262,6 +263,23 @@ function ($decoded) { return $paymentResponse; } + public function createPaymentAndAddCard(PaymentRequest $paymentRequest): AddCardPaymentResponse + { + $this->validateRequestItem($paymentRequest); + + $uri = '/tokenization/pay-and-add-card'; + + return $this->post( + $uri, + $paymentRequest, + function ($decoded) { + return (new AddCardPaymentResponse()) + ->setTransactionId($decoded->transactionId ?? null) + ->setRedirectUrl($decoded->redirectUrl ?? null); + } + ); + } + /** * Create a payment status request. * diff --git a/src/Response/AddCardPaymentResponse.php b/src/Response/AddCardPaymentResponse.php new file mode 100644 index 0000000..c058b0f --- /dev/null +++ b/src/Response/AddCardPaymentResponse.php @@ -0,0 +1,79 @@ +transactionId; + } + + /** + * Set the transaction id. + * + * @param string|null $transactionId + * + * @return self Return self to enable chaining. + */ + public function setTransactionId(?string $transactionId): AddCardPaymentResponse + { + $this->transactionId = $transactionId; + + return $this; + } + + /** + * Get the redirectUrl. + * + * @return string|null + */ + public function getRedirectUrl(): ?string + { + return $this->redirectUrl; + } + + /** + * Set the redirectUrl. + * + * @param string|null $redirectUrl + * + * @return self Return self to enable chaining. + */ + public function setRedirectUrl(?string $redirectUrl): AddCardPaymentResponse + { + $this->redirectUrl = $redirectUrl; + + return $this; + } +} diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 098d302..adce6f6 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -609,4 +609,11 @@ public function testRequestPaymentReportThrowsExceptionWhenEndDateIsInWrongForma ->setEndDate('1.1.2023'); $this->client->requestPaymentReport($reportRequest); } + + public function testPayAndAddCardReturnsTransactionIdAndUrl() + { + $response = $this->client->createPaymentAndAddCard($this->paymentRequest); + $this->assertIsString($response->getTransactionId()); + $this->assertIsString($response->getRedirectUrl()); + } } From 666653bceaedc737fa80999951b552332314bb65 Mon Sep 17 00:00:00 2001 From: juhopekkavuorela Date: Fri, 30 Jun 2023 13:18:07 +0300 Subject: [PATCH 02/32] Update readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 816d2a8..63e12bf 100644 --- a/README.md +++ b/README.md @@ -113,6 +113,7 @@ List of `Client::class` methods | requestSettlements() | Request settlements | | requestPaymentReport() | Request payment report | | requestPaymentReportBySettlement() | Request payment report by settlement ID | +| createPaymentAndAddCard() | Create payment and save card details | --- From ce458d0314f42806b9c61315293a62fb236db2a8 Mon Sep 17 00:00:00 2001 From: juhopekkavuorela Date: Fri, 29 Sep 2023 13:50:58 +0300 Subject: [PATCH 03/32] Assert payment method provider is Provider object --- tests/ClientTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index adce6f6..5f0de2d 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -23,6 +23,7 @@ use Paytrail\SDK\Request\RevertPaymentAuthHoldRequest; use Paytrail\SDK\Request\SettlementRequest; use Paytrail\SDK\Request\ShopInShopPaymentRequest; +use Paytrail\SDK\Model\Provider; class ClientTest extends PaymentRequestTestCase { @@ -510,7 +511,8 @@ public function testGetGroupedPaymentProvidersAcceptsLanguageParameters() { $providers = $this->client->getGroupedPaymentProviders(100, 'EN'); $this->assertIsArray($providers); - $this->assertEquals('Mobile payment methods', $providers['groups'][0]['name']); + // Get first provider groups providers and select first provider from array. + $this->assertInstanceOf(Provider::class, $providers['groups'][0]['providers'][0]); } public function testRequestPaymentReportReturnsRequestId() From 50a03c27f7d63d6f4727bb3e68ef8e48b596be58 Mon Sep 17 00:00:00 2001 From: juhopekkavuorela Date: Fri, 29 Sep 2023 14:06:50 +0300 Subject: [PATCH 04/32] Use latest phstan on CI --- .github/workflows/run-workflow.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-workflow.yaml b/.github/workflows/run-workflow.yaml index 94b2bf7..d24ef08 100644 --- a/.github/workflows/run-workflow.yaml +++ b/.github/workflows/run-workflow.yaml @@ -34,7 +34,7 @@ jobs: uses: php-actions/phpstan@v3 with: php_version: ${{ matrix.php-version }} - version: 1.9.14 + version: latest configuration: phpstan.neon memory_limit: 256M From 9bd886909567a873a23dbf281847ccd396afc830 Mon Sep 17 00:00:00 2001 From: Joonas Loueranta Date: Thu, 12 Oct 2023 13:18:20 +0200 Subject: [PATCH 05/32] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e3ac96..da01a3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.6.0] - 2023-10-12 +### Added +- Add pay and add card endpoint +### Fixed +- Fix payment provider unit test + ## [2.5.2] - 2023-05-05 ### Fixed - Improved refundRequest Validation From 4a8483fd8bd05ad54d075c96bb606850672ca681 Mon Sep 17 00:00:00 2001 From: = <=> Date: Wed, 10 Jan 2024 12:30:43 +0200 Subject: [PATCH 06/32] Validate too long item descriptions on client side --- composer.json | 3 ++- src/Client.php | 1 + src/Model/Item.php | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a07cee6..69c7df6 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,8 @@ "require": { "php": ">=7.3", "ext-json": "*", - "ext-curl": "*" + "ext-curl": "*", + "ext-mbstring": "*" }, "require-dev": { "phpunit/phpunit": "^10.0 || ^9.0", diff --git a/src/Client.php b/src/Client.php index 663f80c..159d137 100644 --- a/src/Client.php +++ b/src/Client.php @@ -234,6 +234,7 @@ function ($decoded) { * @return PaymentResponse * @throws HmacException Thrown if HMAC calculation fails for responses. * @throws ValidationException Thrown if payment validation fails. + * @throws ClientException Thrown if API call fails. */ public function createShopInShopPayment(ShopInShopPaymentRequest $payment): PaymentResponse { diff --git a/src/Model/Item.php b/src/Model/Item.php index 3847dca..25527ca 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -397,6 +397,9 @@ public function validate() if (empty($props['productCode'])) { throw new ValidationException('productCode is empty'); } + if (mb_strlen($props['description']) > 1000) { + throw new ValidationException('description does not meet maximum length of 1000'); + } return true; } From 8e349fe3c9b703c861acb9c6562a79f08bdab364 Mon Sep 17 00:00:00 2001 From: = <=> Date: Wed, 10 Jan 2024 12:42:19 +0200 Subject: [PATCH 07/32] Add null check --- src/Model/Item.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/Item.php b/src/Model/Item.php index 25527ca..98549a4 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -397,7 +397,7 @@ public function validate() if (empty($props['productCode'])) { throw new ValidationException('productCode is empty'); } - if (mb_strlen($props['description']) > 1000) { + if ($props['description'] !== null && mb_strlen($props['description']) > 1000) { throw new ValidationException('description does not meet maximum length of 1000'); } From 1e3c0e14faffa8555025740bdd2a41735ff1a75b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Ka=C5=82u=C5=BCny?= Date: Tue, 27 Feb 2024 11:37:31 +0100 Subject: [PATCH 08/32] SQMAGOPC-232: add customProviders to payment_response --- src/Client.php | 3 ++- src/Response/PaymentResponse.php | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/Client.php b/src/Client.php index 663f80c..b643804 100644 --- a/src/Client.php +++ b/src/Client.php @@ -219,7 +219,8 @@ function ($decoded) { ->setTerms($decoded->terms ?? null) ->setGroups($decoded->groups ?? []) ->setReference($decoded->reference ?? null) - ->setProviders($decoded->providers ?? []); + ->setProviders($decoded->providers ?? []) + ->setCustomProviders((array)$decoded->customProviders ?? []); } ); diff --git a/src/Response/PaymentResponse.php b/src/Response/PaymentResponse.php index 5ec4671..4bb4618 100644 --- a/src/Response/PaymentResponse.php +++ b/src/Response/PaymentResponse.php @@ -59,6 +59,13 @@ class PaymentResponse implements ResponseInterface */ protected $providers = []; + /** + * Custom providers. + * + * @var object + */ + protected $customProviders = \stdClass::class; + /** * Get the transaction id. * @@ -203,4 +210,27 @@ public function setProviders(array $providers): PaymentResponse return $this; } + + /** + * Get custom providers. + * + * @return array|string + */ + public function getCustomProviders(): array + { + return $this->customProviders ?? []; + } + + /** + * Set custom providers. + * + * @param array|null $customProviders + * @return PaymentResponse + */ + public function setCustomProviders(?array $customProviders): PaymentResponse + { + $this->customProviders = $customProviders; + + return $this; + } } From 0486afcc64c76daf8303d54809fbd03f2209b163 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Ka=C5=82u=C5=BCny?= Date: Tue, 27 Feb 2024 11:40:04 +0100 Subject: [PATCH 09/32] SQMAGOPC-232: change properties --- src/Response/PaymentResponse.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Response/PaymentResponse.php b/src/Response/PaymentResponse.php index 4bb4618..53e8e2e 100644 --- a/src/Response/PaymentResponse.php +++ b/src/Response/PaymentResponse.php @@ -62,9 +62,9 @@ class PaymentResponse implements ResponseInterface /** * Custom providers. * - * @var object + * @var array */ - protected $customProviders = \stdClass::class; + protected $customProviders = []; /** * Get the transaction id. From 5f1c769929dff7254db8e8cf803c84cbd1a75336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Ka=C5=82u=C5=BCny?= Date: Tue, 27 Feb 2024 11:43:46 +0100 Subject: [PATCH 10/32] SQMAGOPC-232: fix PHPDoc --- src/Response/PaymentResponse.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Response/PaymentResponse.php b/src/Response/PaymentResponse.php index 53e8e2e..181fc8c 100644 --- a/src/Response/PaymentResponse.php +++ b/src/Response/PaymentResponse.php @@ -214,7 +214,7 @@ public function setProviders(array $providers): PaymentResponse /** * Get custom providers. * - * @return array|string + * @return array */ public function getCustomProviders(): array { From a591f5053d724b0fb45ebe218629a6add6de1ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Ka=C5=82u=C5=BCny?= Date: Tue, 27 Feb 2024 12:58:55 +0100 Subject: [PATCH 11/32] SQMAGOPC-232: fix test --- tests/ClientTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 5f0de2d..05df1ef 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -237,7 +237,7 @@ public function testGetTokenRequest() 'partial_pan' => '0024', 'expire_year' => '2023', 'expire_month' => '11', - 'cvc_required' => 'no', + 'cvc_required' => 'not_tested', 'funding' => 'debit', 'category' => 'unknown', 'country_code' => 'FI', From 7b646f7048573561532226874adb60007d755c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Ka=C5=82u=C5=BCny?= Date: Tue, 27 Feb 2024 17:38:47 +0100 Subject: [PATCH 12/32] SQMAGOPC-232: change card details in test --- tests/ClientTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 05df1ef..c65158a 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -235,9 +235,9 @@ public function testGetTokenRequest() 'type' => 'Visa', 'bin' => '415301', 'partial_pan' => '0024', - 'expire_year' => '2023', + 'expire_year' => '2026', 'expire_month' => '11', - 'cvc_required' => 'not_tested', + 'cvc_required' => 'no', 'funding' => 'debit', 'category' => 'unknown', 'country_code' => 'FI', From 81c8723921f308a9b5d92f39c5621cad83177aef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Ka=C5=82u=C5=BCny?= Date: Wed, 28 Feb 2024 09:52:37 +0100 Subject: [PATCH 13/32] SQMAGOPC-232: change card token --- tests/ClientTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index c65158a..313379c 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -216,7 +216,7 @@ public function testAddCardFormRequest() public function testGetTokenRequest() { - $checkoutTokenizationId = '818c478e-5682-46bf-97fd-b9c2b93a3fcd'; + $checkoutTokenizationId = 'b34e5821-2a85-4840-8b27-21ef81168bec'; $client = $this->client; @@ -230,19 +230,19 @@ public function testGetTokenRequest() $responseJsonData = $response->jsonSerialize(); $expectedArray = [ - 'token' => 'c7441208-c2a1-4a10-8eb6-458bd8eaa64f', + 'token' => '798b445a-2216-46b7-ad1a-000f40ced6e8', 'card' => [ 'type' => 'Visa', 'bin' => '415301', 'partial_pan' => '0024', 'expire_year' => '2026', 'expire_month' => '11', - 'cvc_required' => 'no', + 'cvc_required' => 'not_tested', 'funding' => 'debit', 'category' => 'unknown', 'country_code' => 'FI', 'pan_fingerprint' => '693a68deec6d6fa363c72108f8d656d4fd0b6765f5457dd1c139523f4daaafce', - 'card_fingerprint' => 'c34cdd1952deb81734c012fbb11eabc56c4d61d198f28b448327ccf13f45417f' + 'card_fingerprint' => '24973f9037d418c0258ee61d90970c15a1c434a457d3974c9cdc12742f87c673' ], 'customer' => [ 'network_address' => '93.174.192.154', From 2d2c94d7b380c561d03e302523cd878091bf5a2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Ka=C5=82u=C5=BCny?= Date: Wed, 28 Feb 2024 09:56:31 +0100 Subject: [PATCH 14/32] SQMAGOPC-232: change customer data --- tests/ClientTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 313379c..d8298d2 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -245,8 +245,8 @@ public function testGetTokenRequest() 'card_fingerprint' => '24973f9037d418c0258ee61d90970c15a1c434a457d3974c9cdc12742f87c673' ], 'customer' => [ - 'network_address' => '93.174.192.154', - 'country_code' => 'FI' + 'network_address' => '89.35.145.204', + 'country_code' => 'PL' ] ]; From 2c010687f7f337d63e1b89e2531a2d8972c3c6e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Ka=C5=82u=C5=BCny?= Date: Wed, 28 Feb 2024 10:03:09 +0100 Subject: [PATCH 15/32] SQMAGOPC-232: change other tokens in tests --- tests/ClientTest.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index d8298d2..f8f3588 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -261,7 +261,7 @@ public function testCitPaymentRequestCharge() $client = $this->client; $paymentRequest = $this->citPaymentRequest; - $citPaymentRequest = $paymentRequest->setToken('c7441208-c2a1-4a10-8eb6-458bd8eaa64f'); + $citPaymentRequest = $paymentRequest->setToken('798b445a-2216-46b7-ad1a-000f40ced6e8'); $this->assertTrue($citPaymentRequest->validate()); @@ -287,7 +287,7 @@ public function testMitPaymentRequestCharge() $client = $this->client; $paymentRequest = $this->mitPaymentRequest; - $mitPaymentRequest = $paymentRequest->setToken('c7441208-c2a1-4a10-8eb6-458bd8eaa64f'); + $mitPaymentRequest = $paymentRequest->setToken('798b445a-2216-46b7-ad1a-000f40ced6e8'); $this->assertTrue($mitPaymentRequest->validate()); @@ -328,7 +328,7 @@ public function testCitPaymentRequestAuthorizationHold() $client = $this->client; $paymentRequest = $this->citPaymentRequest; - $citPaymentRequest = $paymentRequest->setToken('c7441208-c2a1-4a10-8eb6-458bd8eaa64f'); + $citPaymentRequest = $paymentRequest->setToken('798b445a-2216-46b7-ad1a-000f40ced6e8'); $this->assertTrue($citPaymentRequest->validate()); @@ -354,7 +354,7 @@ public function testMitPaymentRequestAuthorizationHold() $client = $this->client; $paymentRequest = $this->mitPaymentRequest; - $mitPaymentRequest = $paymentRequest->setToken('c7441208-c2a1-4a10-8eb6-458bd8eaa64f'); + $mitPaymentRequest = $paymentRequest->setToken('798b445a-2216-46b7-ad1a-000f40ced6e8'); $this->assertTrue($mitPaymentRequest->validate()); @@ -396,7 +396,7 @@ public function testCitPaymentRequestCommit() $paymentRequest = $this->citPaymentRequest; $transactionId = 'c12e224e-806f-11ea-9de3-33451a6f6d70'; - $citPaymentRequest = $paymentRequest->setToken('c7441208-c2a1-4a10-8eb6-458bd8eaa64f'); + $citPaymentRequest = $paymentRequest->setToken('798b445a-2216-46b7-ad1a-000f40ced6e8'); $this->assertTrue($citPaymentRequest->validate()); @@ -410,7 +410,7 @@ public function testMitPaymentRequestCommit() $paymentRequest = $this->mitPaymentRequest; $transactionId = 'c12e224e-806f-11ea-9de3-33451a6f6d70'; - $mitPaymentRequest = $paymentRequest->setToken('c7441208-c2a1-4a10-8eb6-458bd8eaa64f'); + $mitPaymentRequest = $paymentRequest->setToken('798b445a-2216-46b7-ad1a-000f40ced6e8'); $this->assertTrue($mitPaymentRequest->validate()); @@ -423,7 +423,7 @@ public function testRevertCitPaymentAuthorizationHold() $client = $this->client; $paymentRequest = $this->citPaymentRequest; - $citPaymentRequest = $paymentRequest->setToken('c7441208-c2a1-4a10-8eb6-458bd8eaa64f'); + $citPaymentRequest = $paymentRequest->setToken('798b445a-2216-46b7-ad1a-000f40ced6e8'); $this->assertTrue($citPaymentRequest->validate()); @@ -448,7 +448,7 @@ public function testRevertMitPaymentAuthorizationHold() $client = $this->client; $paymentRequest = $this->mitPaymentRequest; - $mitPaymentRequest = $paymentRequest->setToken('c7441208-c2a1-4a10-8eb6-458bd8eaa64f'); + $mitPaymentRequest = $paymentRequest->setToken('798b445a-2216-46b7-ad1a-000f40ced6e8'); $this->assertTrue($mitPaymentRequest->validate()); From 774f16a657220ef1c2f1bbc756f12e70597b31dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Ka=C5=82u=C5=BCny?= Date: Wed, 28 Feb 2024 10:08:43 +0100 Subject: [PATCH 16/32] SQMAGOPC-232: change 3DS card token in tests --- tests/ClientTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index f8f3588..f7e60a0 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -313,7 +313,7 @@ public function testCitPaymentRequestCharge3DS() $client = $this->client; $paymentRequest = $this->citPaymentRequest; - $citPaymentRequest = $paymentRequest->setToken('40037d79-5c7f-4ffe-bf86-2d2025b64c36'); + $citPaymentRequest = $paymentRequest->setToken('8d3cb70a-7911-42c4-81cd-5318a5f269a4'); $this->assertTrue($citPaymentRequest->validate()); @@ -380,7 +380,7 @@ public function testCitPaymentRequestAuthorizationHold3DS() $client = $this->client; $paymentRequest = $this->citPaymentRequest; - $citPaymentRequest = $paymentRequest->setToken('40037d79-5c7f-4ffe-bf86-2d2025b64c36'); + $citPaymentRequest = $paymentRequest->setToken('8d3cb70a-7911-42c4-81cd-5318a5f269a4'); $this->assertTrue($citPaymentRequest->validate()); From fcfa76c38aaa660d98d643c9ea81948e7cb9294e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Ka=C5=82u=C5=BCny?= Date: Wed, 28 Feb 2024 10:23:31 +0100 Subject: [PATCH 17/32] SQMAGOPC-232: add comments for tests --- tests/ClientTest.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index f7e60a0..5a96bd3 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -216,6 +216,12 @@ public function testAddCardFormRequest() public function testGetTokenRequest() { + // To update after 11/2026 + // Get new tokenization_id, card and customer details. + // 'add-card' action will return tokenization_id, + // and with tokenization_id we could get card and customer details. + // Card used: 0024 https://docs.paytrail.com/#/payment-method-providers?id=test-cards-for-payments + $checkoutTokenizationId = 'b34e5821-2a85-4840-8b27-21ef81168bec'; $client = $this->client; @@ -310,6 +316,10 @@ public function testMitPaymentRequestCharge() public function testCitPaymentRequestCharge3DS() { + // To update after 11/2026 + // Card required with 3DS + // Card: 0170 https://docs.paytrail.com/#/payment-method-providers?id=test-cards-for-payments + $client = $this->client; $paymentRequest = $this->citPaymentRequest; From 8e75d89cd09b6805c7896934e2c4987145174c58 Mon Sep 17 00:00:00 2001 From: Joonas Loueranta Date: Thu, 21 Mar 2024 10:39:44 +0100 Subject: [PATCH 18/32] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index da01a3b..e8c0afa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.7.0] - 2024-03-21 +### Added +- Added customProviders to createPayment() response + ## [2.6.0] - 2023-10-12 ### Added - Add pay and add card endpoint From 585cfa0f9237533c17cbf31e0fd129c793017425 Mon Sep 17 00:00:00 2001 From: Mikko Pesari Date: Mon, 25 Mar 2024 12:59:18 +0200 Subject: [PATCH 19/32] Run tests on PHP 8.3 --- .github/workflows/run-workflow.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-workflow.yaml b/.github/workflows/run-workflow.yaml index d24ef08..88f1a30 100644 --- a/.github/workflows/run-workflow.yaml +++ b/.github/workflows/run-workflow.yaml @@ -14,7 +14,7 @@ jobs: continue-on-error: ${{ matrix.experimental }} strategy: matrix: - php-version: ['7.3', '7.4', '8.0', '8.1', '8.2'] + php-version: ['7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] experimental: [false] steps: - uses: actions/checkout@v3 From 0f0aeb6a2c48114f3e6183c8dda119093b81de76 Mon Sep 17 00:00:00 2001 From: Mikko Pesari Date: Mon, 25 Mar 2024 12:43:28 +0200 Subject: [PATCH 20/32] Fix access to possibly undefined property --- src/Client.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Client.php b/src/Client.php index b643804..fd22ae7 100644 --- a/src/Client.php +++ b/src/Client.php @@ -220,7 +220,7 @@ function ($decoded) { ->setGroups($decoded->groups ?? []) ->setReference($decoded->reference ?? null) ->setProviders($decoded->providers ?? []) - ->setCustomProviders((array)$decoded->customProviders ?? []); + ->setCustomProviders((array)($decoded->customProviders ?? [])); } ); From 9236ec9b208de9ee1f9a7e0f99b4c379298572f8 Mon Sep 17 00:00:00 2001 From: Joonas Loueranta Date: Tue, 16 Apr 2024 14:14:16 +0200 Subject: [PATCH 21/32] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8c0afa..7b23031 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.7.1] - 2024-04-16 +### Added +- Run tests on PHP 8.3 +### Fixed +- Fix access to possibly undefined property +- Validate too long item descriptions on client side + ## [2.7.0] - 2024-03-21 ### Added - Added customProviders to createPayment() response From 3adef5bdfdae470f14d594c57e804fa18092602c Mon Sep 17 00:00:00 2001 From: Konrad Konieczny <51909244+konrad-konieczny@users.noreply.github.com> Date: Wed, 22 May 2024 17:23:04 +0200 Subject: [PATCH 22/32] remove negative rows validation --- src/Model/Item.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Model/Item.php b/src/Model/Item.php index 98549a4..111c26f 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -379,9 +379,6 @@ public function validate() if ($props['unitPrice'] === null) { throw new ValidationException('Item unitPrice is empty'); } - if ($props['unitPrice'] < 0) { - throw new ValidationException('Items unitPrice can\'t be a negative number'); - } if ($props['unitPrice'] > 99999999) { throw new ValidationException('Items unitPrice can\'t be over 99999999'); } From 0a268dd009d3e5016a02eafe76ce8e39e6f570fe Mon Sep 17 00:00:00 2001 From: "konrad.konieczny" Date: Tue, 4 Jun 2024 17:34:35 +0200 Subject: [PATCH 23/32] add shop in shop negative validation --- src/Model/Item.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Model/Item.php b/src/Model/Item.php index 111c26f..4fa32a5 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -414,6 +414,10 @@ public function validateShopInShop() throw new ValidationException('merchant is empty'); } + if ($props['unitPrice'] < 0) { + throw new ValidationException('Shop-in-shop item unitPrice can\'t be a negative number'); + } + return true; } } From 45043494b5e2f15e22f8570951bd9eb7533e02e3 Mon Sep 17 00:00:00 2001 From: "konrad.konieczny" Date: Tue, 4 Jun 2024 17:34:49 +0200 Subject: [PATCH 24/32] update unit test --- tests/Model/ItemTest.php | 51 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/tests/Model/ItemTest.php b/tests/Model/ItemTest.php index b544c34..0df2900 100644 --- a/tests/Model/ItemTest.php +++ b/tests/Model/ItemTest.php @@ -83,9 +83,19 @@ public function testItemWithoutProductCodeThrowsError() public static function providerForUnitPriceLimitValues() { return [ - 'Negative amount' => [-1, false], - 'Zero amount' => [0, true], - 'Maximum amount' => [99999999, true], + 'Negative amount' => [-1, true], + 'Zero amount' => [0, true], + 'Maximum amount' => [99999999, true], + 'Over maximum amount' => [100000000, false] + ]; + } + + public static function providerForUnitPriceLimitValuesShopInShop() + { + return [ + 'Negative amount' => [-1, false], + 'Zero amount' => [0, true], + 'Maximum amount' => [99999999, true], 'Over maximum amount' => [100000000, false] ]; } @@ -111,4 +121,39 @@ public function testUnitPriceLimitValues($unitPrice, $expectedResult) $this->assertEquals($expectedResult, $validationResult); } + + public function testValidateShopInShopThrowsExceptionWhenMerchantIsEmpty(): void + { + $this->expectException(ValidationException::class); + $this->expectExceptionMessage('merchant is empty'); + + $item = (new Item()) + ->setUnitPrice(213) + ->setUnits(2) + ->setProductCode('pr1') + ->validateShopInShop(); + } + + /** + * @dataProvider providerForUnitPriceLimitValuesShopInShop + */ + public function testValidateShopInShopThrowsExceptionWhenUnitPriceIsNegative($unitPrice, $expectedResult): void + { + $item = new Item(); + $item->setUnitPrice($unitPrice); + $item->setUnits(2); + $item->setProductCode('pr1'); + $item->setMerchant('merchant1'); + + + try { + $item->validate(); + $validationResult = $item->validateShopInShop(); + } catch (ValidationException $exception) { + $validationResult = false; + } + + $this->assertEquals($expectedResult, $validationResult); + + } } From 7eb487e7c670e997b744e7e76bd02029a1f44448 Mon Sep 17 00:00:00 2001 From: "konrad.konieczny" Date: Tue, 4 Jun 2024 17:36:03 +0200 Subject: [PATCH 25/32] reformat --- tests/Model/ItemTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Model/ItemTest.php b/tests/Model/ItemTest.php index 0df2900..f8b9880 100644 --- a/tests/Model/ItemTest.php +++ b/tests/Model/ItemTest.php @@ -145,7 +145,6 @@ public function testValidateShopInShopThrowsExceptionWhenUnitPriceIsNegative($un $item->setProductCode('pr1'); $item->setMerchant('merchant1'); - try { $item->validate(); $validationResult = $item->validateShopInShop(); @@ -154,6 +153,5 @@ public function testValidateShopInShopThrowsExceptionWhenUnitPriceIsNegative($un } $this->assertEquals($expectedResult, $validationResult); - } } From ff4181cdf6b919b37519b2cd854f192d297353cc Mon Sep 17 00:00:00 2001 From: "konrad.konieczny" Date: Tue, 4 Jun 2024 18:12:47 +0200 Subject: [PATCH 26/32] add shopinshop request validation test --- tests/Model/ItemTest.php | 33 -------- .../Request/ShopInShopPaymentRequestTest.php | 82 +++++++++++++++++++ 2 files changed, 82 insertions(+), 33 deletions(-) diff --git a/tests/Model/ItemTest.php b/tests/Model/ItemTest.php index f8b9880..424768d 100644 --- a/tests/Model/ItemTest.php +++ b/tests/Model/ItemTest.php @@ -121,37 +121,4 @@ public function testUnitPriceLimitValues($unitPrice, $expectedResult) $this->assertEquals($expectedResult, $validationResult); } - - public function testValidateShopInShopThrowsExceptionWhenMerchantIsEmpty(): void - { - $this->expectException(ValidationException::class); - $this->expectExceptionMessage('merchant is empty'); - - $item = (new Item()) - ->setUnitPrice(213) - ->setUnits(2) - ->setProductCode('pr1') - ->validateShopInShop(); - } - - /** - * @dataProvider providerForUnitPriceLimitValuesShopInShop - */ - public function testValidateShopInShopThrowsExceptionWhenUnitPriceIsNegative($unitPrice, $expectedResult): void - { - $item = new Item(); - $item->setUnitPrice($unitPrice); - $item->setUnits(2); - $item->setProductCode('pr1'); - $item->setMerchant('merchant1'); - - try { - $item->validate(); - $validationResult = $item->validateShopInShop(); - } catch (ValidationException $exception) { - $validationResult = false; - } - - $this->assertEquals($expectedResult, $validationResult); - } } diff --git a/tests/Request/ShopInShopPaymentRequestTest.php b/tests/Request/ShopInShopPaymentRequestTest.php index b55f965..111209c 100644 --- a/tests/Request/ShopInShopPaymentRequestTest.php +++ b/tests/Request/ShopInShopPaymentRequestTest.php @@ -14,6 +14,8 @@ class ShopInShopPaymentRequestTest extends TestCase { + + public function testShopInShopPaymentRequest() { $r = new ShopInShopPaymentRequest(); @@ -129,4 +131,84 @@ public function testShopInShopPaymentRequestFail() $r->validate(); } + + public static function shopInShopPaymentRequestItems() + { + return [ + 'negative item failing validation' => [ + 'itemsPrice' => [20, -10], + 'amount' => 10, + 'expectedResult' => false + ], + 'positive validation' => [ + 'itemsPrice' => [20, 10], + 'amount' => 30, + 'expectedResult' => true + ], + ]; + } + + /** + * @dataProvider shopInShopPaymentRequestItems + */ + public function testNegativeRowsValidation($itemsPrice, $amount, $expectedResult) + { + $r = new ShopInShopPaymentRequest(); + $r->setAmount($amount); + $r->setStamp('RequestStamp'); + $r->setReference('RequestReference123'); + $r->setCurrency('EUR'); + $r->setLanguage('EN'); + + $i = 0; + $items = []; + foreach ($itemsPrice as $price) { + $com = new Commission(); + $com->setMerchant('123456'); + $com->setAmount(2); + + $item = new Item(); + $item->setStamp('someStamp' . $i) + ->setDeliveryDate('12.12.2020') + ->setProductCode('pr1' . $i) + ->setVatPercentage(25) + ->setUnitPrice($price) + ->setUnits(1) + ->setMerchant('222222') + ->setReference('1-2') + ->setCommission($com); + + $items[] = $item; + $i++; + } + + $r->setItems($items); + + $c = new Customer(); + $c->setEmail('customer@email.com'); + + $r->setCustomer($c); + + $cb = new CallbackUrl(); + $cb->setCancel('https://somedomain.com/cancel') + ->setSuccess('https://somedomain.com/success'); + + $r->setCallbackUrls($cb); + + $redirect = new CallbackUrl(); + $redirect->setSuccess('https://someother.com/success') + ->setCancel('https://someother.com/cancel'); + + $r->setRedirectUrls($redirect); + + try { + + $result = $r->validate(); + } catch (ValidationException $e) { + echo $e->getMessage(); + $result = false; + } + + $this->assertEquals($expectedResult, $result); + } } From 78a2288606b075476b1062e570d2aaa1df288a53 Mon Sep 17 00:00:00 2001 From: "konrad.konieczny" Date: Tue, 4 Jun 2024 18:16:36 +0200 Subject: [PATCH 27/32] reformat --- tests/Request/ShopInShopPaymentRequestTest.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/Request/ShopInShopPaymentRequestTest.php b/tests/Request/ShopInShopPaymentRequestTest.php index 111209c..fce2d4c 100644 --- a/tests/Request/ShopInShopPaymentRequestTest.php +++ b/tests/Request/ShopInShopPaymentRequestTest.php @@ -14,8 +14,6 @@ class ShopInShopPaymentRequestTest extends TestCase { - - public function testShopInShopPaymentRequest() { $r = new ShopInShopPaymentRequest(); @@ -140,7 +138,7 @@ public static function shopInShopPaymentRequestItems() 'amount' => 10, 'expectedResult' => false ], - 'positive validation' => [ + 'positive validation' => [ 'itemsPrice' => [20, 10], 'amount' => 30, 'expectedResult' => true @@ -160,7 +158,7 @@ public function testNegativeRowsValidation($itemsPrice, $amount, $expectedResult $r->setCurrency('EUR'); $r->setLanguage('EN'); - $i = 0; + $i = 0; $items = []; foreach ($itemsPrice as $price) { $com = new Commission(); @@ -202,10 +200,8 @@ public function testNegativeRowsValidation($itemsPrice, $amount, $expectedResult $r->setRedirectUrls($redirect); try { - $result = $r->validate(); } catch (ValidationException $e) { - echo $e->getMessage(); $result = false; } From 38d9cee5f1399647b1447c01f638f3a8d8a18da1 Mon Sep 17 00:00:00 2001 From: Joonas Loueranta Date: Thu, 6 Jun 2024 11:52:08 +0200 Subject: [PATCH 28/32] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b23031..fcb5cad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.7.2] - 2024-06-06 +### Changed +- Updated validation to support negative item rows + ## [2.7.1] - 2024-04-16 ### Added - Run tests on PHP 8.3 From 5d837d10e3ec8b3dbc95062ee33848b9fefae91e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Ka=C5=82u=C5=BCny?= Date: Mon, 1 Jul 2024 17:11:29 +0200 Subject: [PATCH 29/32] SQMAGOPC-595: update VatPercentage type for vat change --- src/Interfaces/ItemInterface.php | 8 ++++---- src/Model/Item.php | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Interfaces/ItemInterface.php b/src/Interfaces/ItemInterface.php index 25b3a61..1f00fa2 100644 --- a/src/Interfaces/ItemInterface.php +++ b/src/Interfaces/ItemInterface.php @@ -59,17 +59,17 @@ public function setUnits(?int $units): ItemInterface; /** * Get the VAT percentage. * - * @return int + * @return float */ - public function getVatPercentage(): ?int; + public function getVatPercentage(): ?float; /** * Set the VAT percentage. * - * @param int|null $vatPercentage + * @param float|null $vatPercentage * @return ItemInterface Return self to enable chaining. */ - public function setVatPercentage(?int $vatPercentage): ItemInterface; + public function setVatPercentage(?float $vatPercentage): ItemInterface; /** * Get the product code. diff --git a/src/Model/Item.php b/src/Model/Item.php index 4fa32a5..a221f9e 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -43,7 +43,7 @@ class Item implements \JsonSerializable, ItemInterface /** * The VAT percentage. * - * @var integer + * @var float */ protected $vatPercentage; @@ -159,9 +159,9 @@ public function setUnits(?int $units): ItemInterface /** * Get the VAT percentage. * - * @return int + * @return float */ - public function getVatPercentage(): ?int + public function getVatPercentage(): ?float { return $this->vatPercentage; } @@ -169,10 +169,10 @@ public function getVatPercentage(): ?int /** * Set the VAT percentage. * - * @param int $vatPercentage + * @param float $vatPercentage * @return ItemInterface Return self to enable chaining. */ - public function setVatPercentage(?int $vatPercentage): ItemInterface + public function setVatPercentage(?float $vatPercentage): ItemInterface { $this->vatPercentage = $vatPercentage; From 369da1abb9c447566ddcf687a3e9b5e65bfdcddd Mon Sep 17 00:00:00 2001 From: Konsta Kotivuori Date: Tue, 16 Jul 2024 15:59:21 +0300 Subject: [PATCH 30/32] Fix submerchant parameter for settlement and report request --- src/Request/ReportBySettlementRequest.php | 8 ++++---- src/Request/ReportRequest.php | 8 ++++---- src/Request/SettlementRequest.php | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Request/ReportBySettlementRequest.php b/src/Request/ReportBySettlementRequest.php index 3a6645e..702705b 100644 --- a/src/Request/ReportBySettlementRequest.php +++ b/src/Request/ReportBySettlementRequest.php @@ -11,7 +11,7 @@ class ReportBySettlementRequest implements \JsonSerializable protected $requestType; protected $callbackUrl; protected $reportFields; - protected $subMerchant; + protected $submerchant; public function validate() { @@ -74,12 +74,12 @@ public function setReportFields(array $reportFields): self /** * Set submerchant. * - * @param int $subMerchant + * @param int $submerchant * @return $this */ - public function setSubMerchant(int $subMerchant): self + public function setSubMerchant(int $submerchant): self { - $this->subMerchant = $subMerchant; + $this->submerchant = $submerchant; return $this; } diff --git a/src/Request/ReportRequest.php b/src/Request/ReportRequest.php index 0a7c216..5cb9f48 100644 --- a/src/Request/ReportRequest.php +++ b/src/Request/ReportRequest.php @@ -22,7 +22,7 @@ class ReportRequest implements \JsonSerializable private $endDate; private $limit; private $reportFields; - private $subMerchant; + private $submerchant; public function validate() { @@ -164,12 +164,12 @@ public function setReportFields(array $reportFields): self /** * Set submerchant. * - * @param int $subMerchant + * @param int $submerchant * @return $this */ - public function setSubMerchant(int $subMerchant): self + public function setSubMerchant(int $submerchant): self { - $this->subMerchant = $subMerchant; + $this->submerchant = $submerchant; return $this; } diff --git a/src/Request/SettlementRequest.php b/src/Request/SettlementRequest.php index d9179ac..166883a 100644 --- a/src/Request/SettlementRequest.php +++ b/src/Request/SettlementRequest.php @@ -15,7 +15,7 @@ class SettlementRequest implements \JsonSerializable protected $endDate; protected $reference; protected $limit; - protected $subMerchant; + protected $submerchant; public function validate() { @@ -102,12 +102,12 @@ public function setLimit(int $limit): self /** * Set submerchant. * - * @param int $subMerchant + * @param int $submerchant * @return $this */ - public function setSubMerchant(int $subMerchant): self + public function setSubMerchant(int $submerchant): self { - $this->subMerchant = $subMerchant; + $this->submerchant = $submerchant; return $this; } From 5ffaba9084b5b2918afb9d55bb5d27903b630a7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Ka=C5=82u=C5=BCny?= Date: Mon, 29 Jul 2024 11:26:05 +0200 Subject: [PATCH 31/32] SQMAGOPC: update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcb5cad..ee01a26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.7.3] - 2024-07-29 +### Added +- Support the new VAT in Finland + ## [2.7.2] - 2024-06-06 ### Changed - Updated validation to support negative item rows From b1e7b1d6be88174a42147e0991620bf09b4cb1ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Ka=C5=82u=C5=BCny?= Date: Mon, 29 Jul 2024 12:12:21 +0200 Subject: [PATCH 32/32] SQMAGOPC-595: update VAT value in tests --- tests/ClientTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 5a96bd3..e0374cc 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -47,7 +47,7 @@ protected function setUp(): void $this->item = (new Item()) ->setProductCode('pr1') - ->setVatPercentage(24) + ->setVatPercentage(25.5) ->setReference('itemReference123') ->setStamp('itemStamp-1' . rand(1, 999999)) ->setUnits(1) @@ -57,7 +57,7 @@ protected function setUp(): void $this->item2 = (new Item()) ->setDeliveryDate('2020-12-12') ->setProductCode('pr2') - ->setVatPercentage(24) + ->setVatPercentage(25.5) ->setReference('itemReference123') ->setStamp('itemStamp-2' . rand(1, 999999)) ->setUnits(2)