diff --git a/Block/Adminhtml/System/Config/Form/Field/cbtLabel.php b/Block/Adminhtml/System/Config/Form/Field/cbtLabel.php new file mode 100644 index 0000000..8280216 --- /dev/null +++ b/Block/Adminhtml/System/Config/Form/Field/cbtLabel.php @@ -0,0 +1,34 @@ +helper = $helper; + parent::__construct($context); + } + + + protected function _getElementHtml(AbstractElement $element) + { + return $this->helper->getCbtCountry(); + } +} \ No newline at end of file diff --git a/Block/Config.php b/Block/Config.php index 3b21ac0..6b7e97c 100644 --- a/Block/Config.php +++ b/Block/Config.php @@ -4,6 +4,7 @@ use Magento\Framework\View\Element\Template; use Afterpay\Afterpay\Model\Config\Payovertime; +use Afterpay\Afterpay\Model\Payovertime as AfterpayPayovertime; use Magento\Framework\Json\Helper\Data; class Config extends Template @@ -29,11 +30,13 @@ public function __construct( Payovertime $payovertime, Data $dataHelper, Template\Context $context, + AfterpayPayovertime $afterpayPayovertime, array $data ) { $this->_payOverTime = $payovertime; $this->_dataHelper = $dataHelper; + $this->afterpayPayovertime = $afterpayPayovertime; parent::__construct($context, $data); } @@ -59,12 +62,7 @@ public function getAfterpayJsUrl() */ public function checkCurrency() { - $supportedCurrency=['AUD','NZD','USD','CAD']; - if(in_array($this->_payOverTime->getCurrencyCode(),$supportedCurrency)){ - return true; - } - else{ - return false; - } + return $this->afterpayPayovertime->canUseForCurrency($this->_payOverTime->getCurrencyCode()) && $this->_payOverTime->isActive(); + } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c6ab1b..b28e7e0 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ # Afterpay Magento 2 Extension Changelog +## Version 3.4.1 + +_Wed 05 May 2021_ + +### Supported Editions & Versions + +Tested and verified in clean installations of Magento 2: + +- Magento Enterprise Edition (EE) version 2.4.2 + +### Highlights + +- Improved support for Cross Border Trade (CBT). +- Improved handling of exceptions at Checkout. +- Improved JS configurations. +- Improved support for native Terms and Conditions. +- Improved support for local currency formatting on product detail pages. + +--- + ## Version 3.4.0 _Wed 24 Mar 2021_ diff --git a/Controller/Payment/Response.php b/Controller/Payment/Response.php index da2a912..2c976bd 100644 --- a/Controller/Payment/Response.php +++ b/Controller/Payment/Response.php @@ -40,6 +40,7 @@ class Response extends \Magento\Framework\App\Action\Action protected $_quoteValidator; protected $_timezone; protected $_afterpayApiPayment; + protected $_expressPayment; /** * Response constructor. @@ -60,6 +61,10 @@ class Response extends \Magento\Framework\App\Action\Action * @param \Magento\Sales\Model\Order\Payment\Transaction\Repository $transactionRepository * @param \Magento\Framework\Notification\NotifierInterface $notifierPool * @param \Afterpay\Afterpay\Model\Adapter\V2\AfterpayOrderPaymentCapture $paymentCapture + * @param \Magento\Quote\Model\QuoteValidator $quoteValidator + * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone + * @param \Afterpay\Afterpay\Model\Adapter\AfterpayPayment $afterpayApiPayment + * @param \Afterpay\Afterpay\Model\Adapter\AfterpayExpressPayment $expressPayment */ public function __construct( \Magento\Framework\App\Action\Context $context, @@ -82,7 +87,8 @@ public function __construct( \Afterpay\Afterpay\Model\Adapter\V2\AfterpayOrderPaymentCapture $paymentCapture, \Magento\Quote\Model\QuoteValidator $quoteValidator, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone, - \Afterpay\Afterpay\Model\Adapter\AfterpayPayment $afterpayApiPayment + \Afterpay\Afterpay\Model\Adapter\AfterpayPayment $afterpayApiPayment, + \Afterpay\Afterpay\Model\Adapter\AfterpayExpressPayment $expressPayment ) { $this->_resultForwardFactory = $resultForwardFactory; $this->response = $response; @@ -104,6 +110,7 @@ public function __construct( $this->_quoteValidator = $quoteValidator; $this->_timezone = $timezone; $this->_afterpayApiPayment = $afterpayApiPayment; + $this->_expressPayment = $expressPayment; parent::__construct($context); } @@ -164,12 +171,12 @@ private function _processAuthCapture($query) if (!$response_check) { // Check the order token being use throw new \Magento\Framework\Exception\LocalizedException(__('There are issues when processing your payment. Invalid Token')); - } elseif ($merchant_order_id != $response_check['merchantReference']) { - // Check order id - throw new \Magento\Framework\Exception\LocalizedException(__('There are issues when processing your payment. Invalid Merchant Reference')); } elseif (round($quote->getBaseGrandTotal(), 2) != round($response_check['amount']['amount'], 2)) { // Check the order amount throw new \Magento\Framework\Exception\LocalizedException(__('There are issues when processing your payment. Invalid Amount')); + } elseif ($this->_expressPayment->isCartUpdated($quote, $response_check['items'])) { + // Check cart Items + throw new \Magento\Framework\Exception\LocalizedException(__('There are issues when processing your payment. Invalid Cart Items')); } if(!$this->_helper->getConfig('payment/afterpaypayovertime/payment_flow') || $this->_helper->getConfig('payment/afterpaypayovertime/payment_flow')=="immediate" || $quote->getIsVirtual()){ diff --git a/Helper/Data.php b/Helper/Data.php index 14bde6d..150817f 100644 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -12,17 +12,20 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper protected $_logger; protected $_afterpayConfig; protected $_moduleList; + protected $_countryFactory; public function __construct( \Magento\Framework\App\Helper\Context $context, \Afterpay\Afterpay\Model\Logger\Logger $logger, \Afterpay\Afterpay\Model\Config\Payovertime $afterpayConfig, - \Magento\Framework\Module\ModuleListInterface $moduleList + \Magento\Framework\Module\ModuleListInterface $moduleList, + \Magento\Directory\Model\CountryFactory $countryFactory ) { parent::__construct($context); $this->_logger = $logger; $this->_afterpayConfig = $afterpayConfig; $this->_moduleList = $moduleList; + $this->_countryFactory = $countryFactory; } public function debug($message, array $context = []) @@ -38,6 +41,26 @@ public function getModuleVersion() return $moduleInfo['setup_version']; } + public function getCbtCountry() + { + $cbtEnabled="Disabled"; + if($this->_afterpayConfig->isCbtEnabled()){ + $cbtEnabled = "Enabled"; + $cbtCountries = $this->_afterpayConfig->getCbtCountry(); + if(!empty($cbtCountries)){ + $cbtCountryCode=explode(",",$cbtCountries); + $counrtyNames=[]; + foreach($cbtCountryCode AS $countryCode){ + if($country = $this->_countryFactory->create()->loadByCode($countryCode)){ + $counrtyNames[] = $country->getName(); + } + } + $cbtEnabled = $cbtEnabled." [ ".implode(" | ",$counrtyNames)." ]"; + } + } + return $cbtEnabled; + } + public function getConfig($config_path) { return $this->scopeConfig->getValue( diff --git a/Model/Adapter/AfterpayExpressPayment.php b/Model/Adapter/AfterpayExpressPayment.php index 9f248c7..f83ceec 100644 --- a/Model/Adapter/AfterpayExpressPayment.php +++ b/Model/Adapter/AfterpayExpressPayment.php @@ -193,7 +193,7 @@ public function formatAmount($amount) public function isCartUpdated($quoteData, $responseItems) { $isCartupdated = false; - $quoteItems = $quoteData->getAllItems(); + $quoteItems = $quoteData->getAllVisibleItems(); if ($quoteData->getItemsCount()!= count($responseItems)) { $isCartupdated = true; $this->_helper->debug('Cart Items count does not match. Quote Count : '.$quoteData->getItemsCount().' & Response count : '.count($responseItems)); diff --git a/Model/Config/Payovertime.php b/Model/Config/Payovertime.php index 2ae82d5..e170969 100644 --- a/Model/Config/Payovertime.php +++ b/Model/Config/Payovertime.php @@ -426,6 +426,24 @@ public function getExpressCheckoutKey() { return $this->_getConfigData(self::EXPRESS_CHECKOUT_KEY); } + /** + * Get cbt enabled/disabled + * + * @return int + */ + public function isCbtEnabled() + { + return $this->_getConfigData(self::ENABLE_CBT); + } + + /* Get cbt countries + * + * @return string + */ + public function getCbtCountry() + { + return $this->_getConfigData(self::CBT_COUNTRY); + } } diff --git a/Model/Config/Save/Plugin.php b/Model/Config/Save/Plugin.php index ae02479..2d14721 100644 --- a/Model/Config/Save/Plugin.php +++ b/Model/Config/Save/Plugin.php @@ -119,14 +119,9 @@ public function aroundSave( } $countryName=""; - if($enable_cbt=="1"){ - $countryName = $this->_scopeConfig->getValue('general/country/default', $scope,$scopeId); - if(isset($response['CBT']['countries']) && !empty($response['CBT']['countries'])){ - if(is_array($response['CBT']['countries'])){ - $countryName .=",".implode(",",$response['CBT']['countries']); - } - } - } + if($enable_cbt=="1" && !empty($response['CBT']['countries']) && is_array($response['CBT']['countries'])){ + $countryName =implode(",",$response['CBT']['countries']); + } diff --git a/Model/ConfigProvider.php b/Model/ConfigProvider.php index 1bf04ab..0568652 100644 --- a/Model/ConfigProvider.php +++ b/Model/ConfigProvider.php @@ -20,14 +20,19 @@ class ConfigProvider implements ConfigProviderInterface * @var Config\Payovertime */ protected $afterpayConfig; + /** + * @var Payovertime + */ + protected $afterpayPayovertime; /** * ConfigProvider constructor. * @param Config\Payovertime $config */ - public function __construct(\Afterpay\Afterpay\Model\Config\Payovertime $config) + public function __construct(\Afterpay\Afterpay\Model\Config\Payovertime $config,\Afterpay\Afterpay\Model\Payovertime $afterpayPayovertime) { $this->afterpayConfig = $config; + $this->afterpayPayovertime = $afterpayPayovertime; } /** @@ -51,6 +56,7 @@ public function getConfig() 'paymentAction' => $this->afterpayConfig->getPaymentAction(), 'termsConditionUrl' => self::TERMS_CONDITION_LINK, 'currencyCode' => $this->afterpayConfig->getCurrencyCode(), + 'baseCurrencyCode' => $this->afterpayPayovertime->getStoreCurrencyCode(), ], ], ]); diff --git a/Model/Payovertime.php b/Model/Payovertime.php index 35ac3ab..716e48f 100644 --- a/Model/Payovertime.php +++ b/Model/Payovertime.php @@ -54,7 +54,7 @@ class Payovertime extends \Magento\Payment\Model\Method\AbstractMethod /** * For dependency injection */ - protected $supportedContryCurrencyCodes = array('AU'=>'AUD','NZ'=>'NZD','US'=>'USD','CA'=>'CAD'); + protected $supportedContryCurrencyCodes = array('AU'=>'AUD','NZ'=>'NZD','US'=>'USD','CA'=>'CAD','GB'=>'GBP'); protected $afterPayPaymentTypeCode = self::AFTERPAY_PAYMENT_TYPE_CODE; protected $logger; @@ -321,14 +321,14 @@ public function isAvailable(\Magento\Quote\Api\Data\CartInterface $quote = null) public function canUseForCurrency($currencyCode) { $canUseForCurrency= false; - + $storeCurrencyCode=$this->getStoreCurrencyCode(); if (in_array($currencyCode, $this->supportedContryCurrencyCodes) ) { - $canUseForCurrency=parent::canUseForCurrency($currencyCode); - //Currency Check for Cross Border trade - if(!empty($this->getConfigData('enable_cbt'))){ + if ($currencyCode==$storeCurrencyCode ) { + $canUseForCurrency=parent::canUseForCurrency($currencyCode); + }else if(!empty($this->getConfigData('enable_cbt')) && !empty($this->getConfigData('cbt_country'))){ + //Currency Check for Cross Border trade $specifiedCountires=explode(",",$this->getConfigData('cbt_country')); - $canUseForCurrency=false; foreach($specifiedCountires AS $country){ if(isset($this->supportedContryCurrencyCodes[$country]) && ($currencyCode==$this->supportedContryCurrencyCodes[$country])){ $canUseForCurrency=parent::canUseForCurrency($currencyCode); @@ -408,4 +408,16 @@ public function fetchTransactionInfo(InfoInterface $payment, $transactionId) // return to the parent return parent::fetchTransactionInfo($payment, $transactionId); } + /** + * Calculated the merchant's store currency code + * + * @return $text + */ + public function getStoreCurrencyCode() + { + $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); + $storeManager = $objectManager->get('\Magento\Store\Model\StoreManagerInterface'); + $store = $storeManager->getStore(); + return $store->getBaseCurrencyCode(); + } } diff --git a/assets.ini b/assets.ini deleted file mode 100644 index aaa4f39..0000000 --- a/assets.ini +++ /dev/null @@ -1,45 +0,0 @@ -; These are assets values in the Afterpay - Magento2 plugin - -[USD] - name = "US" - product_page1 = "or 4 installments of " - product_page2 = 'by More info' - product_page_from = "or 4 installments from " - cart_page1 = "Check out with Afterpay and pay by installments. - Pay 4 installments of " - cart_page2 = "
Use your payment card, approval decision online.
- More info" - -[AUD] - name = "AU" - product_page1 = "or 4 interest-free payments of " - product_page2 = ' - Learn more' - product_page_from = "or 4 interest-free payments from " - cart_page1 = "Check out with Afterpay and pay by instalments. - Simply pay 4 fortnightly instalments of " - cart_page2 = "
Use your payment card, instant approval.
- Learn more" - -[NZD] - name = "NZ" - product_page1 = "or 4 interest-free payments of " - product_page2 = ' - Learn more' - product_page_from = "or 4 interest-free payments from " - cart_page1 = "Check out with Afterpay and pay by instalments. - Simply pay 4 fortnightly instalments of " - cart_page2 = "
Use your payment card, instant approval.
- Learn more" - -[CAD] - name = "CA" - product_page1 = "or 4 instalments of " - product_page2 = 'by More info' - product_page_from = "or 4 instalments from " - cart_page1 = "Check out with Afterpay and pay by instalments. - Pay 4 instalments of " - cart_page2 = "
Use your payment card, approval decision online.
- More info" - - \ No newline at end of file diff --git a/composer.json b/composer.json index 5f98038..4fb0618 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "license" : "OSL-3.0", "type" : "magento2-module", "description" : "Magento 2 Afterpay Payment Module", - "version" : "3.4.0", + "version" : "3.4.1", "authors" : [{ "name" : "Afterpay", "homepage" : "https://www.afterpay.com" diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 4379895..371f878 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -94,6 +94,12 @@ + + + + Afterpay\Afterpay\Block\Adminhtml\System\Config\Form\Field\cbtLabel + + diff --git a/etc/module.xml b/etc/module.xml index 219a96d..4097b36 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -8,7 +8,7 @@ */ --> - + diff --git a/view/frontend/web/js/view/cart/afterpay-cart.js b/view/frontend/web/js/view/cart/afterpay-cart.js index 950c8b8..40e7f11 100644 --- a/view/frontend/web/js/view/cart/afterpay-cart.js +++ b/view/frontend/web/js/view/cart/afterpay-cart.js @@ -18,7 +18,7 @@ require( //CountryCode Object to pass in initialize function. var countryCurrencyMapping ={AUD:"AU", NZD:"NZ", USD:"US",CAD:"CA"}; - var countryCode = (afterpayData.currencyCode in countryCurrencyMapping)? countryCurrencyMapping[afterpayData.currencyCode]:''; + var countryCode = (afterpayData.baseCurrencyCode in countryCurrencyMapping)? countryCurrencyMapping[afterpayData.baseCurrencyCode]:''; var isShippingRequired= (!quote.isVirtual())?true:false; if( $("#afterpay-express-button").length && countryCode!=""){ AfterPay.initializeForPopup({ @@ -54,13 +54,16 @@ require( }, onComplete: function (orderData) { - $("body").trigger('processStart'); + if (orderData.data.status == 'SUCCESS') { $.ajax({ url: mageUrl.build("afterpay/payment/express")+'?action=confirm', method: 'POST', data: orderData.data, + beforeSend: function(){ + $("body").trigger('processStart'); + }, success: function(result){ $("body").trigger('processStop'); if (result.success) { @@ -71,10 +74,13 @@ require( window.location.href = mageUrl.build("checkout/onepage/success"); } - } + }, + complete: function(){ + $("body").trigger('processStop'); + } }); } - $("body").trigger('processStop'); + }, pickup: false, diff --git a/view/frontend/web/js/view/payment/method-renderer/afterpaypayovertime.js b/view/frontend/web/js/view/payment/method-renderer/afterpaypayovertime.js index 27457d0..c19afa2 100644 --- a/view/frontend/web/js/view/payment/method-renderer/afterpaypayovertime.js +++ b/view/frontend/web/js/view/payment/method-renderer/afterpaypayovertime.js @@ -185,7 +185,7 @@ define( //CountryCode Object to pass in initialize function. var countryCurrencyMapping ={AUD:"AU", NZD:"NZ", USD:"US",CAD:"CA"}; - var countryCode = (afterpay.currencyCode in countryCurrencyMapping)? {countryCode: countryCurrencyMapping[afterpay.currencyCode]}:{}; + var countryCode = (afterpay.baseCurrencyCode in countryCurrencyMapping)? {countryCode: countryCurrencyMapping[afterpay.baseCurrencyCode]}:{}; //Update billing address of the quote setBillingAddressAction(globalMessageList); diff --git a/view/frontend/web/js/view/product/afterpay-products.js b/view/frontend/web/js/view/product/afterpay-products.js index 8457ec5..09ef4d4 100644 --- a/view/frontend/web/js/view/product/afterpay-products.js +++ b/view/frontend/web/js/view/product/afterpay-products.js @@ -27,19 +27,7 @@ require( let price_raw = $(".page-main [data-price-type=finalPrice]:first").text() || ''; if (!price_raw) price_raw = $('.page-main .product-info-price .price-final_price .price-wrapper:not([data-price-type="oldPrice"]) span.price:first').text(); - - var price = price_raw.match(/[\d\.]+/g); - - var product_variant_price=parseFloat($('.page-main .product-info-price span.price-final_price > span[data-price-type="finalPrice"]').attr('data-price-amount')); - if(price != null){ - if (price[1]) { - product_variant_price = price[0]+price[1]; - } else { - product_variant_price = price[0]; - } - } - - $('afterpay-placement').attr('data-amount',product_variant_price); + $('afterpay-placement').attr('data-amount',price_raw); } diff --git a/view/frontend/web/template/payment/afterpaypayovertime.html b/view/frontend/web/template/payment/afterpaypayovertime.html index 355cf7a..9956ef6 100644 --- a/view/frontend/web/template/payment/afterpaypayovertime.html +++ b/view/frontend/web/template/payment/afterpaypayovertime.html @@ -27,6 +27,11 @@ +
+ + + +