Skip to content

Commit

Permalink
PLUG-106: Add custom error type that is always deduplicated and inval…
Browse files Browse the repository at this point in the history
…idates frontend cache
  • Loading branch information
lighe committed Jun 14, 2024
1 parent 750d493 commit 33972e8
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 26 deletions.
7 changes: 6 additions & 1 deletion Controller/Checkout/Redirect.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use TrueLayer\Connect\Api\Log\LogService;
use TrueLayer\Connect\Service\Order\HPPService;
use TrueLayer\Connect\Service\Order\PaymentCreationService;
use TrueLayer\Connect\Service\Order\PaymentErrorMessageManager;
use TrueLayer\Exceptions\ApiRequestJsonSerializationException;
use TrueLayer\Exceptions\ApiResponseUnsuccessfulException;
use TrueLayer\Exceptions\InvalidArgumentException;
Expand All @@ -31,6 +32,7 @@ class Redirect extends BaseController implements HttpGetActionInterface
private Session $checkoutSession;
private OrderRepositoryInterface $orderRepository;
private PaymentCreationService $paymentCreationService;
private PaymentErrorMessageManager $paymentErrorMessageManager;
private HPPService $hppService;

/**
Expand All @@ -39,6 +41,7 @@ class Redirect extends BaseController implements HttpGetActionInterface
* @param Session $checkoutSession
* @param OrderRepositoryInterface $orderRepository
* @param PaymentCreationService $paymentCreationService
* @param PaymentErrorMessageManager $paymentErrorMessageManager
* @param HPPService $hppService
* @param LogService $logger
*/
Expand All @@ -48,13 +51,15 @@ public function __construct(
Session $checkoutSession,
OrderRepositoryInterface $orderRepository,
PaymentCreationService $paymentCreationService,
PaymentErrorMessageManager $paymentErrorMessageManager,
HPPService $hppService,
LogService $logger
)
{
$this->checkoutSession = $checkoutSession;
$this->orderRepository = $orderRepository;
$this->paymentCreationService = $paymentCreationService;
$this->paymentErrorMessageManager = $paymentErrorMessageManager;
$this->hppService = $hppService;
$logger = $logger->addPrefix('RedirectController');
parent::__construct($context, $jsonFactory, $logger);
Expand Down Expand Up @@ -113,7 +118,7 @@ private function failOrder(): void
*/
private function redirectToFailPage(): ResponseInterface
{
$this->context->getMessageManager()->addErrorMessage(__('There was an issue creating your payment. Please try again.'));
$this->paymentErrorMessageManager->addMessage('There was an issue creating your payment. Please try again.');
return $this->redirect('checkout/cart/index');
}
}
11 changes: 5 additions & 6 deletions Controller/Checkout/Status.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Checkout\Model\Session;
use Magento\Framework\Message\MessageInterface;
use Magento\Sales\Api\OrderRepositoryInterface;
use TrueLayer\Connect\Api\Log\LogService as LogRepository;
use TrueLayer\Connect\Helper\ValidationHelper;
use TrueLayer\Connect\Model\Config\Repository as ConfigRepository;
use TrueLayer\Connect\Service\Client\ClientFactory;
use TrueLayer\Connect\Api\Transaction\Payment\PaymentTransactionRepositoryInterface as TransactionRepository;
use TrueLayer\Connect\Helper\PaymentFailureReasonHelper;
use TrueLayer\Connect\Service\Order\PaymentErrorMessageManager;
use TrueLayer\Connect\Service\Order\PaymentUpdate\PaymentFailedService;
use TrueLayer\Connect\Service\Order\PaymentUpdate\PaymentSettledService;
use TrueLayer\Interfaces\Payment\PaymentFailedInterface;
Expand All @@ -41,6 +41,7 @@ class Status extends BaseController implements HttpPostActionInterface
private ClientFactory $clientFactory;
private ConfigRepository $configRepository;
private TransactionRepository $transactionRepository;
private PaymentErrorMessageManager $paymentErrorMessageManager;

