Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[ECP-9037] - Support Dispute webhooks on webhook module #57

Merged
merged 11 commits into from
Mar 29, 2024
2 changes: 2 additions & 0 deletions src/EventCodes.php
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
5 changes: 5 additions & 0 deletions src/Notification.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
61 changes: 61 additions & 0 deletions src/Processor/AbstractDisputeNotificationProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php declare(strict_types=1);
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Webhook Module for PHP
*
* Copyright (c) 2021 Adyen N.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
*/

namespace Adyen\Webhook\Processor;

use Adyen\Webhook\PaymentStates;

abstract class AbstractDisputeNotificationProcessor extends Processor implements ProcessorInterface
{
const DISPUTE_STATUS_UNDEFENDED = "Undefended";
const DISPUTE_STATUS_LOST = "Lost";
const DISPUTE_STATUS_ACCEPTED = "Accepted";
const FINAL_DISPUTE_STATUSES = [
self::DISPUTE_STATUS_LOST,
self::DISPUTE_STATUS_ACCEPTED,
self::DISPUTE_STATUS_UNDEFENDED
];
const DISPUTE_STATUS = "disputeStatus";


const CHARGEBACK_ORDER_STATES = [
PaymentStates::STATE_PAID,
PaymentStates::STATE_IN_PROGRESS,
];

public function process(): ?string
{
$state = $this->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;
}
}
16 changes: 1 addition & 15 deletions src/Processor/ChargebackProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
32 changes: 32 additions & 0 deletions src/Processor/NotificationOfChargebackProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php declare(strict_types=1);
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Webhook Module for PHP
*
* Copyright (c) 2021 Adyen N.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
*/

namespace Adyen\Webhook\Processor;

class NotificationOfChargebackProcessor extends AbstractDisputeNotificationProcessor implements ProcessorInterface
{
public function process(): ?string
{
return $this->unchanged();
}
}
4 changes: 3 additions & 1 deletion src/Processor/ProcessorFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
];

/**
Expand Down
32 changes: 32 additions & 0 deletions src/Processor/RequestForInformationProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php declare(strict_types=1);
/**
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen Webhook Module for PHP
*
* Copyright (c) 2022 Adyen N.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*
*/

namespace Adyen\Webhook\Processor;

class RequestForInformationProcessor extends AbstractDisputeNotificationProcessor implements ProcessorInterface
{
public function process(): ?string
{
return $this->unchanged();
}
}
16 changes: 1 addition & 15 deletions src/Processor/SecondChargebackProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
22 changes: 12 additions & 10 deletions tests/Unit/Processor/ProcessorFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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']
];
}

Expand Down
Loading