diff --git a/Block/Callback/Redirect.php b/Block/Callback/Redirect.php index ff8c9643..aaaafa32 100755 --- a/Block/Callback/Redirect.php +++ b/Block/Callback/Redirect.php @@ -15,5 +15,6 @@ class Redirect extends Template { protected function _prepareLayout() { + return $this; } } diff --git a/Block/Callback/Verify.php b/Block/Callback/Verify.php index 6b7e560c..3dfdf10e 100755 --- a/Block/Callback/Verify.php +++ b/Block/Callback/Verify.php @@ -16,5 +16,7 @@ class Verify extends Template protected function _prepareLayout() { $this->setMessage(__('OKAY')); + + return $this; } } diff --git a/Block/System/Config/Button.php b/Block/System/Config/Button.php new file mode 100644 index 00000000..4c430255 --- /dev/null +++ b/Block/System/Config/Button.php @@ -0,0 +1,78 @@ +request = $request; + } + + /** + * @param AbstractElement $element + * + * @return mixed + */ + protected function _getElementHtml(AbstractElement $element) + { + return $this->_toHtml(); + } + + /** + * @return string + */ + public function getCustomUrl() + { + return $this->getUrl('sdmaltapay/system_config/button'); + } + + /** + * @return string + */ + public function getButtonHtml() + { + $button = $this->getLayout()->createBlock( + 'Magento\Backend\Block\Widget\Button' + )->setData( + [ + 'id' => 'sync_button', + 'label' => __('Synchronize Terminals') + ] + ); + + return $button->toHtml(); + } + + /** + * @return int + */ + public function getUrlInterfaceData() + { + $request = $this->_request; + + return (int) $request->getParam('store', 0); + } +} \ No newline at end of file diff --git a/Block/System/Config/ChangeOrderStatusButton.php b/Block/System/Config/ChangeOrderStatusButton.php new file mode 100644 index 00000000..a24a0cb8 --- /dev/null +++ b/Block/System/Config/ChangeOrderStatusButton.php @@ -0,0 +1,78 @@ +request = $request; + } + + /** + * @param AbstractElement $element + * + * @return mixed + */ + protected function _getElementHtml(AbstractElement $element) + { + return $this->_toHtml(); + } + + /** + * @return string + */ + public function getCustomUrl() + { + return $this->getUrl('sdmaltapay/system_config/changeorderstatusbutton'); + } + + /** + * @return string + */ + public function getButtonHtml() + { + $button = $this->getLayout()->createBlock( + 'Magento\Backend\Block\Widget\Button' + )->setData( + [ + 'id' => 'change_order_status', + 'label' => __('Change Status Now') + ] + ); + + return $button->toHtml(); + } + + /** + * @return int + */ + public function getUrlInterfaceData() + { + $request = $this->_request; + + return (int) $request->getParam('store', 0); + } +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index d9019b2b..93874cc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,32 @@ # Changelog All notable changes to this project will be documented in this file. +## [3.0.0] +**Improvements** +- Add support when cart and catalog rules are applied simultaneously +- Make text "No saved credit cards" translatable +- Add a button to trigger the sync of the terminals with the gateway +- Add configurations section to setup cron scheduler to change the status of the pending order to cancel +- Add support for Apple Pay +- Support multiple logos/icons option for terminals. + +**Fixes** +- Cancel order issues when there is no transaction +- Order failing issue when applying a fixed discount on the cart +- Product stock not updating when order status change from cancel to processing +- Saved credit cards grid styling for mobile view +- Success page rendering issue when placing an order in incognito mode with the MobilePay +- Cancel order if payment_status is "released" in notification callback +- Handle empty synch button response +- Stock quantity calculation issue +- Canceled order qty from item grid is missing +- Order status set to "closed" despite the orders being in a pre-auth state. +- Order status set to "closed" for "Vipps" payment method +- Incorrect discount calculation +- Support tax exclusive configurations +- Order status set to "pending" on "incomplete" response +- Release stock qty on order cancellation + ## [2.0.5] **Fixes** - Resolve compilation issue for Magento 2.1.9 and below diff --git a/Controller/Adminhtml/System/Config/Button.php b/Controller/Adminhtml/System/Config/Button.php new file mode 100644 index 00000000..e5dbaaa2 --- /dev/null +++ b/Controller/Adminhtml/System/Config/Button.php @@ -0,0 +1,295 @@ +resultJsonFactory = $resultJsonFactory; + $this->systemConfig = $systemConfig; + $this->resourceConfig = $resourceConfig; + $this->storeConfig = $storeConfig; + $this->_response = $response; + $this->cacheTypeList = $cacheTypeList; + $this->storeManager = $storeManager; + $this->_state = $state; + $this->_resource = $resource; + parent::__construct($context); + } + + /** + * @return Json + */ + public function execute() + { + + $currentStoreID = (int)$this->getRequest()->getParam('storeid'); + if ($currentStoreID == 0) { + $scopeCode = ScopeConfigInterface::SCOPE_TYPE_DEFAULT; + } else { + $scopeCode = ScopeInterface::SCOPE_STORES; + } + $currentCurrency = $this->storeConfig->getValue( + self::COUNTRY_CODE_PATH, + $scopeCode, + $currentStoreID + ); + + try { + $call = new Terminals($this->systemConfig->getAuth()); + /** @var TerminalsResponse $response */ + $response = $call->call(); + $terminalList = $this->getTerminal($response, $currentCurrency); + + if (!empty($terminalList) && count($terminalList) <= 5) { + if ($this->checkConfigAlreadyExist($terminalList, $scopeCode, $currentStoreID)) { + $message = __('Terminals are already configured, please check the dropdown manually.'); + } else { + $this->saveTerminalConfig($terminalList, $currentStoreID, $scopeCode); + $this->cacheTypeList->cleanType(cacheConfig::TYPE_IDENTIFIER); + $message = __('Terminals successfully configured!'); + } + } else { + $message = __('We could not match terminals to this store. Too many terminals exist, please check the dropdown manually.'); + } + + } catch (ClientException $e) { + $message = __("Error:" . $e->getMessage()); + } catch (Exception $e) { + $message = __("Error:" . $e->getMessage()); + } + + /** @var Json $result */ + $result = $this->resultJsonFactory->create(); + + return $result->setData(['message' => $message]); + } + + /** + * @param $response array + * @param $currentCurrency string + * + * @return array + */ + public function getTerminal($response, $currentCurrency) + { + $terminals = []; + foreach ($response->Terminals as $terminal) { + if ($terminal->Country == $currentCurrency) { + $terminals[] = $terminal->Title; + } + } + + return $terminals; + } + + /** + * @param $terminals array + * @param $currentStoreID int + * @param $scopeCode string + */ + public function saveTerminalConfig($terminals, $currentStoreID, $scopeCode) + { + $i = 1; + foreach ($terminals as $terminal) { + $this->resourceConfig->saveConfig( + 'payment/terminal' . $i . '/active', + 1, + $scopeCode, + $currentStoreID + ); + + $this->resourceConfig->saveConfig( + 'payment/terminal' . $i . '/title', + $terminal, + $scopeCode, + $currentStoreID + ); + + $this->resourceConfig->saveConfig( + 'payment/terminal' . $i . '/language', + null, + $scopeCode, + $currentStoreID + ); + + $this->resourceConfig->saveConfig( + 'payment/terminal' . $i . '/capture', + 0, + $scopeCode, + $currentStoreID + ); + + $this->resourceConfig->saveConfig( + 'payment/terminal' . $i . '/terminallogo', + '', + $scopeCode, + $currentStoreID + ); + + $this->resourceConfig->saveConfig( + 'payment/terminal' . $i . '/showlogoandtitle', + 0, + $scopeCode, + $currentStoreID + ); + + $this->resourceConfig->saveConfig( + 'payment/terminal' . $i . '/savecardtoken', + 0, + $scopeCode, + $currentStoreID + ); + + $this->resourceConfig->saveConfig( + 'payment/terminal' . $i . '/avscontrol', + 0, + $scopeCode, + $currentStoreID + ); + + $this->resourceConfig->saveConfig( + 'payment/terminal' . $i . '/enforceavs', + 0, + $scopeCode, + $currentStoreID + ); + + $this->resourceConfig->saveConfig( + 'payment/terminal' . $i . '/avs_acceptance', + 0, + $scopeCode, + $currentStoreID + ); + + $this->resourceConfig->saveConfig( + 'payment/terminal' . $i . '/sort_order', + 0, + $scopeCode, + $currentStoreID + ); + + $this->resourceConfig->saveConfig( + 'payment/terminal' . $i . '/terminalname', + $terminal, + $scopeCode, + $currentStoreID + ); + + $i++; + } + } + + /** + * @param $terminalList array + * @param $scopeCode string + * + * @return bool + */ + public function checkConfigAlreadyExist($terminalList, $scopeCode, $scopeID) + { + $i = 1; + $terminalConfigured = false; + $tableName = $this->_resource->getTableName('core_config_data'); + foreach ($terminalList as $terminal) { + //Initiate Connection + $connection = $this->_resource->getConnection(); + $path = 'payment/terminal' . $i . '/active'; + $scope = $scopeCode; + $scopeId = $scopeID; + $select = $connection->select() + ->from( + ['c' => $tableName], + ['config_id'] + ) + ->where( + "c.path = :path" + )->where( + "c.scope = :scope" + )->where( + "c.scope_id = :scope_id" + ); + $bind = ['path' => $path, 'scope' => $scope, 'scope_id' => $scopeId]; + + if ($connection->fetchOne($select, $bind)) { + $terminalConfigured = true; + break; + } + $i++; + } + + return $terminalConfigured; + } +} \ No newline at end of file diff --git a/Controller/Adminhtml/System/Config/ChangeOrderStatusButton.php b/Controller/Adminhtml/System/Config/ChangeOrderStatusButton.php new file mode 100644 index 00000000..ab8079f3 --- /dev/null +++ b/Controller/Adminhtml/System/Config/ChangeOrderStatusButton.php @@ -0,0 +1,119 @@ +logger = $logger; + $this->resultJsonFactory = $resultJsonFactory; + $this->orderRepository = $orderRepository; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->scopeConfig = $scopeConfig; + $this->orderCollection = $orderCollection; + parent::__construct($context); + } + + /** + * @return Json + */ + public function execute() + { + $completeStatus = 'canceled'; + try + { + $orderCollection = $this->orderCollection->create(); + $orderCollection->addAttributeToFilter('status','pending') + ->addAttributeToFilter('altapay_payment_form_url', ['neq' => 'NULL']); + + if (array_filter($orderCollection->getData())) { + foreach ($orderCollection as $order) { + $order = $this->orderRepository->get($order->getEntityId()); + $order->setStatus($completeStatus)->setState($completeStatus); + + $this->orderRepository->save($order); + } + + $message = __('Order status has been changed from pending to canceled'); + + } else { + $message = __('No order exist with pendng status'); + } + } catch (\Exception $e) + { + $message = __("Error:" . $e->getMessage()); + } + + /** @var Json $result */ + $result = $this->resultJsonFactory->create(); + + return $result->setData(['message' => $message]); + } +} \ No newline at end of file diff --git a/Controller/Customer/Index.php b/Controller/Customer/Index.php index 1d55fb2e..303a7250 100644 --- a/Controller/Customer/Index.php +++ b/Controller/Customer/Index.php @@ -38,6 +38,12 @@ public function __construct( parent::__construct($context); } + /** + * Dispatch request + * + * @return \Magento\Framework\Controller\ResultInterface|ResponseInterface|void + * @throws \Magento\Framework\Exception\NotFoundException + */ public function execute() { $action = $this->getRequest()->getParam('action'); @@ -80,7 +86,7 @@ public function execute() $model->setPrimary(0)->save(); } $response = ['status' => 'updated']; - } catch (Exception $e) { + } catch (\Exception $e) { $response = ['status' => 'error']; } } diff --git a/Controller/Index.php b/Controller/Index.php index 2da1466b..009ce687 100755 --- a/Controller/Index.php +++ b/Controller/Index.php @@ -17,6 +17,9 @@ use Magento\Sales\Model\Order; use Psr\Log\LoggerInterface; use SDM\Altapay\Model\Generator; +use Magento\Framework\Controller\Result\RedirectFactory; +use Magento\Framework\Encryption\EncryptorInterface; +use Magento\Framework\Math\Random; abstract class Index extends Action { @@ -69,7 +72,10 @@ public function __construct( Quote $quote, Session $checkoutSession, Generator $generator, - LoggerInterface $logger + LoggerInterface $logger, + EncryptorInterface $encryptor, + Random $random, + RedirectFactory $redirectFactory ) { parent::__construct($context); $this->order = $order; @@ -78,6 +84,9 @@ public function __construct( $this->generator = $generator; $this->logger = $logger; $this->pageFactory = $pageFactory; + $this->encryptor = $encryptor; + $this->random = $random; + $this->redirectFactory = $redirectFactory; } /** @@ -103,4 +112,25 @@ protected function writeLog() $this->logger->debug(print_r($this->getRequest()->getParams(), true)); $this->logger->debug('- END: ' . $calledClass); } + + /** + * @param string $orderId + * + * @return mixed + */ + protected function setSuccessPath($orderId) + { + $resultRedirect = $this->redirectFactory->create(); + if ($orderId) { + $order = $this->order->loadByIncrementId($orderId); + $uniqueHash = $this->random->getUniqueHash(); + $order->setAltapayOrderHash($uniqueHash); + $order->getResource()->save($order); + $resultRedirect->setPath('checkout/onepage/success',['success_token' => $uniqueHash]); + } else { + $resultRedirect->setPath('checkout/onepage/success'); + } + + return $resultRedirect; + } } diff --git a/Controller/Index/ApplePay.php b/Controller/Index/ApplePay.php new file mode 100644 index 00000000..9c0f577c --- /dev/null +++ b/Controller/Index/ApplePay.php @@ -0,0 +1,96 @@ +storeConfig = $storeConfig; + $this->systemConfig = $systemConfig; + $this->_storeManager = $storeManager; + $this->_urlInterface = $urlInterface; + } + + /** + * @return void + */ + public function execute() + { + $storeCode = $this->getStoreCode(); + $validationUrl = $this->getRequest()->getParam('validationUrl'); + $terminalName = $this->getRequest()->getParam('termminalid'); + $currentUrl = $this->_urlInterface->getBaseUrl(); + $domain = parse_url($currentUrl, PHP_URL_HOST); + $auth = $this->systemConfig->getAuth($storeCode); + $api = new TestAuthentication($auth); + $response = $api->call(); + if (!$response) { + return false; + } + $request = new CardWalletSession($auth); + $request->setTerminal($terminalName) + ->setValidationUrl($validationUrl) + ->setDomain($domain); + + $response = $request->call(); + if ($response->Result === 'Success') { + echo json_encode($response->ApplePaySession); + } + } + + /** + * Get Store code + * + * @return string + */ + public function getStoreCode() + { + return $this->_storeManager->getStore()->getCode(); + } +} \ No newline at end of file diff --git a/Controller/Index/ApplePayResponse.php b/Controller/Index/ApplePayResponse.php new file mode 100644 index 00000000..b0f490e2 --- /dev/null +++ b/Controller/Index/ApplePayResponse.php @@ -0,0 +1,80 @@ +_checkoutSession = $checkoutSession; + $this->gateway = $gateway; + $this->redirectFactory = $redirectFactory; + $this->order = $order; + $this->random = $random; + $this->_orderRepository = $orderRepository; + } + + public function execute() + { + $orderId = $this->_checkoutSession->getLastOrderId(); + if ($this->checkPost()) { + $params = $this->gateway->createRequestApplepay( + $this->getRequest()->getParam('paytype'), + $orderId, + $this->getRequest()->getParam('providerData') + ); + + echo json_encode($params); + } + } + + /** + * @return mixed + */ + public function checkPost() + { + return $this->getRequest()->isPost(); + } + +} \ No newline at end of file diff --git a/Controller/Index/Cancel.php b/Controller/Index/Cancel.php new file mode 100644 index 00000000..32b40340 --- /dev/null +++ b/Controller/Index/Cancel.php @@ -0,0 +1,63 @@ +_checkoutSession = $checkoutSession; + $this->order = $order; + $this->paymentHandler = $paymentHandler; + } + + /** + * @return void + */ + public function execute() + { + $orderId = $this->_checkoutSession->getLastOrderId(); + $order = $this->order->load($orderId); + $this->paymentHandler->setCustomOrderStatus($order, Order::STATE_CANCELED, 'cancel'); + $order->addStatusHistoryComment("ApplePay payment status - ". $order->getStatus()); + $order->setIsNotified(false); + $order->getResource()->save($order); + } +} \ No newline at end of file diff --git a/Controller/Index/Fail.php b/Controller/Index/Fail.php index ab8c293d..5b79e75e 100755 --- a/Controller/Index/Fail.php +++ b/Controller/Index/Fail.php @@ -60,6 +60,7 @@ public function execute() break; case "failed": case "error": + case "incomplete": $this->generator->handleFailedStatusAction($this->getRequest(), $msg, $merchantError, $status); break; default: @@ -69,7 +70,7 @@ public function execute() $msg = $e->getMessage(); } - if ($status == 'failed' || $status == 'error' || $status == 'cancelled') { + if ($status == 'failed' || $status == 'error' || $status == 'cancelled' || $status == 'incomplete') { $resultRedirect = $this->prepareRedirect('checkout/cart', [], $msg); } else { $resultRedirect = $this->prepareRedirect('checkout', ['_fragment' => 'payment'], $msg); diff --git a/Controller/Index/Notification.php b/Controller/Index/Notification.php index 73f53ff3..96611303 100755 --- a/Controller/Index/Notification.php +++ b/Controller/Index/Notification.php @@ -84,6 +84,7 @@ private function handleNotification($status, $msg, $merchantError) break; case "error": case "failed": + case "incomplete": $this->generator->handleFailedStatusAction($this->getRequest(), $msg, $merchantError, $status); break; case "succeeded": diff --git a/Controller/Index/Ok.php b/Controller/Index/Ok.php index ad635316..043a0f86 100755 --- a/Controller/Index/Ok.php +++ b/Controller/Index/Ok.php @@ -27,6 +27,7 @@ public function execute() $this->writeLog(); $checkAvs = false; $post = $this->getRequest()->getPostValue(); + $orderId = $post['shop_orderid']; if (isset($post['avs_code']) && isset($post['avs_text'])) { $checkAvs = $this->generator->avsCheck( $this->getRequest(), @@ -37,7 +38,7 @@ public function execute() if ($this->checkPost() && $checkAvs == false) { $this->generator->handleOkAction($this->getRequest()); - return $this->_redirect('checkout/onepage/success'); + return $this->setSuccessPath($orderId); } else { $this->_eventManager->dispatch('order_cancel_after', ['order' => $this->order]); diff --git a/Controller/Index/Request.php b/Controller/Index/Request.php index 4a320d73..a53e37fa 100755 --- a/Controller/Index/Request.php +++ b/Controller/Index/Request.php @@ -26,21 +26,18 @@ class Request extends Index */ public function execute() { - $this->writeLog(); + $this->writeLog(); + $result = new DataObject(); + $response = $this->getResponse(); if ($this->checkPost()) { $params = $this->generator->createRequest( $this->getRequest()->getParam('paytype'), $this->getRequest()->getParam('orderid') ); - - $result = new DataObject(); - $response = $this->getResponse(); $result->addData($params); - - return $response->representJson($result->toJson()); } - die('No post!?'); + return $response->representJson($result->toJson()); } } diff --git a/Helper/Data.php b/Helper/Data.php index a9bdc415..e5a961fe 100644 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -76,20 +76,21 @@ public function __construct( */ public function transactionDetail($orderId) { - $order = $this->order->load($orderId); + $versionDetails = []; + $order = $this->order->load($orderId); if ($order->getId()) { $storeName = $order->getStore()->getName(); $websiteName = $order->getStore()->getWebsite()->getName(); $moduleInfo = $this->moduleList->getOne(self::MODULE_CODE); - $versionDetails = []; $versionDetails['ecomPlatform'] = 'Magento'; $versionDetails['ecomVersion'] = $this->productMetadata->getVersion(); $versionDetails['ecomPluginName'] = $moduleInfo['name']; $versionDetails['ecomPluginVersion'] = $moduleInfo['setup_version']; $versionDetails['otherInfo'] = 'websiteName - ' . $websiteName . ', storeName - ' . $storeName; - return $versionDetails; } + + return $versionDetails; } /** diff --git a/Model/ApplePayOrder.php b/Model/ApplePayOrder.php new file mode 100644 index 00000000..483eaad1 --- /dev/null +++ b/Model/ApplePayOrder.php @@ -0,0 +1,254 @@ +checkoutSession = $checkoutSession; + $this->stockItem = $stockItem; + $this->stockRegistry = $stockRegistry; + $this->systemConfig = $systemConfig; + $this->order = $order; + $this->paymentHandler = $paymentHandler; + $this->transactionFactory = $transactionFactory; + } + + /** + * @param $comment + * @param RequestInterface $request + * + * @throws AlreadyExistsException + */ + public function handleCardWalletPayment($response, $order) + { + $max_date = ''; + $latestTransKey = ''; + foreach ($response->Transactions as $key=>$value) { + if ($value->CreatedDate > $max_date) { + $max_date = $value->CreatedDate; + $latestTransKey = $key; + } + } + if ($response && $response->Result === 'Success' && isset($response->Transactions[$latestTransKey])) { + $transaction = $response->Transactions[$latestTransKey]; + $paymentType = $transaction->AuthType; + $responseStatus = $transaction->TransactionStatus; + $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE; + $storeCode = $order->getStore()->getCode(); + if ($order->getId()) { + $cardType = ''; + $expires = ''; + //Update stock quantity + if($order->getState() == 'canceled') { + $this->updateStockQty($order); + } + $this->resetCanceledQty($order); + if (isset($transaction->CreditCardExpiry->Month) && isset($transaction->CreditCardExpiry->Year)) { + $expires = $transaction->CreditCardExpiry->Month . '/' . $transaction->CreditCardExpiry->Year; + } + if (isset($transaction->PaymentSchemeName)) { + $cardType = $transaction->PaymentSchemeName; + } + $payment = $order->getPayment(); + $payment->setPaymentId($transaction->PaymentId); + $payment->setLastTransId($transaction->TransactionId); + $payment->setCcTransId($transaction->CreditCardToken); + $payment->setAdditionalInformation('cc_token', $transaction->CreditCardToken); + $payment->setAdditionalInformation('expires', $expires); + $payment->setAdditionalInformation('card_type', $cardType); + $payment->setAdditionalInformation('payment_type', $paymentType); + $payment->save(); + //save transaction data + $parametersData = null; + $transactionData = json_encode($response); + $this->addTransactionData( + $order->getIncrementId(), + $transaction->TransactionId, + $transaction->PaymentId, + $transactionData, + $parametersData + ); + $orderStatusAfterPayment = $this->systemConfig->getStatusConfig('process', $storeScope, $storeCode); + $orderStatusCapture = $this->systemConfig->getStatusConfig('autocapture', $storeScope, $storeCode); + $setOrderStatus = true; + $orderState = Order::STATE_PROCESSING; + $statusKey = 'process'; + + if ($this->isCaptured($response, $storeCode, $storeScope, $latestTransKey) && $orderStatusCapture == "complete") { + if ($this->orderLines->sendShipment($order)) { + $orderState = Order::STATE_COMPLETE; + $statusKey = 'autocapture'; + $order->addStatusHistoryComment(__(ConstantConfig::PAYMENT_COMPLETE)); + } else { + $setOrderStatus = false; + $order->addStatusToHistory($orderStatusCapture, ConstantConfig::PAYMENT_COMPLETE, false); + } + } else { + if ($orderStatusAfterPayment) { + $orderState = $orderStatusAfterPayment; + } + } + if ($setOrderStatus) { + $this->paymentHandler->setCustomOrderStatus($order, $orderState, $statusKey); + } + $order->addStatusHistoryComment("ApplePay Status: ". $response->Result); + $order->setIsNotified(false); + $order->getResource()->save($order); + + } + } else { + $this->paymentHandler->setCustomOrderStatus($order, Order::STATE_CANCELED, 'cancel'); + $order->addStatusHistoryComment("Order status: ". $response->Result); + $order->setIsNotified(false); + $order->getResource()->save($order); + } + } + + public function sortFunction($a, $b) { + return strtotime($b["date"]) - strtotime($a["date"]); + } + + protected function updateStockQty($order) + { + $cart = $this->modelCart; + $quoteItems = $this->checkoutSession->getQuote()->getItemsCollection(); + foreach ($order->getAllItems() as $item) { + $stockQty = $this->stockItem->getStockQty($item->getProductId(), $item->getStore()->getWebsiteId()); + $qty = $stockQty - $item->getQtyOrdered(); + $stockItem = $this->stockRegistry->getStockItemBySku($item['sku']); + $stockItem->setQty($qty); + $stockItem->setIsInStock((bool)$qty); + $this->stockRegistry->updateStockItemBySku($item['sku'], $stockItem); + } + foreach($quoteItems as $item) + { + $cart->removeItem($item->getId())->save(); + } + } + + /** + * @param $order + * + * @return void + */ + public function resetCanceledQty($order) { + foreach ($order->getAllItems() as $item) { + if ($item->getQtyCanceled() > 0) { + $item->setQtyCanceled($item->getQtyToCancel()); + $item->save(); + } + } + } + /** + * @param $response + * @param $storeCode + * @param $storeScope + * + * @return bool|\Magento\Payment\Model\MethodInterface + */ + private function isCaptured($response, $storeCode, $storeScope, $latestTransKey) + { + $isCaptured = false; + foreach (SystemConfig::getTerminalCodes() as $terminalName) { + $terminalConfig = $this->systemConfig->getTerminalConfigFromTerminalName( + $terminalName, + 'terminalname', + $storeScope, + $storeCode + ); + if ($terminalConfig === $response->Transactions[$latestTransKey]->Terminal) { + $isCaptured = $this->systemConfig->getTerminalConfigFromTerminalName( + $terminalName, + 'capture', + $storeScope, + $storeCode + ); + break; + } + } + + return $isCaptured; + } + + /** + * It creates the entity and saves the JSON request. + * + * @param string $orderid + * @param string $transactionid + * @param string $paymentid + * @param string $transactiondata + * @param string $parametersdata + */ + public function addTransactionData($orderid, $transactionid, $paymentid, $transactiondata, $parametersdata) + { + /** @var Transaction $transaction */ + $transaction = $this->transactionFactory->create(); + $transaction->setOrderid($orderid); + $transaction->setTransactionid($transactionid); + $transaction->setPaymentid($paymentid); + $transaction->setTransactiondata($transactiondata); + $transaction->setParametersdata($parametersdata); + $transaction->getResource()->save($transaction); + } + +} \ No newline at end of file diff --git a/Model/Config/CronConfig.php b/Model/Config/CronConfig.php new file mode 100644 index 00000000..3ec8e061 --- /dev/null +++ b/Model/Config/CronConfig.php @@ -0,0 +1,117 @@ +_runModelPath = $runModelPath; + $this->_configValueFactory = $configValueFactory; + $this->scopeConfig = $scopeConfig; + parent::__construct($context, $registry, $scopeConfig, $cacheTypeList, $resource, $resourceCollection, $data); + } + + /** + * @return mixed + * @throws \Exception + */ + public function afterSave() + { + $time = $this->getData('groups/sdm_altapay_config/groups/cronScheduled/fields/time/value'); + $frequency = $this->getData('groups/sdm_altapay_config/groups/cronScheduled/fields/frequency/value'); + $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE; + $cronEnabled = $this->scopeConfig->getValue(self::CRON_ENABLED, $storeScope); + try + { + if($cronEnabled) { + $cronExprArray = [ + intval($time[1]), //Minute + intval($time[0]), //Hour + $frequency == \Magento\Cron\Model\Config\Source\Frequency::CRON_MONTHLY ? '1' : '*', + '*', + $frequency == \Magento\Cron\Model\Config\Source\Frequency::CRON_WEEKLY ? '1' : '*', + ]; + $cronExprString = join(' ', $cronExprArray); + + $this->_configValueFactory->create()->load( + self::CRON_STRING_PATH, + 'path' + )->setValue( + $cronExprString + )->setPath( + self::CRON_STRING_PATH + )->save(); + $this->_configValueFactory->create()->load( + self::CRON_MODEL_PATH, + 'path' + )->setValue( + $this->_runModelPath + )->setPath( + self::CRON_MODEL_PATH + )->save(); + } + } + catch (\Exception $e) + { + throw new \Exception(__('Something went wrong, Can\'t save the cron expression.')); + } + return parent::afterSave(); + } + } \ No newline at end of file diff --git a/Model/Config/Source/CronConfig.php b/Model/Config/Source/CronConfig.php new file mode 100644 index 00000000..3ec8e061 --- /dev/null +++ b/Model/Config/Source/CronConfig.php @@ -0,0 +1,117 @@ +_runModelPath = $runModelPath; + $this->_configValueFactory = $configValueFactory; + $this->scopeConfig = $scopeConfig; + parent::__construct($context, $registry, $scopeConfig, $cacheTypeList, $resource, $resourceCollection, $data); + } + + /** + * @return mixed + * @throws \Exception + */ + public function afterSave() + { + $time = $this->getData('groups/sdm_altapay_config/groups/cronScheduled/fields/time/value'); + $frequency = $this->getData('groups/sdm_altapay_config/groups/cronScheduled/fields/frequency/value'); + $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE; + $cronEnabled = $this->scopeConfig->getValue(self::CRON_ENABLED, $storeScope); + try + { + if($cronEnabled) { + $cronExprArray = [ + intval($time[1]), //Minute + intval($time[0]), //Hour + $frequency == \Magento\Cron\Model\Config\Source\Frequency::CRON_MONTHLY ? '1' : '*', + '*', + $frequency == \Magento\Cron\Model\Config\Source\Frequency::CRON_WEEKLY ? '1' : '*', + ]; + $cronExprString = join(' ', $cronExprArray); + + $this->_configValueFactory->create()->load( + self::CRON_STRING_PATH, + 'path' + )->setValue( + $cronExprString + )->setPath( + self::CRON_STRING_PATH + )->save(); + $this->_configValueFactory->create()->load( + self::CRON_MODEL_PATH, + 'path' + )->setValue( + $this->_runModelPath + )->setPath( + self::CRON_MODEL_PATH + )->save(); + } + } + catch (\Exception $e) + { + throw new \Exception(__('Something went wrong, Can\'t save the cron expression.')); + } + return parent::afterSave(); + } + } \ No newline at end of file diff --git a/Model/ConfigProvider.php b/Model/ConfigProvider.php index 7055a751..ec4fbddf 100755 --- a/Model/ConfigProvider.php +++ b/Model/ConfigProvider.php @@ -2,7 +2,7 @@ /** * Altapay Module for Magento 2.x. * - * Copyright © 2020 Altapay. All rights reserved. + * Copyright © 2018 Altapay. All rights reserved. * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ @@ -15,21 +15,24 @@ use Magento\Payment\Helper\Data; use Altapay\Api\Test\TestAuthentication; use Altapay\Api\Test\TestConnection; -use Magento\Store\Model\ScopeInterface; use SDM\Altapay\Model\SystemConfig; -use Altapay\Authentication; +use SDM\Altapay\Authentication; use Magento\Framework\App\Config\ScopeConfigInterface; use Magento\Payment\Model\Config; use Magento\Payment\Model\Config\Source\Allmethods; use Magento\Framework\View\Asset\Repository; use SDM\Altapay\Model\TokenFactory; use Magento\Customer\Model\Session; -use Magento\Payment\Model\MethodInterface; +use Magento\Checkout\Model\Session as CheckoutSession; +use Magento\Store\Model\StoreManagerInterface; class ConfigProvider implements ConfigProviderInterface { const CODE = 'sdm_altapay'; + protected $_checkoutSession; + + protected $_storeManager; /** * @var Data */ @@ -89,7 +92,9 @@ public function __construct( ScopeConfigInterface $scopeConfig, Repository $assetRepository, TokenFactory $dataToken, - Session $customerSession + Session $customerSession, + CheckoutSession $checkoutSession, + StoreManagerInterface $storeManager ) { $this->data = $data; $this->escaper = $escaper; @@ -100,6 +105,8 @@ public function __construct( $this->assetRepository = $assetRepository; $this->dataToken = $dataToken; $this->customerSession = $customerSession; + $this->_checkoutSession = $checkoutSession; + $this->_storeManager = $storeManager; } /** @@ -111,7 +118,12 @@ public function getConfig() { $store = null; $activePaymentMethod = $this->getActivePaymentMethod(); - + $getCurrentQuote = $this->_checkoutSession->getQuote(); + $config = []; + $baseUrl = $this->_storeManager->getStore()->getBaseUrl(); + $grandTotal = $getCurrentQuote->getGrandTotal(); + $countryCode = $this->scopeConfig->getValue('general/country/default', + \Magento\Store\Model\ScopeInterface::SCOPE_STORE); return [ 'payment' => [ self::CODE => [ @@ -120,7 +132,11 @@ public function getConfig() ), 'auth' => $this->checkAuth(), 'connection' => $this->checkConn(), - 'terminaldata' => $activePaymentMethod + 'terminaldata' => $activePaymentMethod, + 'grandTotalAmount' => $grandTotal, + 'countryCode' => $countryCode, + 'currencyCode' => $this->_storeManager->getStore()->getBaseCurrencyCode(), + 'baseUrl' => $baseUrl ] ] ]; @@ -128,7 +144,7 @@ public function getConfig() public function getActivePaymentMethod() { - $storeScope = ScopeInterface::SCOPE_STORE; + $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE; $storeCode = $this->systemConfig->resolveCurrentStoreCode(); $methods = []; $allPaymentMethod = $this->data->getPaymentMethods(); @@ -166,12 +182,15 @@ public function getActivePaymentMethod() $terminalStatus = $this->scopeConfig->getValue($paymentCode . '/active', $storeScope, $storeCode); $terminalLogo = $this->scopeConfig->getValue($paymentCode . '/terminallogo', $storeScope, $storeCode); if (!empty($terminalLogo)) { - $logoURL = $this->getLogoFilePath($terminalLogo); + $logoURL = $this->getLogoPath($terminalLogo); } else { $logoURL = ''; } $showBoth = $this->scopeConfig->getValue($paymentCode . '/showlogoandtitle', $storeScope, $storeCode); $saveCardToken = $this->scopeConfig->getValue($paymentCode . '/savecardtoken', $storeScope, $storeCode); + $isApplePay = $this->scopeConfig->getValue($paymentCode . '/isapplepay', $storeScope, $storeCode); + $applePayLabel = $this->scopeConfig->getValue($paymentCode . '/applepaylabel', $storeScope, $storeCode); + if ($terminalStatus == 1) { $methods[$key] = [ 'label' => $label, @@ -180,7 +199,9 @@ public function getActivePaymentMethod() 'terminalstatus' => $terminalStatus, 'terminallogo' => $logoURL, 'showlogoandtitle' => $showBoth, - 'enabledsavetokens' => $saveCardToken + 'enabledsavetokens' => $saveCardToken, + 'isapplepay' => $isApplePay, + 'applepaylabel' => $applePayLabel ]; if ($saveCardToken == 1 && !empty($savedTokenList)) { $methods[$key]['savedtokenlist'] = json_encode($savedTokenList); @@ -197,16 +218,18 @@ public function getActivePaymentMethod() * * @return mixed|null */ - public function getLogoFilePath($name) + public function getLogoPath($name) { - $fileId = 'SDM_Altapay::images/' . $name . '.png'; - $params = ['area' => 'frontend']; - $asset = $this->assetRepository->createAsset($fileId, $params); - try { - return $asset->getUrl(); - } catch (\Exception $e) { - return null; + $path = []; + $terminalLogo = explode(",",$name); + foreach ($terminalLogo as $logoName) { + $fileId = 'SDM_Altapay::images/' . $logoName . '.png'; + $params = ['area' => 'frontend']; + $asset = $this->assetRepository->createAsset($fileId, $params); + $path[] = $asset->getUrl(); } + + return $path; } public function checkAuth() @@ -242,7 +265,7 @@ public function checkConn() } /** - * @return MethodInterface + * @return \Magento\Payment\Model\MethodInterface */ protected function getData() { @@ -250,7 +273,7 @@ protected function getData() } /** - * @param array $collection + * @param $collection * * @return string */ @@ -267,4 +290,4 @@ private function ccTokenPrimaryOption($collection) return $primaryOptionId; } -} +} \ No newline at end of file diff --git a/Model/Cron/UpdateOrderStatus.php b/Model/Cron/UpdateOrderStatus.php new file mode 100644 index 00000000..b7d5784a --- /dev/null +++ b/Model/Cron/UpdateOrderStatus.php @@ -0,0 +1,107 @@ +logger = $logger; + $this->orderRepository = $orderRepository; + $this->searchCriteriaBuilder = $searchCriteriaBuilder; + $this->scopeConfig = $scopeConfig; + $this->orderCollection = $orderCollection; + } + + public function execute() + { + $completeStatus = 'canceled'; + $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE; + $cronEnabled = $this->scopeConfig->getValue(self::CRON_ENABLED, $storeScope); + try + { + if (!$cronEnabled){ + $this->logger->info('Cron is not enabled'); + return; + } + $orderCollection = $this->orderCollection->create(); + $orderCollection->addAttributeToFilter('status','pending') + ->addAttributeToFilter('altapay_payment_form_url', ['neq' => 'NULL']); + + if (array_filter($orderCollection->getData())) { + foreach ($orderCollection as $order) { + + $order = $this->orderRepository->get($order->getEntityId()); + $order->setStatus($completeStatus)->setState($completeStatus); + + $this->orderRepository->save($order); + } + + $this->logger->info('Order status has been changed from pending to canceled'); + } else { + + $this->logger->info('No order exist with pending status'); + } + } + catch (\Exception $e) + { + throw new \Exception(__('Something went wrong , '.$e->getMessage())); + } + } + +} \ No newline at end of file diff --git a/Model/Generator.php b/Model/Generator.php index 4513c58e..a0b13559 100755 --- a/Model/Generator.php +++ b/Model/Generator.php @@ -36,9 +36,15 @@ use SDM\Altapay\Model\Handler\DiscountHandler; use SDM\Altapay\Model\Handler\CreatePaymentHandler; use SDM\Altapay\Model\TokenFactory; +use SDM\Altapay\Model\ApplePayOrder; use Magento\Sales\Model\OrderFactory; use Altapay\Response\PaymentRequestResponse; +use Altapay\Api\Payments\CardWalletAuthorize; use Magento\Payment\Model\MethodInterface; +use Magento\Checkout\Model\Cart; +use Magento\CatalogInventory\Api\StockStateInterface; +use Magento\CatalogInventory\Api\StockRegistryInterface; +use Psr\Log\LoggerInterface; /** * Class Generator @@ -46,6 +52,10 @@ */ class Generator { + /** + * @var LoggerInterface + */ + protected $logger; /** * @var Helper Data */ @@ -118,6 +128,18 @@ class Generator * @var OrderFactory */ private $orderFactory; + /** + * @var StockStateInterface + */ + private $stockItem; + /** + * @var StockRegistryInterface + */ + private $stockRegistry; + /** + * @var Cart + */ + private $modelCart; /** * @@ -139,6 +161,9 @@ class Generator * @param DiscountHandler $discountHandler * @param CreatePaymentHandler $paymentHandler * @param TokenFactory $dataToken + * @param StockStateInterface $stockItem + * @param StockRegistryInterface $stockRegistry + * @param Cart $modelCart */ public function __construct( Quote $quote, @@ -158,7 +183,12 @@ public function __construct( PriceHandler $priceHandler, DiscountHandler $discountHandler, CreatePaymentHandler $paymentHandler, - TokenFactory $dataToken + TokenFactory $dataToken, + StockStateInterface $stockItem, + StockRegistryInterface $stockRegistry, + Cart $modelCart, + ApplePayOrder $applePayOrder, + LoggerInterface $logger ) { $this->quote = $quote; $this->urlInterface = $urlInterface; @@ -178,6 +208,11 @@ public function __construct( $this->discountHandler = $discountHandler; $this->paymentHandler = $paymentHandler; $this->dataToken = $dataToken; + $this->stockItem = $stockItem; + $this->stockRegistry = $stockRegistry; + $this->modelCart = $modelCart; + $this->applePayOrder = $applePayOrder; + $this->logger = $logger; } /** @@ -194,7 +229,7 @@ public function createRequest($terminalId, $orderId) if ($order->getId()) { $couponCode = $order->getDiscountDescription(); $couponCodeAmount = $order->getDiscountAmount(); - $discountAllItems = $this->discountHandler->allItemsHaveDiscount($order->getAllVisibleItems()); + $discountAllItems = $this->discountHandler->allItemsHaveDiscount($order->getAllItems()); $orderLines = $this->itemOrderLines($couponCodeAmount, $order, $discountAllItems); if ($this->orderLines->sendShipment($order) && !empty($order->getShippingMethod(true))) { $orderLines[] = $this->orderLines->handleShipping($order, $discountAllItems, true); @@ -205,7 +240,7 @@ public function createRequest($terminalId, $orderId) if (!empty($this->fixedProductTax($order))) { $orderLines[] = $this->orderLines->fixedProductTaxOrderLine($this->fixedProductTax($order)); } - $request = $this->preparePaymentRequest($order, $orderLines, $orderId, $terminalId); + $request = $this->preparePaymentRequest($order, $orderLines, $orderId, $terminalId, null); if ($request) { return $this->sendPaymentRequest($order, $request); } @@ -221,7 +256,7 @@ public function createRequest($terminalId, $orderId) */ public function restoreOrderFromOrderId($orderId) { - $order = $this->orderLoader->getOrderByOrderIncrementId($orderId); + $order = $this->orderFactory->create()->loadByIncrementId($orderId); if ($order->getId()) { $quote = $this->quote->loadByIdWithoutStore($order->getQuoteId()); $quote->setIsActive(1)->setReservedOrderId(null); @@ -379,6 +414,9 @@ public function handleOrderStateAction( $response = $callback->call(); if ($response) { $order = $this->loadOrderFromCallback($response); + if ($orderStatus === 'canceled') { + $order->cancel(); + } $order->setState($orderState); $order->setIsNotified(false); if ($transactionInfo !== null) { @@ -411,17 +449,38 @@ private function completeCheckout($comment, RequestInterface $request) { $callback = new Callback($request->getParams()); $response = $callback->call(); - $paymentStatus = $response->type; + $paymentType = $response->type; $requireCapture = $response->requireCapture; + $paymentStatus = strtolower($response->paymentStatus); + $responseStatus = $response->status; + $max_date = ''; + $latestTransKey = ''; + + if ($paymentStatus === 'released') { + $this->handleCancelStatusAction($request, $responseStatus); + return; + } + if ($response) { $order = $this->loadOrderFromCallback($response); $storeScope = ScopeInterface::SCOPE_STORE; $storeCode = $order->getStore()->getCode(); + foreach ($response->Transactions as $key=>$value) { + if ($value->CreatedDate > $max_date) { + $max_date = $value->CreatedDate; + $latestTransKey = $key; + } + } if ($order->getId()) { $cardType = ''; $expires = ''; - if (isset($response->Transactions[0])) { - $transaction = $response->Transactions[0]; + //Update stock quantity + if($order->getState() == 'canceled') { + $this->updateStockQty($order); + } + $this->resetCanceledQty($order); + if (isset($response->Transactions[$latestTransKey])) { + $transaction = $response->Transactions[$latestTransKey]; if (isset($transaction->CreditCardExpiry->Month) && isset($transaction->CreditCardExpiry->Year)) { $expires = $transaction->CreditCardExpiry->Month . '/' . $transaction->CreditCardExpiry->Year; } @@ -437,6 +496,7 @@ private function completeCheckout($comment, RequestInterface $request) $payment->setAdditionalInformation('masked_credit_card', $response->maskedCreditCard); $payment->setAdditionalInformation('expires', $expires); $payment->setAdditionalInformation('card_type', $cardType); + $payment->setAdditionalInformation('payment_type', $paymentType); $payment->save(); //send order confirmation email $this->sendOrderConfirmationEmail($comment, $order); @@ -449,7 +509,7 @@ private function completeCheckout($comment, RequestInterface $request) $orderState = Order::STATE_PROCESSING; $statusKey = 'process'; - if ($this->isCaptured($response, $storeCode, $storeScope)) { + if ($this->isCaptured($response, $storeCode, $storeScope, $latestTransKey)) { if ($orderStatusCapture == "complete") { if ($this->orderLines->sendShipment($order)) { $orderState = Order::STATE_COMPLETE; @@ -471,15 +531,38 @@ private function completeCheckout($comment, RequestInterface $request) $order->addStatusHistoryComment($comment); $order->addStatusHistoryComment($this->getTransactionInfoFromResponse($response)); $order->setIsNotified(false); + $order->getResource()->save($order); - if (strtolower($paymentStatus) == 'paymentandcapture') { + if (strtolower($paymentType) === 'paymentandcapture' || strtolower($paymentType) === 'subscriptionandcharge') { $this->createInvoice($order, $requireCapture); } } } } + /** + * @param $order + * return void + */ + public function updateStockQty($order) + { + $cart = $this->modelCart; + $quoteItems = $this->checkoutSession->getQuote()->getItemsCollection(); + foreach ($order->getAllItems() as $item) { + $stockQty = $this->stockItem->getStockQty($item->getProductId(), $item->getStore()->getWebsiteId()); + $qty = $stockQty - $item->getQtyOrdered(); + $stockItem = $this->stockRegistry->getStockItemBySku($item['sku']); + $stockItem->setQty($qty); + $stockItem->setIsInStock((bool)$qty); + $this->stockRegistry->updateStockItemBySku($item['sku'], $stockItem); + } + foreach($quoteItems as $item) + { + $cart->removeItem($item->getId())->save(); + } + } + /** * @param $response * @@ -526,7 +609,7 @@ public function fixedProductTax($order) $weeTaxAmount = 0; foreach ($order->getAllItems() as $item) { - $weeTaxAmount += $item->getWeeeTaxAppliedRowAmount(); + $weeTaxAmount += $item->getWeeeTaxAppliedRowAmount(); } return $weeTaxAmount; @@ -543,7 +626,6 @@ public function fixedProductTax($order) private function itemOrderLines($couponCodeAmount, $order, $discountAllItems) { $orderLines = []; - $couponCode = $order->getDiscountDescription(); $storePriceIncTax = $this->storeConfig->storePriceIncTax(); foreach ($order->getAllItems() as $item) { @@ -565,21 +647,21 @@ private function itemOrderLines($couponCodeAmount, $order, $discountAllItems) $unitPrice = bcdiv($unitPriceWithoutTax, 1, 2); } else { $unitPrice = $productOriginalPrice; - $unitPriceWithoutTax = $productOriginalPrice; } $dataForPrice = $this->priceHandler->dataForPrice( $item, $unitPrice, - $couponCode, - $this->discountHandler->getItemDiscount($discountAmount, $productOriginalPrice, - $item->getQtyOrdered()) + $couponCodeAmount, + $this->discountHandler->getItemDiscount($discountAmount, $productOriginalPrice, $item->getQtyOrdered()), + $discountAllItems ); $taxAmount = $dataForPrice["taxAmount"]; + $catalogDiscount = $dataForPrice["catalogDiscount"]; $discount = $this->discountHandler->orderLineDiscount( $discountAllItems, - $dataForPrice["discount"] + $dataForPrice["discount"], + $catalogDiscount ); - $catalogDiscount = $dataForPrice["catalogDiscount"]; $itemTaxAmount = $taxAmount; $orderLines[] = $this->orderLines->itemOrderLine( $item, @@ -592,12 +674,8 @@ private function itemOrderLines($couponCodeAmount, $order, $discountAllItems) $roundingCompensation = $this->priceHandler->compensationAmountCal( $item, $unitPrice, - $unitPriceWithoutTax, $taxAmount, $discount, - $couponCodeAmount, - $catalogDiscount, - $storePriceIncTax, true ); // check if rounding compensation amount, send in the separate orderline @@ -636,9 +714,9 @@ private function restoreOrderAndReturnError($order) * @param $orderId * @param $terminalId * - * @return mixed + * @return bool|PaymentRequest|CardWalletAuthorize */ - private function preparePaymentRequest($order, $orderLines, $orderId, $terminalId) + private function preparePaymentRequest($order, $orderLines, $orderId, $terminalId, $providerData) { $storeScope = $this->storeConfig->getStoreScope(); $storeCode = $order->getStore()->getCode(); @@ -650,9 +728,14 @@ private function preparePaymentRequest($order, $orderLines, $orderId, $terminalI return false; } $terminalName = $this->systemConfig->getTerminalConfig($terminalId, 'terminalname', $storeScope, $storeCode); + $isApplePay = $this->systemConfig->getTerminalConfig($terminalId, 'isapplepay', $storeScope, $storeCode); //Transaction Info $transactionDetail = $this->helper->transactionDetail($orderId); $request = new PaymentRequest($auth); + if ($isApplePay) { + $request = new CardWalletAuthorize($auth); + $request->setProviderData($providerData); + } $request->setTerminal($terminalName) ->setShopOrderId($order->getIncrementId()) ->setAmount((float)number_format($order->getGrandTotal(), 2, '.', '')) @@ -661,7 +744,7 @@ private function preparePaymentRequest($order, $orderLines, $orderId, $terminalI ->setConfig($this->setConfig()) ->setTransactionInfo($transactionDetail) ->setSalesTax((float)number_format($order->getTaxAmount(), 2, '.', '')) - ->setCookie($_SERVER['HTTP_COOKIE']); + ->setCookie($this->request->getServer('HTTP_COOKIE')); $post = $this->request->getPostValue(); @@ -756,7 +839,7 @@ private function sendPaymentRequest($order, $request) * * @return bool|MethodInterface */ - private function isCaptured($response, $storeCode, $storeScope) + private function isCaptured($response, $storeCode, $storeScope, $latestTransKey) { $isCaptured = false; foreach (SystemConfig::getTerminalCodes() as $terminalName) { @@ -766,7 +849,7 @@ private function isCaptured($response, $storeCode, $storeScope) $storeScope, $storeCode ); - if ($terminalConfig === $response->Transactions[0]->Terminal) { + if ($terminalConfig === $response->Transactions[$latestTransKey]->Terminal) { $isCaptured = $this->systemConfig->getTerminalConfigFromTerminalName( $terminalName, 'capture', @@ -870,7 +953,7 @@ public function checkAvsConfig($response, $storeCode, $storeScope, $configField) $storeScope, $storeCode ); - if ($terminalConfig === $response->Transactions[0]->Terminal) { + if ($terminalConfig === $response->Transactions[$this->getLatestTransaction($response)]->Terminal) { $isEnabled = $this->systemConfig->getTerminalConfigFromTerminalName( $terminalName, $configField, @@ -901,7 +984,7 @@ public function getAcceptedAvsResults($response, $storeCode, $storeScope) $storeScope, $storeCode ); - if ($terminalConfig === $response->Transactions[0]->Terminal) { + if ($terminalConfig === $response->Transactions[$this->getLatestTransaction($response)]->Terminal) { $acceptedAvsResults = $this->systemConfig->getTerminalConfigFromTerminalName( $terminalName, 'avs_acceptance', @@ -926,4 +1009,77 @@ public function savePaymentData($response, $order) $payment->setLastTransId($response->transactionId); $payment->save(); } + + /** + * @param $order + * + * @return void + */ + public function resetCanceledQty($order) { + foreach ($order->getAllItems() as $item) { + if ($item->getQtyCanceled() > 0) { + $item->setQtyCanceled($item->getQtyToCancel()); + $item->save(); + } + } + } + + public function getLatestTransaction($response) { + $max_date = ''; + $latestTransKey = ''; + foreach ($response->Transactions as $key=>$value) { + if ($value->CreatedDate > $max_date) { + $max_date = $value->CreatedDate; + $latestTransKey = $key; + } + } + return $latestTransKey; + } + /** + * @param $terminalId + * @param $orderId + * @param $providerData + * + * @return mixed + */ + public function createRequestApplepay($terminalId, $orderId, $providerData) + { + $storeScope = $this->storeConfig->getStoreScope(); + $order = $this->order->load($orderId); + $storeCode = $order->getStore()->getCode(); + if ($order->getId()) { + $couponCode = $order->getDiscountDescription(); + $couponCodeAmount = $order->getDiscountAmount(); + $discountAllItems = $this->discountHandler->allItemsHaveDiscount($order->getAllItems()); + $orderLines = $this->itemOrderLines($couponCodeAmount, $order, $discountAllItems); + if ($this->orderLines->sendShipment($order) && !empty($order->getShippingMethod(true))) { + $orderLines[] = $this->orderLines->handleShipping($order, $discountAllItems, true); + //Shipping Discount Tax Compensation Amount + $compAmount = $this->discountHandler->hiddenTaxDiscountCompensation($order, $discountAllItems, true); + if ($compAmount > 0 && $discountAllItems == false) { + $orderLines[] = $this->orderLines->compensationOrderLine( + "Shipping compensation", + "comp-ship", + $compAmount + ); + } + } + if ($discountAllItems && abs($couponCodeAmount) > 0) { + $orderLines[] = $this->orderLines->discountOrderLine($couponCodeAmount, $couponCode); + } + if(!empty($this->fixedProductTax($order))){ + $orderLines[] = $this->orderLines->fixedProductTaxOrderLine($this->fixedProductTax($order)); + } + $request = $this->preparePaymentRequest($order, $orderLines, $orderId, $terminalId, $providerData); + if ($request) { + $response = $request->call(); + $this->applePayOrder->handleCardWalletPayment($response, $order); + + return $response; + } + } + + return $this->restoreOrderAndReturnError($order); + } + } diff --git a/Model/Handler/DiscountHandler.php b/Model/Handler/DiscountHandler.php index e567e2a5..9a8b8a89 100644 --- a/Model/Handler/DiscountHandler.php +++ b/Model/Handler/DiscountHandler.php @@ -90,15 +90,31 @@ public function getAppliedDiscounts($item) * * @return int|string */ - public function orderLineDiscount($discountOnAllItems, $discount) + public function orderLineDiscount($discountOnAllItems, $discount, $catalogDiscount) { - if ($discountOnAllItems) { + if ($discountOnAllItems && !$catalogDiscount) { $discount = 0; } return number_format($discount, 2, '.', ''); } + /** + * Calculate combination of cart and catalog price rule. + * + * @param $originalPrice + * @param $rowTotal + * + * @return float|int + */ + public function combinationDiscount($originalPrice, $rowTotal) + { + $discountAmount = $originalPrice - $rowTotal; + $discountPercentage = ($discountAmount / $originalPrice) * 100; + + return number_format($discountPercentage, 2, '.', ''); + } + /** * Get discount applied to shipping. * @@ -143,7 +159,7 @@ public function catalogDiscount($originalPrice, $discountedPrice) /** * @param $originalPrice - * @param $discountedPrice + * @param $priceInclTax * @param $discountAmount * @param $quantity * @param $discountOnAllItems @@ -152,19 +168,32 @@ public function catalogDiscount($originalPrice, $discountedPrice) */ public function getItemDiscountInformation( $originalPrice, - $discountedPrice, + $priceInclTax, $discountAmount, $quantity, - $discountOnAllItems + $discountOnAllItems, + $item, + $taxAmount ) { + $rowTotal = $item->getRowTotal()-$item->getDiscountAmount()+$item->getTaxAmount()+$item->getDiscountTaxCompensationAmount(); $discount = ['discount' => 0, 'catalogDiscount' => false]; - if (!empty($discountAmount)) { + $originalPriceWithTax = $originalPrice + $taxAmount; + if ($discountAmount && $originalPrice == $priceInclTax) { $discountAmount = ($discountAmount * 100) / ($originalPrice * $quantity); - } elseif ($originalPrice > 0 && $originalPrice > $discountedPrice) { - $discount['catalog'] = true; - $discountAmount = $this->catalogDiscount($originalPrice, $discountedPrice); + } elseif ($originalPrice > 0 && $originalPrice > $priceInclTax && empty($discountAmount)) { + $discount['catalogDiscount'] = true; + $discountAmount = $this->catalogDiscount($originalPrice, $priceInclTax); + } elseif ($originalPrice > 0 && $originalPrice > $priceInclTax && $discountAmount) { + $discount['catalogDiscount'] = true; + if (!$this->storeConfig->storePriceIncTax()) { + $discountAmount = $originalPriceWithTax - $rowTotal; + $discountPercentage = ($discountAmount * 100) / $originalPriceWithTax; + $discountAmount = $discountPercentage; + } else { + $discountAmount = $this->combinationDiscount($originalPrice, $rowTotal); + } } - $discount['discount'] = $this->orderLineDiscount($discountOnAllItems, $discountAmount); + $discount['discount'] = $this->orderLineDiscount($discountOnAllItems, $discountAmount, $discount['catalogDiscount']); return $discount; } @@ -180,9 +209,18 @@ public function allItemsHaveDiscount($orderItems) { $discountOnAllItems = true; foreach ($orderItems as $item) { - $appliedRule = $item->getAppliedRuleIds(); - $productType = $item->getProductType(); - if (!empty($appliedRule)) { + $appliedRule = $item->getAppliedRuleIds(); + $productType = $item->getProductType(); + $originalPrice = $item->getBaseOriginalPrice(); + + if ($this->storeConfig->storePriceIncTax()) { + $price = $item->getPriceInclTax(); + } else { + $price = $item->getPrice(); + } + if ($originalPrice > $price) { + $discountOnAllItems = false; + } elseif (!empty($appliedRule)) { $appliedRuleArr = explode(",", $appliedRule); foreach ($appliedRuleArr as $ruleId) { $coupon = $this->storeConfig->getRuleInformationByID($ruleId); diff --git a/Model/Handler/PriceHandler.php b/Model/Handler/PriceHandler.php index c6fea3d5..59e191f2 100644 --- a/Model/Handler/PriceHandler.php +++ b/Model/Handler/PriceHandler.php @@ -49,23 +49,35 @@ public function __construct( * * @return mixed */ - public function dataForPrice($item, $unitPrice, $couponCode, $itemDiscount) + public function dataForPrice($item, $unitPrice, $couponAmount, $itemDiscount, $discountAllItems) { $data["catalogDiscount"] = false; $taxPercent = $item->getTaxPercent(); $quantity = $item->getQtyOrdered(); $originalPrice = $item->getBaseOriginalPrice(); + $data["taxAmount"] = $this->calculateTaxAmount($unitPrice, $taxPercent, $quantity); + $rowTotal = ($item->getRowTotal()-$item->getDiscountAmount()+$item->getTaxAmount()+$item->getDiscountTaxCompensationAmount()); if ($this->storeConfig->storePriceIncTax()) { $price = $item->getPriceInclTax(); } else { $price = $item->getPrice(); } - $data["taxAmount"] = $this->calculateTaxAmount($unitPrice, $taxPercent, $quantity); - if ($originalPrice > $price && empty($couponCode)) { + if ($originalPrice > $price && abs((float)$couponAmount) > 0 && !$discountAllItems) { + $originalPrice = $originalPrice * $quantity; + $originalPriceWithTax = $originalPrice + $data["taxAmount"]; $data["catalogDiscount"] = true; - $data["discount"] = $this->discountHandler->catalogDiscount($originalPrice, $price); + if (!$this->storeConfig->storePriceIncTax()) { + $discountAmount = $originalPriceWithTax - $rowTotal; + $discountPercentage = ($discountAmount * 100) / $originalPriceWithTax; + $data["discount"] = $discountPercentage; + } else { + $data["discount"] = $this->discountHandler->combinationDiscount($originalPrice, $rowTotal); + } + } else if ($originalPrice > $price && !(float)$couponAmount) { + $data["catalogDiscount"] = true; + $data["discount"] = $this->discountHandler->catalogDiscount($originalPrice, $price); } else { - $data["discount"] = $itemDiscount; + $data["discount"] = $itemDiscount; } return $data; @@ -113,37 +125,20 @@ public function getPriceWithoutTax($price, $taxPercentage) public function compensationAmountCal( $item, $unitPrice, - $unitPriceWithoutTax, $taxAmount, $discountedAmount, - $couponCodeAmount, - $catalogDiscountCheck, - $storePriceIncTax, - $newOrder - ) { + $newOrder) + { if ($newOrder) { - $quantity = $item->getQtyOrdered(); - $taxPercent = $item->getTaxPercent(); + $quantity = $item->getQtyOrdered(); } else { - $quantity = $item->getQty(); - $taxPercent = $item->getOrderItem()->getTaxPercent(); + $quantity = $item->getQty(); } - - $compensation = 0; //Discount compensation calculation - Gateway calculation pattern $gatewaySubTotal = ($unitPrice * $quantity) + $taxAmount; $gatewaySubTotal = $gatewaySubTotal - ($gatewaySubTotal * ($discountedAmount / 100)); - // Magento calculation pattern - if (abs($couponCodeAmount) > 0 && $storePriceIncTax) { - $cmsPriceCal = $unitPriceWithoutTax * $quantity; - $cmsTaxCal = $cmsPriceCal * ($taxPercent / 100); - $cmsSubTotal = $cmsPriceCal + $cmsTaxCal; - $cmsSubTotal = $cmsSubTotal - ($cmsSubTotal * ($discountedAmount / 100)); - $compensation = $cmsSubTotal - $gatewaySubTotal; - } elseif ($catalogDiscountCheck || empty($couponCodeAmount) || $couponCodeAmount == 0) { - $cmsSubTotal = $item->getBaseRowTotal() + $item->getBaseTaxAmount(); - $compensation = $cmsSubTotal - $gatewaySubTotal; - } + $cmsSubTotal = $item->getRowTotal() - $item->getDiscountAmount() + $item->getTaxAmount() + $item->getDiscountTaxCompensationAmount(); + $compensation = $cmsSubTotal - $gatewaySubTotal; return $compensation; } diff --git a/Observer/CaptureObserver.php b/Observer/CaptureObserver.php index 8ec8a5c8..38833040 100755 --- a/Observer/CaptureObserver.php +++ b/Observer/CaptureObserver.php @@ -167,6 +167,7 @@ private function itemOrderLines($couponCodeAmount, $invoice, $discountAllItems) if ($qty > 0 && $productType != 'bundle' && $item->getPriceInclTax()) { $discountAmount = $item->getDiscountAmount(); $originalPrice = $item->getOrderItem()->getOriginalPrice(); + $totalPrice = $originalPrice * $qty; if ($originalPrice == 0) { $originalPrice = $item->getPriceInclTax(); @@ -180,35 +181,32 @@ private function itemOrderLines($couponCodeAmount, $invoice, $discountAllItems) } else { $price = $item->getPrice(); $unitPrice = $originalPrice; - $priceWithoutTax = $originalPrice; $taxAmount = $this->priceHandler->calculateTaxAmount($unitPrice, $taxPercent, $qty); } $itemDiscountInformation = $this->discountHandler->getItemDiscountInformation( - $originalPrice, + $totalPrice, $price, $discountAmount, $qty, - $discountAllItems + $discountAllItems, + $item, + $taxAmount ); $discountedAmount = $itemDiscountInformation['discount']; - $catalogDiscountCheck = $itemDiscountInformation['catalogDiscount']; $orderLines[] = $this->orderLines->itemOrderLine( $item, $unitPrice, $discountedAmount, $taxAmount, $invoice->getOrder(), - false + false, + $discountAllItems ); $roundingCompensation = $this->priceHandler->compensationAmountCal( $item, $unitPrice, - $priceWithoutTax, $taxAmount, $discountedAmount, - $couponCodeAmount, - $catalogDiscountCheck, - $storePriceIncTax, false ); // check if rounding compensation amount, send in the separate orderline @@ -290,7 +288,7 @@ private function sendInvoiceRequest($invoice, $orderLines, $orderObject, $paymen $this->logger->info('Response body', json_decode($xml, true)); //Update comments if capture fail $xml = simplexml_load_string($body); - if ($xml->Body->Result == 'Error' || $xml->Body->Result == 'Failed') { + if ($xml->Body->Result == 'Error' || $xml->Body->Result == 'Failed' || $xml->Body->Result == 'Incomplete') { $orderObject->addStatusHistoryComment('Capture failed: ' . $xml->Body->MerchantErrorMessage) ->setIsCustomerNotified(false); $orderObject->getResource()->save($orderObject); @@ -317,7 +315,7 @@ public function fixedProductTax($invoice) $weeTaxAmount = 0; foreach ($invoice->getAllItems() as $item) { - $weeTaxAmount += $item->getWeeeTaxAppliedRowAmount(); + $weeTaxAmount += $item->getWeeeTaxAppliedRowAmount(); } return $weeTaxAmount; diff --git a/Observer/CheckoutCartIndex.php b/Observer/CheckoutCartIndex.php index 8676ec92..491dac9f 100755 --- a/Observer/CheckoutCartIndex.php +++ b/Observer/CheckoutCartIndex.php @@ -24,6 +24,7 @@ use Magento\Framework\Session\SessionManagerInterface; use SDM\Altapay\Model\ConstantConfig; use Magento\Store\Model\ScopeInterface; +use Magento\Catalog\Model\Indexer\Product\Price\Processor; class CheckoutCartIndex implements ObserverInterface { @@ -77,7 +78,8 @@ public function __construct( Coupon $coupon, CouponUsage $couponUsage, StockManagementInterface $stockManagement, - SystemConfig $systemConfig + SystemConfig $systemConfig, + Processor $priceIndexer ) { $this->session = $session; $this->quoteFactory = $quoteFactory; @@ -87,6 +89,7 @@ public function __construct( $this->couponUsage = $couponUsage; $this->stockManagement = $stockManagement; $this->systemConfig = $systemConfig; + $this->priceIndexer = $priceIndexer; } @@ -141,7 +144,8 @@ public function execute(Observer $observer) if ($order->getCouponCode()) { $this->resetCouponAfterCancellation($order); } - + //revert quantity when cancel order + $this->revertOrderQty($order); //revert quantity when cancel order $orderItems = $order->getAllItems(); foreach ($orderItems as $item) { @@ -214,4 +218,20 @@ public function verifyIfOrderStatus($orderStatusConfigBefore, $currentOrderStatu return false; } + + /** + * @param $order + */ + public function revertOrderQty($order) + { + foreach ($order->getAllItems() as $item) { + $qty = $item->getQtyOrdered() - max($item->getQtyShipped(), $item->getQtyInvoiced()) - $item->getQtyCanceled(); + if ($item->getId() && $item->getProductId() && empty($item->getChildrenItems()) && $qty) { + $this->stockManagement->backItemQty($item->getProductId(), $qty, $item->getStore()->getWebsiteId()); + } + $item->setQtyCanceled($item['qty_ordered']); + $item->save(); + $this->priceIndexer->reindexRow($item->getProductId()); + } + } } diff --git a/Observer/CreditmemoRefundObserver.php b/Observer/CreditmemoRefundObserver.php index adf15d61..7cdd85a0 100755 --- a/Observer/CreditmemoRefundObserver.php +++ b/Observer/CreditmemoRefundObserver.php @@ -173,7 +173,7 @@ private function itemOrderLines($couponCodeAmount, $discountAllItems, $memo) if ($qty > 0 && $productType != 'bundle') { $discountAmount = $item->getDiscountAmount(); $originalPrice = $item->getOrderItem()->getOriginalPrice(); - + $totalPrice = $originalPrice * $qty; if ($originalPrice == 0) { $originalPrice = $item->getPriceInclTax(); } @@ -186,15 +186,16 @@ private function itemOrderLines($couponCodeAmount, $discountAllItems, $memo) } else { $price = $item->getPrice(); $unitPrice = $originalPrice; - $priceWithoutTax = $originalPrice; $taxAmount = $this->priceHandler->calculateTaxAmount($unitPrice, $taxPercent, $qty); } $itemDiscountInformation = $this->discountHandler->getItemDiscountInformation( - $originalPrice, + $totalPrice, $price, $discountAmount, $qty, - $discountAllItems + $discountAllItems, + $item, + $taxAmount ); if ($item->getPriceInclTax()) { $discountedAmount = $itemDiscountInformation['discount']; @@ -211,12 +212,8 @@ private function itemOrderLines($couponCodeAmount, $discountAllItems, $memo) $roundingCompensation = $this->priceHandler->compensationAmountCal( $item, $unitPrice, - $priceWithoutTax, $taxAmount, $discountedAmount, - $couponCodeAmount, - $catalogDiscount, - $storePriceIncTax, false ); //send the rounding mismatch value into separate orderline if any @@ -268,7 +265,7 @@ private function sendRefundRequest($memo, $orderLines, $orderObject, $payment, $ //Update comments if refund fail $xml = simplexml_load_string($body); - if ($xml->Body->Result == 'Error' || $xml->Body->Result == 'Failed') { + if ($xml->Body->Result == 'Error' || $xml->Body->Result == 'Failed' || $xml->Body->Result == 'Incomplete') { $orderObject->addStatusHistoryComment('Refund failed: ' . $xml->Body->MerchantErrorMessage) ->setIsCustomerNotified(false); $orderObject->getResource()->save($orderObject); @@ -289,7 +286,7 @@ public function fixedProductTax($memo) $weeTaxAmount = 0; foreach ($memo->getAllItems() as $item) { - $weeTaxAmount += $item->getWeeeTaxAppliedRowAmount(); + $weeTaxAmount += $item->getWeeeTaxAppliedRowAmount(); } return $weeTaxAmount; diff --git a/Observer/OrderCancelObserver.php b/Observer/OrderCancelObserver.php index 9f2fbebe..59869e29 100755 --- a/Observer/OrderCancelObserver.php +++ b/Observer/OrderCancelObserver.php @@ -49,7 +49,7 @@ public function execute(Observer $observer) /** @var Payment $payment */ $payment = $order->getPayment(); - if (in_array($payment->getMethod(), SystemConfig::getTerminalCodes())) { + if (in_array($payment->getMethod(), SystemConfig::getTerminalCodes()) && $payment->getLastTransId()) { $api = new ReleaseReservation($this->systemConfig->getAuth($order->getStore()->getCode())); $api->setTransaction($payment->getLastTransId()); /** @var ReleaseReservationResponse $response */ diff --git a/Plugin/Checkout/Controller/Onepage/Success.php b/Plugin/Checkout/Controller/Onepage/Success.php new file mode 100644 index 00000000..95b7ce6c --- /dev/null +++ b/Plugin/Checkout/Controller/Onepage/Success.php @@ -0,0 +1,85 @@ +coreRegistry = $coreRegistry; + $this->checkoutSession = $checkoutSession; + $this->orderFactory = $orderFactory; + $this->orderColl = $orderColl; + } + + /** + * @param \Magento\Checkout\Controller\Onepage\Success $subject + */ + public function beforeExecute(\Magento\Checkout\Controller\Onepage\Success $subject) + { + $hash = $subject->getRequest()->getParam('success_token', false); + if (!$hash) { + return; + } + $collectionData = $this->orderColl->create()->addFieldToSelect( + 'increment_id' + )->addFieldToFilter( + 'altapay_order_hash', + $hash + ); + $collectionInfo = $collectionData->getData(); + foreach ($collectionInfo as $data) { + $orderId = $data['increment_id']; + if ($orderId && is_numeric($orderId)) { + $order = $this->orderFactory->loadByIncrementId($orderId); + if ($order && $order->getId() && $order->getAltapayOrderHash() !== null) { + $this->checkoutSession->setLastQuoteId($order->getQuoteId()); + $this->checkoutSession->setLastSuccessQuoteId($order->getQuoteId()); + $this->checkoutSession->setLastOrderId($order->getId()); + $this->checkoutSession->setLastRealOrderId($order->getIncrementId()); + $this->checkoutSession->setLastOrderStatus($order->getStatus()); + $order->setAltapayOrderHash(null); + $order->getResource()->save($order); + } + + } + } + } +} \ No newline at end of file diff --git a/Setup/UpgradeSchema.php b/Setup/UpgradeSchema.php index d98c6be8..3997fbba 100644 --- a/Setup/UpgradeSchema.php +++ b/Setup/UpgradeSchema.php @@ -171,6 +171,21 @@ public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $con )->setComment('Altapay Tokens'); $setup->getConnection()->createTable($altapayTokenTableName); } + $orderHash = "altapay_order_hash"; + if (!$setup->getConnection()->tableColumnExists($setup->getTable($orderTable), $orderHash)) { + $setup->getConnection()->addColumn( + $setup->getTable($orderTable), + $orderHash, + [ + 'type' => Table::TYPE_TEXT, + 'length' => 65536, + 'nullable' => true, + 'visible' => false, + 'comment' => 'Alapay Order Hash', + ] + ); + } + $setup->endSetup(); } } \ No newline at end of file diff --git a/etc/adminhtml/routes.xml b/etc/adminhtml/routes.xml new file mode 100644 index 00000000..b3b7ae97 --- /dev/null +++ b/etc/adminhtml/routes.xml @@ -0,0 +1,18 @@ + + + + + + + + + + \ No newline at end of file diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 342b0a82..6f1e19c4 100755 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -12,17 +12,38 @@
- - + 1 + + + + + Magento\Config\Model\Config\Source\Yesno + + + + Magento\Cron\Model\Config\Source\Frequency + SDM\Altapay\Model\Config\CronConfig + + + + + + SDM\Altapay\Block\System\Config\ChangeOrderStatusButton + + + 0 - + You can find your Api Keys in your AltaPay Merchnat Account]]> SDM\Altapay\Block\Adminhtml\Render\Version @@ -41,19 +62,19 @@ - - payment/altapay_config/productionurl + + payment/altapay_config/productionurl - - Can we connect to Altapay + + Can we connect to AltaPay SDM\Altapay\Model\Config\Source\Connection - - Can we authenticate to Altapay - Remember to save after you have typed your API login and password + + Can we authenticate to AltaPay - Remember to save after you have typed your API login and password SDM\Altapay\Model\Config\Source\Authentication @@ -92,14 +113,23 @@ SDM\Altapay\Model\Config\Source\Order\Status\Cancel payment/altapay_status/cancel - + The status on the order if autocapture is enabled SDM\Altapay\Model\Config\Source\Order\Status\Autocapture payment/altapay_status/autocapture - + + 0 + + + + + SDM\Altapay\Block\System\Config\Button + + + diff --git a/etc/adminhtml/system/terminal1.xml b/etc/adminhtml/system/terminal1.xml index 5a45339a..04ba526d 100755 --- a/etc/adminhtml/system/terminal1.xml +++ b/etc/adminhtml/system/terminal1.xml @@ -22,32 +22,42 @@ payment/terminal1/title - + Select terminal - Remember to save configuration after you have added your API login and password, to get your terminals payment/terminal1/terminalname SDM\Altapay\Model\Config\Source\Terminals altapay-terminal-name + + + Magento\Config\Model\Config\Source\Yesno + payment/terminal1/isapplepay + + + + Add custom text for the Apple Pay popup label + payment/terminal1/applepaylabel + - + Force the language of the payment page SDM\Altapay\Model\Config\Source\Languages payment/terminal1/language - + If you only sell download products, which are delivered immediately you can turn this on Magento\Config\Model\Config\Source\Yesno payment/terminal1/capture - - + Select terminal - Remember to save configuration after you have added your API login and password, to get your terminals payment/terminal2/terminalname SDM\Altapay\Model\Config\Source\Terminals altapay-terminal-name + + + Magento\Config\Model\Config\Source\Yesno + payment/terminal2/isapplepay + + + + Add custom text for the Apple Pay popup label + payment/terminal1/applepaylabel + - + Force the language of the payment page SDM\Altapay\Model\Config\Source\Languages payment/terminal2/language - + If you only sell download products, which are delivered immediately you can turn this on Magento\Config\Model\Config\Source\Yesno payment/terminal2/capture - - + Select terminal - Remember to save configuration after you have added your API login and password, to get your terminals payment/terminal3/terminalname SDM\Altapay\Model\Config\Source\Terminals altapay-terminal-name + + + Magento\Config\Model\Config\Source\Yesno + payment/terminal3/isapplepay + + + + Add custom text for the Apple Pay popup label + payment/terminal1/applepaylabel + - + Force the language of the payment page SDM\Altapay\Model\Config\Source\Languages payment/terminal3/language - + If you only sell download products, which are delivered immediately you can turn this on Magento\Config\Model\Config\Source\Yesno payment/terminal3/capture - - + Select terminal - Remember to save configuration after you have added your API login and password, to get your terminals payment/terminal4/terminalname SDM\Altapay\Model\Config\Source\Terminals altapay-terminal-name + + + Magento\Config\Model\Config\Source\Yesno + payment/terminal4/isapplepay + + + + Add custom text for the Apple Pay popup label + payment/terminal1/applepaylabel + - + Force the language of the payment page SDM\Altapay\Model\Config\Source\Languages payment/terminal4/language - + If you only sell download products, which are delivered immediately you can turn this on Magento\Config\Model\Config\Source\Yesno payment/terminal4/capture - - + Select terminal - Remember to save configuration after you have added your API login and password, to get your terminals payment/terminal5/terminalname SDM\Altapay\Model\Config\Source\Terminals altapay-terminal-name + + + Magento\Config\Model\Config\Source\Yesno + payment/terminal5/isapplepay + + + + Add custom text for the Apple Pay popup label + payment/terminal1/applepaylabel + - + Force the language of the payment page SDM\Altapay\Model\Config\Source\Languages payment/terminal5/language - + If you only sell download products, which are delivered immediately you can turn this on Magento\Config\Model\Config\Source\Yesno payment/terminal5/capture -