From ab617e22132fd4441390cd1a00540bfc0a5ea9b8 Mon Sep 17 00:00:00 2001 From: Olivier Dolbeau Date: Thu, 11 Apr 2024 21:10:26 +0200 Subject: [PATCH] Implement payment refund --- src/Http/ApiCaller.php | 16 ++++++------ src/Service/PaymentService.php | 14 ++++++++++- .../Functional/Service/PaymentServiceTest.php | 25 ++++++++++++++++++- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/Http/ApiCaller.php b/src/Http/ApiCaller.php index c9cfc39..811bcea 100644 --- a/src/Http/ApiCaller.php +++ b/src/Http/ApiCaller.php @@ -22,16 +22,17 @@ public function __construct( /** * @template T of HelloassoObject * - * @param class-string $responseClassType + * @param class-string $responseClassType + * @param array $options HttpClient request options * * @return T */ - public function post(string $url, array|HelloassoObject|null $body, string $responseClassType): HelloassoObject + public function post(string $url, array|HelloassoObject|null $body, string $responseClassType, ?array $options = []): HelloassoObject { - $response = $this->httpClient->request(Request::METHOD_POST, $url, [ + $response = $this->httpClient->request(Request::METHOD_POST, $url, array_merge([ 'auth_bearer' => $this->tokenManager->getAccessToken(), 'body' => $this->serializer->serialize($body, 'json'), - ]); + ], $options)); return $this->responseHandler->deserializeResponse($response, $responseClassType); } @@ -43,12 +44,11 @@ public function post(string $url, array|HelloassoObject|null $body, string $resp * * @return T */ - public function get(string $url, string $responseClassType, array|HelloassoObject|null $request = null): HelloassoObject + public function get(string $url, string $responseClassType, ?array $options = []): HelloassoObject { - $response = $this->httpClient->request(Request::METHOD_GET, $url, [ + $response = $this->httpClient->request(Request::METHOD_GET, $url, array_merge([ 'auth_bearer' => $this->tokenManager->getAccessToken(), - 'body' => $request, - ]); + ], $options)); return $this->responseHandler->deserializeResponse($response, $responseClassType); } diff --git a/src/Service/PaymentService.php b/src/Service/PaymentService.php index 5c83e4f..37b7009 100644 --- a/src/Service/PaymentService.php +++ b/src/Service/PaymentService.php @@ -30,6 +30,18 @@ public function retrieve(int $id): Payment */ public function all(array $params = []): PaymentCollection { - return $this->apiCaller->get("/v5/organizations/{$this->organizationSlug}/payments", PaymentCollection::class, $params); + return $this->apiCaller->get("/v5/organizations/{$this->organizationSlug}/payments", PaymentCollection::class, [ + 'query' => $params, + ]); + } + + /** + * @throws HelloassoApiException + */ + public function refund(int $id, array $params = []): Payment + { + return $this->apiCaller->post("/v5/payments/$id/refund", null, Payment::class, [ + 'query' => $params, + ]); } } diff --git a/tests/Functional/Service/PaymentServiceTest.php b/tests/Functional/Service/PaymentServiceTest.php index 7c44e0b..99f6890 100644 --- a/tests/Functional/Service/PaymentServiceTest.php +++ b/tests/Functional/Service/PaymentServiceTest.php @@ -4,6 +4,7 @@ namespace Helloasso\Tests\Functional\Service; +use Helloasso\Enums\PaymentState; use Helloasso\Models\Statistics\Payment; use Helloasso\Models\Statistics\PaymentCollection; use Helloasso\Tests\Functional\FunctionalTestCase; @@ -16,7 +17,7 @@ public function testAll(): void $this->assertInstanceOf(PaymentCollection::class, $paymentCollection); if ($paymentCollection->isEmpty()) { - $this->markTestSkipped(); + $this->markTestSkipped('No payment fund in collection'); } $paymentId = $paymentCollection->getData()[0]->getId(); @@ -24,5 +25,27 @@ public function testAll(): void $payment = $this->getClient()->payment->retrieve($paymentId); $this->assertInstanceOf(Payment::class, $payment); $this->assertSame($paymentId, $payment->getId()); + + $this->markTestSkipped('Refund test is disable for now as it requires special permissions, even on sandbox environment.'); + + /* @phpstan-ignore-next-line Ignored due do skipped test */ + if (null === $refundablePayment = $this->getRefundablePayment($paymentCollection)) { + $this->markTestSkipped('No refundable payment found in collection'); + } + + $payment = $this->getClient()->payment->refund($refundablePayment->getId(), ['comment' => 'Refunded from functional test']); + $this->assertSame(PaymentState::Refunded, $payment->getState()); + } + + /* @phpstan-ignore-next-line Ignored due do skipped test */ + private function getRefundablePayment(PaymentCollection $paymentCollection): ?Payment + { + foreach ($paymentCollection->getData() as $payment) { + if (PaymentState::Authorized === $payment->getState()) { + return $payment; + } + } + + return null; } }