diff --git a/src/Services/ResourceService.php b/src/Services/ResourceService.php index b4bedfe1..16821523 100755 --- a/src/Services/ResourceService.php +++ b/src/Services/ResourceService.php @@ -209,6 +209,16 @@ public function fetchResourceByUrl($url) } $resource = $unzer->fetchReversal($paymentId, $resourceId); break; + case $resourceType === IdStrings::CHARGEBACK: + $paymentId = IdService::getResourceIdFromUrl($url, IdStrings::PAYMENT); + $chargeId = IdService::getResourceIdOrNullFromUrl($url, IdStrings::CHARGE); + + $resource = $this->fetchChargebackById( + $paymentId, + $resourceId, + $chargeId + ); + break; case $resourceType === IdStrings::PAYOUT: $resource = $unzer->fetchPayout(IdService::getResourceIdFromUrl($url, IdStrings::PAYMENT)); break; diff --git a/test/integration/WebhookTest.php b/test/integration/WebhookTest.php index beeb0f52..bdae8add 100755 --- a/test/integration/WebhookTest.php +++ b/test/integration/WebhookTest.php @@ -14,6 +14,7 @@ use UnzerSDK\Constants\ApiResponseCodes; use UnzerSDK\Constants\WebhookEvents; use UnzerSDK\Exceptions\UnzerApiException; +use UnzerSDK\Resources\TransactionTypes\Chargeback; use UnzerSDK\Resources\Webhook; use UnzerSDK\test\BaseIntegrationTest; use function count; @@ -22,6 +23,7 @@ class WebhookTest extends BaseIntegrationTest { // + const CHARGEDBACK_PAYMENT_ID = 's-pay-341196'; /** * Verify Webhook resource can be registered and fetched. @@ -221,6 +223,27 @@ public function bulkSettingOnlyOneWebhookShouldBePossible(): void $this->assertEquals($url, $webhook->getUrl()); } + /** + * @test + */ + public function testFetchResourceFromEvent(): void + { + $webhookNotification = [ + 'event' => 'chargebacks', + 'publicKey' => 's-pub-xyz', + 'retrieveUrl' => 'https://sbx-api.unzer.com/v1/payments/' . self::CHARGEDBACK_PAYMENT_ID . '/charges/s-chg-1/chargebacks/s-cbk-1', + 'paymentId' => self::CHARGEDBACK_PAYMENT_ID + ]; + + // when + $chargeback = $this->unzer->fetchResourceFromEvent(json_encode($webhookNotification)); + + // then + $this->assertInstanceOf(Chargeback::class, $chargeback); + $this->assertNotNull($chargeback); + $this->assertEquals('s-cbk-1', $chargeback->getId()); + } + // // diff --git a/test/unit/Services/WebhooksServiceTest.php b/test/unit/Services/WebhooksServiceTest.php index b21f9404..df5519c6 100755 --- a/test/unit/Services/WebhooksServiceTest.php +++ b/test/unit/Services/WebhooksServiceTest.php @@ -11,16 +11,18 @@ namespace UnzerSDK\test\unit\Services; -use UnzerSDK\Unzer; +use RuntimeException; +use stdClass; use UnzerSDK\Interfaces\ResourceServiceInterface; +use UnzerSDK\Resources\TransactionTypes\Charge; +use UnzerSDK\Resources\TransactionTypes\Chargeback; use UnzerSDK\Resources\Webhook; use UnzerSDK\Resources\Webhooks; use UnzerSDK\Services\ResourceService; use UnzerSDK\Services\WebhookService; use UnzerSDK\test\BasePaymentTest; use UnzerSDK\test\unit\DummyResource; -use RuntimeException; -use stdClass; +use UnzerSDK\Unzer; class WebhooksServiceTest extends BasePaymentTest { @@ -328,6 +330,54 @@ public function fetchResourceByEventWithEmptyRetrieveUrlShouldThrowException(): $webhookService->fetchResourceFromEvent(); } + /** + * Verify that a chargeback is returned from a webhook event. + * + * @test + */ + public function fetchChargebackByEventShouldReturnChargeback(): void + { + // given + $unzer = new Unzer('s-priv-1234'); + $webhookService = new WebhookService($unzer); + + $paymentId = 's-pay-42'; + $chargeId = 's-chg-1'; + $chargebackId = 's-cbk-1'; + $retrieveUrl = "https://api.unzer.com/v1/payments/{$paymentId}/charges/{$chargeId}/chargebacks/{$chargebackId}"; + + // Partial mock: keep original behavior except fetchChargebackById which we want to intercept + $resourceServiceMock = $this->getMockBuilder(ResourceService::class) + ->setConstructorArgs([$unzer]) + ->setMethods(['fetchChargebackById']) + ->getMock(); + + $chargeback = (new Chargeback(10.0)) + ->setId($chargebackId) + ->setParentResource((new Charge())->setId($chargeId)); + + $resourceServiceMock->expects($this->once()) + ->method('fetchChargebackById') + ->with($paymentId, $chargebackId, $chargeId) + ->willReturn($chargeback); + + $webhookService->setResourceService($resourceServiceMock); + + $eventJson = json_encode([ + 'event' => 'chargeback', + 'publicKey' => 's-pub-xyz', + 'retrieveUrl' => $retrieveUrl, + 'paymentId' => $paymentId + ]); + + // when + $fetchedChargeback = $webhookService->fetchResourceFromEvent($eventJson); + + // then + $this->assertSame($chargeback, $fetchedChargeback); + $this->assertNotNull($fetchedChargeback); + } + /** * Verify exception is thrown if the retrieveURL is empty. *