Skip to content

Commit

Permalink
ASW-0 Merge branch 'release-3.8.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
bortefi committed May 5, 2022
2 parents b5bb983 + 8be7bc1 commit 4359f67
Show file tree
Hide file tree
Showing 23 changed files with 310 additions and 55 deletions.
1 change: 1 addition & 0 deletions Components/Builder/NotificationBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public function fromParams($params): Notification
}

$notification->setOrder($order);
$notification->setOrderId($order->getId());

if (isset($params['pspReference'])) {
$notification->setPspReference($params['pspReference']);
Expand Down
32 changes: 16 additions & 16 deletions Components/IncomingNotificationManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace AdyenPayment\Components;

use AdyenPayment\Components\Builder\NotificationBuilder;
use AdyenPayment\Exceptions\DuplicateNotificationException;
use AdyenPayment\Exceptions\InvalidParameterException;
use AdyenPayment\Exceptions\OrderNotFoundException;
use AdyenPayment\Models\Feedback\TextNotificationItemFeedback;
Expand All @@ -18,32 +19,24 @@
*/
class IncomingNotificationManager
{
/**
* @var LoggerInterface
*/
private $logger;

/**
* @var NotificationBuilder
*/
private $notificationBuilder;

/**
* @var ModelManager
*/
private $entityManager;
private LoggerInterface $logger;
private NotificationBuilder $notificationBuilder;
private ModelManager $entityManager;
private NotificationManager $notificationManager;

/**
* IncomingNotificationManager constructor.
*/
public function __construct(
LoggerInterface $logger,
NotificationBuilder $notificationBuilder,
ModelManager $entityManager
ModelManager $entityManager,
NotificationManager $notificationManager
) {
$this->logger = $logger;
$this->notificationBuilder = $notificationBuilder;
$this->entityManager = $entityManager;
$this->notificationManager = $notificationManager;
}

/**
Expand All @@ -60,6 +53,9 @@ public function convertNotifications(array $textNotifications): void
$notification = $this->notificationBuilder->fromParams(
json_decode($textNotificationItem->getTextNotification(), true)
);

$this->notificationManager->guardDuplicate($notification);

$this->entityManager->persist($notification);
}
} catch (InvalidParameterException $exception) {
Expand All @@ -70,10 +66,14 @@ public function convertNotifications(array $textNotifications): void
$this->logger->warning(
$exception->getMessage().' '.$textNotificationItem->getTextNotification()
);
} catch (DuplicateNotificationException $exception) {
$this->logger->notice(
$exception->getMessage()
);
}
$this->entityManager->remove($textNotificationItem);
$this->entityManager->flush();
}
$this->entityManager->flush();
}

/**
Expand Down
19 changes: 19 additions & 0 deletions Components/NotificationManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace AdyenPayment\Components;

use AdyenPayment\Exceptions\DuplicateNotificationException;
use AdyenPayment\Models\Enum\NotificationStatus;
use AdyenPayment\Models\Notification;
use Doctrine\ORM\EntityRepository;
Expand Down Expand Up @@ -98,4 +99,22 @@ public function getLastNotificationForPspReference(string $pspReference)
return;
}
}

public function guardDuplicate(Notification $notification): void
{
$record = $this->notificationRepository->findOneBy([
'orderId' => $notification->getOrderId(),
'pspReference' => $notification->getPspReference(),
'paymentMethod' => $notification->getPaymentMethod(),
'success' => $notification->isSuccess(),
'eventCode' => $notification->getEventCode(),
'merchantAccountCode' => $notification->getMerchantAccountCode(),
'amountValue' => $notification->getAmountValue(),
'amountCurrency' => $notification->getAmountCurrency(),
]);

if ($record instanceof Notification) {
throw DuplicateNotificationException::withNotification($record);
}
}
}
30 changes: 14 additions & 16 deletions Components/NotificationProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace AdyenPayment\Components;

use AdyenPayment\Components\NotificationProcessor\NotificationProcessorInterface;
use AdyenPayment\Exceptions\DuplicateNotificationException;
use AdyenPayment\Exceptions\NoNotificationProcessorFoundException;
use AdyenPayment\Exceptions\OrderNotFoundException;
use AdyenPayment\Models\Enum\NotificationStatus;
Expand All @@ -26,21 +27,10 @@ class NotificationProcessor
* @var NotificationProcessorInterface[]
*/
private $processors;

/**
* @var LoggerInterface
*/
private $logger;

/**
* @var ModelManager
*/
private $modelManager;

/**
* @var ContainerAwareEventManager
*/
private $eventManager;
private LoggerInterface $logger;
private ModelManager $modelManager;
private ContainerAwareEventManager $eventManager;
private NotificationManager $notificationManager;

/**
* NotificationProcessor constructor.
Expand All @@ -50,11 +40,13 @@ class NotificationProcessor
public function __construct(
LoggerInterface $logger,
ModelManager $modelManager,
ContainerAwareEventManager $eventManager
ContainerAwareEventManager $eventManager,
NotificationManager $notificationManager
) {
$this->logger = $logger;
$this->modelManager = $modelManager;
$this->eventManager = $eventManager;
$this->notificationManager = $notificationManager;
}

/**
Expand All @@ -68,6 +60,10 @@ public function processMany(Traversable $notifications): \Generator
foreach ($notifications as $notification) {
try {
yield from $this->process($notification);
} catch (DuplicateNotificationException $exception) {
$this->logger->notice(
$exception->getMessage()
);
} catch (NoNotificationProcessorFoundException $exception) {
$this->logger->notice(
'No notification processor found',
Expand Down Expand Up @@ -105,6 +101,8 @@ public function processMany(Traversable $notifications): \Generator
*/
private function process(Notification $notification): \Generator
{
$this->notificationManager->guardDuplicate($notification);

$processors = $this->findProcessors($notification);

if (empty($processors)) {
Expand Down
21 changes: 15 additions & 6 deletions Controllers/Frontend/DisableRecurringToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ class Shopware_Controllers_Frontend_DisableRecurringToken extends Enlight_Contro
{
private ApiJsonResponse $frontendJsonResponse;
private DisableTokenRequestHandlerInterface $disableTokenRequestHandler;
private Shopware_Components_Snippet_Manager $snippets;

public function preDispatch(): void
{
$this->frontendJsonResponse = $this->get(FrontendJsonResponse::class);
$this->disableTokenRequestHandler = $this->get(DisableTokenRequestHandler::class);
$this->snippets = $this->get('snippets');
}

public function disabledAction(): void
Expand All @@ -29,7 +31,11 @@ public function disabledAction(): void
$this->frontendJsonResponse->sendJsonBadRequestResponse(
$this->Front(),
$this->Response(),
'Invalid method.'
$this->snippets->getNamespace('adyen/checkout/error')->get(
'disableTokenInvalidMethodMessage',
'Invalid method.',
true
)
);

return;
Expand All @@ -40,20 +46,23 @@ public function disabledAction(): void
$this->frontendJsonResponse->sendJsonBadRequestResponse(
$this->Front(),
$this->Response(),
'Missing recurring token param.'
$this->snippets->getNamespace('adyen/checkout/error')->get(
'disableTokenMissingRecurringTokenMessage',
'Missing recurring token param.',
true
)
);

return;
}

$result = $this->disableTokenRequestHandler->disableToken($recurringToken, Shopware()->Shop());
if (!$result->isSuccess()) {
$this->frontendJsonResponse->sendJsonResponse(
$this->frontendJsonResponse->sendJsonBadRequestResponse(
$this->Front(),
$this->Response(),
JsonResponse::create(
['error' => true, 'message' => $result->message()],
Response::HTTP_BAD_REQUEST
$this->snippets->getNamespace('adyen/checkout/error')->get(
$result->message()
)
);

Expand Down
18 changes: 11 additions & 7 deletions Enricher/Payment/PaymentMethodEnricher.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function __invoke(array $shopwareMethod, PaymentMethod $paymentMethod): a
{
return array_merge($shopwareMethod, [
'enriched' => true,
'additionaldescription' => $this->enrichAdditionalDescription($paymentMethod),
'additionaldescription' => $this->enrichAdditionalDescription($shopwareMethod, $paymentMethod),
'image' => $this->imageLogoProvider->provideByType($paymentMethod->adyenType()->type()),
'isStoredPayment' => $paymentMethod->isStoredPayment(),
'isAdyenPaymentMethod' => true,
Expand All @@ -37,19 +37,23 @@ public function __invoke(array $shopwareMethod, PaymentMethod $paymentMethod): a
);
}

private function enrichAdditionalDescription(PaymentMethod $adyenMethod): string
private function enrichAdditionalDescription(array $shopwareMethod, PaymentMethod $adyenMethod): string
{
$description = $this->snippets
->getNamespace('adyen/method/description')
->get($adyenMethod->adyenType()->type()) ?? '';
$additionalDescription = $shopwareMethod['additionaldescription'] ?? '';

if ('' === $additionalDescription) {
$additionalDescription = $this->snippets
->getNamespace('adyen/method/description')
->get($shopwareMethod['attribute']['adyen_type'] ?? '') ?? '';
}

if (!$adyenMethod->isStoredPayment()) {
return $description;
return $additionalDescription;
}

return sprintf(
'%s%s: %s',
($description ? $description.' ' : ''),
($additionalDescription ? $additionalDescription.' ' : ''),
$this->snippets
->getNamespace('adyen/checkout/payment')
->get('CardNumberEndingOn', 'Card number ending on', true),
Expand Down
28 changes: 28 additions & 0 deletions Exceptions/DuplicateNotificationException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace AdyenPayment\Exceptions;

use AdyenPayment\Models\Notification;

final class DuplicateNotificationException extends \RunTimeException
{
public static function withNotification(Notification $notification): self
{
return new self(sprintf(
'Duplicate notification is not handled. '.
'Notification with id: "%s", orderId: "%s", pspReference: "%s", status: "%s", paymentMethod: "%s", eventCode: "%s", success: "%s", merchantAccountCode: "%s", amountValue: "%s", amountCurrency: "%s"',
$notification->getId(),
$notification->getOrderId(),
$notification->getPspReference(),
$notification->getStatus(),
$notification->getPaymentMethod(),
$notification->getEventCode(),
$notification->isSuccess(),
$notification->getMerchantAccountCode(),
$notification->getAmountValue(),
$notification->getAmountCurrency()
));
}
}
48 changes: 46 additions & 2 deletions Resources/frontend/js/jquery.adyen-disable-payment.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,67 @@
* CSS classes selector to clear the error elements
*/
errorClassSelector: '.alert.is--error.is--rounded.is--adyen-error',
/**
* @var string modalSelector
* CSS classes selector to use as confirmation modal content.
*/
modalSelector: '.adyenDisableTokenConfirmationModal',
/**
* @var string modalConfirmButtonSelector
* CSS classes selector for the disable-confirm button
*/
modalConfirmButtonSelector: '.disableConfirm',
/**
* @var string modalCancelButtonSelector
* CSS classes selector for the disable-cancel button
*/
modalCancelButtonSelector: '.disableCancel',
/**
* @var string errorMessageClass
* CSS classes for the error message element
*/
errorMessageClass: 'alert--content'
errorMessageClass: 'alert--content',
/**
* @var string modalErrorContainerSelector
* CSS classes for the error message container in the modal
*/
modalErrorContainerSelector: '.modal-error-container',
},
init: function () {
var me = this;
me.applyDataAttributes();
me.modalContent = $(me.opts.modalSelector).html() || '';
me.$el.on('click', $.proxy(me.enableDisableButtonClick, me));
},
enableDisableButtonClick: function () {
var me = this;
if (0 === me.opts.adyenStoredMethodId.length) {
return;
}
if('' === me.modalContent){
return;
}
me.modal = $.modal.open(me.modalContent, {
showCloseButton: true,
closeOnOverlay: false,
additionalClass: 'adyen-modal disable-token-confirmation'
});
me.buttonConfirm = $(me.opts.modalConfirmButtonSelector);
me.buttonConfirm.on('click', $.proxy(me.runDisableTokenCall, me));
me.buttonCancel = $(me.opts.modalCancelButtonSelector);
me.buttonCancel.on('click', $.proxy(me.closeModal, me));
},
closeModal: function () {
var me = this;
if(!me.modal){
return;
}
me.modal.close();
},
runDisableTokenCall: function () {
var me = this;
$.loadingIndicator.open();
$.loadingIndicator.loader.$loader.addClass('over-modal');
$.post({
url: me.opts.adyenDisableTokenUrl,
dataType: 'json',
Expand All @@ -58,7 +102,7 @@
$(me.opts.errorClassSelector).remove();
var error = $('<div />').addClass(me.opts.errorClass);
error.append($('<div />').addClass(me.opts.errorMessageClass).html(message));
me.$el.parent().append(error);
$(me.opts.modalErrorContainerSelector).append(error);
}
});
})(jQuery);
2 changes: 1 addition & 1 deletion Resources/frontend/js/jquery.adyen-payment-selection.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
adyenOrderTotal: '',
adyenOrderCurrency: '',
resetSessionUrl: '',
adyenConfigAjaxUrl: '/frontend/adyenconfig/index',
adyenConfigAjaxUrl: '',
/**
* Fallback environment variable
*
Expand Down
Loading

0 comments on commit 4359f67

Please sign in to comment.