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.
*