diff --git a/Block/Cart/Button.php b/Block/Cart/Button.php index 5b5596c..5037e70 100644 --- a/Block/Cart/Button.php +++ b/Block/Cart/Button.php @@ -3,7 +3,7 @@ * Magento 2 extensions for Afterpay Payment * * @author Afterpay - * @copyright 2016-2020 Afterpay https://www.afterpay.com + * @copyright 2016-2021 Afterpay https://www.afterpay.com */ namespace Afterpay\Afterpay\Block\Cart; @@ -13,6 +13,7 @@ use Magento\Customer\Model\Session as CustomerSession; use Magento\Framework\View\Element\Template\Context; use Magento\Framework\Locale\Resolver as Resolver; +use Magento\Framework\Serialize\Serializer\Json as JsonHelper; class Button extends \Afterpay\Afterpay\Block\JsConfig @@ -24,6 +25,10 @@ class Button extends \Afterpay\Afterpay\Block\JsConfig protected $afterpayPayovertime; protected $checkoutSession; protected $customerSession; + /** + * @var JsonHelper + */ + protected $_jsonHelper; /** * Button constructor. @@ -32,6 +37,7 @@ class Button extends \Afterpay\Afterpay\Block\JsConfig * @param AfterpayPayovertime $afterpayPayovertime * @param CheckoutSession $checkoutSession * @param CustomerSession $customerSession + * @param JsonHelper $jsonHelper * @param array $data * @param Resolver $localeResolver */ @@ -41,6 +47,7 @@ public function __construct( AfterpayPayovertime $afterpayPayovertime, CheckoutSession $checkoutSession, CustomerSession $customerSession, + JsonHelper $jsonHelper, array $data=[], Resolver $localeResolver ) { @@ -48,7 +55,8 @@ public function __construct( $this->afterpayPayovertime = $afterpayPayovertime; $this->checkoutSession = $checkoutSession; $this->customerSession = $customerSession; - parent::__construct($afterpayConfig,$context, $localeResolver,$data); + parent::__construct($afterpayConfig,$afterpayPayovertime,$context, $localeResolver,$jsonHelper,$data); + } /** @@ -58,37 +66,37 @@ protected function _getPaymentIsActive() { return $this->afterpayConfig->isActive(); } - + /** * @return bool */ public function canShow() { - // check if payment is active + // check if payment is active if (!$this->_getPaymentIsActive()) { return false; } else{ //Check for Supported currency if($this->afterpayConfig->getCurrencyCode()){ - + $quote = $this->checkoutSession->getQuote(); // get grand total (final amount need to be paid) $grandTotal =$quote->getGrandTotal(); $excluded_categories=$this->afterpayConfig->getExcludedCategories(); - - if($this->afterpayPayovertime->canUseForCurrency($this->afterpayConfig->getCurrencyCode()) ){ - + + if($this->afterpayPayovertime->canUseForCurrency($this->afterpayConfig->getCurrencyCode()) ){ + if($excluded_categories !=""){ $objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $productRepository = $objectManager->get('\Magento\Catalog\Model\ProductRepository'); $excluded_categories_array = explode(",",$excluded_categories); - + foreach ($quote->getAllVisibleItems() as $item) { $productid = $item->getProductId(); $product=$productRepository->getById($productid); $categoryids = $product->getCategoryIds(); - + foreach($categoryids as $k) { if(in_array($k,$excluded_categories_array)){ @@ -102,25 +110,25 @@ public function canShow() else{ return false; } - } + } else { return false; } } } - + /** * @return string */ public function getFinalAmount() { - + $grandTotal = $this->checkoutSession->getQuote()->getGrandTotal(); - + return !empty($grandTotal)?number_format($grandTotal, 2,".",""):"0.00"; - + } - /* + /* * @return boolean */ public function canUseCurrency() @@ -131,8 +139,27 @@ public function canUseCurrency() { $canUse= $this->afterpayPayovertime->canUseForCurrency($this->afterpayConfig->getCurrencyCode()); } - + return $canUse; - + + } + /* + * @return boolean + */ + public function isWithinLimits() + { + $isWithinLimits=false; + $grandTotal = $this->checkoutSession->getQuote()->getGrandTotal(); + if($grandTotal > 0 && $this->afterpayConfig->getMaxOrderLimit() >= $grandTotal && $this->afterpayConfig->getMinOrderLimit() <= $grandTotal){ + $isWithinLimits = true; + } + return $isWithinLimits; + } + /* + * @return boolean + **/ + public function isQuoteVirtual() + { + return $this->checkoutSession->getQuote()->isVirtual(); } } diff --git a/Block/Catalog/Installments.php b/Block/Catalog/Installments.php index cb01f20..3685647 100644 --- a/Block/Catalog/Installments.php +++ b/Block/Catalog/Installments.php @@ -3,7 +3,7 @@ * Magento 2 extensions for Afterpay Payment * * @author Afterpay - * @copyright 2016-2020 Afterpay https://www.afterpay.com + * @copyright 2016-2021 Afterpay https://www.afterpay.com */ namespace Afterpay\Afterpay\Block\Catalog; @@ -11,8 +11,10 @@ use Afterpay\Afterpay\Model\Config\Payovertime as AfterpayConfig; use Afterpay\Afterpay\Model\Payovertime as AfterpayPayovertime; use Magento\Framework\Locale\Resolver as Resolver; +use Magento\Framework\Serialize\Serializer\Json as JsonHelper; use Magento\Framework\Registry as Registry; use Magento\Framework\View\Element\Template\Context; +use Magento\Checkout\Model\Session as CheckoutSession; class Installments extends JsConfig { @@ -35,20 +37,32 @@ class Installments extends JsConfig * @var Resolver */ private $localeResolver; + /** + * @var CheckoutSession + */ + protected $checkoutSession; + /** + * @var JsonHelper + */ + protected $_jsonHelper; /** * @param Context $context * @param Registry $registry * @param AfterpayConfig $afterpayConfig * @param AfterpayPayovertime $afterpayPayovertime + * @param JsonHelper $jsonHelper * @param array $data * @param Resolver $localeResolver + * @param CheckoutSession $checkoutSession */ public function __construct( Context $context, Registry $registry, AfterpayConfig $afterpayConfig, AfterpayPayovertime $afterpayPayovertime, + CheckoutSession $checkoutSession, + JsonHelper $jsonHelper, array $data, Resolver $localeResolver ) { @@ -56,7 +70,8 @@ public function __construct( $this->afterpayConfig = $afterpayConfig; $this->afterpayPayovertime = $afterpayPayovertime; $this->localeResolver = $localeResolver; - parent::__construct($afterpayConfig, $context, $localeResolver, $data); + $this->checkoutSession = $checkoutSession; + parent::__construct($afterpayConfig, $afterpayPayovertime,$context, $localeResolver,$jsonHelper, $data); } /** @@ -65,14 +80,16 @@ public function __construct( public function canShow(): bool { // check if payment is active + $product = $this->registry->registry('product'); + if ($this->_getPaymentIsActive() && $this->afterpayConfig->getCurrencyCode() && - $this->afterpayPayovertime->canUseForCurrency($this->afterpayConfig->getCurrencyCode()) + $this->afterpayPayovertime->canUseForCurrency($this->afterpayConfig->getCurrencyCode() && + $product->isSalable()) ) { $excluded_categories = $this->afterpayConfig->getExcludedCategories(); if ($excluded_categories != "") { $excluded_categories_array = explode(",", $excluded_categories); - $product = $this->registry->registry('product'); $categoryids = $product->getCategoryIds(); foreach ($categoryids as $k) { if (in_array($k, $excluded_categories_array)) { @@ -123,4 +140,22 @@ public function canUseCurrency() return $canUse; } + /** + * @return boolean + */ + public function isProductVirtual() + { + $isVirtual=false; + + $product = $this->registry->registry('product'); + + if ($product->getIsVirtual()) { + $isVirtual=true; + if ($this->checkoutSession->hasQuote()) { + $isVirtual=$this->checkoutSession->getQuote()->isVirtual(); + } + } + + return $isVirtual; + } } diff --git a/Block/JsConfig.php b/Block/JsConfig.php index d18057b..956bfe8 100644 --- a/Block/JsConfig.php +++ b/Block/JsConfig.php @@ -1,37 +1,53 @@ _payOverTime = $payovertime; + + $this->_configPayovertime = $configPayovertime; + $this->_payOvertime = $payOvertime; $this->localeResolver = $localeResolver; + $this->_jsonHelper = $jsonHelper; parent::__construct($context, $data); } @@ -39,7 +55,6 @@ public function __construct( protected function _construct() { parent::_construct(); - return $this; } /** @@ -47,25 +62,25 @@ protected function _construct() */ public function getMaxOrderLimit() { - return number_format($this->_payOverTime->getMaxOrderLimit(), 2,".",""); + return number_format($this->_configPayovertime->getMaxOrderLimit(), 2,".",""); } - + /** * @return float */ public function getMinOrderLimit() { - return number_format($this->_payOverTime->getMinOrderLimit(), 2,".",""); + return number_format($this->_configPayovertime->getMinOrderLimit(), 2,".",""); } - + /** * @return bool */ protected function _getPaymentIsActive() { - return $this->_payOverTime->isActive(); + return $this->_configPayovertime->isActive(); } - + /* Get Current Locale * * @return string @@ -73,14 +88,14 @@ protected function _getPaymentIsActive() public function getCurrentLocale() { $currentLocale=$this->localeResolver->getLocale(); - $country_code=$this->_payOverTime->getCurrentCountryCode(); + $country_code=$this->_configPayovertime->getCurrentCountryCode(); if(!empty($country_code) && stripos($currentLocale,$country_code)=== false){ $currentLocale="en_".strtoupper($country_code); } - + return $currentLocale; // eg. fr_CA } - + /** * Get JS Library URL * @@ -88,7 +103,7 @@ public function getCurrentLocale() */ public function getAfterpayJsLibUrl() { - return $this->_payOverTime->getJSLibUrl('afterpay-1.x.js'); + return $this->_configPayovertime->getJSLibUrl('afterpay-1.x.js'); } /** * check if payment is active @@ -103,16 +118,25 @@ public function isPaymentMethodActive() } return $isPaymentMethodActive; } - + /* Get Current Currency * * @return string */ public function getCurrentCurrency() { - return $this->_payOverTime->getCurrencyCode(); // eg. AUD + return $this->_configPayovertime->getCurrencyCode(); // eg. AUD + } + + /* Get Base Currency + * + * @return string + */ + public function getBaseCurrency() + { + return $this->_payOvertime->getStoreCurrencyCode(); // eg. AUD } - + /** * check if payment is active for product page * @@ -121,12 +145,12 @@ public function getCurrentCurrency() public function isDisplayOnProductPage() { $isEnabledForProductPage=true; - if (!$this->_payOverTime->isEnabledForProductDisplayPage()) { + if (!$this->_configPayovertime->isEnabledForProductDisplayPage()) { $isEnabledForProductPage= false; } return $isEnabledForProductPage; } - + /** * check if payment is active for cart page * @@ -134,17 +158,90 @@ public function isDisplayOnProductPage() */ public function isDisplayOnCartPage() { - return $this->_payOverTime->isEnabledForCartPage(); + return $this->_configPayovertime->isEnabledForCartPage(); } - /** - * Get Express Checkout JS URL + * check if express checkout is active for minicart + * + * @return int + */ + public function isDisplayECOnMiniCart() + { + return $this->_configPayovertime->isExpressCheckoutMiniCartPage(); + } + + /** + * Get Express Checkout JS URL * * @return bool|string */ public function getAfterpayECJsUrl() { - $express_checkout_key=$this->_payOverTime->getExpressCheckoutKey(); - return $this->_payOverTime->getWebUrl('afterpay.js',array("merchant_key"=>!empty($express_checkout_key)?$express_checkout_key:"")); + return $this->_configPayovertime->getWebUrl('afterpay.js',array("merchant_key"=>"magento2")); + } + + /** + * Get Afterpay Configs + * + * @return string + */ + public function getAfterpayConfigs() + { + /** + * adding config array + */ + $config = array( + 'paymentActive'=>$this->_getPaymentIsActive(), + 'currencyCode' => $this->getCurrentCurrency(), + 'baseCurrencyCode' => $this->getBaseCurrency(), + 'minLimit'=>$this->getMinOrderLimit(), + 'maxLimit'=>$this->getMaxOrderLimit() + ); + return $this->getJsonEncode($config); + } + /** + * check if enable express checkout for product page + * + * @return int + */ + public function isDisplayEConProductPage() + { + return $this->_configPayovertime->isExpressCheckoutProductPage(); + } + /** + * check if enable express checkout for cart page + * + * @return int + */ + public function isDisplayEConCartPage() + { + return $this->_configPayovertime->isExpressCheckoutCartPage(); + } + /** + * Get store identifier + * + * @return int + */ + public function getStore() + { + return $this->_configPayovertime->getStoreId(); + } + + /** + * @param $data + * @return bool|false|string + */ + public function getJsonEncode($data) + { + return $this->_jsonHelper->serialize($data); // it's same as like json_encode + } + + /** + * @param $data + * @return array|bool|float|int|mixed|string|null + */ + public function getJsonDecode($data) + { + return $this->_jsonHelper->unserialize($data); // it's same as like json_decode } } diff --git a/CHANGELOG.md b/CHANGELOG.md index b28e7e0..049fefb 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,26 @@ # Afterpay Magento 2 Extension Changelog +## Version 3.4.2 + +_Wed 16 June 2021_ + +### Supported Editions & Versions + +Tested and verified in clean installations of Magento 2: + +- Magento Enterprise Edition (EE) version 2.4.2 + +### Highlights + +- Extended Express Checkout to support Product Detail Pages (PDP) and mini-cart. +- Introduced a separate section for Express Checkout in the Admin Panel. +- Removed the requirement to provide a key for Express Checkout in the Admin Panel. +- Improved handing of invalid customer addresses. +- Improved error handling in Express Checkout. +- Improved JS configurations. + +--- + ## Version 3.4.1 _Wed 05 May 2021_ diff --git a/Model/Adapter/AfterpayExpressPayment.php b/Model/Adapter/AfterpayExpressPayment.php index f83ceec..7024c41 100644 --- a/Model/Adapter/AfterpayExpressPayment.php +++ b/Model/Adapter/AfterpayExpressPayment.php @@ -18,38 +18,38 @@ class AfterpayExpressPayment { protected $_checkoutSession; - + protected $_orderRepository; - + protected $_quoteFactory; - + protected $_afterpayOrderTokenV2; - + protected $_jsonHelper; - + protected $_helper; - + protected $_quoteRepository; - + protected $_totalsCollector; - + protected $_paymentCapture; - + protected $_transactionRepository; - + protected $_objectManager; - + protected $_transactionBuilder; - + protected $_paymentRepository; - + /** * Shipping method converter * * @var \Magento\Quote\Model\Cart\ShippingMethodConverter */ protected $_converter; - + /** * @var Payovertime $_payOverTime */ @@ -60,25 +60,25 @@ class AfterpayExpressPayment * @param \Magento\Framework\App\Action\Context $context * @param \Magento\Checkout\Model\Session $checkoutSession */ - public function __construct( - CheckoutSession $checkoutSession, + public function __construct( + CheckoutSession $checkoutSession, \Magento\Sales\Model\OrderRepository $orderRepository, - QuoteFactory $quoteFactory, - AfterpayOrderTokenV2 $afterpayOrderTokenV2, + QuoteFactory $quoteFactory, + AfterpayOrderTokenV2 $afterpayOrderTokenV2, JsonHelper $jsonHelper, Helper $helper, - QuoteRepository $quoteRepository, - \Magento\Quote\Model\Quote\TotalsCollector $totalsCollector, - Converter $converter, - \Afterpay\Afterpay\Model\Adapter\V2\AfterpayOrderPaymentCapture $paymentCapture, - \Magento\Sales\Model\Order\Payment\Transaction\Repository $transactionRepository, + QuoteRepository $quoteRepository, + \Magento\Quote\Model\Quote\TotalsCollector $totalsCollector, + Converter $converter, + \Afterpay\Afterpay\Model\Adapter\V2\AfterpayOrderPaymentCapture $paymentCapture, + \Magento\Sales\Model\Order\Payment\Transaction\Repository $transactionRepository, \Magento\Framework\ObjectManagerInterface $objectManager, \Magento\Sales\Model\Order\Payment\Transaction\BuilderInterface $transactionBuilder, \Magento\Sales\Model\Order\Payment\Repository $paymentRepository, \Afterpay\Afterpay\Model\Config\Payovertime $payovertime ) { - $this->_checkoutSession = $checkoutSession; + $this->_checkoutSession = $checkoutSession; $this->_orderRepository = $orderRepository; $this->_quoteFactory = $quoteFactory; $this->_afterpayOrderTokenV2 = $afterpayOrderTokenV2; @@ -93,7 +93,7 @@ public function __construct( $this->_transactionBuilder = $transactionBuilder; $this->_paymentRepository = $paymentRepository; $this->_payOverTime = $payovertime; - + } /** * @@ -116,10 +116,10 @@ public function getAfterPayExpressOrderToken($afterpayOrderToken, $payment, $tar 'mode' => \Afterpay\Afterpay\Model\Config\Source\CartMode::EXPRESS_CHECKOUT ]); } - + $result = $this->_jsonHelper->jsonDecode($result->getBody(), true); $orderToken = array_key_exists('token', $result) ? $result['token'] : false; - + if ($orderToken) { $payment->setAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::ADDITIONAL_INFORMATION_KEY_TOKEN, $orderToken); } else { @@ -128,7 +128,7 @@ public function getAfterPayExpressOrderToken($afterpayOrderToken, $payment, $tar } return $payment; } - + /** * Get Region Id * @@ -139,10 +139,10 @@ public function getAfterPayExpressOrderToken($afterpayOrderToken, $payment, $tar public function getRegionId($stateCode, $countryCode) { $region = $this->_objectManager->create('Magento\Directory\Model\Region'); - + return $region->loadByCode($stateCode, $countryCode)->getId(); } - + /** * Get list of available shipping methods * @@ -156,7 +156,7 @@ public function getShippingDetails($quote) if (! $quote->isVirtual()) { $shippingAddress = $quote->getShippingAddress(); $shippingAddress->setCollectShippingRates(true); - + $this->_totalsCollector->collectAddressTotals($quote, $shippingAddress); $shippingRates = $shippingAddress->getGroupedAllShippingRates(); foreach ($shippingRates as $carrierRates) { @@ -166,11 +166,11 @@ public function getShippingDetails($quote) } } return $output; - + } - - - + + + /** * Format amount upto 2 decimal * @@ -182,7 +182,7 @@ public function formatAmount($amount) { return number_format($amount, 2, '.', ''); } - + /* * Is cart Updated * @param \Magento\Quote\Model\Quote $quoteData @@ -194,14 +194,19 @@ public function isCartUpdated($quoteData, $responseItems) { $isCartupdated = false; $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)); } else { foreach ($quoteItems as $items) { $itemFound = array_search($items->getSku(), array_column($responseItems, 'sku')); - if ($itemFound === false) { - $this->_helper->debug('Cart Items '.$items->getSku().' does not match.'); + if ($itemFound === false) { + $this->_helper->debug('Cart items '.$items->getName().' does not match.'); + $isCartupdated = true; + break; + }elseif($items->getQty() != $responseItems[$itemFound]['quantity']){ + $this->_helper->debug('Quantity of cart item - '.$items->getName().' does not match.'); $isCartupdated = true; break; } @@ -210,7 +215,7 @@ public function isCartUpdated($quoteData, $responseItems) } return $isCartupdated; } - + /** * Update Order databased on response */ @@ -219,28 +224,28 @@ public function setOrderData($data) $quote = $this->_checkoutSession->getQuote(); $billingAddress = $quote->getBillingAddress(); $shippingAddress = $quote->getShippingAddress(); - + // Set first name & lastname in shipping address $fullName = explode(' ', $data['shipping']['name']); $lastName = array_pop($fullName); if (count($fullName) == 0) { // if $order['shipping']['name'] contains only one word $firstName = $lastName; - } else { + } else { $firstName = implode(' ', $fullName); } - + // Set Customer Data $customerSession = $this->_objectManager->get('Magento\Customer\Model\Session'); $customerRepository = $this->_objectManager->get('Magento\Customer\Api\CustomerRepositoryInterface'); - + if ($customerSession->isLoggedIn()) { $customerId = $customerSession->getCustomer()->getId(); $customer = $customerRepository->getById($customerId); - + // customer login $quote->setCustomer($customer); - + // Set Billing Details if (empty($billingAddress) || empty($billingAddress->getStreetLine(1)) || empty($billingAddress->getFirstname())) { $billingID = $customerSession->getCustomer()->getDefaultBilling(); @@ -249,15 +254,15 @@ public function setOrderData($data) $billingAddress->addData($address->getData()); } } else { - + $quote->setCustomerEmail($data['consumer']['email']) ->setCustomerIsGuest(true) ->setCustomerGroupId(\Magento\Customer\Api\Data\GroupInterface::NOT_LOGGED_IN_ID) ->setCustomerFirstname($data['consumer']['givenNames']) ->setCustomerLastname($data['consumer']['surname']); - + // Set Billing Details - + $billingAddress->setFirstname($firstName) ->setLastname($lastName) ->setEmail($data['consumer']['email']) @@ -271,11 +276,11 @@ public function setOrderData($data) ->setRegionId($this->getRegionId($data['shipping']['region'], $data['shipping']['countryCode'])) ->setPostcode($data['shipping']['postcode']) ->setCountryId($data['shipping']['countryCode']); - + // Set flag for same billing and shipping address $shippingAddress->setSameAsBilling(1); } - + // Set Shipping Details if (! $quote->isVirtual()) { $shippingAddress->setFirstname($firstName) @@ -297,13 +302,13 @@ public function setOrderData($data) } else { $billingAddress->setPaymentMethod(\Afterpay\Afterpay\Model\Payovertime::METHOD_CODE); } - + $quote->collectTotals(); - + $this->_quoteRepository->save($quote); $this->_checkoutSession->replaceQuote($quote); } - + /* * Calculate Total Discount for the given order */ @@ -314,23 +319,23 @@ public function calculateTotalDiscount($order) $totalDiscountAmount = $storeCredit + $giftCardAmount; return number_format($totalDiscountAmount, 2, '.', ''); } - + /* * Capture payment for Virtal products */ public function captureVirtual($order = null, $payment = null) { $totalCaptureAmount = 0.00; - + foreach ($order->getAllItems() as $items) { if ($items->getIsVirtual()) { $itemPrice = ($items->getQtyOrdered() * $items->getPrice()) + $items->getBaseTaxAmount(); $totalCaptureAmount = $totalCaptureAmount + ($itemPrice - $items->getDiscountAmount()); } } - + $totalDiscountAmount = $payment->getAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::ROLLOVER_DISCOUNT); - + if ($totalDiscountAmount != 0) { if ($totalCaptureAmount >= $totalDiscountAmount) { $totalCaptureAmount = $totalCaptureAmount - $totalDiscountAmount; @@ -341,20 +346,20 @@ public function captureVirtual($order = null, $payment = null) } $payment->setAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::ROLLOVER_DISCOUNT, number_format($totalDiscountAmount, 2, '.', '')); } - + if ($totalCaptureAmount >= 1) { $afterpay_order_id = $payment->getAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::ADDITIONAL_INFORMATION_KEY_ORDERID); $merchant_order_id = $order->getIncrementId(); $currencyCode = $order->getOrderCurrencyCode(); - + $totalAmount = [ 'amount' => number_format($totalCaptureAmount, 2, '.', ''), 'currency' => $currencyCode ]; - + $response = $this->_paymentCapture->send($totalAmount, $merchant_order_id, $afterpay_order_id); $response = $this->_jsonHelper->jsonDecode($response->getBody()); - + if (! array_key_exists("errorCode", $response)) { $payment->setAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::PAYMENT_STATUS, $response['paymentState']); if (array_key_exists('openToCaptureAmount', $response) && ! empty($response['openToCaptureAmount'])) { @@ -369,7 +374,7 @@ public function captureVirtual($order = null, $payment = null) } } } - + /* * Create Transaction */ @@ -379,7 +384,7 @@ public function createTransaction($order = null, $paymentData = [], $payment = n $payment->setLastTransId($paymentData['id']); $payment->setTransactionId($paymentData['id']); $formatedPrice = $order->getBaseCurrency()->formatTxt($order->getGrandTotal()); - + $message = __('The authorized amount is %1.', $formatedPrice); // get the object of builder class $trans = $this->_transactionBuilder; @@ -390,23 +395,23 @@ public function createTransaction($order = null, $paymentData = [], $payment = n -> // build method creates the transaction and returns the object build(\Magento\Sales\Model\Order\Payment\Transaction::TYPE_CAPTURE); - + $payment->addTransactionCommentsToOrder($transaction, $message); $payment->setParentTransactionId(null); $this->_paymentRepository->save($payment); - + $order->setBaseCustomerBalanceInvoiced(null); $order->setCustomerBalanceInvoiced(null); $this->_orderRepository->save($order); - + $transaction = $this->_transactionRepository->save($transaction); return $transaction->getTransactionId(); } catch (\Exception $e) { // log errors here $this->_helper->debug("_createTransaction : Transaction Exception: There was a problem with creating the transaction. " . $e->getMessage()); } - } - + } + /* * Validate order amount */ @@ -416,7 +421,7 @@ public function isValidOrderAmount($orderAmount) $min_limit= $this->formatAmount($this->_payOverTime->getMinOrderLimit()); $orderTotal=$this->formatAmount($orderAmount); return ($orderTotal<=$max_limit && $orderTotal>=$min_limit); - + } - + } diff --git a/Model/Config/Payovertime.php b/Model/Config/Payovertime.php index e170969..d89ef43 100644 --- a/Model/Config/Payovertime.php +++ b/Model/Config/Payovertime.php @@ -39,6 +39,9 @@ class Payovertime const CBT_COUNTRY = 'cbt_country'; const ENABLE_FOR_PRODUCT_PAGE= "enable_for_product_page"; const ENABLE_FOR_CART_PAGE = "enable_for_cart_page"; + const EXPRESS_CHECKOUT_PRODUCT_PAGE = "express_checkout_product_page"; + const EXPRESS_CHECKOUT_CART_PAGE = "express_checkout_cart_page"; + const EXPRESS_CHECKOUT_MINICART_PAGE = "express_checkout_minicart_page"; const EXPRESS_CHECKOUT_KEY = "express_checkout_key"; /** @@ -175,7 +178,7 @@ public function getSiteConfig($apiMode, $type, $websiteId) $store = $storeManager->getStore(); $currency = $store->getCurrentCurrencyCode(); - + //In case of multiple websites, find the currency for the selected store based on the website ID. if (!empty($websiteId)) { $websites = $storeManager->getWebsites(); @@ -188,7 +191,7 @@ public function getSiteConfig($apiMode, $type, $websiteId) } } } - } + } $url =""; if ($type=='api_url') { @@ -214,7 +217,7 @@ public function getSiteConfig($apiMode, $type, $websiteId) $url = 'https://portal.afterpay.com/'; } } - + // get JS Library URL if ($type=='js_lib_url') { if ($apiMode == 'Sandbox') { @@ -388,7 +391,7 @@ private function _cleanup_string($string) $result = preg_replace("/[^a-zA-Z0-9]+/", "", $string); return $result; } - + /** * @return bool */ @@ -396,7 +399,7 @@ public function isEnabledForProductDisplayPage() { return (bool)$this->_getConfigData(self::ENABLE_FOR_PRODUCT_PAGE); } - + /** * @return int */ @@ -404,7 +407,7 @@ public function isEnabledForCartPage() { return $this->_getConfigData(self::ENABLE_FOR_CART_PAGE); } - + /** * Calculated the currency code * @@ -416,7 +419,7 @@ public function getCurrentCountryCode() $countryCode = $this->scopeConfig->getValue('general/country/default', \Magento\Store\Model\ScopeInterface::SCOPE_WEBSITES,$websiteId); return $countryCode; } - + /** * Get config for express checkout key * @@ -434,8 +437,8 @@ public function getExpressCheckoutKey() public function isCbtEnabled() { return $this->_getConfigData(self::ENABLE_CBT); - } - + } + /* Get cbt countries * * @return string @@ -444,6 +447,36 @@ public function getCbtCountry() { return $this->_getConfigData(self::CBT_COUNTRY); } - - + /** + * @return int + */ + public function isExpressCheckoutProductPage() + { + return $this->_getConfigData(self::EXPRESS_CHECKOUT_PRODUCT_PAGE); + } + /** + * @return int + */ + public function isExpressCheckoutCartPage() + { + return $this->_getConfigData(self::EXPRESS_CHECKOUT_CART_PAGE); + } + /** + * @return int + */ + public function isExpressCheckoutMiniCartPage() + { + return $this->_getConfigData(self::EXPRESS_CHECKOUT_MINICART_PAGE); + } + + /** + * Get store identifier + * + * @return int + */ + public function getStoreId() + { + return $this->storeManager->getStore()->getId(); + } + } diff --git a/Model/Config/Save/Plugin.php b/Model/Config/Save/Plugin.php index 2d14721..7d20332 100644 --- a/Model/Config/Save/Plugin.php +++ b/Model/Config/Save/Plugin.php @@ -60,7 +60,7 @@ public function aroundSave( \Magento\Config\Model\Config $subject, \Closure $proceed ) { - + //first saving run to eliminate possibilities of conflicting config results $returnValue=$proceed(); @@ -70,12 +70,12 @@ public function aroundSave( $configRequest = $subject->getGroups(); if(!empty($configRequest) && is_array($configRequest)){ $this->requested = array_key_exists(\Afterpay\Afterpay\Model\Payovertime::METHOD_CODE, $configRequest); - + if ($this->requested) { $config_array=$configRequest[\Afterpay\Afterpay\Model\Payovertime::METHOD_CODE]['groups'][\Afterpay\Afterpay\Model\Payovertime::METHOD_CODE . '_basic']['fields'][\Afterpay\Afterpay\Model\Config\Payovertime::ACTIVE]; - + if(array_key_exists('value',$config_array)){ - + if($config_array['value'] == '1'){ $response = $this->afterpayTotalLimit->getLimit(); $response = $this->jsonHelper->jsonDecode($response->getBody()); @@ -84,7 +84,7 @@ public function aroundSave( // default min and max if not provided $minTotal = "0"; $maxTotal = "0"; - + // understand the response from the API $minTotal = array_key_exists('minimumAmount',$response) && isset($response['minimumAmount']['amount']) ? $response['minimumAmount']['amount'] : "0"; $maxTotal = array_key_exists('maximumAmount',$response) && isset($response['maximumAmount']['amount']) ? $response['maximumAmount']['amount'] : "0"; @@ -101,12 +101,12 @@ public function aroundSave( // Check for Cross Border Trade(CBT) $enable_cbt = (array_key_exists('CBT',$response) && isset($response['CBT']['enabled']) && ($response['CBT']['enabled']===true)) ? "1" : "0"; - + // Get current Store Id $storeId=(int) $this->request->getParam('store', 0); // Get current Website Id $websiteId = (int) $this->request->getParam('website', 0); - + // Set current scope $scope='default'; $scopeId=0; @@ -117,23 +117,23 @@ public function aroundSave( $scope=ScopeInterface::SCOPE_STORE; $scopeId=$storeId; } - + $countryName=""; if($enable_cbt=="1" && !empty($response['CBT']['countries']) && is_array($response['CBT']['countries'])){ $countryName =implode(",",$response['CBT']['countries']); } - - - + + + // Save Cross Border Trade(CBT) details on config request - $this->configWriter->save("payment/afterpaypayovertime/".\Afterpay\Afterpay\Model\Config\Payovertime::ENABLE_CBT, $enable_cbt, $scope, $scopeId); - $this->configWriter->save("payment/afterpaypayovertime/".\Afterpay\Afterpay\Model\Config\Payovertime::CBT_COUNTRY, $countryName, $scope, $scopeId); - + $this->configWriter->save("payment/afterpaypayovertime/".\Afterpay\Afterpay\Model\Config\Payovertime::ENABLE_CBT, $enable_cbt, $scope, $scopeId); + $this->configWriter->save("payment/afterpaypayovertime/".\Afterpay\Afterpay\Model\Config\Payovertime::CBT_COUNTRY, $countryName, $scope, $scopeId); + $subject->setGroups($configRequest); $returnValue=$proceed(); } else { $this->messageManager->addWarningMessage('Afterpay Update Limits Failed. Please check Merchant ID and Key.'); - + } } } diff --git a/Model/Response.php b/Model/Response.php index 74c5547..028deff 100644 --- a/Model/Response.php +++ b/Model/Response.php @@ -25,7 +25,7 @@ class Response const RESPONSE_STATUS_PENDING = 'PENDING'; const RESPONSE_STATUS_FAILED = 'FAILED'; const RESPONSE_STATUS_DECLINED = 'DECLINED'; - + const PAYMENT_STATUS_AUTH_APPROVED = 'AUTH_APPROVED'; const PAYMENT_STATUS_CAPTURED = 'CAPTURED'; const PAYMENT_STATUS_PARTIALLY_CAPTURED = 'PARTIALLY_CAPTURED'; @@ -240,7 +240,7 @@ public function updatePayment(\Magento\Sales\Model\Order $order, $orderId) $payment->setAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::ADDITIONAL_INFORMATION_KEY_ORDERID, $orderId); // have save here to link afterpay order id right after checking the API $this->_paymentRepository->save($payment); - + // debug mode $this->helper->debug('Added Afterpay Payment ID ' . $orderId . ' for Magento order ' . $order->getIncrementId()); } @@ -321,22 +321,22 @@ public function calculateRefund($payment, $amount) $result = []; $override = []; $orderId = $payment->getAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::ADDITIONAL_INFORMATION_KEY_ORDERID); - + if($orderId) { - + $order = $payment->getOrder(); $creditmemo = $payment->getCreditmemo(); $amountToCapture = 0.00; $storeCredit = $creditmemo->getCustomerBalanceAmount(); $override = ["website_id" => $order->getStore()->getWebsiteId()]; - + $afterpayPaymentStatus = $payment->getAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::PAYMENT_STATUS); - + if($afterpayPaymentStatus == self::PAYMENT_STATUS_CAPTURED){ $afterpayRefund = true; } - elseif($afterpayPaymentStatus == self::PAYMENT_STATUS_PARTIALLY_CAPTURED || $afterpayPaymentStatus == self::PAYMENT_STATUS_AUTH_APPROVED){ - + elseif($afterpayPaymentStatus == self::PAYMENT_STATUS_PARTIALLY_CAPTURED || $afterpayPaymentStatus == self::PAYMENT_STATUS_AUTH_APPROVED){ + $orderTotal = $order->getGrandTotal(); $shippingApplied = $creditmemo->getShippingInclTax(); $adjustmentPositive = $creditmemo->getAdjustmentPositive(); @@ -356,17 +356,17 @@ public function calculateRefund($payment, $amount) $orderShippingAmount = $order->getShippingInclTax(); $actualOpenToCaptureAmount = $openToCaptureAmount - ($rolloverRefund + $rolloverAmount); $shippingRefunded = ($order->getShippingRefunded() + $order->getShippingTaxRefunded()) - $shippingApplied; - + if($orderDiscount > 0){ $refundedDiscount = $order->getCustomerBalanceRefunded() + $order->getGiftCardsRefunded(); $appliedDiscount = $creditmemo->getCustomerBalanceAmount() + $creditmemo->getGiftCardsAmount(); } - + foreach ($creditmemo->getAllItems() as $item) { $orderItem = $item->getOrderItem(); if (!$orderItem->getHasChildren()) { $qtyToRefund = $item->getQty(); - + if($orderItem->getIsVirtual()){ $amountCaptured = $amountCaptured + $this->calculateItemPrice($orderItem,$qtyToRefund); } @@ -385,28 +385,28 @@ public function calculateRefund($payment, $amount) } } } - + if($order->getShipmentsCollection()->count() > 0 && number_format($orderTotal - $openToCaptureAmount, 2, '.', '') > 0.00){ $amountCaptured = $amountCaptured + ($orderShippingAmount - ($orderShippingAmount - $shippingApplied)); } - + if($capturedDiscount > 0 && $appliedDiscount > 0){ if($amount > 0){ $amountCaptured = $amountCaptured - $capturedDiscount; } } - + if($order->getShipmentsCollection()->count() == 0){ $amountNotCaptured = $amountCaptured + $orderShippingAmount; } - + if(number_format($amount - $orderTotal, 2, '.', '') == 0.00){ //Full Order Refund if($actualOpenToCaptureAmount != $orderTotal){ $amount = $amount - $actualOpenToCaptureAmount; $afterpayRefund = true; } - $afterpayVoid = true; + $afterpayVoid = true; } else { @@ -420,7 +420,7 @@ public function calculateRefund($payment, $amount) $amountToRefund = $amount - $amountCaptured; $amount = $amountCaptured; } - + $afterpayRefund = true; } else{ @@ -428,9 +428,9 @@ public function calculateRefund($payment, $amount) $amount = 0.00; } } - + if($appliedDiscount > 0){ - + if($amount == 0.00 && $amountToRefund == 0.00){ $amountToCapture = min($appliedDiscount - ($rolloverDiscount + $rolloverRefund), $amountNotCaptured); } @@ -442,7 +442,7 @@ public function calculateRefund($payment, $amount) $amountToCapture = 0.00; } $reducedRolloverDiscount = max((($appliedDiscount - $amountCaptured) - $amountToCapture),0.00); - + if($rolloverDiscount > 0){ $payment->setAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::ROLLOVER_DISCOUNT, max(($rolloverDiscount - $reducedRolloverDiscount),"0.00")); } @@ -450,7 +450,7 @@ public function calculateRefund($payment, $amount) $payment->setAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::ROLLOVER_DISCOUNT, "0.00"); } } - + if(number_format($amountToRefund - $actualOpenToCaptureAmount, 2, '.', '') == 0.00){ $amountToCapture = 0.00; $afterpayVoid = true; @@ -458,12 +458,12 @@ public function calculateRefund($payment, $amount) elseif($amountToRefund < $actualOpenToCaptureAmount && $amountToRefund != 0.00){ if($order->getShipmentsCollection()->count()==0){ $amountInclShipping = $amountToRefund + (($orderShippingAmount-$shippingRefunded) - $shippingApplied); - + if(number_format(($amountInclShipping+ $amountToCapture) - $orderTotal, 2, '.', '') == 0.00 || number_format(($amountInclShipping+ $amountToCapture) - $actualOpenToCaptureAmount, 2, '.', '') == 0.00){ if($shippingApplied < $orderShippingAmount){ $amountToCapture = $amountToCapture + (($orderShippingAmount-$shippingRefunded) - $shippingApplied); } - $afterpayVoid = true; + $afterpayVoid = true; } elseif(number_format($amountInclShipping - $orderTotal, 2, '.', '') == 0.00 || number_format($amountInclShipping - $actualOpenToCaptureAmount, 2, '.', '') == 0.00){ $afterpayVoid = true; @@ -477,11 +477,11 @@ public function calculateRefund($payment, $amount) else{ if($amountToCapture > 0){ if(number_format(($amountToRefund + ($amountToCapture - $shippingApplied)) - $actualOpenToCaptureAmount, 2, '.', '') == 0.00 || number_format(($amountToRefund + ($amountToCapture - $shippingApplied)) - $orderTotal, 2, '.', '') == 0.00){ - $amountToCapture = $amountToCapture - $shippingApplied; + $amountToCapture = $amountToCapture - $shippingApplied; $afterpayVoid = true; } elseif(number_format(($amountToRefund + ($amountToCapture - $shippingApplied)) - $actualOpenToCaptureAmount, 2, '.', '') > 0.00){ - $amountToCapture = $amountToCapture - (($amountToRefund + $amountToCapture) - $openToCaptureAmount); + $amountToCapture = $amountToCapture - (($amountToRefund + $amountToCapture) - $openToCaptureAmount); $afterpayVoid = true; } else{ @@ -508,16 +508,16 @@ public function calculateRefund($payment, $amount) } } $result['success'] = $this->afterpayProcessRefund($payment,$order,$amountToCapture,$afterpayRefund,$amount,$afterpayVoid,$orderId,$override); - + if($storeCredit > 0){ $storeCredit = $storeCredit + $order->getBaseCustomerBalanceRefunded(); $order->setBaseCustomerBalanceRefunded($storeCredit); $order->setCustomerBalanceRefunded($storeCredit); } - } + } else { - throw new \Magento\Framework\Exception\LocalizedException(__('There are no Afterpay payment linked to this order. Please use refund offline for this order.')); + throw new \Magento\Framework\Exception\LocalizedException(__('There are no Afterpay payment linked to this order. Please use "refund offline" for this order.')); } return $result; } @@ -534,29 +534,29 @@ public function lastShipmentProcessRefund($payment, $amount) $result = []; $amountToCapture = 0.00; $orderId = $payment->getAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::ADDITIONAL_INFORMATION_KEY_ORDERID); - + if($orderId) { $order = $payment->getOrder(); if($amount > 0){ $override = ["website_id" => $order->getStore()->getWebsiteId()]; - + $afterpayPaymentStatus = $payment->getAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::PAYMENT_STATUS); if($afterpayPaymentStatus == self::PAYMENT_STATUS_CAPTURED){ $afterpayRefund = true; } - elseif($afterpayPaymentStatus == self::PAYMENT_STATUS_PARTIALLY_CAPTURED || $afterpayPaymentStatus == self::PAYMENT_STATUS_AUTH_APPROVED){ - + elseif($afterpayPaymentStatus == self::PAYMENT_STATUS_PARTIALLY_CAPTURED || $afterpayPaymentStatus == self::PAYMENT_STATUS_AUTH_APPROVED){ + $orderTotal = $order->getGrandTotal(); $openToCaptureAmount = $payment->getAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::OPEN_TOCAPTURE_AMOUNT); $rolloverRefund = $payment->getAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::ROLLOVER_REFUND); - $refundAmountAvailable = $orderTotal - $openToCaptureAmount; - + $refundAmountAvailable = $orderTotal - $openToCaptureAmount; + if(number_format($amount - $orderTotal, 2, '.', '') == 0.00){ if($openToCaptureAmount != $orderTotal){ $amount = $amount - $openToCaptureAmount; $afterpayRefund = true; } - $afterpayVoid = true; + $afterpayVoid = true; } else { @@ -564,7 +564,7 @@ public function lastShipmentProcessRefund($payment, $amount) $afterpayVoid = true; } elseif($amount < $openToCaptureAmount){ - + $rolloverRefund = $rolloverRefund + $amount; $payment->setAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::ROLLOVER_REFUND, number_format($rolloverRefund, 2, '.', '')); $result['success'] = true; @@ -577,10 +577,10 @@ public function lastShipmentProcessRefund($payment, $amount) } } } - + $result['success'] = $this->afterpayProcessRefund($payment,$order,$amountToCapture,$afterpayRefund,$amount,$afterpayVoid,$orderId,$override); - } - + } + return $result; } /** @@ -598,7 +598,7 @@ public function afterpayProcessRefund($payment,$order,$amountToCapture,$afterpay 'amount' => number_format($amountToCapture, 2, '.', ''), 'currency' => $order->getOrderCurrencyCode() ]; - + $captureResponse = $this->paymentCapture->send($totalAmount,$merchant_order_id,$orderId,$override); $captureResponse = $this->jsonHelper->jsonDecode($captureResponse->getBody()); @@ -612,36 +612,36 @@ public function afterpayProcessRefund($payment,$order,$amountToCapture,$afterpay else{ $this->helper->debug("Transaction Exception : " . json_encode($captureResponse)); throw new \Magento\Framework\Exception\LocalizedException(__('Afterpay API Error: ' .$captureResponse['message'])); - } + } } //Refund reqest if($afterpayRefund && $amount > 0){ - + $refundResponse = $this->afterpayApiPayment->refund(number_format($amount, 2, '.', ''),$orderId,$order->getOrderCurrencyCode(),$override); $refundResponse = $this->jsonHelper->jsonDecode($refundResponse->getBody()); if (!empty($refundResponse['refundId'])) { $success = true; - + } else { $this->helper->debug('Afterpay API Error: ' . $refundResponse['message']); throw new \Magento\Framework\Exception\LocalizedException(__('Afterpay API Error: ' .$refundResponse['message'])); } } - + if($afterpayVoid){ //Void request $voidResponse = $this->afterpayApiPayment->voidOrder($orderId,$override); $voidResponse = $this->jsonHelper->jsonDecode($voidResponse->getBody()); - + if(!array_key_exists("errorCode",$voidResponse)) { $payment->setAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::PAYMENT_STATUS, $voidResponse['paymentState']); - + if(array_key_exists('openToCaptureAmount',$voidResponse) && !empty($voidResponse['openToCaptureAmount'])){ $payment->setAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::OPEN_TOCAPTURE_AMOUNT,$voidResponse['openToCaptureAmount']['amount']); } - + if($payment->getAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::ROLLOVER_REFUND) > 0){ $payment->setAdditionalInformation(\Afterpay\Afterpay\Model\Payovertime::ROLLOVER_REFUND, "0.00"); } @@ -667,10 +667,10 @@ public function calculateItemPrice($item,$qty){ $totalQtyOrdered = $item->getQtyOrdered(); $totalTaxAmount = $item->getBaseTaxAmount(); $totalDiscount = $item->getDiscountAmount(); - + $taxPerItem = $totalTaxAmount/$totalQtyOrdered; $discountPerItem = $totalDiscount / $totalQtyOrdered; - + $pricePerItem = $item->getPrice() + $taxPerItem; $itemPrice = $qty * ($pricePerItem - $discountPerItem); return $itemPrice; diff --git a/Plugin/Checkout/CustomerData/Cart.php b/Plugin/Checkout/CustomerData/Cart.php new file mode 100644 index 0000000..9d95fce --- /dev/null +++ b/Plugin/Checkout/CustomerData/Cart.php @@ -0,0 +1,39 @@ +_configPayovertime = $configPayovertime; + } + + public function aroundGetItemData( + \Magento\Checkout\CustomerData\AbstractItem $subject, + \Closure $proceed, + \Magento\Quote\Model\Quote\Item $item + ) { + $data = $proceed($item); + $result['is_virtual'] = $item->getProduct()->getIsVirtual(); + $result['afterpay_restricted'] = false; + $excluded_categories = $this->_configPayovertime->getExcludedCategories(); + + if($excluded_categories !="") { + $excluded_categories_array = explode(",",$excluded_categories); + foreach($item->getProduct()->getCategoryIds() as $k) + { + if(in_array($k,$excluded_categories_array)){ + $result['afterpay_restricted'] = true; + } + } + } + return \array_merge( + $result, + $data + ); + } +} diff --git a/composer.json b/composer.json index 4fb0618..d93902c 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.1", + "version" : "3.4.2", "authors" : [{ "name" : "Afterpay", "homepage" : "https://www.afterpay.com" @@ -17,4 +17,4 @@ "Afterpay\\Afterpay\\" : "" } } -} \ No newline at end of file +} diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 371f878..3d4579a 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -19,12 +19,12 @@ - + Afterpay\Afterpay\Block\Adminhtml\System\Config\Form\Field\Label - + @@ -129,26 +129,23 @@ - - + + Magento\Config\Model\Config\Source\Yesno payment/afterpaypayovertime/enable_for_product_page + Show/Hide Afterpay installments message on Product Display page + - + - - - Afterpay\Afterpay\Model\Config\Source\CartMode + + + Magento\Config\Model\Config\Source\Yesno payment/afterpaypayovertime/enable_for_cart_page - - - - - - payment/afterpaypayovertime/express_checkout_key + Show/Hide Afterpay installments message on Cart page - + Afterpay\Afterpay\Model\Source\PaymentFlow @@ -156,8 +153,30 @@ here]]> - - + + + + + + Magento\Config\Model\Config\Source\Yesno + payment/afterpaypayovertime/express_checkout_product_page + + + + + + Magento\Config\Model\Config\Source\Yesno + payment/afterpaypayovertime/express_checkout_cart_page + + + + + + Magento\Config\Model\Config\Source\Yesno + payment/afterpaypayovertime/express_checkout_minicart_page + + + @@ -176,4 +195,4 @@ - \ No newline at end of file + diff --git a/etc/config.xml b/etc/config.xml index 6941484..3027d5e 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -21,8 +21,11 @@ AU 0 1 - 1 + 1 + 0 + 0 + 0 - \ No newline at end of file + diff --git a/etc/frontend/di.xml b/etc/frontend/di.xml index 31291b6..3b2e2d8 100644 --- a/etc/frontend/di.xml +++ b/etc/frontend/di.xml @@ -15,4 +15,7 @@ + + + diff --git a/etc/module.xml b/etc/module.xml index 4097b36..3d86b41 100644 --- a/etc/module.xml +++ b/etc/module.xml @@ -8,7 +8,7 @@ */ --> - + diff --git a/view/frontend/layout/catalog_product_view.xml b/view/frontend/layout/catalog_product_view.xml index 33fbbe2..6693438 100644 --- a/view/frontend/layout/catalog_product_view.xml +++ b/view/frontend/layout/catalog_product_view.xml @@ -8,13 +8,9 @@ */ --> - - - - - + - \ No newline at end of file + diff --git a/view/frontend/layout/checkout_cart_index.xml b/view/frontend/layout/checkout_cart_index.xml index dbd94a5..df06027 100644 --- a/view/frontend/layout/checkout_cart_index.xml +++ b/view/frontend/layout/checkout_cart_index.xml @@ -8,10 +8,6 @@ */ --> - - - - @@ -20,4 +16,4 @@ - + \ No newline at end of file diff --git a/view/frontend/layout/checkout_index_index.xml b/view/frontend/layout/checkout_index_index.xml index 69b1bad..676a710 100644 --- a/view/frontend/layout/checkout_index_index.xml +++ b/view/frontend/layout/checkout_index_index.xml @@ -8,10 +8,7 @@ */ --> - - - - + @@ -53,5 +50,6 @@ + - \ No newline at end of file + diff --git a/view/frontend/layout/default.xml b/view/frontend/layout/default.xml new file mode 100644 index 0000000..0359dec --- /dev/null +++ b/view/frontend/layout/default.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + diff --git a/view/frontend/templates/afterpay/cart.phtml b/view/frontend/templates/afterpay/cart.phtml index 0f91c47..f39cd79 100644 --- a/view/frontend/templates/afterpay/cart.phtml +++ b/view/frontend/templates/afterpay/cart.phtml @@ -3,11 +3,12 @@ * Magento 2 extensions for Afterpay Payment * * @author Afterpay - * @copyright 2016-2020 Afterpay https://www.afterpay.com + * @copyright 2016-2021 Afterpay https://www.afterpay.com */ +/** @var Afterpay\Afterpay\Block\Cart\Button $block*/ $cartDisplayMode = (int) $block->isDisplayOnCartPage(); $data_amount = $block->getFinalAmount(); -if ($block->isPaymentMethodActive() && $cartDisplayMode != \Afterpay\Afterpay\Model\Config\Source\CartMode::DISABLED && $block->canUseCurrency() && $data_amount>0) { +if ($block->isPaymentMethodActive() && $block->canUseCurrency() && $data_amount>0) { $afterpay_eligible = "true"; if (($block->canShow() === false)) { $afterpay_eligible = "false"; @@ -19,19 +20,23 @@ if ($block->isPaymentMethodActive() && $cartDisplayMode != \Afterpay\Afterpay\Mo if ((float) $min_limit < 1) { $show_lower_limit = "false"; } + + if($cartDisplayMode != \Afterpay\Afterpay\Model\Config\Source\CartMode::DISABLED){ + if(!$block->isDisplayECOnMiniCart()){ ?> - getCurrentCurrency(); $data_locale = $block->getCurrentLocale(); - + $enable_cbt = $this->helper('Afterpay\Afterpay\Helper\Data')->getConfig('payment/afterpaypayovertime/enable_cbt'); $data_enable_cbt = ! empty($enable_cbt) ? "true" : "false"; ?> -isPaymentMethodActive() && $cartDisplayMode != \Afterpay\Afterpay\Mo data-show-lower-limit="" data-cart-is-eligible="" data-intro-text="Pay in"> + + = $min_limit && $data_amount <= $max_limit && $afterpay_eligible != "false" ) { - if ($cartDisplayMode == \Afterpay\Afterpay\Model\Config\Source\CartMode::EXPRESS_CHECKOUT) { + if ($cartDisplayMode == \Afterpay\Afterpay\Model\Config\Source\CartMode::EXPRESS_CHECKOUT || $block->isDisplayEConCartPage() ) { ?> - - + + + + + + + diff --git a/view/frontend/templates/afterpay/product.phtml b/view/frontend/templates/afterpay/product.phtml index 110c0f8..0249d3b 100644 --- a/view/frontend/templates/afterpay/product.phtml +++ b/view/frontend/templates/afterpay/product.phtml @@ -3,40 +3,86 @@ * Magento 2 extensions for Afterpay Payment * * @author Afterpay - * @copyright 2016-2020 Afterpay https://www.afterpay.com + * @copyright 2016-2021 Afterpay https://www.afterpay.com */ -/** @var \Afterpay\Afterpay\Block\Catalog\Installments $block */ +/** @var Afterpay\Afterpay\Block\Catalog\Installments $block */ + $product_type = $block->getTypeOfProduct(); $data_amount = $block->getFinalAmount(); -if($block->isPaymentMethodActive() && $block->isDisplayOnProductPage() && $product_type != "grouped" && $block->canUseCurrency() && $data_amount>0){ + +if ($block->isPaymentMethodActive() && $product_type != "grouped" && $block->canUseCurrency() && $data_amount > 0) { $afterpay_eligible = "true"; if (($block->canShow() === false)) { $afterpay_eligible = "false"; } - $min_limit=$block->getMinOrderLimit(); - $show_lower_limit="true"; - if((float)$min_limit<1){ - $show_lower_limit="false"; + $min_limit = $block->getMinOrderLimit(); + $show_lower_limit = "true"; + if ((float)$min_limit < 1) { + $show_lower_limit = "false"; } - ?> - - getCurrentCurrency(); - $data_locale = $block->getCurrentLocale(); + $max_limit = $block->getMaxOrderLimit(); + $productPriceFormat = $this->helper('Magento\Tax\Helper\Data')->getPriceFormat($block->getStore()); + $priceFormat = $block->getJsonDecode($productPriceFormat); + $isECenabled=$block->isDisplayEConProductPage(); + $isDisplay=(int)$block->isDisplayOnProductPage(); + if (!$block->isDisplayECOnMiniCart()) { + ?> + + isDisplayOnProductPage()) { ?> + + getCurrentCurrency(); + $data_locale = $block->getCurrentLocale(); + + $enable_cbt = $this->helper('Afterpay\Afterpay\Helper\Data')->getConfig('payment/afterpaypayovertime/enable_cbt'); + $data_enable_cbt = !empty($enable_cbt) ? "true" : "false"; + ?> + " + data-thousands-separator=""> - $enable_cbt = $this->helper('Afterpay\Afterpay\Helper\Data')->getConfig('payment/afterpaypayovertime/enable_cbt'); - $data_enable_cbt = ! empty($enable_cbt) ? "true" : "false"; + - - + + isDisplayEConProductPage() && $afterpay_eligible != "false") { ?> + + + + diff --git a/view/frontend/web/css/afterpay.css b/view/frontend/web/css/afterpay.css index cca9a56..24efb04 100644 --- a/view/frontend/web/css/afterpay.css +++ b/view/frontend/web/css/afterpay.css @@ -145,7 +145,7 @@ color: #ffffff; cursor: pointer; display: inline-block; - + } .afterpay.primary:focus, .afterpay.primary:active, @@ -163,10 +163,19 @@ fieldset[disabled] .afterpay.primary { pointer-events: none; } -.checkout-methods-items button.express-button { +button.express-button { float:none; width: 267px; max-width: 100%; margin-top: 10px; cursor: pointer; -} \ No newline at end of file +} + +button.afterpay.minicart.express-button { + float:none; + width: 100%; + max-width: 100%; + margin-top: 10px; + cursor: pointer; + text-align:center; +} diff --git a/view/frontend/web/js/view/cart/afterpay-cart.js b/view/frontend/web/js/view/cart/afterpay-cart.js index 40e7f11..18ea66d 100644 --- a/view/frontend/web/js/view/cart/afterpay-cart.js +++ b/view/frontend/web/js/view/cart/afterpay-cart.js @@ -3,101 +3,17 @@ * See COPYING.txt for license details. */ require( - [ - "jquery", - "Magento_Catalog/js/price-utils", - "Magento_Checkout/js/model/quote", - 'mage/url', - 'Magento_Customer/js/customer-data' - ], - function ( $, priceUtils, quote,mageUrl,customerData) { - // Afterpay Express Checkout - function initAfterpayExpress() { + [ + "jquery", + "Magento_Checkout/js/model/quote" + ], + function ( $, quote) { - var afterpayData = window.checkoutConfig.payment.afterpay; + $(".cart-totals").bind("DOMSubtreeModified", function() { + var totals = quote.getTotals()(); + const epsilon = Number.EPSILON || Math.pow(2, -52); + $('afterpay-placement').attr('data-amount',(Math.round((parseFloat(totals['base_grand_total']) + epsilon) * 100) / 100).toFixed(2)); - //CountryCode Object to pass in initialize function. - var countryCurrencyMapping ={AUD:"AU", NZD:"NZ", USD:"US",CAD:"CA"}; - var countryCode = (afterpayData.baseCurrencyCode in countryCurrencyMapping)? countryCurrencyMapping[afterpayData.baseCurrencyCode]:''; - var isShippingRequired= (!quote.isVirtual())?true:false; - if( $("#afterpay-express-button").length && countryCode!=""){ - AfterPay.initializeForPopup({ - countryCode: countryCode, // fetch - shippingOptionRequired: isShippingRequired, //fetch for virtual type - buyNow: true, - target: '#afterpay-express-button', - onCommenceCheckout: function(actions){ - $.ajax({ - url: mageUrl.build("afterpay/payment/express")+'?action=start', - success: function(data){ - if (!data.success) { - actions.reject(data.message); - } else { - actions.resolve(data.token); - } - } - }); - }, - onShippingAddressChange: function (shippingData, actions) { - $.ajax({ - url: mageUrl.build("afterpay/payment/express")+'?action=change', - method: 'POST', - data: shippingData, - success: function(options){ - if (options.hasOwnProperty('error')) { - actions.reject(AfterPay.constants.SERVICE_UNAVAILABLE, options.message); - } else { - actions.resolve(options.shippingOptions); - } - } - }); + }); - }, - onComplete: function (orderData) { - - 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) { - //To Clear mini-cart - var sections = ['cart']; - customerData.invalidate(sections); - customerData.reload(sections, true); - - window.location.href = mageUrl.build("checkout/onepage/success"); - } - }, - complete: function(){ - $("body").trigger('processStop'); - } - }); - } - - - }, - pickup: false, - }); - - } - } - - $(document).ready(function() { - initAfterpayExpress(); - }); - - $(".cart-totals").bind("DOMSubtreeModified", function() { - var totals = quote.getTotals()(); - const epsilon = Number.EPSILON || Math.pow(2, -52); - $('afterpay-placement').attr('data-amount',(Math.round((parseFloat(totals['base_grand_total']) + epsilon) * 100) / 100).toFixed(2)); - - }); - -}); + }); diff --git a/view/frontend/web/js/view/cart/afterpay-minicart.js b/view/frontend/web/js/view/cart/afterpay-minicart.js new file mode 100644 index 0000000..83ebc66 --- /dev/null +++ b/view/frontend/web/js/view/cart/afterpay-minicart.js @@ -0,0 +1,44 @@ +/** + * Copyright © 2016 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +define( + [ + "jquery", + "Magento_Catalog/js/price-utils", + 'mage/url', + 'Magento_Customer/js/customer-data' + ], + function ( $, priceUtils,mageUrl,customerData) { + return function (config){ + function canDispayExpress(){ + var minicart_subtotal = customerData.get('cart')().subtotalAmount; + + if (!isAfterpayRestricted() && parseFloat(minicart_subtotal) >= parseFloat(config.afterpayConfig.minLimit) && parseFloat(minicart_subtotal) <= parseFloat(config.afterpayConfig.maxLimit) && (config.afterpayConfig.paymentActive)) { + $('#afterpay-minicart-express-button').show(); + } else { + $('#afterpay-minicart-express-button').hide(); + } + } + + + function isAfterpayRestricted(){ + var cartItems = customerData.get('cart')().items; + var afterpayRestricted = false; + if(cartItems && cartItems.length > 0){ + $.each(cartItems,function(key,val){ + if(val.afterpay_restricted){ + afterpayRestricted = true; + return false; + } + }); + } + return afterpayRestricted; + } + $(document).ready(function() { + $('[data-block=\'minicart\']').on('contentUpdated', function () { + canDispayExpress(); + }); + }); + } + }); diff --git a/view/frontend/web/js/view/express/afterpay-express.js b/view/frontend/web/js/view/express/afterpay-express.js new file mode 100644 index 0000000..60609ff --- /dev/null +++ b/view/frontend/web/js/view/express/afterpay-express.js @@ -0,0 +1,167 @@ +/** + * Magento 2 extensions for Afterpay Payment + * + * @author Afterpay + * @copyright 2016-2021 Afterpay https://www.afterpay.com + */ +define( + [ + "jquery", + 'mage/url', + 'Magento_Customer/js/customer-data' + ], + function ( $, mageUrl,customerData) { + var expressCheckout= {}; + return function (config) { + + // Afterpay Express Checkout + function initAfterpayExpress() { + var afterpayData = config.afterpayConfig; + + //CountryCode Object to pass in initialize function. + var countryCurrencyMapping ={AUD:"AU", NZD:"NZ", USD:"US",CAD:"CA"}; + var countryCode = (afterpayData.baseCurrencyCode in countryCurrencyMapping)? countryCurrencyMapping[afterpayData.baseCurrencyCode]:''; + + if( $(".express-button").length && countryCode!=""){ + AfterPay.initializeForPopup({ + countryCode: countryCode, + buyNow: true, + shippingOptionRequired: true, + target: '.express-button', + onCommenceCheckout: function(actions){ + + if(expressCheckout.buttonType != 'undefined' && expressCheckout.buttonType == 'product-page'){ + if(isFormValid()) { + if(config.productType != "bundle"){ + $("#product_addtocart_form").submit(); + } + AfterPay.shippingOptionRequired = Boolean(!config.isProductVirtual); + + setTimeout(function () { + $.ajax({ + url: mageUrl.build("afterpay/payment/express") + '?action=start', + success: function (data) { + if (!data.success) { + actions.reject(AfterPay.constants.SERVICE_UNAVAILABLE); + } else { + actions.resolve(data.token); + } + } + }); + }, 5000); + }else { + AfterPay.close(); + actions.reject(AfterPay.constants.SERVICE_UNAVAILABLE); + + } + }else{ + if(expressCheckout.buttonType!="undefined"){ + switch(expressCheckout.buttonType) { + case "cart": + AfterPay.shippingOptionRequired = Boolean(!config.isCartVirtual); + break; + case "mini-cart": + AfterPay.shippingOptionRequired = isShippingRequired(); + break; + } + } + + $.ajax({ + url: mageUrl.build("afterpay/payment/express") + '?action=start', + success: function (data) { + if (!data.success) { + actions.reject(AfterPay.constants.SERVICE_UNAVAILABLE); + } else { + actions.resolve(data.token); + } + } + }); + } + + }, + onShippingAddressChange: function (shippingData, actions) { + $.ajax({ + url: mageUrl.build("afterpay/payment/express")+'?action=change', + method: 'POST', + data: shippingData, + success: function(options){ + if (options.hasOwnProperty('error')) { + actions.reject(AfterPay.constants.SERVICE_UNAVAILABLE); + } else { + actions.resolve(options.shippingOptions); + } + } + }); + + }, + onComplete: function (orderData) { + 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){ + if (result.success) { + //To Clear mini-cart + var sections = ['cart']; + customerData.invalidate(sections); + customerData.reload(sections, true); + window.location.href = mageUrl.build("checkout/onepage/success"); + } + else if(expressCheckout.buttonType != 'undefined' && expressCheckout.buttonType == 'product-page' && isFormValid()){ + window.location.href = window.checkout.shoppingCartUrl; + } + }, + complete: function(){ + $("body").trigger('processStop'); + } + }); + } + else if(expressCheckout.buttonType != 'undefined' && expressCheckout.buttonType == 'product-page' && isFormValid()){ + window.location.href = window.checkout.shoppingCartUrl; + $("body").trigger('processStop'); + } + }, + pickup: false, + }); + + } + } + //Validate Product form + function isFormValid(){ + if (!$('#product_addtocart_form').valid()) { + return false; + } + return true; + } + //Get isShippingRequired for mini-cart + function isShippingRequired(){ + var isShippingRequired = false; + var cartItems = customerData.get('cart')().items; + if(cartItems && cartItems.length > 0){ + $.each(cartItems,function(key,val){ + if(!val.is_virtual){ + isShippingRequired = true; + return false; + } + }); + } + return isShippingRequired; + } + + $(document).ready(function () { + + $(".express-button").on('click', function() { + if ($(this).is('[data-afterpay-entry-point]') && typeof AfterPay != 'undefined') { + expressCheckout.buttonType = $(this).data('afterpay-entry-point'); + } else { + expressCheckout.buttonType = 'product-page'; // set a default button type + } + }); + initAfterpayExpress(); + }); + } + }); 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 c19afa2..4231c7a 100644 --- a/view/frontend/web/js/view/payment/method-renderer/afterpaypayovertime.js +++ b/view/frontend/web/js/view/payment/method-renderer/afterpaypayovertime.js @@ -49,7 +49,7 @@ define( var total = quote.getCalculatedTotal(); var format = window.checkoutConfig.priceFormat.pattern var afterpay = window.checkoutConfig.payment.afterpay; - + storage.get(resourceUrlManager.getUrlForCartTotals(quote), false) .done( function (response) { @@ -60,8 +60,8 @@ define( $(".afterpay_instalments_amount").text(format.replace(/%s/g, installmentFee.toFixed(window.checkoutConfig.priceFormat.precision))); $(".afterpay_instalments_amount_last").text(format.replace(/%s/g, installmentFeeLast.toFixed(window.checkoutConfig.priceFormat.precision))); - - + + if (afterpay.currencyCode == 'USD' || afterpay.currencyCode == 'CAD' ) { $(".afterpay_total_amount").text(format.replace(/%s/g, installmentFee.toFixed(window.checkoutConfig.priceFormat.precision))); return format.replace(/%s/g, installmentFee); @@ -69,7 +69,7 @@ define( $(".afterpay_total_amount").text(format.replace(/%s/g, amount.toFixed(window.checkoutConfig.priceFormat.precision))); return format.replace(/%s/g, amount); } - + } ) .fail( @@ -97,16 +97,16 @@ define( afterpayCheckoutText = '4 interest-free instalments of'; break; default: - afterpayCheckoutText = 'Four interest-free payments totalling'; + afterpayCheckoutText = 'Four interest-free payments totalling'; } - + return afterpayCheckoutText; - }, + }, getFirstInstalmentText: function () { var afterpay = window.checkoutConfig.payment.afterpay; var afterpayFirstInstalmentText = ''; - + switch(afterpay.currencyCode){ case 'USD': case 'CAD': @@ -114,26 +114,26 @@ define( break; default: afterpayFirstInstalmentText = 'First instalment'; - + } - - + + return afterpayFirstInstalmentText; }, getTermsText: function () { var afterpay = window.checkoutConfig.payment.afterpay; var afterpayTermsText = ''; - + switch(afterpay.currencyCode){ case 'USD': case 'CAD': afterpayTermsText = 'You will be redirected to the Afterpay website to fill out your payment information. You will be redirected back to our site to complete your order.'; break; - default: + default: afterpayTermsText = 'You will be redirected to the Afterpay website when you proceed to checkout.'; } - + return afterpayTermsText; }, getTermsLink: function () { @@ -150,7 +150,7 @@ define( default: afterpayCheckoutTermsLink="https://www.afterpay.com/terms/"; } - + return afterpayCheckoutTermsLink; }, @@ -182,14 +182,15 @@ define( var data = $("#co-shipping-form").serialize(); var email = window.checkoutConfig.customerData.email; var ajaxRedirected = false; - + //CountryCode Object to pass in initialize function. var countryCurrencyMapping ={AUD:"AU", NZD:"NZ", USD:"US",CAD:"CA"}; var countryCode = (afterpay.baseCurrencyCode in countryCurrencyMapping)? {countryCode: countryCurrencyMapping[afterpay.baseCurrencyCode]}:{}; - + //Update billing address of the quote - setBillingAddressAction(globalMessageList); + const setBillingAddressActionResult = setBillingAddressAction(globalMessageList); + setBillingAddressActionResult.done(function () { //handle guest and registering customer emails if (!window.checkoutConfig.quoteData.customer_id) { email = document.getElementById("customer-email").value; @@ -246,6 +247,9 @@ define( customerData.invalidate(['cart']); $('body').trigger('processStop'); }); + }).fail(function () { + window.scrollTo({top: 0, behavior: 'smooth'}); + }); } }, @@ -255,16 +259,16 @@ define( * @param response */ afterPlaceOrder: function () { - + // start afterpay payment is here var afterpay = window.checkoutConfig.payment.afterpay; // Making sure it using current flow var url = mageUrl.build("afterpay/payment/process"); - + //Update billing address of the quote setBillingAddressAction(globalMessageList); - + $.ajax({ url: url, method:'post', diff --git a/view/frontend/web/js/view/product/afterpay-products.js b/view/frontend/web/js/view/product/afterpay-products.js index 09ef4d4..82f4f50 100644 --- a/view/frontend/web/js/view/product/afterpay-products.js +++ b/view/frontend/web/js/view/product/afterpay-products.js @@ -2,35 +2,72 @@ * Copyright © 2016 Magento. All rights reserved. * See COPYING.txt for license details. */ -require( - [ - "jquery", - "Magento_Catalog/js/price-utils" - ], - function ( $, priceUtils, quote ) { +define( + [ + "jquery", + "Magento_Catalog/js/price-utils", + 'mage/url', + 'Magento_Customer/js/customer-data' + ], + function ( $, priceUtils, mageUrl,customerData) { - $(document).ready(function($) { - setFinalAmount(); + return function (config) { - $('body').on('click change', $('form#product_addtocart_form'), function (e) { - setFinalAmount(); - }); - $('body').on('input', $('form#product_addtocart_form select'), function (e) { - setTimeout(function() { - $('form#product_addtocart_form').trigger('change'); - }, 3); - }); - }); + $(document).ready(function ($) { - function setFinalAmount(){ + setFinalAmount(); - 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(); + $('body').on('click change', $('form#product_addtocart_form'), function (e) { + setFinalAmount(); + }); + $('body').on('input', $('form#product_addtocart_form select'), function (e) { + setTimeout(function () { + $('form#product_addtocart_form').trigger('change'); + }, 3); + }); - $('afterpay-placement').attr('data-amount',price_raw); - } + }); - } -); + function setFinalAmount() { + + 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(); + + // Show Express Checkout button + + var newPrice=price_raw.match(/[\d\.\,]+/g); + var price =price_to_number(newPrice[0],config.productPriceFormat.decimalSymbol,config.productPriceFormat.groupSymbol); + if(config.isDisplay==1) { + const epsilon = Number.EPSILON || Math.pow(2, -52); + $('afterpay-placement').attr('data-amount', (Math.round((parseFloat(price) + epsilon) * 100) / 100).toFixed(2)); + } + if(config.isECenabled==1) { + if ((config.afterpayConfig.paymentActive == true && price <= config.afterpayConfig.maxLimit && price >= config.afterpayConfig.minLimit && price > 0)) { + + $("#afterpay-pdp-express-button").show(); + } else { + $("#afterpay-pdp-express-button").hide(); + } + } + + + } + + //Function to convert currency to number + function price_to_number(amount,decimalSymbol,groupSymbol){ + if(!amount){return 0;} + if(decimalSymbol=="," && groupSymbol=="."){ + //Eg. 10.000.500,61 => price_to_number => 10000500.61 + amount=amount.split('.').join(''); + amount=amount.split(',').join('.'); + }else { + //Eg. 10,000,500.61 => price_to_number => 10000500.61 + amount = amount.split(',').join(''); + } + return Number(amount.replace(/[^0-9.]/g, "")); + } + }; + } +);