Skip to content

Commit

Permalink
ACP-2626 ABort Webhook handling when payment is in state cancelled an…
Browse files Browse the repository at this point in the history
…d a refund webhook is called (#11)
  • Loading branch information
stereomon authored Jul 25, 2024
1 parent 072ca3d commit 37627f7
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@
<property name="content" type="string"/>
<property name="payment" type="Payment"/>
<property name="appConfig" type="AppConfig"/>
<property name="abortHandling" type="bool" description="This flag can be used to abort further Webhook handling."/>
</transfer>

<transfer name="WebhookResponse" strict="true">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ public function handleWebhook(WebhookRequestTransfer $webhookRequestTransfer, We
try {
$webhookRequestTransfer = $this->extendWebhookRequestTransfer($webhookRequestTransfer);

if ($webhookRequestTransfer->getAbortHandling() === true) {
// This will result in a 200 OK Response send back to the caller of the webhook endpoint.
return $webhookResponseTransfer->setIsSuccessful(true);
}

$webhookResponseTransfer = $this->appPaymentPlatformPlugin->handleWebhook($webhookRequestTransfer, $webhookResponseTransfer);
} catch (Throwable $throwable) {
$this->getLogger()->error($throwable->getMessage(), [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

use Generated\Shared\Transfer\WebhookRequestTransfer;
use Spryker\Zed\AppPayment\Business\Payment\AppConfig\AppConfigLoader;
use Spryker\Zed\AppPayment\Business\Payment\Status\PaymentStatus;
use Spryker\Zed\AppPayment\Dependency\Plugin\AppPaymentPlatformPluginInterface;
use Spryker\Zed\AppPayment\Persistence\AppPaymentRepositoryInterface;

Expand All @@ -29,6 +30,12 @@ public function extendWebhookRequestTransfer(WebhookRequestTransfer $webhookRequ
$webhookRequestTransfer->setPaymentOrFail($paymentTransfer);
$webhookRequestTransfer->setAppConfigOrFail($appConfigTransfer);

// When the Payment Service Provider calls the refund webhook and the payment was cancelled before, there is no need for further process this webhook.
// This happens when the Payment is cancelled on the Tenant side before the refund process was initialized.
if ($webhookRequestTransfer->getTypeOrFail() === WebhookDataType::REFUND && $paymentTransfer->getStatus() === PaymentStatus::STATUS_CANCELED) {
return $webhookRequestTransfer->setAbortHandling(true);
}

if ($webhookRequestTransfer->getTypeOrFail() === WebhookDataType::REFUND) {
$webhookRequestTransfer->setRefundOrFail(
$this->appPaymentRepository->getRefundByRefundId($webhookRequestTransfer->getRefundOrFail()->getRefundIdOrFail()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Spryker\Zed\AppPayment\AppPaymentDependencyProvider;
use Spryker\Zed\AppPayment\Business\Message\MessageBuilder;
use Spryker\Zed\AppPayment\Business\Payment\Refund\PaymentRefundStatus;
use Spryker\Zed\AppPayment\Business\Payment\Status\PaymentStatus;
use Spryker\Zed\AppPayment\Business\Payment\Webhook\WebhookDataType;
use Spryker\Zed\AppPayment\Communication\Plugin\AppWebhook\PaymentWebhookHandlerPlugin;
use Spryker\Zed\AppPayment\Dependency\Plugin\AppPaymentPlatformPluginInterface;
Expand Down Expand Up @@ -146,6 +147,25 @@ public function testHandleRefundWebhookReturnsA400BadRequestWhenThereIsNoSuchPay
$this->tester->seeResponseContainsErrorMessage(MessageBuilder::refundByRefundIdNotFound($refundId));
}

public function testHandleRefundWebhookReturnsA200OkWhenTheThePaymentIsInStateCancelled(): void
{
// Arrange
$transactionId = Uuid::uuid4()->toString();
$tenantIdentifier = Uuid::uuid4()->toString();
$refundId = Uuid::uuid4()->toString();

$this->tester->haveAppConfigForTenant($tenantIdentifier);
$this->tester->havePaymentForTransactionId($transactionId, $tenantIdentifier, PaymentStatus::STATUS_CANCELED);

$this->tester->mockGlueRequestWebhookMapperPlugin(WebhookDataType::REFUND, $transactionId, $refundId);

// Act
$this->tester->sendPost($this->tester->buildWebhookUrl(), ['web hook content received from third party payment provider']);

// Assert
$this->tester->seeResponseCodeIs(Response::HTTP_OK);
}

public function testHandleRefundWebhookReturnsA400BadRequestWhenRefundIdHasBeenChangedByPlatformPlugin(): void
{
// Arrange
Expand Down

0 comments on commit 37627f7

Please sign in to comment.