diff --git a/Controller/Payment/Capture.php b/Controller/Payment/Capture.php index 7d30e16..4d3f098 100644 --- a/Controller/Payment/Capture.php +++ b/Controller/Payment/Capture.php @@ -11,6 +11,7 @@ use Magento\Framework\Message\ManagerInterface; use Magento\Payment\Gateway\CommandInterface; use Magento\Store\Model\StoreManagerInterface; +use Psr\Log\LoggerInterface; class Capture implements HttpGetActionInterface { @@ -23,15 +24,17 @@ class Capture implements HttpGetActionInterface private $placeOrderProcessor; private $validateCheckoutDataCommand; private $storeManager; + private $logger; public function __construct( - RequestInterface $request, - Session $session, - RedirectFactory $redirectFactory, - ManagerInterface $messageManager, - PlaceOrderProcessor $placeOrderProcessor, - CommandInterface $validateCheckoutDataCommand, - StoreManagerInterface $storeManager + RequestInterface $request, + Session $session, + RedirectFactory $redirectFactory, + ManagerInterface $messageManager, + PlaceOrderProcessor $placeOrderProcessor, + CommandInterface $validateCheckoutDataCommand, + StoreManagerInterface $storeManager, + LoggerInterface $logger ) { $this->request = $request; $this->session = $session; @@ -40,10 +43,12 @@ public function __construct( $this->placeOrderProcessor = $placeOrderProcessor; $this->validateCheckoutDataCommand = $validateCheckoutDataCommand; $this->storeManager = $storeManager; + $this->logger = $logger; } public function execute() { + $afterpayOrderToken = $this->request->getParam('orderToken'); if ($this->request->getParam('status') == self::CHECKOUT_STATUS_CANCELLED) { $this->messageManager->addErrorMessage( (string)__('You have cancelled your Afterpay payment. Please select an alternative payment method.') @@ -57,6 +62,10 @@ public function execute() $this->messageManager->addErrorMessage( (string)__('Afterpay payment is declined. Please select an alternative payment method.') ); + $this->logger->info( + 'Afterpay payment(' . $afterpayOrderToken . ') response status is "' . $this->request->getParam('status') + . '".' . 'Customer has been redirected to the cart page.' + ); return $this->redirectFactory->create()->setPath('checkout/cart', [ '_scope' => $this->storeManager->getStore() @@ -65,7 +74,6 @@ public function execute() try { $quote = $this->session->getQuote(); - $afterpayOrderToken = $this->request->getParam('orderToken'); $this->placeOrderProcessor->execute($quote, $this->validateCheckoutDataCommand, $afterpayOrderToken); } catch (\Throwable $e) { $errorMessage = $e instanceof LocalizedException diff --git a/Gateway/Response/Checkout/CheckoutItemsAmountValidationHandler.php b/Gateway/Response/Checkout/CheckoutItemsAmountValidationHandler.php index 464ed67..4aad650 100644 --- a/Gateway/Response/Checkout/CheckoutItemsAmountValidationHandler.php +++ b/Gateway/Response/Checkout/CheckoutItemsAmountValidationHandler.php @@ -15,14 +15,14 @@ public function handle(array $handlingSubject, array $response) if (round(1 * $grandTotal, 2) != round(1 * $response['amount']['amount'], 2)) { throw new \Magento\Framework\Exception\LocalizedException( - __('There are issues when processing your payment. Invalid Amount') + __('There was a issue with the processing of your payment. Invalid amount.') ); } $quoteItems = $quote->getAllVisibleItems(); $responseItems = $response['items']; - $invalidCartItemsExceptionMessage = __('There are issues when processing your payment. Invalid Cart Items'); + $invalidCartItemsExceptionMessage = __('There was a issue with the processing of your payment. Invalid cart items.'); if (count($quoteItems) != count($responseItems)) { throw new \Magento\Framework\Exception\LocalizedException($invalidCartItemsExceptionMessage); diff --git a/Model/Payment/Capture/CancelOrderProcessor.php b/Model/Payment/Capture/CancelOrderProcessor.php index ab5e2e2..454a5b0 100644 --- a/Model/Payment/Capture/CancelOrderProcessor.php +++ b/Model/Payment/Capture/CancelOrderProcessor.php @@ -2,6 +2,10 @@ namespace Afterpay\Afterpay\Model\Payment\Capture; +use Magento\Framework\Exception\LocalizedException; +use Magento\Payment\Gateway\Command\CommandException; +use Magento\Quote\Model\Quote\Payment; + class CancelOrderProcessor { private $paymentDataObjectFactory; @@ -27,7 +31,17 @@ public function __construct( $this->quotePaidStorage = $quotePaidStorage; } - public function execute(\Magento\Quote\Model\Quote\Payment $payment, int $quoteId): void + /** + * @param Payment $payment + * @param int $quoteId + * @param \Throwable|null $e + * + * @return void + * @throws CommandException + * @throws LocalizedException + * @throws \Throwable + */ + public function execute(\Magento\Quote\Model\Quote\Payment $payment, int $quoteId, \Throwable $e = null): void { if (!$this->config->getIsReversalEnabled()) { return; @@ -48,6 +62,10 @@ public function execute(\Magento\Quote\Model\Quote\Payment $payment, int $quoteI $afterpayPayment = $this->quotePaidStorage->getAfterpayPaymentIfQuoteIsPaid($quoteId); if (!$afterpayPayment) { + if ($e instanceof LocalizedException) { + throw $e; + } + throw new \Magento\Framework\Exception\LocalizedException( __( 'Afterpay payment declined. Please select an alternative payment method.' diff --git a/Model/Payment/Capture/PlaceOrderProcessor.php b/Model/Payment/Capture/PlaceOrderProcessor.php index 8ee68c4..a8ebce6 100644 --- a/Model/Payment/Capture/PlaceOrderProcessor.php +++ b/Model/Payment/Capture/PlaceOrderProcessor.php @@ -55,10 +55,10 @@ public function execute(Quote $quote, CommandInterface $checkoutDataCommand, str $payment = $quote->getPayment(); try { - $payment->setAdditionalInformation(CheckoutInterface::AFTERPAY_TOKEN, $afterpayOrderToken); - $isCBTCurrencyAvailable = $this->checkCBTCurrencyAvailability->checkByQuote($quote); - $payment->setAdditionalInformation(CheckoutInterface::AFTERPAY_IS_CBT_CURRENCY, $isCBTCurrencyAvailable); - $payment->setAdditionalInformation(CheckoutInterface::AFTERPAY_CBT_CURRENCY, $quote->getQuoteCurrencyCode()); + $payment->setAdditionalInformation(CheckoutInterface::AFTERPAY_TOKEN, $afterpayOrderToken); + $isCBTCurrencyAvailable = $this->checkCBTCurrencyAvailability->checkByQuote($quote); + $payment->setAdditionalInformation(CheckoutInterface::AFTERPAY_IS_CBT_CURRENCY, $isCBTCurrencyAvailable); + $payment->setAdditionalInformation(CheckoutInterface::AFTERPAY_CBT_CURRENCY, $quote->getQuoteCurrencyCode()); if (!$quote->getCustomerId()) { $quote->setCustomerEmail($quote->getBillingAddress()->getEmail()) diff --git a/Model/Payment/PaymentErrorProcessor.php b/Model/Payment/PaymentErrorProcessor.php index cf2c8bb..86c83f0 100644 --- a/Model/Payment/PaymentErrorProcessor.php +++ b/Model/Payment/PaymentErrorProcessor.php @@ -48,7 +48,7 @@ public function execute(Quote $quote, \Throwable $e, Payment $payment): int $this->orderRepository->save($order); return (int)$order->getEntityId(); - } catch (NoSuchEntityException $e) { + } catch (NoSuchEntityException $exception) { throw $e; } } @@ -58,7 +58,7 @@ public function execute(Quote $quote, \Throwable $e, Payment $payment): int throw $e; } - $this->cancelOrderProcessor->execute($payment, (int)$quote->getId()); + $this->cancelOrderProcessor->execute($payment, (int)$quote->getId(), $e); if ($e instanceof LocalizedException) { throw $e; diff --git a/Model/Shipment/Express/CreateShippingOption.php b/Model/Shipment/Express/CreateShippingOption.php index 7d4fe9c..5f5d8d0 100644 --- a/Model/Shipment/Express/CreateShippingOption.php +++ b/Model/Shipment/Express/CreateShippingOption.php @@ -63,8 +63,8 @@ private function createShippingOptionByMethod( return [ 'id' => implode('_', [$shippingMethod->getCarrierCode(), $shippingMethod->getMethodCode()]), - 'name' => $shippingMethod->getCarrierTitle(), - 'description' => $shippingMethod->getCarrierTitle(), + 'name' => !empty($shippingMethod->getCarrierTitle()) ? $shippingMethod->getCarrierTitle() : $shippingMethod->getMethodTitle(), + 'description' => !empty($shippingMethod->getCarrierTitle()) ? $shippingMethod->getCarrierTitle() : $shippingMethod->getMethodTitle(), 'shippingAmount' => [ 'amount' => $this->formatPrice($shippingAmount), 'currency' => $currency diff --git a/Model/StockItemsValidator/StockItemsValidatorProxy.php b/Model/StockItemsValidator/StockItemsValidatorProxy.php index 6677872..c1ef8aa 100644 --- a/Model/StockItemsValidator/StockItemsValidatorProxy.php +++ b/Model/StockItemsValidator/StockItemsValidatorProxy.php @@ -2,9 +2,26 @@ namespace Afterpay\Afterpay\Model\StockItemsValidator; +use Afterpay\Afterpay\Gateway\Validator\StockItemsValidatorFactory; +use Afterpay\Afterpay\Model\SourceValidatorServiceFactory; +use Afterpay\Afterpay\Model\Spi\StockItemsValidatorInterface; use Magento\Framework\App\ObjectManager; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Module\Manager; +use Magento\Framework\ObjectManager\NoninterceptableInterface; +use Magento\InventoryCatalogApi\Api\DefaultSourceProviderInterface; +use Magento\InventoryCatalogApi\Model\IsSingleSourceModeInterface; +use Magento\InventoryConfigurationApi\Api\GetStockItemConfigurationInterface; +use Magento\InventoryConfigurationApi\Exception\SkuIsNotAssignedToStockException; +use Magento\InventorySalesApi\Api\GetStockBySalesChannelInterface; +use Magento\InventoryShipping\Model\GetItemsToDeductFromShipment; +use Magento\InventoryShipping\Model\SourceDeductionRequestFromShipmentFactory as SourceDeductionRequestFactory; +use Magento\InventorySourceDeductionApi\Model\GetSourceItemBySourceCodeAndSku; +use Magento\Sales\Model\Order\Shipment; -class StockItemsValidatorProxy implements \Afterpay\Afterpay\Model\Spi\StockItemsValidatorInterface, \Magento\Framework\ObjectManager\NoninterceptableInterface // @codingStandardsIgnoreLine + +class StockItemsValidatorProxy implements StockItemsValidatorInterface, NoninterceptableInterface { private $subject = null; private $stockItemValidatorFactory; @@ -12,9 +29,9 @@ class StockItemsValidatorProxy implements \Afterpay\Afterpay\Model\Spi\StockItem private $moduleManager; public function __construct( - \Afterpay\Afterpay\Gateway\Validator\StockItemsValidatorFactory $stockItemsValidatorFactory, - \Afterpay\Afterpay\Model\SourceValidatorServiceFactory $sourceValidatorServiceFactory, - \Magento\Framework\Module\Manager $moduleManager + StockItemsValidatorFactory $stockItemsValidatorFactory, + SourceValidatorServiceFactory $sourceValidatorServiceFactory, + Manager $moduleManager ) { $this->stockItemValidatorFactory = $stockItemsValidatorFactory; $this->sourceValidatorServiceFactory = $sourceValidatorServiceFactory; @@ -23,11 +40,11 @@ public function __construct( /** * Check msi functionality existing if no then skip validation - * @throws \Magento\Framework\Exception\LocalizedException - * @throws \Magento\Framework\Exception\NoSuchEntityException - * @throws \Magento\InventoryConfigurationApi\Exception\SkuIsNotAssignedToStockException + * @throws LocalizedException + * @throws NoSuchEntityException + * @throws SkuIsNotAssignedToStockException */ - public function validate(\Magento\Sales\Model\Order\Shipment $shipment): void + public function validate(Shipment $shipment): void { if (!$this->moduleManager->isEnabled('Magento_InventoryCatalogApi') || !$this->moduleManager->isEnabled('Magento_InventoryShipping') || @@ -41,23 +58,25 @@ public function validate(\Magento\Sales\Model\Order\Shipment $shipment): void $stockItemsValidator->validate($shipment); } - private function getStockItemValidator(): \Afterpay\Afterpay\Model\Spi\StockItemsValidatorInterface + private function getStockItemValidator(): StockItemsValidatorInterface { if ($this->subject == null) { $objectManager = ObjectManager::getInstance(); $sourceValidatorService = $this->sourceValidatorServiceFactory->create([ - 'getSourceItemBySourceCodeAndSku' => $objectManager->create('\\Magento\\InventorySourceDeductionApi\\Model\\GetSourceItemBySourceCodeAndSku'), // @codingStandardsIgnoreLine - 'getStockItemConfiguration' => $objectManager->create('\\Magento\\InventoryConfigurationApi\\Api\\GetStockItemConfigurationInterface'), // @codingStandardsIgnoreLine - 'getStockBySalesChannel' => $objectManager->create('\\Magento\\InventorySalesApi\\Api\\GetStockBySalesChannelInterface'), + + 'getSourceItemBySourceCodeAndSku' => $objectManager->create(GetSourceItemBySourceCodeAndSku::class), + 'getStockItemConfiguration' => $objectManager->create(GetStockItemConfigurationInterface::class), + 'getStockBySalesChannel' => $objectManager->create(GetStockBySalesChannelInterface::class), ]); $this->subject = $this->stockItemValidatorFactory->create([ - 'isSingleSourceMode' => $objectManager->create('\\Magento\\InventoryCatalogApi\\Model\\IsSingleSourceModeInterface'), // @codingStandardsIgnoreLine - 'defaultSourceProvider' => $objectManager->create('\\Magento\\InventoryCatalogApi\\Api\\DefaultSourceProviderInterface'), // @codingStandardsIgnoreLine - 'getItemsToDeductFromShipment' => $objectManager->create('\\Magento\\InventoryShipping\\Model\\GetItemsToDeductFromShipment'), // @codingStandardsIgnoreLine - 'sourceDeductionRequestFromShipmentFactory' => $objectManager->create('\\Magento\\InventoryShipping\\Model\\SourceDeductionRequestFromShipmentFactory'), // @codingStandardsIgnoreLine - 'sourceValidatorService' => $sourceValidatorService, + 'isSingleSourceMode' => $objectManager->create(IsSingleSourceModeInterface::class), + 'defaultSourceProvider' => $objectManager->create(DefaultSourceProviderInterface::class), + 'getItemsToDeductFromShipment' => $objectManager->create(GetItemsToDeductFromShipment::class), + 'sourceDeductionRequestFromShipmentFactory' => $objectManager->create(SourceDeductionRequestFactory::class), + 'sourceValidatorService' => $sourceValidatorService, ]); } + return $this->subject; } } diff --git a/composer.json b/composer.json index 493d4a3..073f0fe 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "license": "Apache-2.0", "type": "magento2-module", "description": "Magento 2 Afterpay Payment Module", - "version": "4.3.0", + "version": "4.3.1", "require": { "php": "~7.1.3||~7.2.0||~7.3.0||~7.4.0", "magento/framework": "^102.0", diff --git a/etc/csp_whitelist.xml b/etc/csp_whitelist.xml index a314b66..6ae77d7 100644 --- a/etc/csp_whitelist.xml +++ b/etc/csp_whitelist.xml @@ -3,8 +3,6 @@ - https://portal.sandbox.clearpay.co.uk - https://portal.clearpay.co.uk https://portal.sandbox.afterpay.com https://portal.afterpay.com https://static.afterpay.com @@ -14,20 +12,16 @@ - static.afterpay.com - static.sandbox.afterpay.com + *.afterpay.com *.squarecdn.com https://hbiq.net https://iq.afterpay-beta.com https://iq.afterpay.com - *.clearpay.co.uk - widgets.sandbox.afterpay.com - widgets.sandbox.clearpay.co.uk @@ -38,8 +32,12 @@ - https://static.afterpay.com - https://site-assets.afterpay.com/ + *.afterpay.com/ + + + + + *.squarecdn.com diff --git a/etc/frontend/di.xml b/etc/frontend/di.xml index 6475767..1d769ff 100644 --- a/etc/frontend/di.xml +++ b/etc/frontend/di.xml @@ -14,6 +14,7 @@ Afterpay\Afterpay\Gateway\Command\ValidateCheckoutDataCommand + Afterpay\Afterpay\Logger @@ -27,7 +28,9 @@ Afterpay\Afterpay\Model\Url\Lib\ExpressCheckoutLibUrlProvider - Afterpay\Afterpay\Model\Config::XML_PATH_ENABLE_EXPRESS_CHECKOUT_ACTION_PRODUCT + + Afterpay\Afterpay\Model\Config::XML_PATH_ENABLE_EXPRESS_CHECKOUT_ACTION_PRODUCT + @@ -38,13 +41,17 @@ Afterpay\Afterpay\Model\Url\Lib\ExpressCheckoutLibUrlProvider - Afterpay\Afterpay\Model\Config::XML_PATH_ENABLE_EXPRESS_CHECKOUT_ACTION_CART_PAGE + + Afterpay\Afterpay\Model\Config::XML_PATH_ENABLE_EXPRESS_CHECKOUT_ACTION_CART_PAGE + Afterpay\Afterpay\Model\Url\Lib\ExpressCheckoutLibUrlProvider - Afterpay\Afterpay\Model\Config::XML_PATH_ENABLE_EXPRESS_CHECKOUT_ACTION_MINI_CART + + Afterpay\Afterpay\Model\Config::XML_PATH_ENABLE_EXPRESS_CHECKOUT_ACTION_MINI_CART + @@ -67,7 +74,7 @@ - + diff --git a/etc/module.xml b/etc/module.xml index aef58de..3a96f0d 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -1,7 +1,7 @@ - + diff --git a/view/frontend/web/js/service/container/pricebox-widget-mixin.js b/view/frontend/web/js/service/container/pricebox-widget-mixin.js index 3ea1da2..ad96ac0 100644 --- a/view/frontend/web/js/service/container/pricebox-widget-mixin.js +++ b/view/frontend/web/js/service/container/pricebox-widget-mixin.js @@ -10,7 +10,7 @@ define([ }, updatePrice: function (newPrices) { const res = this._super(newPrices); - if (this._checkIsFinalPriceDefined() && this.element.closest('product-info-main')) { + if (this._checkIsFinalPriceDefined() && this.element.closest('.product-info-main').length > 0) { containerModel.setCurrentProductId(this.element.data('productId')); containerModel.setPrice(this.cache.displayPrices.finalPrice.amount); } diff --git a/view/frontend/web/js/view/payment/method-renderer/afterpay.js b/view/frontend/web/js/view/payment/method-renderer/afterpay.js index f4c9ea9..2858e2a 100755 --- a/view/frontend/web/js/view/payment/method-renderer/afterpay.js +++ b/view/frontend/web/js/view/payment/method-renderer/afterpay.js @@ -36,6 +36,12 @@ define([ getMPID: function () { return window.checkoutConfig.payment.afterpay.mpid; }, + getAmount: function() { + let amount = window .checkoutConfig.payment.afterpay.isCBTCurrency + ? quote.totals().grand_total : quote.totals().base_grand_total; + + return amount; + }, continueToAfterpay: function (data, event) { const self = this; diff --git a/view/frontend/web/template/payment/afterpay.html b/view/frontend/web/template/payment/afterpay.html index 613fba4..b161a96 100644 --- a/view/frontend/web/template/payment/afterpay.html +++ b/view/frontend/web/template/payment/afterpay.html @@ -11,7 +11,8 @@ 'data-mpid':getMPID(), 'data-platform': 'Magento', 'data-page-type': 'checkout', - 'data-type':'logo'} + 'data-type':'logo', + 'data-amount':getAmount()} ">