diff --git a/src/EventCodes.php b/src/EventCodes.php index 278c110..0887d29 100644 --- a/src/EventCodes.php +++ b/src/EventCodes.php @@ -48,4 +48,6 @@ final class EventCodes const CHARGEBACK = "CHARGEBACK"; const CHARGEBACK_REVERSED = "CHARGEBACK_REVERSED"; const SECOND_CHARGEBACK = "SECOND_CHARGEBACK"; + const NOTIFICATION_OF_CHARGEBACK = "NOTIFICATION_OF_CHARGEBACK"; + const REQUEST_FOR_INFORMATION = "REQUEST_FOR_INFORMATION"; } diff --git a/src/Notification.php b/src/Notification.php index c0d971a..63db687 100644 --- a/src/Notification.php +++ b/src/Notification.php @@ -63,6 +63,11 @@ public function getEventCode(): string return $this->eventCode; } + public function getAdditionalData(): array + { + return $this->additionalData ?? []; + } + public function isSuccess(): bool { return in_array($this->success, [true, "true"], true); diff --git a/src/Processor/AbstractDisputeNotificationProcessor.php b/src/Processor/AbstractDisputeNotificationProcessor.php new file mode 100644 index 0000000..1298c2b --- /dev/null +++ b/src/Processor/AbstractDisputeNotificationProcessor.php @@ -0,0 +1,59 @@ +initialState; + $additionalData = $this->notification->getAdditionalData(); + $disputeStatus = $additionalData[self::DISPUTE_STATUS] ?? null; + + if ($this->notification->isSuccess() && + isset($disputeStatus) && + in_array($disputeStatus, self::FINAL_DISPUTE_STATUSES) && + in_array($state, self::CHARGEBACK_ORDER_STATES)) { + $state = PaymentStates::STATE_REFUNDED; + } + + return $state; + } +} diff --git a/src/Processor/ChargebackProcessor.php b/src/Processor/ChargebackProcessor.php index b0b82e2..0815b6b 100644 --- a/src/Processor/ChargebackProcessor.php +++ b/src/Processor/ChargebackProcessor.php @@ -23,21 +23,7 @@ namespace Adyen\Webhook\Processor; -use Adyen\Webhook\PaymentStates; - -class ChargebackProcessor extends Processor implements ProcessorInterface +class ChargebackProcessor extends AbstractDisputeNotificationProcessor implements ProcessorInterface { - public function process(): ?string - { - $state = $this->initialState; - - if (in_array( - $state, - [PaymentStates::STATE_NEW, PaymentStates::STATE_IN_PROGRESS, PaymentStates::STATE_PENDING] - )) { - $state = $this->notification->isSuccess() ? PaymentStates::CHARGE_BACK : PaymentStates::STATE_FAILED; - } - return $state; - } } diff --git a/src/Processor/NotificationOfChargebackProcessor.php b/src/Processor/NotificationOfChargebackProcessor.php new file mode 100644 index 0000000..7b499fe --- /dev/null +++ b/src/Processor/NotificationOfChargebackProcessor.php @@ -0,0 +1,32 @@ +unchanged(); + } +} diff --git a/src/Processor/ProcessorFactory.php b/src/Processor/ProcessorFactory.php index d909432..ed80ed5 100644 --- a/src/Processor/ProcessorFactory.php +++ b/src/Processor/ProcessorFactory.php @@ -51,7 +51,9 @@ class ProcessorFactory EventCodes::VOID_PENDING_REFUND => VoidPendingRefundProcessor::class, EventCodes::CHARGEBACK => ChargebackProcessor::class, EventCodes::CHARGEBACK_REVERSED => ChargebackReversedProcessor::class, - EventCodes::SECOND_CHARGEBACK => SecondChargebackProcessor::class + EventCodes::SECOND_CHARGEBACK => SecondChargebackProcessor::class, + EventCodes::NOTIFICATION_OF_CHARGEBACK => NotificationOfChargebackProcessor::class, + EventCodes::REQUEST_FOR_INFORMATION => RequestForInformationProcessor::class ]; /** diff --git a/src/Processor/RequestForInformationProcessor.php b/src/Processor/RequestForInformationProcessor.php new file mode 100644 index 0000000..6f9ce8a --- /dev/null +++ b/src/Processor/RequestForInformationProcessor.php @@ -0,0 +1,32 @@ +unchanged(); + } +} diff --git a/src/Processor/SecondChargebackProcessor.php b/src/Processor/SecondChargebackProcessor.php index d2d7bc5..6d5b743 100644 --- a/src/Processor/SecondChargebackProcessor.php +++ b/src/Processor/SecondChargebackProcessor.php @@ -23,21 +23,7 @@ namespace Adyen\Webhook\Processor; -use Adyen\Webhook\PaymentStates; - -class SecondChargebackProcessor extends Processor implements ProcessorInterface +class SecondChargebackProcessor extends AbstractDisputeNotificationProcessor implements ProcessorInterface { - public function process(): ?string - { - $state = $this->initialState; - - if (in_array( - $state, - [PaymentStates::STATE_NEW, PaymentStates::STATE_IN_PROGRESS, PaymentStates::STATE_PENDING] - )) { - $state = $this->notification->isSuccess() ? PaymentStates::CHARGE_BACK : PaymentStates::STATE_FAILED; - } - return $state; - } } diff --git a/tests/Unit/Processor/ProcessorFactoryTest.php b/tests/Unit/Processor/ProcessorFactoryTest.php index 22a1a46..3d7312f 100644 --- a/tests/Unit/Processor/ProcessorFactoryTest.php +++ b/tests/Unit/Processor/ProcessorFactoryTest.php @@ -184,18 +184,20 @@ public function processorPaymentStatesProvider(): array [EventCodes::VOID_PENDING_REFUND, PaymentStates::STATE_NEW, PaymentStates::STATE_CANCELLED, 'true'], [EventCodes::VOID_PENDING_REFUND, PaymentStates::STATE_IN_PROGRESS, PaymentStates::STATE_CANCELLED, 'true'], [EventCodes::VOID_PENDING_REFUND, PaymentStates::STATE_PENDING, PaymentStates::STATE_CANCELLED, 'true'], - [EventCodes::CHARGEBACK, PaymentStates::STATE_NEW, PaymentStates::CHARGE_BACK, 'true'], - [EventCodes::CHARGEBACK, PaymentStates::STATE_IN_PROGRESS, PaymentStates::CHARGE_BACK, 'true'], - [EventCodes::CHARGEBACK, PaymentStates::STATE_PENDING, PaymentStates::CHARGE_BACK, 'true'], + [EventCodes::CHARGEBACK, PaymentStates::STATE_NEW, PaymentStates::STATE_NEW, 'true'], + [EventCodes::CHARGEBACK, PaymentStates::STATE_IN_PROGRESS, PaymentStates::STATE_IN_PROGRESS, 'true'], + [EventCodes::CHARGEBACK, PaymentStates::STATE_PENDING, PaymentStates::STATE_PENDING, 'true'], [EventCodes::CHARGEBACK_REVERSED, PaymentStates::STATE_NEW, PaymentStates::STATE_CANCELLED, 'true'], - [EventCodes::CHARGEBACK_REVERSED, PaymentStates::STATE_IN_PROGRESS, PaymentStates::STATE_CANCELLED, 'true'], + [EventCodes::CHARGEBACK_REVERSED, PaymentStates::STATE_IN_PROGRESS, PaymentStates::STATE_CANCELLED, + 'true'], [EventCodes::CHARGEBACK_REVERSED, PaymentStates::STATE_PENDING, PaymentStates::STATE_CANCELLED, 'true'], - [EventCodes::SECOND_CHARGEBACK, PaymentStates::STATE_NEW, PaymentStates::CHARGE_BACK, 'true'], - [EventCodes::SECOND_CHARGEBACK, PaymentStates::STATE_IN_PROGRESS, PaymentStates::CHARGE_BACK, 'true'], - [EventCodes::SECOND_CHARGEBACK, PaymentStates::STATE_PENDING, PaymentStates::CHARGE_BACK, 'true'], - [EventCodes::SECOND_CHARGEBACK, PaymentStates::STATE_NEW, PaymentStates::STATE_FAILED, 'false'], - [EventCodes::SECOND_CHARGEBACK, PaymentStates::STATE_IN_PROGRESS, PaymentStates::STATE_FAILED, 'false'], - [EventCodes::SECOND_CHARGEBACK, PaymentStates::STATE_PENDING, PaymentStates::STATE_FAILED, 'false'] + [EventCodes::SECOND_CHARGEBACK, PaymentStates::STATE_NEW, PaymentStates::STATE_NEW, 'true'], + [EventCodes::SECOND_CHARGEBACK, PaymentStates::STATE_IN_PROGRESS, PaymentStates::STATE_IN_PROGRESS, 'true'], + [EventCodes::SECOND_CHARGEBACK, PaymentStates::STATE_PENDING, PaymentStates::STATE_PENDING, 'true'], + [EventCodes::SECOND_CHARGEBACK, PaymentStates::STATE_NEW, PaymentStates::STATE_NEW, 'false'], + [EventCodes::SECOND_CHARGEBACK, PaymentStates::STATE_IN_PROGRESS, PaymentStates::STATE_IN_PROGRESS, + 'false'], + [EventCodes::SECOND_CHARGEBACK, PaymentStates::STATE_PENDING, PaymentStates::STATE_PENDING, 'false'] ]; }