From 22d073eba7824c0e51404865e61782e52aa96b00 Mon Sep 17 00:00:00 2001 From: Alex Kratky Date: Mon, 24 Nov 2025 15:50:27 +0100 Subject: [PATCH 1/5] 6254-api-endpoints-v2 --- doc/index.md | 51 ++++++++++++++-- doc/preauth-payments.md | 16 ++++- doc/saving-authorization.md | 24 +++++++- doc/subscription.md | 32 ++++++++++ src/Model/ApiResponse.php | 45 +++++++++++++- ...alizePaymentBySavedAuthorizationParams.php | 60 +++++++++++++------ .../RealizeSubscriptionPaymentParams.php | 29 ++++++++- src/Service/ApiService.php | 35 +++++++---- src/Service/ApiServiceInterface.php | 5 +- src/TheClient.php | 6 +- src/TheConfig.php | 6 +- tests/RealizePreauthorizationPaymentTest.php | 10 +++- .../RealizeSavedAuthorizationPaymentTest.php | 11 +++- tests/RealizeSubscriptionPaymentTest.php | 11 +++- 14 files changed, 284 insertions(+), 57 deletions(-) diff --git a/doc/index.md b/doc/index.md index 6402665..99ead79 100644 --- a/doc/index.md +++ b/doc/index.md @@ -123,7 +123,7 @@ Will create payment. ### realizePreauthorizedPayment -Will realize preauth payment +Will realize preauth payment (V2 API endpoint) #### Parameters @@ -131,6 +131,14 @@ Will realize preauth payment | --- | --- | --- | | $params | RealizePreauthorizedPaymentParams | required | +#### Return + +| return type | | +| --- | --- | +| ApiResponse | Returns response with state ('paid', 'waiting_for_confirmation') and status code | + +**Note**: V2 API may return async response (HTTP 202) with state 'waiting_for_confirmation'. You will receive a notification when processing completes. + ### cancelPreauthorizedPayment Will cancel preauth payment @@ -182,7 +190,7 @@ Return information about transactions history ### realizeRegularSubscriptionPayment -Realize subscription payment. +Realize subscription payment (V2 API endpoint) #### Parameters @@ -191,9 +199,17 @@ Realize subscription payment. | $uid | string | required | UID of parent payment | | $params | RealizeRegularSubscriptionPaymentParams | required | | +#### Return + +| return type | | +| --- | --- | +| ApiResponse | Returns response with state ('paid', 'error', 'waiting_for_confirmation'), parent availability info, and status code | + +**Note**: V2 API may return async response (HTTP 202). Always check `isRecurringPaymentsAvailable()` to determine if the parent payment can be used for more payments. + ### realizeIrregularSubscriptionPayment -Realize subscription payment. +Realize subscription payment (V2 API endpoint) #### Parameters @@ -202,9 +218,17 @@ Realize subscription payment. | $uid | string | required | UID of parent payment | | $params | RealizeIrregularSubscriptionPaymentParams | required | | +#### Return + +| return type | | +| --- | --- | +| ApiResponse | Returns response with state ('paid', 'error', 'waiting_for_confirmation'), parent availability info, and status code | + +**Note**: V2 API may return async response (HTTP 202). Always check `isRecurringPaymentsAvailable()` to determine if the parent payment can be used for more payments. + ### realizeUsageBasedSubscriptionPayment -Realize subscription payment. +Realize subscription payment (V2 API endpoint) #### Parameters @@ -213,17 +237,32 @@ Realize subscription payment. | $uid | string | required | UID of parent payment | | $params | RealizeUsageBasedSubscriptionPaymentParams | required | | +#### Return + +| return type | | +| --- | --- | +| ApiResponse | Returns response with state ('paid', 'error', 'waiting_for_confirmation'), parent availability info, and status code | + +**Note**: V2 API may return async response (HTTP 202). Always check `isRecurringPaymentsAvailable()` to determine if the parent payment can be used for more payments. ### realizePaymentBySavedAuthorization -Create new payment using saved authorization. +Create new payment using saved authorization (V2 API endpoint) #### Parameters | name | type | | description | | --- | --- | --- | --- | | $uid | string | required | UID of parent payment | -| $params | RealizePaymentBySavedAuthorizationParams | required | | +| $params | RealizePaymentBySavedAuthorizationParams | required | Requires amount and currency code in V2 API | + +#### Return + +| return type | | +| --- | --- | +| ApiResponse | Returns response with state ('paid', 'error', 'waiting_for_confirmation'), parent availability info, and status code | + +**Note**: V2 API requires amount and currency code (both required). May return async response (HTTP 202). Always check `isRecurringPaymentsAvailable()` to determine if the saved authorization is still valid. ### getPaymentUrlsForPayment diff --git a/doc/preauth-payments.md b/doc/preauth-payments.md index a246cd7..f7910dd 100644 --- a/doc/preauth-payments.md +++ b/doc/preauth-payments.md @@ -28,11 +28,25 @@ Once you are ready to capture the funds, call `realizePreauthorizedPayment()`: ```php /** @var \ThePay\ApiClient\TheClient $thePayClient */ $params = new \ThePay\ApiClient\Model\RealizePreauthorizedPaymentParams(100, 'PREAUTH_PAYMENT_001'); -$thePayClient->realizePreauthorizedPayment($params); +$response = $thePayClient->realizePreauthorizedPayment($params); + +if ($response->wasSuccessful()) { + echo 'Preauthorized payment was realized successfully'; +} else if ($response->getState() === 'waiting_for_confirmation') { + echo 'Payment is being processed, you will receive a notification when complete'; +} else { + echo 'Payment realization failed'; +} ``` You may capture less than the originally preauthorized amount, but never more. +**Note about V2 API:** +The V2 API supports asynchronous payment processing: +- HTTP 200 with state `paid` means immediate success +- HTTP 202 with state `waiting_for_confirmation` means the payment is being processed asynchronously +- You will receive a notification when the async payment completes (state changes to `paid` or `preauth_cancelled`) + ## Cancel a Preauthorized Payment If you decide not to capture the funds, you can cancel the preauthorization: diff --git a/doc/saving-authorization.md b/doc/saving-authorization.md index 7678364..8e23b94 100644 --- a/doc/saving-authorization.md +++ b/doc/saving-authorization.md @@ -26,9 +26,10 @@ After the created payment was paid, we can realize new payment by saved authoriz ```php /** @var \ThePay\ApiClient\TheClient $thePayClient */ +// V2 API requires amount and currency code // first parameter is uid of new (child) payment -// second parameter contains amount in cents, if sets to null it will use amount of parent payment, required if third parameter is set -// third parameter contains currency code, if sets to null it will use currency code of parent payment, required if second parameter is set +// second parameter contains amount in cents (required) +// third parameter contains currency code (required) $params = new \ThePay\ApiClient\Model\RealizePaymentBySavedAuthorizationParams('childpayment', 1000, 'EUR'); // adding items is optional, if you do not add any item, items from parent payment will be used @@ -38,9 +39,26 @@ $params->addItem($item); // first parameter is uid of parent payment (the one we create above with savedAuthorization set to true). // method will return ApiResponse -$response = $thePayClient->realizePaymentBySavedAuthorization('subscriptionpayment', $params); +$response = $thePayClient->realizePaymentBySavedAuthorization('savedauthtest', $params); if ($response->wasSuccessful()) { echo 'Payment was realized using saved authorization'; +} else if ($response->getState() === 'waiting_for_confirmation') { + echo 'Payment is being processed, you will receive a notification when complete'; +} + +// Check if more payments can be realized with this saved authorization +if ($response->isRecurringPaymentsAvailable() === false) { + echo 'Saved authorization is no longer valid, customer needs to authorize a new payment'; } ``` + +**Note about V2 API:** +The V2 API introduces several important changes: +- **Amount and currency are now required** - you must always specify both parameters +- **Asynchronous processing**: Payment may return HTTP 202 with state `waiting_for_confirmation` + - HTTP 200 with state `paid` means immediate success + - HTTP 200 with state `error` means immediate failure + - HTTP 202 with state `waiting_for_confirmation` means async processing +- **Parent availability tracking**: Check `isRecurringPaymentsAvailable()` to know if the saved authorization is still valid +- You will receive a notification when async payments complete (state changes to `paid` or `error`) diff --git a/doc/subscription.md b/doc/subscription.md index 2693726..577ed22 100644 --- a/doc/subscription.md +++ b/doc/subscription.md @@ -55,9 +55,27 @@ $response = $thePayClient->realizeRegularSubscriptionPayment('subscriptionpaymen if ($response->wasSuccessful()) { echo 'Subscription payment was realized'; +} else { + // Check if payment is still processing asynchronously + if ($response->getState() === 'waiting_for_confirmation') { + echo 'Payment is being processed, you will receive a notification when complete'; + } +} + +// Check if more payments can be realized with this parent +if ($response->isRecurringPaymentsAvailable() === false) { + echo 'No more payments can be realized with this parent, inform customer to create new subscription'; } ``` +**Note about V2 API:** +The V2 API supports asynchronous payment processing: +- HTTP 200 with state `paid` means immediate success +- HTTP 200 with state `error` means immediate failure +- HTTP 202 with state `waiting_for_confirmation` means the payment is being processed asynchronously +- You will receive a notification when the async payment completes (state changes to `paid` or `error`) +- Always check `parent.recurring_payments_available` to know if the subscription should end + ### Realizing irregular subscription payment type ```php @@ -77,6 +95,13 @@ $response = $thePayClient->realizeIrregularSubscriptionPayment('subscriptionpaym if ($response->wasSuccessful()) { echo 'Subscription payment was realized'; +} else if ($response->getState() === 'waiting_for_confirmation') { + echo 'Payment is being processed, you will receive a notification when complete'; +} + +// Check if more payments can be realized +if ($response->isRecurringPaymentsAvailable() === false) { + echo 'Parent payment no longer available for new subscriptions'; } ``` @@ -100,5 +125,12 @@ $response = $thePayClient->realizeUsageBasedSubscriptionPayment('subscriptionpay if ($response->wasSuccessful()) { echo 'Subscription payment was realized'; +} else if ($response->getState() === 'waiting_for_confirmation') { + echo 'Payment is being processed, you will receive a notification when complete'; +} + +// Check if more payments can be realized +if ($response->isRecurringPaymentsAvailable() === false) { + echo 'Parent payment no longer available for new subscriptions'; } ``` diff --git a/src/Model/ApiResponse.php b/src/Model/ApiResponse.php index 0265b3b..92f383b 100644 --- a/src/Model/ApiResponse.php +++ b/src/Model/ApiResponse.php @@ -15,6 +15,9 @@ class ApiResponse /** @var int */ private $statusCode; + /** @var array|null */ + private $parent; + /** * ApiResponse constructor. * @@ -27,6 +30,7 @@ public function __construct($values, $statusCode) $this->state = isset($data['state']) ? $data['state'] : null; $this->message = isset($data['message']) ? $data['message'] : null; + $this->parent = isset($data['parent']) ? $data['parent'] : null; $this->statusCode = $statusCode; } @@ -55,12 +59,47 @@ public function getStatusCode() } /** - * Determines if the subscription payment was realized. + * Get parent payment information (for subscription and saved authorization payments). + * + * @return array|null + */ + public function getParent() + { + return $this->parent; + } + + /** + * Check if recurring payments are still available for the parent payment. + * Only applicable for subscription and saved authorization payments. + * + * @return bool|null Returns null if parent information is not available + */ + public function isRecurringPaymentsAvailable() + { + if ($this->parent === null) { + return null; + } + + return isset($this->parent['recurring_payments_available']) + ? (bool) $this->parent['recurring_payments_available'] + : null; + } + + /** + * Determines if the payment was realized successfully. * - * @return bool + * @return bool|null Return null if the payment is still being processed asynchronously. */ public function wasSuccessful() { - return $this->statusCode === 200 && $this->state === 'success'; + if ($this->statusCode === 200 && $this->state === 'paid' || $this->state === 'success') { + return true; + } + + if ($this->statusCode === 202 && $this->state === 'waiting_for_confirmation') { + return null; + } + + return false; } } diff --git a/src/Model/RealizePaymentBySavedAuthorizationParams.php b/src/Model/RealizePaymentBySavedAuthorizationParams.php index 95b68d2..cec3455 100644 --- a/src/Model/RealizePaymentBySavedAuthorizationParams.php +++ b/src/Model/RealizePaymentBySavedAuthorizationParams.php @@ -9,7 +9,7 @@ final class RealizePaymentBySavedAuthorizationParams implements SignableRequest { - /** @var Amount|null */ + /** @var Amount */ private $amount; /** @var CreatePaymentItem[] */ @@ -18,7 +18,7 @@ final class RealizePaymentBySavedAuthorizationParams implements SignableRequest /** @var Identifier */ private $uid; - /** @var CurrencyCode|null */ + /** @var CurrencyCode */ private $currencyCode; /** @var string|null */ @@ -27,25 +27,30 @@ final class RealizePaymentBySavedAuthorizationParams implements SignableRequest /** @var string|null */ protected $descriptionForMerchant = null; + /** @var string|null */ + protected $notifUrl = null; + /** * RealizePaymentBySavedAuthorizationParams constructor. * * @param string $uid - * @param int|null $amount - payment amount in cents, if set to null it will use amount from parent payment, required if $currencyCode is present - * @param string|null $currencyCode required if $amount is present + * @param int $amount - payment amount in cents (required) + * @param string $currencyCode - currency code (required) * @param string|null $orderId * @param string|null $descriptionForMerchant + * @param string|null $notifUrl */ - public function __construct($uid, $amount = null, $currencyCode = null, $orderId = null, $descriptionForMerchant = null) + public function __construct($uid, $amount, $currencyCode, $orderId = null, $descriptionForMerchant = null, $notifUrl = null) { - if (($amount === null && $currencyCode !== null) || ($amount !== null && $currencyCode === null)) { - throw new InvalidArgumentException('Amount and currency code is required if one of these parameters have value.'); + if ($amount === null || $currencyCode === null) { + throw new InvalidArgumentException('Amount and currency code are required for V2 API.'); } $this->uid = new Identifier($uid); - $this->amount = $amount === null ? null : new Amount($amount); - $this->currencyCode = $currencyCode === null ? null : new CurrencyCode($currencyCode); + $this->amount = new Amount($amount); + $this->currencyCode = new CurrencyCode($currencyCode); $this->orderId = $orderId; $this->descriptionForMerchant = $descriptionForMerchant; + $this->notifUrl = $notifUrl; } /** @@ -96,6 +101,24 @@ public function getDescriptionForMerchant() return $this->descriptionForMerchant; } + /** + * @return string|null + */ + public function getNotifUrl() + { + return $this->notifUrl; + } + + /** + * @param string|null $notifUrl + * @return RealizePaymentBySavedAuthorizationParams + */ + public function setNotifUrl($notifUrl) + { + $this->notifUrl = $notifUrl; + return $this; + } + /** * If no items will be set, the items from parent payment will be used. * @@ -116,22 +139,25 @@ public function toArray() { $result = [ 'uid' => $this->uid->getValue(), - 'items' => null, - 'orderId' => $this->orderId, - 'descriptionForMerchant' => $this->descriptionForMerchant, + 'value' => [ + 'amount' => (string) $this->amount->getValue(), + 'currency' => $this->currencyCode->getValue(), + ], + 'order_id' => $this->orderId, + 'description_for_merchant' => $this->descriptionForMerchant, ]; if ($this->items) { + $result['items'] = []; foreach ($this->items as $item) { $result['items'][] = $item->toArray(); } + } else { + $result['items'] = null; } - if ($this->amount) { - $result['value'] = [ - 'amount' => $this->amount->getValue(), - 'currency' => $this->currencyCode->getValue(), - ]; + if ($this->notifUrl !== null) { + $result['notif_url'] = $this->notifUrl; } return $result; diff --git a/src/Model/RealizeSubscriptionPaymentParams.php b/src/Model/RealizeSubscriptionPaymentParams.php index a430991..793c1a2 100644 --- a/src/Model/RealizeSubscriptionPaymentParams.php +++ b/src/Model/RealizeSubscriptionPaymentParams.php @@ -22,6 +22,9 @@ abstract class RealizeSubscriptionPaymentParams implements SignableRequest /** @var string|null */ protected $descriptionForMerchant = null; + /** @var string|null */ + protected $notifUrl = null; + /** * @return Amount */ @@ -62,6 +65,24 @@ public function getDescriptionForMerchant() return $this->descriptionForMerchant; } + /** + * @return string|null + */ + public function getNotifUrl() + { + return $this->notifUrl; + } + + /** + * @param string|null $notifUrl + * @return RealizeSubscriptionPaymentParams + */ + public function setNotifUrl($notifUrl) + { + $this->notifUrl = $notifUrl; + return $this; + } + /** * If no items will be set, the items from parent payment will be used. * @@ -81,7 +102,7 @@ public function addItem(CreatePaymentItem $item) public function toArray() { $result = [ - 'payment_uid' => $this->uid->getValue(), + 'uid' => $this->uid->getValue(), 'items' => null, 'order_id' => $this->orderId, 'description_for_merchant' => $this->descriptionForMerchant, @@ -94,7 +115,11 @@ public function toArray() } if ($this->amount) { - $result['amount'] = $this->amount->getValue(); + $result['amount'] = (string) $this->amount->getValue(); + } + + if ($this->notifUrl !== null) { + $result['notif_url'] = $this->notifUrl; } return $result; diff --git a/src/Service/ApiService.php b/src/Service/ApiService.php index daff607..6003715 100644 --- a/src/Service/ApiService.php +++ b/src/Service/ApiService.php @@ -260,10 +260,10 @@ public function realizeRegularSubscriptionPayment(Identifier $parentPaymentUid, { $jsonParams = $params->toArray(); - $url = $this->url(['payments', $parentPaymentUid, 'subscription', SubscriptionType::REGULAR]); + $url = $this->url(['v2', 'projects', $this->config->getProjectId(), 'payments', $parentPaymentUid, 'subscription', SubscriptionType::REGULAR], [], false); $response = $this->sendRequest(self::METHOD_POST, $url, $jsonParams); - if ( ! in_array($response->getStatusCode(), [200, 201], true)) { + if ( ! in_array($response->getStatusCode(), [200, 202], true)) { throw $this->buildException($url, $response); } @@ -279,10 +279,10 @@ public function realizeIrregularSubscriptionPayment(Identifier $parentPaymentUid { $jsonParams = $params->toArray(); - $url = $this->url(['payments', $parentPaymentUid, 'subscription', SubscriptionType::IRREGULAR]); + $url = $this->url(['v2', 'projects', $this->config->getProjectId(), 'payments', $parentPaymentUid, 'subscription', SubscriptionType::IRREGULAR], [], false); $response = $this->sendRequest(self::METHOD_POST, $url, $jsonParams); - if ( ! in_array($response->getStatusCode(), [200, 201], true)) { + if ( ! in_array($response->getStatusCode(), [200, 202], true)) { throw $this->buildException($url, $response); } @@ -298,10 +298,10 @@ public function realizeUsageBasedSubscriptionPayment(Identifier $parentPaymentUi { $jsonParams = $params->toArray(); - $url = $this->url(['payments', $parentPaymentUid, 'subscription', SubscriptionType::USAGE_BASED]); + $url = $this->url(['v2', 'projects', $this->config->getProjectId(), 'payments', $parentPaymentUid, 'subscription', SubscriptionType::USAGE_BASED], [], false); $response = $this->sendRequest(self::METHOD_POST, $url, $jsonParams); - if ( ! in_array($response->getStatusCode(), [200, 201], true)) { + if ( ! in_array($response->getStatusCode(), [200, 202], true)) { throw $this->buildException($url, $response); } @@ -317,10 +317,10 @@ public function realizePaymentBySavedAuthorization(Identifier $parentPaymentUid, { $jsonParams = $params->toArray(); - $url = $this->url(['payments', $parentPaymentUid, 'savedauthorization']); + $url = $this->url(['v2', 'projects', $this->config->getProjectId(), 'payments', $parentPaymentUid, 'savedauthorization'], [], false); $response = $this->sendRequest(self::METHOD_POST, $url, $jsonParams); - if ( ! in_array($response->getStatusCode(), [200, 201], true)) { + if ( ! in_array($response->getStatusCode(), [200, 202], true)) { throw $this->buildException($url, $response); } @@ -372,18 +372,23 @@ public function changePaymentMethod(Identifier $uid, string $methodCode): void /** * @throws ApiException */ - public function realizePreauthorizedPayment(RealizePreauthorizedPaymentParams $params): void + public function realizePreauthorizedPayment(RealizePreauthorizedPaymentParams $params): ApiResponse { $url = $this->url([ + 'v2', + 'projects', + $this->config->getProjectId(), 'payments', $params->getUid(), 'preauthorized', - ]); + ], [], false); $response = $this->sendRequest(self::METHOD_POST, $url, $params->toArray()); - if ($response->getStatusCode() !== 204) { + if ( ! in_array($response->getStatusCode(), [200, 202], true)) { throw $this->buildException($url, $response); } + + return new ApiResponse($response->getBody()->getContents(), $response->getStatusCode()); } /** @@ -519,12 +524,18 @@ private function url($path = [], $arguments = [], $includeProject = true) array_unshift($path, 'projects', $this->config->getProjectId()); } + $specificVersion = null; + if (isset($path[0]) && is_string($path[0]) && preg_match('/^v[0-9]+$/', $path[0])) { + $specificVersion = array_shift($path); + } + + $pathImploded = implode('/', $path); if (strlen($pathImploded)) { $pathImploded .= '/'; } - $apiUrl = $this->config->getApiUrl(); + $apiUrl = $this->config->getApiUrl($specificVersion); $pathImploded = substr($pathImploded, 0, -1); diff --git a/src/Service/ApiServiceInterface.php b/src/Service/ApiServiceInterface.php index 094bd57..0b5538f 100644 --- a/src/Service/ApiServiceInterface.php +++ b/src/Service/ApiServiceInterface.php @@ -118,7 +118,10 @@ public function getAccountTransactionHistory(TransactionFilter $filter, int $pag */ public function createPayment(CreatePaymentParams $createPaymentParams, ?string $methodCode = null): CreatePaymentResponse; - public function realizePreauthorizedPayment(RealizePreauthorizedPaymentParams $params): void; + /** + * @throws ApiException + */ + public function realizePreauthorizedPayment(RealizePreauthorizedPaymentParams $params): ApiResponse; public function cancelPreauthorizedPayment(Identifier $uid): void; diff --git a/src/TheClient.php b/src/TheClient.php index db78306..04c8eb1 100644 --- a/src/TheClient.php +++ b/src/TheClient.php @@ -283,13 +283,13 @@ public function changePaymentMethod(string $paymentUid, string $methodCode): voi /** * @param RealizePreauthorizedPaymentParams $params - * + * @return ApiResponse * @throws ApiException|InvalidArgumentException */ - public function realizePreauthorizedPayment(RealizePreauthorizedPaymentParams $params): void + public function realizePreauthorizedPayment(RealizePreauthorizedPaymentParams $params): ApiResponse { $this->validateUid($params->getUid()->getValue()); - $this + return $this ->api ->realizePreauthorizedPayment($params); } diff --git a/src/TheConfig.php b/src/TheConfig.php index ba5309a..bccf8af 100644 --- a/src/TheConfig.php +++ b/src/TheConfig.php @@ -57,10 +57,14 @@ public function getGateUrl() } /** + * @param string|null $specificVersion * @return string */ - public function getApiUrl() + public function getApiUrl($specificVersion = null) { + if ($specificVersion) { + return $this->apiUrl->getValue() . $specificVersion . '/'; + } return $this->apiUrl->getValue() . $this->apiVersion . '/'; } diff --git a/tests/RealizePreauthorizationPaymentTest.php b/tests/RealizePreauthorizationPaymentTest.php index a467aff..b0746b9 100644 --- a/tests/RealizePreauthorizationPaymentTest.php +++ b/tests/RealizePreauthorizationPaymentTest.php @@ -46,7 +46,7 @@ public function testRequest(): void ->expects(self::once()) ->method('sendRequest') ->willReturnCallback(function (RequestInterface $request): ResponseInterface { - $expectedUrl = $this->config->getApiUrl() . 'projects/1/payments/abc/preauthorized?merchant_id=' . self::MERCHANT_ID; + $expectedUrl = $this->config->getApiUrl('v2') . 'projects/1/payments/abc/preauthorized?merchant_id=' . self::MERCHANT_ID; self::assertSame('POST', $request->getMethod()); self::assertSame($expectedUrl, $request->getUri()->__toString()); @@ -56,7 +56,11 @@ public function testRequest(): void }) ; - $this->client->realizePreauthorizedPayment(new RealizePreauthorizedPaymentParams(100, 'abc')); + $response = $this->client->realizePreauthorizedPayment(new RealizePreauthorizedPaymentParams(100, 'abc')); + + self::assertInstanceOf(\ThePay\ApiClient\Model\ApiResponse::class, $response); + self::assertSame('paid', $response->getState()); + self::assertTrue($response->wasSuccessful()); } public function testNotOkResponse(): void @@ -70,7 +74,7 @@ public function testNotOkResponse(): void private function getOkResponse(): ResponseInterface { - return new Response(204); + return new Response(200, [], '{"state":"paid","message":"Payment realized successfully"}'); } private function getNotOkResponse(): ResponseInterface diff --git a/tests/RealizeSavedAuthorizationPaymentTest.php b/tests/RealizeSavedAuthorizationPaymentTest.php index 6e2e067..411df0f 100644 --- a/tests/RealizeSavedAuthorizationPaymentTest.php +++ b/tests/RealizeSavedAuthorizationPaymentTest.php @@ -19,8 +19,11 @@ protected function setUp(): void $okResponse = new ApiResponse( '{ - "state": "success", - "message": "Ok" + "state": "paid", + "message": "Ok", + "parent": { + "recurring_payments_available": true + } }', 200 ); @@ -33,9 +36,11 @@ protected function setUp(): void public function testRealizePaymentBySavedAuthorization(): void { - $params = new RealizePaymentBySavedAuthorizationParams('childPayment'); + $params = new RealizePaymentBySavedAuthorizationParams('childPayment', 10000, 'CZK'); $result = $this->client->realizePaymentBySavedAuthorization('parentUid', $params); self::assertSame(ApiResponse::class, get_class($result)); + self::assertTrue($result->wasSuccessful()); + self::assertTrue($result->isRecurringPaymentsAvailable()); } } diff --git a/tests/RealizeSubscriptionPaymentTest.php b/tests/RealizeSubscriptionPaymentTest.php index 246441f..b6ad90f 100644 --- a/tests/RealizeSubscriptionPaymentTest.php +++ b/tests/RealizeSubscriptionPaymentTest.php @@ -21,8 +21,11 @@ protected function setUp(): void $okResponse = new ApiResponse( '{ - "state": "success", - "message": "Ok" + "state": "paid", + "message": "Ok", + "parent": { + "recurring_payments_available": true + } }', 200 ); @@ -41,15 +44,19 @@ public function testRealizeSubscriptionPayment(): void $result = $this->client->realizeRegularSubscriptionPayment('parentUid', $params); self::assertSame(ApiResponse::class, get_class($result)); + self::assertTrue($result->wasSuccessful()); + self::assertTrue($result->isRecurringPaymentsAvailable()); $params = new RealizeIrregularSubscriptionPaymentParams('childPayment2'); $result = $this->client->realizeIrregularSubscriptionPayment('parentUid', $params); self::assertSame(ApiResponse::class, get_class($result)); + self::assertTrue($result->wasSuccessful()); $params = new RealizeUsageBasedSubscriptionPaymentParams('childPayment3', 1000); $result = $this->client->realizeUsageBasedSubscriptionPayment('parentUid', $params); self::assertSame(ApiResponse::class, get_class($result)); + self::assertTrue($result->wasSuccessful()); } } From a125537d2e234c3bb0e22b6b8c4182aefa518377 Mon Sep 17 00:00:00 2001 From: Alex Kratky Date: Mon, 24 Nov 2025 15:52:53 +0100 Subject: [PATCH 2/5] stan fix --- src/Model/RealizePaymentBySavedAuthorizationParams.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Model/RealizePaymentBySavedAuthorizationParams.php b/src/Model/RealizePaymentBySavedAuthorizationParams.php index cec3455..37a22b5 100644 --- a/src/Model/RealizePaymentBySavedAuthorizationParams.php +++ b/src/Model/RealizePaymentBySavedAuthorizationParams.php @@ -42,9 +42,6 @@ final class RealizePaymentBySavedAuthorizationParams implements SignableRequest */ public function __construct($uid, $amount, $currencyCode, $orderId = null, $descriptionForMerchant = null, $notifUrl = null) { - if ($amount === null || $currencyCode === null) { - throw new InvalidArgumentException('Amount and currency code are required for V2 API.'); - } $this->uid = new Identifier($uid); $this->amount = new Amount($amount); $this->currencyCode = new CurrencyCode($currencyCode); From a0a7f172f3fee7f2925d29bba51ed41d8f4a72d1 Mon Sep 17 00:00:00 2001 From: Alex Kratky Date: Tue, 25 Nov 2025 11:13:22 +0100 Subject: [PATCH 3/5] cs fix php8.2 --- src/Model/RealizePaymentBySavedAuthorizationParams.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Model/RealizePaymentBySavedAuthorizationParams.php b/src/Model/RealizePaymentBySavedAuthorizationParams.php index 37a22b5..7ef15a5 100644 --- a/src/Model/RealizePaymentBySavedAuthorizationParams.php +++ b/src/Model/RealizePaymentBySavedAuthorizationParams.php @@ -2,7 +2,6 @@ namespace ThePay\ApiClient\Model; -use InvalidArgumentException; use ThePay\ApiClient\ValueObject\Amount; use ThePay\ApiClient\ValueObject\CurrencyCode; use ThePay\ApiClient\ValueObject\Identifier; From d9ee59adbc8e7d865d48354ad6c19981aa755f64 Mon Sep 17 00:00:00 2001 From: Alex Kratky Date: Wed, 26 Nov 2025 08:24:58 +0100 Subject: [PATCH 4/5] change specific version api getter --- src/Model/ApiResponse.php | 24 +++++++++++++++++++----- src/Service/ApiService.php | 20 +++++++------------- src/TheConfig.php | 2 +- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/Model/ApiResponse.php b/src/Model/ApiResponse.php index 92f383b..ac5b498 100644 --- a/src/Model/ApiResponse.php +++ b/src/Model/ApiResponse.php @@ -87,19 +87,33 @@ public function isRecurringPaymentsAvailable() /** * Determines if the payment was realized successfully. - * - * @return bool|null Return null if the payment is still being processed asynchronously. */ - public function wasSuccessful() + public function wasSuccessful(): bool { - if ($this->statusCode === 200 && $this->state === 'paid' || $this->state === 'success') { + if ($this->statusCode === 200 && ($this->state === 'paid' || $this->state === 'success')) { return true; } + return false; + } + + /** + * Determines if the payment is still being processed + */ + public function isPending(): bool + { if ($this->statusCode === 202 && $this->state === 'waiting_for_confirmation') { - return null; + return true; } return false; } + + /** + * Determines if the payment has failed and will not be processed + */ + public function hasFailed(): bool + { + return ! $this->wasSuccessful() && ! $this->isPending(); + } } diff --git a/src/Service/ApiService.php b/src/Service/ApiService.php index 6003715..90de9b7 100644 --- a/src/Service/ApiService.php +++ b/src/Service/ApiService.php @@ -260,7 +260,7 @@ public function realizeRegularSubscriptionPayment(Identifier $parentPaymentUid, { $jsonParams = $params->toArray(); - $url = $this->url(['v2', 'projects', $this->config->getProjectId(), 'payments', $parentPaymentUid, 'subscription', SubscriptionType::REGULAR], [], false); + $url = $this->url(['projects', $this->config->getProjectId(), 'payments', $parentPaymentUid, 'subscription', SubscriptionType::REGULAR], [], false, 'v2'); $response = $this->sendRequest(self::METHOD_POST, $url, $jsonParams); if ( ! in_array($response->getStatusCode(), [200, 202], true)) { @@ -279,7 +279,7 @@ public function realizeIrregularSubscriptionPayment(Identifier $parentPaymentUid { $jsonParams = $params->toArray(); - $url = $this->url(['v2', 'projects', $this->config->getProjectId(), 'payments', $parentPaymentUid, 'subscription', SubscriptionType::IRREGULAR], [], false); + $url = $this->url(['projects', $this->config->getProjectId(), 'payments', $parentPaymentUid, 'subscription', SubscriptionType::IRREGULAR], [], false, 'v2'); $response = $this->sendRequest(self::METHOD_POST, $url, $jsonParams); if ( ! in_array($response->getStatusCode(), [200, 202], true)) { @@ -298,7 +298,7 @@ public function realizeUsageBasedSubscriptionPayment(Identifier $parentPaymentUi { $jsonParams = $params->toArray(); - $url = $this->url(['v2', 'projects', $this->config->getProjectId(), 'payments', $parentPaymentUid, 'subscription', SubscriptionType::USAGE_BASED], [], false); + $url = $this->url(['projects', $this->config->getProjectId(), 'payments', $parentPaymentUid, 'subscription', SubscriptionType::USAGE_BASED], [], false, 'v2'); $response = $this->sendRequest(self::METHOD_POST, $url, $jsonParams); if ( ! in_array($response->getStatusCode(), [200, 202], true)) { @@ -317,7 +317,7 @@ public function realizePaymentBySavedAuthorization(Identifier $parentPaymentUid, { $jsonParams = $params->toArray(); - $url = $this->url(['v2', 'projects', $this->config->getProjectId(), 'payments', $parentPaymentUid, 'savedauthorization'], [], false); + $url = $this->url(['projects', $this->config->getProjectId(), 'payments', $parentPaymentUid, 'savedauthorization'], [], false, 'v2'); $response = $this->sendRequest(self::METHOD_POST, $url, $jsonParams); if ( ! in_array($response->getStatusCode(), [200, 202], true)) { @@ -375,13 +375,12 @@ public function changePaymentMethod(Identifier $uid, string $methodCode): void public function realizePreauthorizedPayment(RealizePreauthorizedPaymentParams $params): ApiResponse { $url = $this->url([ - 'v2', 'projects', $this->config->getProjectId(), 'payments', $params->getUid(), 'preauthorized', - ], [], false); + ], [], false, 'v2'); $response = $this->sendRequest(self::METHOD_POST, $url, $params->toArray()); if ( ! in_array($response->getStatusCode(), [200, 202], true)) { @@ -508,9 +507,10 @@ public function generatePaymentConfirmationPdf(Identifier $uid, ?LanguageCode $l * @param array $path * @param array $arguments * @param bool $includeProject + * @param string|null $specificVersion * @return string */ - private function url($path = [], $arguments = [], $includeProject = true) + private function url($path = [], $arguments = [], $includeProject = true, $specificVersion = null) { if ( ! isset($arguments['merchant_id'])) { ($arguments['merchant_id'] = $this->config->getMerchantId()); @@ -524,12 +524,6 @@ private function url($path = [], $arguments = [], $includeProject = true) array_unshift($path, 'projects', $this->config->getProjectId()); } - $specificVersion = null; - if (isset($path[0]) && is_string($path[0]) && preg_match('/^v[0-9]+$/', $path[0])) { - $specificVersion = array_shift($path); - } - - $pathImploded = implode('/', $path); if (strlen($pathImploded)) { $pathImploded .= '/'; diff --git a/src/TheConfig.php b/src/TheConfig.php index bccf8af..a72d71f 100644 --- a/src/TheConfig.php +++ b/src/TheConfig.php @@ -57,7 +57,7 @@ public function getGateUrl() } /** - * @param string|null $specificVersion + * @param string|null $specificVersion If specified, it will use this version of the API instead of the default one. * @return string */ public function getApiUrl($specificVersion = null) From f62cba8632bf340c124cfb65d34ac72b66ff5b36 Mon Sep 17 00:00:00 2001 From: Alex Kratky Date: Tue, 2 Dec 2025 08:42:16 +0100 Subject: [PATCH 5/5] resolved feedback --- doc/index.md | 40 +++--- doc/preauth-payments.md | 28 +++-- doc/saving-authorization.md | 36 +++--- doc/subscription.md | 87 ++++++++----- src/Model/ApiResponse.php | 119 ------------------ ...alizePaymentBySavedAuthorizationParams.php | 16 +-- .../RealizePreauthorizedPaymentResult.php | 38 ++++++ .../RealizeSubscriptionPaymentParams.php | 14 +-- src/Model/RecurringPaymentResult.php | 69 ++++++++++ src/Service/ApiService.php | 27 ++-- src/Service/ApiServiceInterface.php | 21 ++-- src/TheClient.php | 23 ++-- src/TheConfig.php | 6 +- tests/RealizePreauthorizationPaymentTest.php | 8 +- .../RealizeSavedAuthorizationPaymentTest.php | 11 +- tests/RealizeSubscriptionPaymentTest.php | 19 ++- 16 files changed, 278 insertions(+), 284 deletions(-) delete mode 100644 src/Model/ApiResponse.php create mode 100644 src/Model/RealizePreauthorizedPaymentResult.php create mode 100644 src/Model/RecurringPaymentResult.php diff --git a/doc/index.md b/doc/index.md index 99ead79..d0aa010 100644 --- a/doc/index.md +++ b/doc/index.md @@ -123,7 +123,7 @@ Will create payment. ### realizePreauthorizedPayment -Will realize preauth payment (V2 API endpoint) +Will realize preauth payment (V2 API endpoint). #### Parameters @@ -135,9 +135,7 @@ Will realize preauth payment (V2 API endpoint) | return type | | | --- | --- | -| ApiResponse | Returns response with state ('paid', 'waiting_for_confirmation') and status code | - -**Note**: V2 API may return async response (HTTP 202) with state 'waiting_for_confirmation'. You will receive a notification when processing completes. +| RealizePreauthorizedPaymentResult | Result with `getState()` returning 'paid' or 'waiting_for_confirmation' | ### cancelPreauthorizedPayment @@ -190,79 +188,71 @@ Return information about transactions history ### realizeRegularSubscriptionPayment -Realize subscription payment (V2 API endpoint) +Realize subscription payment (V2 API endpoint). #### Parameters | name | type | | description | | --- | --- | --- | --- | -| $uid | string | required | UID of parent payment | +| $parentPaymentUid | string | required | UID of parent payment | | $params | RealizeRegularSubscriptionPaymentParams | required | | #### Return | return type | | | --- | --- | -| ApiResponse | Returns response with state ('paid', 'error', 'waiting_for_confirmation'), parent availability info, and status code | - -**Note**: V2 API may return async response (HTTP 202). Always check `isRecurringPaymentsAvailable()` to determine if the parent payment can be used for more payments. +| RecurringPaymentResult | Result with `getState()` and `isRecurringPaymentsAvailable()` | ### realizeIrregularSubscriptionPayment -Realize subscription payment (V2 API endpoint) +Realize subscription payment (V2 API endpoint). #### Parameters | name | type | | description | | --- | --- | --- | --- | -| $uid | string | required | UID of parent payment | +| $parentPaymentUid | string | required | UID of parent payment | | $params | RealizeIrregularSubscriptionPaymentParams | required | | #### Return | return type | | | --- | --- | -| ApiResponse | Returns response with state ('paid', 'error', 'waiting_for_confirmation'), parent availability info, and status code | - -**Note**: V2 API may return async response (HTTP 202). Always check `isRecurringPaymentsAvailable()` to determine if the parent payment can be used for more payments. +| RecurringPaymentResult | Result with `getState()` and `isRecurringPaymentsAvailable()` | ### realizeUsageBasedSubscriptionPayment -Realize subscription payment (V2 API endpoint) +Realize subscription payment (V2 API endpoint). #### Parameters | name | type | | description | | --- | --- | --- | --- | -| $uid | string | required | UID of parent payment | +| $parentPaymentUid | string | required | UID of parent payment | | $params | RealizeUsageBasedSubscriptionPaymentParams | required | | #### Return | return type | | | --- | --- | -| ApiResponse | Returns response with state ('paid', 'error', 'waiting_for_confirmation'), parent availability info, and status code | - -**Note**: V2 API may return async response (HTTP 202). Always check `isRecurringPaymentsAvailable()` to determine if the parent payment can be used for more payments. +| RecurringPaymentResult | Result with `getState()` and `isRecurringPaymentsAvailable()` | ### realizePaymentBySavedAuthorization -Create new payment using saved authorization (V2 API endpoint) +Create new payment using saved authorization (V2 API endpoint). #### Parameters | name | type | | description | | --- | --- | --- | --- | -| $uid | string | required | UID of parent payment | -| $params | RealizePaymentBySavedAuthorizationParams | required | Requires amount and currency code in V2 API | +| $parentPaymentUid | string | required | UID of parent payment | +| $params | RealizePaymentBySavedAuthorizationParams | required | Requires amount and currency code | #### Return | return type | | | --- | --- | -| ApiResponse | Returns response with state ('paid', 'error', 'waiting_for_confirmation'), parent availability info, and status code | - -**Note**: V2 API requires amount and currency code (both required). May return async response (HTTP 202). Always check `isRecurringPaymentsAvailable()` to determine if the saved authorization is still valid. +| RecurringPaymentResult | Result with `getState()` and `isRecurringPaymentsAvailable()` | ### getPaymentUrlsForPayment diff --git a/doc/preauth-payments.md b/doc/preauth-payments.md index f7910dd..4c41f6f 100644 --- a/doc/preauth-payments.md +++ b/doc/preauth-payments.md @@ -1,6 +1,6 @@ # Preauthorized payments -A **preauthorized payment** allows you to reserve (authorize) funds on a customer’s account and capture them later. +A **preauthorized payment** allows you to reserve (authorize) funds on a customer's account and capture them later. This is useful for cases like hotel bookings or rentals, where you charge the customer only after confirming service delivery. By setting `setIsDeposit(false)` when creating a payment, the payment is created as a **preauthorization** instead of a direct deposit. @@ -26,25 +26,27 @@ $thePayClient->createPayment($params); Once you are ready to capture the funds, call `realizePreauthorizedPayment()`: ```php +use ThePay\ApiClient\Model\RealizePreauthorizedPaymentResult; + /** @var \ThePay\ApiClient\TheClient $thePayClient */ $params = new \ThePay\ApiClient\Model\RealizePreauthorizedPaymentParams(100, 'PREAUTH_PAYMENT_001'); -$response = $thePayClient->realizePreauthorizedPayment($params); - -if ($response->wasSuccessful()) { - echo 'Preauthorized payment was realized successfully'; -} else if ($response->getState() === 'waiting_for_confirmation') { - echo 'Payment is being processed, you will receive a notification when complete'; -} else { - echo 'Payment realization failed'; -} +$result = $thePayClient->realizePreauthorizedPayment($params); + +match ($result->getState()) { + RealizePreauthorizedPaymentResult::STATE_PAID => + echo 'Preauthorized payment was realized successfully', + + RealizePreauthorizedPaymentResult::STATE_WAITING_FOR_CONFIRMATION => + echo 'Payment is being processed, you will receive a notification when complete', +}; ``` You may capture less than the originally preauthorized amount, but never more. **Note about V2 API:** The V2 API supports asynchronous payment processing: -- HTTP 200 with state `paid` means immediate success -- HTTP 202 with state `waiting_for_confirmation` means the payment is being processed asynchronously +- State `paid` means immediate success +- State `waiting_for_confirmation` means the payment is being processed asynchronously - You will receive a notification when the async payment completes (state changes to `paid` or `preauth_cancelled`) ## Cancel a Preauthorized Payment @@ -57,4 +59,4 @@ $thePayClient->cancelPreauthorizedPayment('PREAUTH_PAYMENT_001'); ``` **Note on fund release:** -- While the preauthorization is cancelled immediately on ThePay’s side, banks may take some time to release the reserved funds back to the customer’s account. +- While the preauthorization is cancelled immediately on ThePay's side, banks may take some time to release the reserved funds back to the customer's account. diff --git a/doc/saving-authorization.md b/doc/saving-authorization.md index b21f9e1..d1f3b5e 100644 --- a/doc/saving-authorization.md +++ b/doc/saving-authorization.md @@ -1,7 +1,7 @@ # Saving Card Authorization -It is possible to store a customer’s card authorization by enabling the `save_authorization` parameter when creating a payment. -This allows you to create follow-up (“child”) payments seamlessly, without requiring the customer to reauthorize their card. +It is possible to store a customer's card authorization by enabling the `save_authorization` parameter when creating a payment. +This allows you to create follow-up ("child") payments seamlessly, without requiring the customer to reauthorize their card. However, this feature must not be confused with — or used for — [subscription payments](subscription.md). Those have a separate workflow and rules. @@ -29,6 +29,8 @@ Once the payment is successfully completed, the system will store a reusable aut After the original payment (with `save_authorization = true`) has been paid, you can realize a new payment using the stored authorization: ```php +use ThePay\ApiClient\Model\RecurringPaymentResult; + /** @var \ThePay\ApiClient\TheClient $thePayClient */ // First parameter: UID of the new (child) payment @@ -41,17 +43,23 @@ $item = new \ThePay\ApiClient\Model\CreatePaymentItem('item', 'Server setup', 10 $params->addItem($item); // First parameter: UID of the parent payment (one created with saveAuthorization=true) -// The method returns ApiResponse -$response = $thePayClient->realizePaymentBySavedAuthorization('uid_savedauthtest', $params); +// The method returns RecurringPaymentResult +$result = $thePayClient->realizePaymentBySavedAuthorization('uid_savedauthtest', $params); -if ($response->wasSuccessful()) { - echo 'Payment was realized using saved authorization'; -} else if ($response->getState() === 'waiting_for_confirmation') { - echo 'Payment is being processed, you will receive a notification when complete'; -} +match ($result->getState()) { + RecurringPaymentResult::STATE_PAID => + echo 'Payment was realized using saved authorization', + + RecurringPaymentResult::STATE_WAITING_FOR_CONFIRMATION => + echo 'Payment is being processed, you will receive a notification when complete', + + RecurringPaymentResult::STATE_ERROR => + echo 'Payment was not realized', +}; // Check if more payments can be realized with this saved authorization -if ($response->isRecurringPaymentsAvailable() === false) { +if (!$result->isRecurringPaymentsAvailable()) { + // Saved authorization is no longer valid, customer needs to authorize a new payment echo 'Saved authorization is no longer valid, customer needs to authorize a new payment'; } ``` @@ -59,9 +67,9 @@ if ($response->isRecurringPaymentsAvailable() === false) { **Note about V2 API:** The V2 API introduces several important changes: - **Amount and currency are now required** - you must always specify both parameters -- **Asynchronous processing**: Payment may return HTTP 202 with state `waiting_for_confirmation` - - HTTP 200 with state `paid` means immediate success - - HTTP 200 with state `error` means immediate failure - - HTTP 202 with state `waiting_for_confirmation` means async processing +- **Asynchronous processing**: Payment may have these states: + - `paid` - Payment realized successfully + - `error` - Payment realization failed + - `waiting_for_confirmation` - Payment is being processed asynchronously - **Parent availability tracking**: Check `isRecurringPaymentsAvailable()` to know if the saved authorization is still valid - You will receive a notification when async payments complete (state changes to `paid` or `error`) diff --git a/doc/subscription.md b/doc/subscription.md index 31c580a..e5576f8 100644 --- a/doc/subscription.md +++ b/doc/subscription.md @@ -46,6 +46,8 @@ After the parent payment is paid, you may charge the customer again using one of ### Realizing a Regular (Fixed Interval & Fixed Amount) Subscription ```php +use ThePay\ApiClient\Model\RecurringPaymentResult; + /** @var \ThePay\ApiClient\TheClient $thePayClient */ // UID of the new (child) payment @@ -56,35 +58,40 @@ $item = new \ThePay\ApiClient\Model\CreatePaymentItem('item', 'Magazine #2', 105 $params->addItem($item); // Parent payment UID is passed as the first parameter. -// Method returns an ApiResponse. -$response = $thePayClient->realizeRegularSubscriptionPayment('uid_subscriptionpayment', $params); - -if ($response->wasSuccessful()) { - echo 'Subscription payment was realized'; -} else { - // Check if payment is still processing asynchronously - if ($response->getState() === 'waiting_for_confirmation') { - echo 'Payment is being processed, you will receive a notification when complete'; - } -} +// Method returns a RecurringPaymentResult. +$result = $thePayClient->realizeRegularSubscriptionPayment('uid_subscriptionpayment', $params); + +match ($result->getState()) { + RecurringPaymentResult::STATE_PAID => + echo 'Subscription payment was realized', + + RecurringPaymentResult::STATE_WAITING_FOR_CONFIRMATION => + echo 'Payment is being processed, you will receive a notification when complete', + + RecurringPaymentResult::STATE_ERROR => + echo 'Payment was not realized', +}; // Check if more payments can be realized with this parent -if ($response->isRecurringPaymentsAvailable() === false) { - echo 'No more payments can be realized with this parent, inform customer to create new subscription'; +if (!$result->isRecurringPaymentsAvailable()) { + // No more payments can be realized with this parent, inform customer to create new subscription + echo 'Saved authorization is no longer valid, customer needs to authorize a new payment'; } ``` **Note about V2 API:** The V2 API supports asynchronous payment processing: -- HTTP 200 with state `paid` means immediate success -- HTTP 200 with state `error` means immediate failure -- HTTP 202 with state `waiting_for_confirmation` means the payment is being processed asynchronously +- State `paid` means immediate success +- State `error` means immediate failure +- State `waiting_for_confirmation` means the payment is being processed asynchronously - You will receive a notification when the async payment completes (state changes to `paid` or `error`) -- Always check `parent.recurring_payments_available` to know if the subscription should end +- Always check `isRecurringPaymentsAvailable()` to know if the subscription should end ### Realizing an Irregular (Variable Interval & Fixed Amount) Subscription ```php +use ThePay\ApiClient\Model\RecurringPaymentResult; + /** @var \ThePay\ApiClient\TheClient $thePayClient */ // UID of the new (child) payment @@ -95,17 +102,23 @@ $item = new \ThePay\ApiClient\Model\CreatePaymentItem('item', 'New book', 10520, $params->addItem($item); // Parent payment UID is passed as the first parameter. -// Method returns an ApiResponse. -$response = $thePayClient->realizeIrregularSubscriptionPayment('uid_subscriptionpayment', $params); +// Method returns a RecurringPaymentResult. +$result = $thePayClient->realizeIrregularSubscriptionPayment('uid_subscriptionpayment', $params); -if ($response->wasSuccessful()) { - echo 'Subscription payment was realized'; -} else if ($response->getState() === 'waiting_for_confirmation') { - echo 'Payment is being processed, you will receive a notification when complete'; -} +match ($result->getState()) { + RecurringPaymentResult::STATE_PAID => + echo 'Subscription payment was realized', + + RecurringPaymentResult::STATE_WAITING_FOR_CONFIRMATION => + echo 'Payment is being processed, you will receive a notification when complete', + + RecurringPaymentResult::STATE_ERROR => + echo 'Payment was not realized', +}; // Check if more payments can be realized -if ($response->isRecurringPaymentsAvailable() === false) { +if (!$result->isRecurringPaymentsAvailable()) { + // Parent payment no longer available for new subscriptions echo 'Parent payment no longer available for new subscriptions'; } ``` @@ -113,6 +126,8 @@ if ($response->isRecurringPaymentsAvailable() === false) { ### Realizing a Usage-Based (Fixed Interval & Variable Amount) Subscription ```php +use ThePay\ApiClient\Model\RecurringPaymentResult; + /** @var \ThePay\ApiClient\TheClient $thePayClient */ // First param: UID of child payment @@ -125,17 +140,23 @@ $params->addItem($item); // Parent payment UID is passed as the first parameter. -// Method returns an ApiResponse. -$response = $thePayClient->realizeUsageBasedSubscriptionPayment('uid_subscriptionpayment', $params); +// Method returns a RecurringPaymentResult. +$result = $thePayClient->realizeUsageBasedSubscriptionPayment('uid_subscriptionpayment', $params); -if ($response->wasSuccessful()) { - echo 'Subscription payment was realized'; -} else if ($response->getState() === 'waiting_for_confirmation') { - echo 'Payment is being processed, you will receive a notification when complete'; -} +match ($result->getState()) { + RecurringPaymentResult::STATE_PAID => + echo 'Subscription payment was realized', + + RecurringPaymentResult::STATE_WAITING_FOR_CONFIRMATION => + echo 'Payment is being processed, you will receive a notification when complete', + + RecurringPaymentResult::STATE_ERROR => + echo 'Payment was not realized', +}; // Check if more payments can be realized -if ($response->isRecurringPaymentsAvailable() === false) { +if (!$result->isRecurringPaymentsAvailable()) { + // Parent payment no longer available for new subscriptions echo 'Parent payment no longer available for new subscriptions'; } ``` diff --git a/src/Model/ApiResponse.php b/src/Model/ApiResponse.php deleted file mode 100644 index ac5b498..0000000 --- a/src/Model/ApiResponse.php +++ /dev/null @@ -1,119 +0,0 @@ -|null */ - private $parent; - - /** - * ApiResponse constructor. - * - * @param string|array $values - * @param int $statusCode - */ - public function __construct($values, $statusCode) - { - $data = is_array($values) ? $values : Json::decode($values, true); - - $this->state = isset($data['state']) ? $data['state'] : null; - $this->message = isset($data['message']) ? $data['message'] : null; - $this->parent = isset($data['parent']) ? $data['parent'] : null; - $this->statusCode = $statusCode; - } - - /** - * @return string|null - */ - public function getState() - { - return $this->state; - } - - /** - * @return string|null - */ - public function getMessage() - { - return $this->message; - } - - /** - * @return int - */ - public function getStatusCode() - { - return $this->statusCode; - } - - /** - * Get parent payment information (for subscription and saved authorization payments). - * - * @return array|null - */ - public function getParent() - { - return $this->parent; - } - - /** - * Check if recurring payments are still available for the parent payment. - * Only applicable for subscription and saved authorization payments. - * - * @return bool|null Returns null if parent information is not available - */ - public function isRecurringPaymentsAvailable() - { - if ($this->parent === null) { - return null; - } - - return isset($this->parent['recurring_payments_available']) - ? (bool) $this->parent['recurring_payments_available'] - : null; - } - - /** - * Determines if the payment was realized successfully. - */ - public function wasSuccessful(): bool - { - if ($this->statusCode === 200 && ($this->state === 'paid' || $this->state === 'success')) { - return true; - } - - return false; - } - - /** - * Determines if the payment is still being processed - */ - public function isPending(): bool - { - if ($this->statusCode === 202 && $this->state === 'waiting_for_confirmation') { - return true; - } - - return false; - } - - /** - * Determines if the payment has failed and will not be processed - */ - public function hasFailed(): bool - { - return ! $this->wasSuccessful() && ! $this->isPending(); - } -} diff --git a/src/Model/RealizePaymentBySavedAuthorizationParams.php b/src/Model/RealizePaymentBySavedAuthorizationParams.php index 7ef15a5..9aadac9 100644 --- a/src/Model/RealizePaymentBySavedAuthorizationParams.php +++ b/src/Model/RealizePaymentBySavedAuthorizationParams.php @@ -26,8 +26,7 @@ final class RealizePaymentBySavedAuthorizationParams implements SignableRequest /** @var string|null */ protected $descriptionForMerchant = null; - /** @var string|null */ - protected $notifUrl = null; + protected ?string $notifUrl = null; /** * RealizePaymentBySavedAuthorizationParams constructor. @@ -39,7 +38,7 @@ final class RealizePaymentBySavedAuthorizationParams implements SignableRequest * @param string|null $descriptionForMerchant * @param string|null $notifUrl */ - public function __construct($uid, $amount, $currencyCode, $orderId = null, $descriptionForMerchant = null, $notifUrl = null) + public function __construct($uid, $amount, $currencyCode, $orderId = null, $descriptionForMerchant = null, ?string $notifUrl = null) { $this->uid = new Identifier($uid); $this->amount = new Amount($amount); @@ -97,19 +96,12 @@ public function getDescriptionForMerchant() return $this->descriptionForMerchant; } - /** - * @return string|null - */ - public function getNotifUrl() + public function getNotifUrl(): ?string { return $this->notifUrl; } - /** - * @param string|null $notifUrl - * @return RealizePaymentBySavedAuthorizationParams - */ - public function setNotifUrl($notifUrl) + public function setNotifUrl(string $notifUrl): self { $this->notifUrl = $notifUrl; return $this; diff --git a/src/Model/RealizePreauthorizedPaymentResult.php b/src/Model/RealizePreauthorizedPaymentResult.php new file mode 100644 index 0000000..aaeb5ac --- /dev/null +++ b/src/Model/RealizePreauthorizedPaymentResult.php @@ -0,0 +1,38 @@ + $data + */ + public function __construct($data) + { + $decoded = is_array($data) ? $data : Json::decode($data, true); + + $this->state = $decoded['state']; + } + + /** + * @return self::STATE_* + */ + public function getState(): string + { + return $this->state; + } +} diff --git a/src/Model/RealizeSubscriptionPaymentParams.php b/src/Model/RealizeSubscriptionPaymentParams.php index 793c1a2..d074de0 100644 --- a/src/Model/RealizeSubscriptionPaymentParams.php +++ b/src/Model/RealizeSubscriptionPaymentParams.php @@ -22,8 +22,7 @@ abstract class RealizeSubscriptionPaymentParams implements SignableRequest /** @var string|null */ protected $descriptionForMerchant = null; - /** @var string|null */ - protected $notifUrl = null; + protected ?string $notifUrl = null; /** * @return Amount @@ -65,19 +64,12 @@ public function getDescriptionForMerchant() return $this->descriptionForMerchant; } - /** - * @return string|null - */ - public function getNotifUrl() + public function getNotifUrl(): ?string { return $this->notifUrl; } - /** - * @param string|null $notifUrl - * @return RealizeSubscriptionPaymentParams - */ - public function setNotifUrl($notifUrl) + public function setNotifUrl(string $notifUrl): self { $this->notifUrl = $notifUrl; return $this; diff --git a/src/Model/RecurringPaymentResult.php b/src/Model/RecurringPaymentResult.php new file mode 100644 index 0000000..628813b --- /dev/null +++ b/src/Model/RecurringPaymentResult.php @@ -0,0 +1,69 @@ + $data + */ + public function __construct($data) + { + $decoded = is_array($data) ? $data : Json::decode($data, true); + + $this->state = $decoded['state']; + $this->message = $decoded['message'] ?? null; + $this->recurringPaymentsAvailable = $decoded['parent']['recurring_payments_available'] ?? true; + } + + /** + * @return self::STATE_* + */ + public function getState(): string + { + return $this->state; + } + + /** + * Get optional message describing the result. + */ + public function getMessage(): ?string + { + return $this->message; + } + + /** + * Check if more recurring payments can be realized using the parent payment. + * + * When false, the subscription/authorization should end because the parent + * payment is no longer available for new realizations. + * + * In this case, you should inform the customer to create a new subscription + * or authorize a new payment. + */ + public function isRecurringPaymentsAvailable(): bool + { + return $this->recurringPaymentsAvailable; + } +} diff --git a/src/Service/ApiService.php b/src/Service/ApiService.php index 90de9b7..f1a1aa9 100644 --- a/src/Service/ApiService.php +++ b/src/Service/ApiService.php @@ -10,7 +10,6 @@ use ThePay\ApiClient\Filter\PaymentsFilter; use ThePay\ApiClient\Filter\TransactionFilter; use ThePay\ApiClient\Model\AccountBalance; -use ThePay\ApiClient\Model\ApiResponse; use ThePay\ApiClient\Model\Collection\PaymentCollection; use ThePay\ApiClient\Model\Collection\PaymentMethodCollection; use ThePay\ApiClient\Model\Collection\TransactionCollection; @@ -25,8 +24,10 @@ use ThePay\ApiClient\Model\RealizeIrregularSubscriptionPaymentParams; use ThePay\ApiClient\Model\RealizePaymentBySavedAuthorizationParams; use ThePay\ApiClient\Model\RealizePreauthorizedPaymentParams; +use ThePay\ApiClient\Model\RealizePreauthorizedPaymentResult; use ThePay\ApiClient\Model\RealizeRegularSubscriptionPaymentParams; use ThePay\ApiClient\Model\RealizeUsageBasedSubscriptionPaymentParams; +use ThePay\ApiClient\Model\RecurringPaymentResult; use ThePay\ApiClient\TheClient; use ThePay\ApiClient\TheConfig; use ThePay\ApiClient\Utils\Json; @@ -256,7 +257,7 @@ public function getPayments(PaymentsFilter $filter, int $page = 1, int $limit = * * @throws ApiException */ - public function realizeRegularSubscriptionPayment(Identifier $parentPaymentUid, RealizeRegularSubscriptionPaymentParams $params): ApiResponse + public function realizeRegularSubscriptionPayment(Identifier $parentPaymentUid, RealizeRegularSubscriptionPaymentParams $params): RecurringPaymentResult { $jsonParams = $params->toArray(); @@ -267,7 +268,7 @@ public function realizeRegularSubscriptionPayment(Identifier $parentPaymentUid, throw $this->buildException($url, $response); } - return new ApiResponse($response->getBody()->getContents(), $response->getStatusCode()); + return new RecurringPaymentResult($response->getBody()->getContents()); } /** @@ -275,7 +276,7 @@ public function realizeRegularSubscriptionPayment(Identifier $parentPaymentUid, * * @throws ApiException */ - public function realizeIrregularSubscriptionPayment(Identifier $parentPaymentUid, RealizeIrregularSubscriptionPaymentParams $params): ApiResponse + public function realizeIrregularSubscriptionPayment(Identifier $parentPaymentUid, RealizeIrregularSubscriptionPaymentParams $params): RecurringPaymentResult { $jsonParams = $params->toArray(); @@ -286,7 +287,7 @@ public function realizeIrregularSubscriptionPayment(Identifier $parentPaymentUid throw $this->buildException($url, $response); } - return new ApiResponse($response->getBody()->getContents(), $response->getStatusCode()); + return new RecurringPaymentResult($response->getBody()->getContents()); } /** @@ -294,7 +295,7 @@ public function realizeIrregularSubscriptionPayment(Identifier $parentPaymentUid * * @throws ApiException */ - public function realizeUsageBasedSubscriptionPayment(Identifier $parentPaymentUid, RealizeUsageBasedSubscriptionPaymentParams $params): ApiResponse + public function realizeUsageBasedSubscriptionPayment(Identifier $parentPaymentUid, RealizeUsageBasedSubscriptionPaymentParams $params): RecurringPaymentResult { $jsonParams = $params->toArray(); @@ -305,7 +306,7 @@ public function realizeUsageBasedSubscriptionPayment(Identifier $parentPaymentUi throw $this->buildException($url, $response); } - return new ApiResponse($response->getBody()->getContents(), $response->getStatusCode()); + return new RecurringPaymentResult($response->getBody()->getContents()); } /** @@ -313,7 +314,7 @@ public function realizeUsageBasedSubscriptionPayment(Identifier $parentPaymentUi * * @throws ApiException */ - public function realizePaymentBySavedAuthorization(Identifier $parentPaymentUid, RealizePaymentBySavedAuthorizationParams $params): ApiResponse + public function realizePaymentBySavedAuthorization(Identifier $parentPaymentUid, RealizePaymentBySavedAuthorizationParams $params): RecurringPaymentResult { $jsonParams = $params->toArray(); @@ -324,7 +325,7 @@ public function realizePaymentBySavedAuthorization(Identifier $parentPaymentUid, throw $this->buildException($url, $response); } - return new ApiResponse($response->getBody()->getContents(), $response->getStatusCode()); + return new RecurringPaymentResult($response->getBody()->getContents()); } @@ -372,7 +373,7 @@ public function changePaymentMethod(Identifier $uid, string $methodCode): void /** * @throws ApiException */ - public function realizePreauthorizedPayment(RealizePreauthorizedPaymentParams $params): ApiResponse + public function realizePreauthorizedPayment(RealizePreauthorizedPaymentParams $params): RealizePreauthorizedPaymentResult { $url = $this->url([ 'projects', @@ -387,7 +388,7 @@ public function realizePreauthorizedPayment(RealizePreauthorizedPaymentParams $p throw $this->buildException($url, $response); } - return new ApiResponse($response->getBody()->getContents(), $response->getStatusCode()); + return new RealizePreauthorizedPaymentResult($response->getBody()->getContents()); } /** @@ -507,10 +508,10 @@ public function generatePaymentConfirmationPdf(Identifier $uid, ?LanguageCode $l * @param array $path * @param array $arguments * @param bool $includeProject - * @param string|null $specificVersion + * @param non-empty-string|null $specificVersion * @return string */ - private function url($path = [], $arguments = [], $includeProject = true, $specificVersion = null) + private function url($path = [], $arguments = [], $includeProject = true, ?string $specificVersion = null) { if ( ! isset($arguments['merchant_id'])) { ($arguments['merchant_id'] = $this->config->getMerchantId()); diff --git a/src/Service/ApiServiceInterface.php b/src/Service/ApiServiceInterface.php index 0b5538f..d2032b5 100644 --- a/src/Service/ApiServiceInterface.php +++ b/src/Service/ApiServiceInterface.php @@ -6,7 +6,6 @@ use ThePay\ApiClient\Filter\PaymentsFilter; use ThePay\ApiClient\Filter\TransactionFilter; use ThePay\ApiClient\Model\AccountBalance; -use ThePay\ApiClient\Model\ApiResponse; use ThePay\ApiClient\Model\Collection\PaymentCollection; use ThePay\ApiClient\Model\Collection\PaymentMethodCollection; use ThePay\ApiClient\Model\Collection\TransactionCollection; @@ -19,8 +18,10 @@ use ThePay\ApiClient\Model\RealizeIrregularSubscriptionPaymentParams; use ThePay\ApiClient\Model\RealizePaymentBySavedAuthorizationParams; use ThePay\ApiClient\Model\RealizePreauthorizedPaymentParams; +use ThePay\ApiClient\Model\RealizePreauthorizedPaymentResult; use ThePay\ApiClient\Model\RealizeRegularSubscriptionPaymentParams; use ThePay\ApiClient\Model\RealizeUsageBasedSubscriptionPaymentParams; +use ThePay\ApiClient\Model\RecurringPaymentResult; use ThePay\ApiClient\ValueObject\Amount; use ThePay\ApiClient\ValueObject\Identifier; use ThePay\ApiClient\ValueObject\LanguageCode; @@ -61,34 +62,34 @@ public function invalidatePayment(Identifier $paymentUid); /** * @param Identifier $parentPaymentUid UID of payment which initialized this subscription. * @param RealizeRegularSubscriptionPaymentParams $params - * @return ApiResponse + * @return RecurringPaymentResult * @throws ApiException */ - public function realizeRegularSubscriptionPayment(Identifier $parentPaymentUid, RealizeRegularSubscriptionPaymentParams $params); + public function realizeRegularSubscriptionPayment(Identifier $parentPaymentUid, RealizeRegularSubscriptionPaymentParams $params): RecurringPaymentResult; /** * @param Identifier $parentPaymentUid UID of payment which initialized this subscription. * @param RealizeIrregularSubscriptionPaymentParams $params - * @return ApiResponse + * @return RecurringPaymentResult * @throws ApiException */ - public function realizeIrregularSubscriptionPayment(Identifier $parentPaymentUid, RealizeIrregularSubscriptionPaymentParams $params); + public function realizeIrregularSubscriptionPayment(Identifier $parentPaymentUid, RealizeIrregularSubscriptionPaymentParams $params): RecurringPaymentResult; /** * @param Identifier $parentPaymentUid UID of payment which initialized this subscription. * @param RealizeUsageBasedSubscriptionPaymentParams $params - * @return ApiResponse + * @return RecurringPaymentResult * @throws ApiException */ - public function realizeUsageBasedSubscriptionPayment(Identifier $parentPaymentUid, RealizeUsageBasedSubscriptionPaymentParams $params); + public function realizeUsageBasedSubscriptionPayment(Identifier $parentPaymentUid, RealizeUsageBasedSubscriptionPaymentParams $params): RecurringPaymentResult; /** * @param Identifier $parentPaymentUid UID of first payment created with save_authorization=true. * @param RealizePaymentBySavedAuthorizationParams $params - * @return ApiResponse + * @return RecurringPaymentResult * @throws ApiException */ - public function realizePaymentBySavedAuthorization(Identifier $parentPaymentUid, RealizePaymentBySavedAuthorizationParams $params); + public function realizePaymentBySavedAuthorization(Identifier $parentPaymentUid, RealizePaymentBySavedAuthorizationParams $params): RecurringPaymentResult; /** * @param int<1, max> $page @@ -121,7 +122,7 @@ public function createPayment(CreatePaymentParams $createPaymentParams, ?string /** * @throws ApiException */ - public function realizePreauthorizedPayment(RealizePreauthorizedPaymentParams $params): ApiResponse; + public function realizePreauthorizedPayment(RealizePreauthorizedPaymentParams $params): RealizePreauthorizedPaymentResult; public function cancelPreauthorizedPayment(Identifier $uid): void; diff --git a/src/TheClient.php b/src/TheClient.php index 04c8eb1..112fbb0 100644 --- a/src/TheClient.php +++ b/src/TheClient.php @@ -9,7 +9,6 @@ use ThePay\ApiClient\Filter\PaymentsFilter; use ThePay\ApiClient\Filter\TransactionFilter; use ThePay\ApiClient\Model\AccountBalance; -use ThePay\ApiClient\Model\ApiResponse; use ThePay\ApiClient\Model\Collection\PaymentCollection; use ThePay\ApiClient\Model\Collection\PaymentMethodCollection; use ThePay\ApiClient\Model\CreatePaymentParams; @@ -20,8 +19,10 @@ use ThePay\ApiClient\Model\RealizeIrregularSubscriptionPaymentParams; use ThePay\ApiClient\Model\RealizePaymentBySavedAuthorizationParams; use ThePay\ApiClient\Model\RealizePreauthorizedPaymentParams; +use ThePay\ApiClient\Model\RealizePreauthorizedPaymentResult; use ThePay\ApiClient\Model\RealizeRegularSubscriptionPaymentParams; use ThePay\ApiClient\Model\RealizeUsageBasedSubscriptionPaymentParams; +use ThePay\ApiClient\Model\RecurringPaymentResult; use ThePay\ApiClient\Model\SimplePayment; use ThePay\ApiClient\Model\SimpleTransaction; use ThePay\ApiClient\Service\ApiServiceInterface; @@ -146,10 +147,10 @@ public function invalidatePayment($paymentUid) /** * @param string $parentPaymentUid UID of payment which initialized this subscription. * @param RealizeRegularSubscriptionPaymentParams $params - * @return ApiResponse + * @return RecurringPaymentResult * @throws ApiException|InvalidArgumentException */ - public function realizeRegularSubscriptionPayment($parentPaymentUid, RealizeRegularSubscriptionPaymentParams $params) + public function realizeRegularSubscriptionPayment($parentPaymentUid, RealizeRegularSubscriptionPaymentParams $params): RecurringPaymentResult { $this->validateUid($parentPaymentUid); return $this->api->realizeRegularSubscriptionPayment(new Identifier($parentPaymentUid), $params); @@ -158,10 +159,10 @@ public function realizeRegularSubscriptionPayment($parentPaymentUid, RealizeRegu /** * @param string $parentPaymentUid UID of payment which initialized this subscription. * @param RealizeIrregularSubscriptionPaymentParams $params - * @return ApiResponse + * @return RecurringPaymentResult * @throws ApiException|InvalidArgumentException */ - public function realizeIrregularSubscriptionPayment($parentPaymentUid, RealizeIrregularSubscriptionPaymentParams $params) + public function realizeIrregularSubscriptionPayment($parentPaymentUid, RealizeIrregularSubscriptionPaymentParams $params): RecurringPaymentResult { $this->validateUid($parentPaymentUid); return $this->api->realizeIrregularSubscriptionPayment(new Identifier($parentPaymentUid), $params); @@ -170,10 +171,10 @@ public function realizeIrregularSubscriptionPayment($parentPaymentUid, RealizeIr /** * @param string $parentPaymentUid UID of payment which initialized this subscription. * @param RealizeUsageBasedSubscriptionPaymentParams $params - * @return ApiResponse + * @return RecurringPaymentResult * @throws ApiException|InvalidArgumentException */ - public function realizeUsageBasedSubscriptionPayment($parentPaymentUid, RealizeUsageBasedSubscriptionPaymentParams $params) + public function realizeUsageBasedSubscriptionPayment($parentPaymentUid, RealizeUsageBasedSubscriptionPaymentParams $params): RecurringPaymentResult { $this->validateUid($parentPaymentUid); return $this->api->realizeUsageBasedSubscriptionPayment(new Identifier($parentPaymentUid), $params); @@ -182,10 +183,10 @@ public function realizeUsageBasedSubscriptionPayment($parentPaymentUid, RealizeU /** * @param string $parentPaymentUid UID of first payment created with save_authorization=true. * @param RealizePaymentBySavedAuthorizationParams $params - * @return ApiResponse + * @return RecurringPaymentResult * @throws ApiException|InvalidArgumentException */ - public function realizePaymentBySavedAuthorization($parentPaymentUid, RealizePaymentBySavedAuthorizationParams $params) + public function realizePaymentBySavedAuthorization($parentPaymentUid, RealizePaymentBySavedAuthorizationParams $params): RecurringPaymentResult { $this->validateUid($parentPaymentUid); return $this->api->realizePaymentBySavedAuthorization(new Identifier($parentPaymentUid), $params); @@ -283,10 +284,10 @@ public function changePaymentMethod(string $paymentUid, string $methodCode): voi /** * @param RealizePreauthorizedPaymentParams $params - * @return ApiResponse + * @return RealizePreauthorizedPaymentResult * @throws ApiException|InvalidArgumentException */ - public function realizePreauthorizedPayment(RealizePreauthorizedPaymentParams $params): ApiResponse + public function realizePreauthorizedPayment(RealizePreauthorizedPaymentParams $params): RealizePreauthorizedPaymentResult { $this->validateUid($params->getUid()->getValue()); return $this diff --git a/src/TheConfig.php b/src/TheConfig.php index a72d71f..85b8805 100644 --- a/src/TheConfig.php +++ b/src/TheConfig.php @@ -57,12 +57,12 @@ public function getGateUrl() } /** - * @param string|null $specificVersion If specified, it will use this version of the API instead of the default one. + * @param non-empty-string|null $specificVersion If specified, it will use this version of the API instead of the default one. * @return string */ - public function getApiUrl($specificVersion = null) + public function getApiUrl(?string $specificVersion = null): string { - if ($specificVersion) { + if ($specificVersion !== null) { return $this->apiUrl->getValue() . $specificVersion . '/'; } return $this->apiUrl->getValue() . $this->apiVersion . '/'; diff --git a/tests/RealizePreauthorizationPaymentTest.php b/tests/RealizePreauthorizationPaymentTest.php index b0746b9..8ce22b8 100644 --- a/tests/RealizePreauthorizationPaymentTest.php +++ b/tests/RealizePreauthorizationPaymentTest.php @@ -11,6 +11,7 @@ use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; use ThePay\ApiClient\Model\RealizePreauthorizedPaymentParams; +use ThePay\ApiClient\Model\RealizePreauthorizedPaymentResult; use ThePay\ApiClient\Service\ApiService; use ThePay\ApiClient\Service\SignatureService; use ThePay\ApiClient\TheClient; @@ -58,9 +59,8 @@ public function testRequest(): void $response = $this->client->realizePreauthorizedPayment(new RealizePreauthorizedPaymentParams(100, 'abc')); - self::assertInstanceOf(\ThePay\ApiClient\Model\ApiResponse::class, $response); - self::assertSame('paid', $response->getState()); - self::assertTrue($response->wasSuccessful()); + self::assertInstanceOf(RealizePreauthorizedPaymentResult::class, $response); + self::assertSame(RealizePreauthorizedPaymentResult::STATE_PAID, $response->getState()); } public function testNotOkResponse(): void @@ -74,7 +74,7 @@ public function testNotOkResponse(): void private function getOkResponse(): ResponseInterface { - return new Response(200, [], '{"state":"paid","message":"Payment realized successfully"}'); + return new Response(200, [], '{"state":"paid"}'); } private function getNotOkResponse(): ResponseInterface diff --git a/tests/RealizeSavedAuthorizationPaymentTest.php b/tests/RealizeSavedAuthorizationPaymentTest.php index 411df0f..00812e9 100644 --- a/tests/RealizeSavedAuthorizationPaymentTest.php +++ b/tests/RealizeSavedAuthorizationPaymentTest.php @@ -4,7 +4,7 @@ namespace ThePay\ApiClient\Tests; -use ThePay\ApiClient\Model\ApiResponse; +use ThePay\ApiClient\Model\RecurringPaymentResult; use ThePay\ApiClient\Model\RealizePaymentBySavedAuthorizationParams; use ThePay\ApiClient\Service\ApiServiceInterface; use ThePay\ApiClient\TheClient; @@ -17,15 +17,14 @@ protected function setUp(): void { parent::setUp(); - $okResponse = new ApiResponse( + $okResponse = new RecurringPaymentResult( '{ "state": "paid", "message": "Ok", "parent": { "recurring_payments_available": true } - }', - 200 + }' ); $apiService = $this->createMock(ApiServiceInterface::class); @@ -39,8 +38,8 @@ public function testRealizePaymentBySavedAuthorization(): void $params = new RealizePaymentBySavedAuthorizationParams('childPayment', 10000, 'CZK'); $result = $this->client->realizePaymentBySavedAuthorization('parentUid', $params); - self::assertSame(ApiResponse::class, get_class($result)); - self::assertTrue($result->wasSuccessful()); + self::assertSame(RecurringPaymentResult::class, get_class($result)); + self::assertSame(RecurringPaymentResult::STATE_PAID, $result->getState()); self::assertTrue($result->isRecurringPaymentsAvailable()); } } diff --git a/tests/RealizeSubscriptionPaymentTest.php b/tests/RealizeSubscriptionPaymentTest.php index b6ad90f..c86ebe2 100644 --- a/tests/RealizeSubscriptionPaymentTest.php +++ b/tests/RealizeSubscriptionPaymentTest.php @@ -4,7 +4,7 @@ namespace ThePay\ApiClient\Tests; -use ThePay\ApiClient\Model\ApiResponse; +use ThePay\ApiClient\Model\RecurringPaymentResult; use ThePay\ApiClient\Model\RealizeIrregularSubscriptionPaymentParams; use ThePay\ApiClient\Model\RealizeRegularSubscriptionPaymentParams; use ThePay\ApiClient\Model\RealizeUsageBasedSubscriptionPaymentParams; @@ -19,15 +19,14 @@ protected function setUp(): void { parent::setUp(); - $okResponse = new ApiResponse( + $okResponse = new RecurringPaymentResult( '{ "state": "paid", "message": "Ok", "parent": { "recurring_payments_available": true } - }', - 200 + }' ); $apiService = $this->createMock(ApiServiceInterface::class); @@ -43,20 +42,20 @@ public function testRealizeSubscriptionPayment(): void $params = new RealizeRegularSubscriptionPaymentParams('childPayment'); $result = $this->client->realizeRegularSubscriptionPayment('parentUid', $params); - self::assertSame(ApiResponse::class, get_class($result)); - self::assertTrue($result->wasSuccessful()); + self::assertSame(RecurringPaymentResult::class, get_class($result)); + self::assertSame(RecurringPaymentResult::STATE_PAID, $result->getState()); self::assertTrue($result->isRecurringPaymentsAvailable()); $params = new RealizeIrregularSubscriptionPaymentParams('childPayment2'); $result = $this->client->realizeIrregularSubscriptionPayment('parentUid', $params); - self::assertSame(ApiResponse::class, get_class($result)); - self::assertTrue($result->wasSuccessful()); + self::assertSame(RecurringPaymentResult::class, get_class($result)); + self::assertSame(RecurringPaymentResult::STATE_PAID, $result->getState()); $params = new RealizeUsageBasedSubscriptionPaymentParams('childPayment3', 1000); $result = $this->client->realizeUsageBasedSubscriptionPayment('parentUid', $params); - self::assertSame(ApiResponse::class, get_class($result)); - self::assertTrue($result->wasSuccessful()); + self::assertSame(RecurringPaymentResult::class, get_class($result)); + self::assertSame(RecurringPaymentResult::STATE_PAID, $result->getState()); } }