diff --git a/src/Model/Entity/Payments/ApiGetInvoiceResponse.php b/src/Model/Entity/Payments/ApiGetInvoiceResponse.php new file mode 100644 index 000000000..2979eeb81 --- /dev/null +++ b/src/Model/Entity/Payments/ApiGetInvoiceResponse.php @@ -0,0 +1,192 @@ +") + * @JMS\SerializedName("refunds") + */ + public $refunds; + + /** + * @var float + * + * @JMS\Type("float") + * @JMS\SerializedName("discountAmount") + */ + public $discountAmount; +} diff --git a/src/Model/Entity/Payments/ApiImportInvoicePaymentRefund.php b/src/Model/Entity/Payments/ApiImportInvoicePaymentRefund.php new file mode 100644 index 000000000..941da6aee --- /dev/null +++ b/src/Model/Entity/Payments/ApiImportInvoicePaymentRefund.php @@ -0,0 +1,45 @@ +") + * @JMS\SerializedName("refunds") + */ + public $refunds; + + /** + * @var bool + * + * @JMS\Type("bool") + * @JMS\SerializedName("refundable") + */ + public $refundable; +} diff --git a/src/Model/Entity/Payments/ApiImportInvoiceResponse.php b/src/Model/Entity/Payments/ApiImportInvoiceResponse.php new file mode 100644 index 000000000..7bc8a529a --- /dev/null +++ b/src/Model/Entity/Payments/ApiImportInvoiceResponse.php @@ -0,0 +1,29 @@ +invoice = $importInvoice; + } + } +} diff --git a/src/Model/Response/Payments/PaymentGetInvoiceResponse.php b/src/Model/Response/Payments/PaymentGetInvoiceResponse.php new file mode 100644 index 000000000..beb8a8834 --- /dev/null +++ b/src/Model/Response/Payments/PaymentGetInvoiceResponse.php @@ -0,0 +1,30 @@ +payments->getInvoice('7684160f-5ebe-4787-b031-1fc9e659f123'); + * } catch (ApiExceptionInterface $exception) { + * echo sprintf( + * 'Error from RetailCRM API (status code: %d): %s', + * $exception->getStatusCode(), + * $exception->getMessage() + * ); + * + * if (count($exception->getErrorResponse()->errors) > 0) { + * echo PHP_EOL . 'Errors: ' . implode(', ', $exception->getErrorResponse()->errors); + * } + * } + * ``` + * + * @param string $invoiceUuid + * + * @return \RetailCrm\Api\Model\Response\Payments\PaymentGetInvoiceResponse + * @throws \RetailCrm\Api\Interfaces\ApiExceptionInterface + * @throws \RetailCrm\Api\Interfaces\ClientExceptionInterface + * @throws \RetailCrm\Api\Exception\Api\AccountDoesNotExistException + * @throws \RetailCrm\Api\Exception\Api\ApiErrorException + * @throws \RetailCrm\Api\Exception\Api\MissingCredentialsException + * @throws \RetailCrm\Api\Exception\Api\MissingParameterException + * @throws \RetailCrm\Api\Exception\Api\ValidationException + * @throws \RetailCrm\Api\Exception\Client\HandlerException + * @throws \RetailCrm\Api\Exception\Client\HttpClientException + */ + public function getInvoice(string $invoiceUuid): PaymentGetInvoiceResponse + { + /** @var PaymentGetInvoiceResponse $response */ + $response = $this->sendRequest( + RequestMethod::GET, + 'payment/invoice/' . $invoiceUuid, + null, + PaymentGetInvoiceResponse::class + ); + + return $response; + } + + /** + * Makes POST "/api/v5/payment/invoice/import" request. + * + * Example: + * ```php + * use RetailCrm\Api\Factory\SimpleClientFactory; + * use RetailCrm\Api\Interfaces\ApiExceptionInterface; + * use RetailCrm\Api\Model\Entity\Payments\ApiImportInvoiceRequest; + * use RetailCrm\Api\Model\Request\Payments\PaymentImportInvoiceRequest; + * + * $client = SimpleClientFactory::createClient('https://test.retailcrm.pro', 'apiKey'); + * + * $invoice = new ApiImportInvoiceRequest(); + * + * $invoice->paymentId = 979; + * $invoice->externalId = '979'; + * $invoice->status = 'succeeded'; + * $invoice->amount = 6697.0; + * $invoice->currency = 'RUB'; + * $invoice->createdAt = '2025-07-08 00:00:00'; + * $invoice->paidAt = '2025-07-08 00:10:00'; + * $invoice->refundable = true; + * + * try { + * $response = $client->payments->importInvoice(new PaymentImportInvoiceRequest($invoice)); + * } catch (ApiExceptionInterface $exception) { + * echo sprintf( + * 'Error from RetailCRM API (status code: %d): %s', + * $exception->getStatusCode(), + * $exception->getMessage() + * ); + * + * if (count($exception->getErrorResponse()->errors) > 0) { + * echo PHP_EOL . 'Errors: ' . implode(', ', $exception->getErrorResponse()->errors); + * } + * } + * ``` + * + * @param \RetailCrm\Api\Model\Request\Payments\PaymentImportInvoiceRequest $request + * + * @return \RetailCrm\Api\Model\Response\Payments\PaymentImportInvoiceResponse + * @throws \RetailCrm\Api\Interfaces\ApiExceptionInterface + * @throws \RetailCrm\Api\Interfaces\ClientExceptionInterface + * @throws \RetailCrm\Api\Exception\Api\AccountDoesNotExistException + * @throws \RetailCrm\Api\Exception\Api\ApiErrorException + * @throws \RetailCrm\Api\Exception\Api\MissingCredentialsException + * @throws \RetailCrm\Api\Exception\Api\MissingParameterException + * @throws \RetailCrm\Api\Exception\Api\ValidationException + * @throws \RetailCrm\Api\Exception\Client\HandlerException + * @throws \RetailCrm\Api\Exception\Client\HttpClientException + */ + public function importInvoice(PaymentImportInvoiceRequest $request): PaymentImportInvoiceResponse + { + /** @var PaymentImportInvoiceResponse $response */ + $response = $this->sendRequest( + RequestMethod::POST, + 'payment/invoice/import', + $request, + PaymentImportInvoiceResponse::class + ); + + return $response; + } } diff --git a/tests/src/ResourceGroup/PaymentsTest.php b/tests/src/ResourceGroup/PaymentsTest.php index 8186a28d2..a974e16ee 100644 --- a/tests/src/ResourceGroup/PaymentsTest.php +++ b/tests/src/ResourceGroup/PaymentsTest.php @@ -13,9 +13,11 @@ use RetailCrm\Api\Enum\RequestMethod; use RetailCrm\Api\Model\Entity\Payments\ApiCheckRequest; use RetailCrm\Api\Model\Entity\Payments\ApiCreateInvoiceRequest; +use RetailCrm\Api\Model\Entity\Payments\ApiImportInvoiceRequest; use RetailCrm\Api\Model\Entity\Payments\ApiUpdateInvoiceRequest; use RetailCrm\Api\Model\Request\Payments\PaymentCheckRequest; use RetailCrm\Api\Model\Request\Payments\PaymentCreateInvoiceRequest; +use RetailCrm\Api\Model\Request\Payments\PaymentImportInvoiceRequest; use RetailCrm\Api\Model\Request\Payments\PaymentUpdateInvoiceRequest; use RetailCrm\TestUtils\Factory\TestClientFactory; use RetailCrm\TestUtils\TestCase\AbstractApiResourceGroupTestCase; @@ -114,4 +116,60 @@ public function testUpdateInvoice(): void self::assertModelEqualsToResponse($json, $response); } + + public function testGetInvoice(): void + { + $json = <<<'EOF' +{ + "success": false +} +EOF; + + $mock = static::createApiMockBuilder('payment/invoice/7684160f-5ebe-4787-b031-1fc9e659f123'); + $mock->matchMethod(RequestMethod::GET) + ->reply() + ->withBody($json); + + $client = TestClientFactory::createClient($mock->getClient()); + $response = $client->payments->getInvoice('7684160f-5ebe-4787-b031-1fc9e659f123'); + + self::assertModelEqualsToResponse($json, $response); + } + + public function testImportInvoice(): void + { + $json = <<<'EOF' +{ + "success": true, + "invoice": { + "invoiceUuid": "7684160f-5ebe-4787-b031-1fc9e659f123" + } +} +EOF; + + $request = new PaymentImportInvoiceRequest(); + $invoice = new ApiImportInvoiceRequest(); + + $invoice->paymentId = 979; + $invoice->externalId = '979'; + $invoice->status = 'succeeded'; + $invoice->amount = 6697.0; + $invoice->currency = 'RUB'; + $invoice->createdAt = '2025-07-08 00:00:00'; + $invoice->paidAt = '2025-07-08 00:10:00'; + $invoice->refundable = true; + + $request->invoice = $invoice; + + $mock = static::createApiMockBuilder('payment/invoice/import'); + $mock->matchMethod(RequestMethod::POST) + ->matchBody(static::encodeForm($request)) + ->reply() + ->withBody($json); + + $client = TestClientFactory::createClient($mock->getClient()); + $response = $client->payments->importInvoice($request); + + self::assertModelEqualsToResponse($json, $response); + } }