Skip to content

Commit

Permalink
Merge branch 'fix/PIWOO-288-fraud-no-retry' into release/7.4.1
Browse files Browse the repository at this point in the history
  • Loading branch information
mmaymo committed Oct 20, 2023
2 parents b7c92fd + ddd3d2c commit a4f72f0
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/Payment/PaymentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,8 @@ protected function processAsMollieOrder(
}
} catch (ApiException $e) {
$this->handleMollieOutage($e);
//if exception is 422 do not try to create a payment
$this->handleMollieFraudRejection($e);
// Don't try to create a Mollie Payment for Klarna payment methods
$order_payment_method = $order->get_payment_method();
$orderMandatoryPaymentMethods = [
Expand Down Expand Up @@ -873,4 +875,27 @@ public function handleMollieOutage(ApiException $e): void
);
}
}

/**
* Check if the exception is a fraud rejection, if so bail, log and inform user
* @param ApiException $e
* @return void
* @throws ApiException
*/
public function handleMollieFraudRejection(ApiException $e): void
{
$isMollieFraudException = $this->apiHelper->isMollieFraudException($e);
if ($isMollieFraudException) {
$this->logger->debug(
"Creating payment object: The payment was declined due to suspected fraud, stopping process."
);

throw new ApiException(
__(
'Payment failed due to: The payment was declined due to suspected fraud.',
'mollie-payments-for-woocommerce'
)
);
}
}
}
11 changes: 11 additions & 0 deletions src/SDK/Api.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,15 @@ public function isMollieOutageException(\Mollie\Api\Exceptions\ApiException $e):
}
return false;
}

public function isMollieFraudException(\Mollie\Api\Exceptions\ApiException $e): bool
{
$isFraudCode = $e->getCode() === 422;
$isFraudMessage = strpos($e->getMessage(), 'The payment was declined due to suspected fraud') !== false;

if ($isFraudCode && $isFraudMessage) {
return true;
}
return false;
}
}
7 changes: 7 additions & 0 deletions tests/php/Functional/HelperMocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Mollie\Api\MollieApiClient;
use Mollie\WooCommerce\Gateway\MolliePaymentGateway;
use Mollie\WooCommerce\Notice\AdminNotice;
use Mollie\WooCommerce\Payment\MollieOrder;
use Mollie\WooCommerce\Payment\MollieOrderService;
use Mollie\WooCommerce\Payment\OrderInstructionsService;
use Mollie\WooCommerce\Payment\OrderLines;
Expand Down Expand Up @@ -59,6 +60,12 @@ public function paymentFactory($apiClientMock){
);
}

public function mollieOrderMock()
{
return $this->getMockBuilder(MollieOrder::class)
->disableOriginalConstructor()
->getMock();
}
public function noticeMock()
{
return $this->getMockBuilder(AdminNotice::class)
Expand Down
69 changes: 69 additions & 0 deletions tests/php/Functional/Payment/PaymentServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Mollie\WooCommerceTests\Functional\Payment;

use Mollie\Api\Endpoints\OrderEndpoint;
use Mollie\Api\Exceptions\ApiException;
use Mollie\Api\MollieApiClient;
use Mollie\WooCommerce\Gateway\MolliePaymentGateway;
use Mollie\WooCommerce\Payment\PaymentCheckoutRedirectService;
Expand Down Expand Up @@ -129,6 +130,64 @@ public function processPayment_Order_success(){
self::assertEquals($expectedResult, $arrayResult);
}

/**
* @test
* @throws ApiException
*/
public function processAsMollieOrder_BailsIf_FraudException()
{
stubs([
'array_filter' => [],
]);
$mockedException = new TestApiException();
$mockedException->setTestCode(422);
$mockedException->setTestMessage('The payment was declined due to suspected fraud');
$orderEndpointsMock = $this->createConfiguredMock(
OrderEndpoint::class,
[
'create' => new MollieOrderResponse(),
]
);
$paymentMethodId = 'Ideal';
$orderEndpointsMock->method('create')->with([])
->will($this->throwException($mockedException));

$apiClientMock = $this->createMock(MollieApiClient::class);
$apiClientMock->orders = $orderEndpointsMock;
$voucherDefaultCategory = Voucher::NO_CATEGORY;

$testee = new PaymentService(
$this->helperMocks->noticeMock(),
$this->helperMocks->loggerMock(),
$this->helperMocks->paymentFactory($apiClientMock),
$this->helperMocks->dataHelper($apiClientMock),
$this->helperMocks->apiHelper($apiClientMock),
$this->helperMocks->settingsHelper(),
$this->helperMocks->pluginId(),
$this->paymentCheckoutService($apiClientMock),
$voucherDefaultCategory
);
$gateway = $this->mollieGateway($paymentMethodId, $testee);
$testee->setGateway($gateway);
$wcOrderId = 1;
$wcOrderKey = 'wc_order_hxZniP1zDcnM8';
$wcOrder = $this->wcOrder($wcOrderId, $wcOrderKey);
$cusomerId = 1;
$apiKey = 'test_test';
$method = new \ReflectionMethod(PaymentService::class, 'processAsMollieOrder');
$method->setAccessible(true);

$this->expectException(ApiException::class);

$method->invoke(
$testee,
$this->helperMocks->mollieOrderMock(),
$wcOrder,
$cusomerId,
$apiKey
);
}


protected function setUp(): void
{
Expand Down Expand Up @@ -451,5 +510,15 @@ public function getCheckoutUrl()

}

class TestApiException extends \Mollie\Api\Exceptions\ApiException {
public function setTestCode($code) {
$this->code = $code;
}

public function setTestMessage($message) {
$this->message = $message;
}
}



0 comments on commit a4f72f0

Please sign in to comment.