public function __construct(
Context $context,
Expand All @@ -52,6 +53,7 @@ public function __construct(
PaymentFailedService $paymentFailedService,
ConfigRepository $configRepository,
TransactionRepository $transactionRepository,
PaymentErrorMessageManager $paymentErrorMessageManager,
LogRepository $logger
) {
$this->session = $session;
Expand All @@ -61,6 +63,7 @@ public function __construct(
$this->transactionRepository = $transactionRepository;
$this->paymentSettledService = $paymentSettledService;
$this->paymentFailedService = $paymentFailedService;
$this->paymentErrorMessageManager = $paymentErrorMessageManager;
$logger->addPrefix('StatusController');
parent::__construct($context, $jsonFactory, $logger);
}
Expand Down Expand Up @@ -120,11 +123,7 @@ private function getFinalPaymentStatusResponse(string $paymentId): ?ResultInterf
$this->session->restoreQuote();

$errorText = PaymentFailureReasonHelper::getHumanReadableLabel($transaction->getFailureReason());
$errorText = $errorText . ' ' . __('Please try again.');

$messageManager = $this->context->getMessageManager();
$message = $messageManager->createMessage(MessageInterface::TYPE_ERROR)->setText($errorText);
$messageManager->addUniqueMessages([ $message ]);
$this->paymentErrorMessageManager->addMessage($errorText . ' ' . __('Please try again.'));

return $this->urlResponse('checkout/cart');
}
Expand Down
38 changes: 38 additions & 0 deletions Service/Order/PaymentErrorMessageManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php
/**
* Copyright © TrueLayer Ltd. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace TrueLayer\Connect\Service\Order;

use Magento\Framework\Message\ManagerInterface;
use Magento\Framework\Message\MessageInterface;

class PaymentErrorMessageManager
{
private ManagerInterface $messageManager;

/**
* @param ManagerInterface $messageManager
*/
public function __construct(ManagerInterface $messageManager)
{
$this->messageManager = $messageManager;
}

/**
* Add a unique message using our custom truelayer payment error template
* This will trigger a cart and checkout-data refresh on the frontend
* @param string $text
*/
public function addMessage(string $text): void
{
$message = $this->messageManager
->createMessage(MessageInterface::TYPE_ERROR, 'truelayer_payment_error')
->setData(['text' => $text]);

$this->messageManager->addUniqueMessages([ $message ]);
}
}
15 changes: 15 additions & 0 deletions etc/frontend/di.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Framework\View\Element\Message\MessageConfigurationsPool">
<arguments>
<argument name="configurationsMap" xsi:type="array">
<item name="truelayer_payment_error" xsi:type="array">
<item name="renderer" xsi:type="const">\Magento\Framework\View\Element\Message\Renderer\BlockRenderer::CODE</item>
<item name="data" xsi:type="array">
<item name="template" xsi:type="string">TrueLayer_Connect::checkout/payment_error_message.phtml</item>
</item>
</item>
</argument>
</arguments>
</type>
</config>
26 changes: 26 additions & 0 deletions view/frontend/templates/checkout/payment_error_message.phtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

use Magento\Framework\Escaper;

/**
* @var Escaper $escaper
*/
?>

<span class="truelayer-payment-error">
<?=$escaper->escapeHtml(__($block->getData('text')));?>
</span>

<script type="text/x-magento-init">
{
".truelayer-payment-error": {
"Magento_Ui/js/core/app": {
"components": {
"truelayer-pending": {
"component": "TrueLayer_Connect/js/cart_refresh"
}
}
}
}
}
</script>
18 changes: 18 additions & 0 deletions view/frontend/web/js/cart_refresh.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Copyright © TrueLayer Ltd, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

define(['Magento_Customer/js/customer-data', 'uiComponent'], function (customerData, Component) {
'use strict';

return Component.extend({
initialize() {
this._super();

var sections = ['cart', 'checkout-data'];
customerData.invalidate(sections);
customerData.reload(sections, true);
},
});
});
22 changes: 3 additions & 19 deletions view/frontend/web/js/pending.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* See COPYING.txt for license details.
*/

define(['jquery', 'mage/url', 'ko', 'Magento_Customer/js/customer-data', 'uiComponent'], function ($, url, ko, customerData, Component) {
define(['jquery', 'mage/url', 'ko', 'uiComponent'], function ($, url, ko, Component) {
'use strict';

return Component.extend({
Expand Down Expand Up @@ -33,15 +33,10 @@ define(['jquery', 'mage/url', 'ko', 'Magento_Customer/js/customer-data', 'uiComp
$.ajax({
url: this.statusUrl + window.location.search + '&attempt=' + this.requestCount(),
type: 'POST',
dataType: 'json',
contentType: "application/json",
success: (data) => {
if (data && data.redirect) {
this.isRedirecting = true;

var sections = ['cart', 'checkout-data'];
customerData.invalidate(sections);
customerData.reload(sections, true);

window.location.replace(data.redirect);
}
},
Expand All @@ -53,15 +48,4 @@ define(['jquery', 'mage/url', 'ko', 'Magento_Customer/js/customer-data', 'uiComp
})
}
});
});


/*
require([
'Magento_Customer/js/customer-data'
], function (customerData) {
var sections = ['cart'];
customerData.invalidate(sections);
customerData.reload(sections, true);
});
*/
});

0 comments on commit 33972e8

Please sign in to comment.