From 31f8a0fcccee6c21a249fa6a81f243834864bd0e Mon Sep 17 00:00:00 2001 From: sixer1182 Date: Fri, 8 May 2020 08:48:31 +0200 Subject: [PATCH 1/9] [change] (MAGE2-311) Add measures to avoid unexpected errors due foreign payment type. --- Block/Info/AbstractBlock.php | 9 ++++++++- Controller/Index/Redirect.php | 13 ++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Block/Info/AbstractBlock.php b/Block/Info/AbstractBlock.php index dc8e12b785a..7a49f7a47f0 100755 --- a/Block/Info/AbstractBlock.php +++ b/Block/Info/AbstractBlock.php @@ -160,7 +160,14 @@ public function printAdditionalInformationHtml() } if (! empty($this->transactionInfo->getJsonResponse())) { - return $this->getMethod()->additionalPaymentInformation($this->transactionInfo->getJsonResponse()); + $methodInstance = $this->getMethod(); + if (\is_callable([$methodInstance, 'additionalPaymentInformation'])) { + return $methodInstance->additionalPaymentInformation( + $this->transactionInfo->getJsonResponse() + ); + } + + $this->_logger->debug('heidelpay: Could not retrieve additionalPaymentInformation for class: \"' . \get_class($methodInstance) . '\".'); } return ''; diff --git a/Controller/Index/Redirect.php b/Controller/Index/Redirect.php index 5ca9f253271..b2a2447bcb2 100755 --- a/Controller/Index/Redirect.php +++ b/Controller/Index/Redirect.php @@ -206,17 +206,20 @@ protected function updateSessionData($quoteId, Order $order, array $data) $checkoutSession->clearHelperData(); // set QuoteIds - $checkoutSession->setLastQuoteId($quoteId) - ->setLastSuccessQuoteId($quoteId); + $checkoutSession->setLastQuoteId($quoteId)->setLastSuccessQuoteId($quoteId); // set OrderIds $checkoutSession->setLastOrderId($order->getId()) ->setLastRealOrderId($order->getIncrementId()) ->setLastOrderStatus($order->getStatus()); - $additionalPaymentInformation = $order->getPayment() - ->getMethodInstance() - ->additionalPaymentInformation($data); + $methodInstance = $order->getPayment()->getMethodInstance(); + $additionalPaymentInformation = ''; + if (\is_callable([$methodInstance, 'additionalPaymentInformation'])) { + $additionalPaymentInformation = $methodInstance->additionalPaymentInformation($data); + } else { + $this->_logger->error('heidelpay - The payment method seems to be from a different plugin.'); + } $checkoutSession->setHeidelpayInfo($additionalPaymentInformation); } From eca525b61fc316f55fccc26aeb27508a1789ffb6 Mon Sep 17 00:00:00 2001 From: sixer1182 Date: Fri, 8 May 2020 09:02:19 +0200 Subject: [PATCH 2/9] [change] (MAGE2-311) Fetch last order instead of first to make sure previous, cancelled orders are ignored and only the last (supposedly) valid order is used. --- Controller/Index/Push.php | 2 +- Controller/Index/Redirect.php | 12 +++++++-- Helper/Order.php | 26 ++++++++++++++++--- Helper/Payment.php | 7 ++--- .../Controller/Index/PushHandlingTest.php | 6 ++--- 5 files changed, 40 insertions(+), 13 deletions(-) diff --git a/Controller/Index/Push.php b/Controller/Index/Push.php index 498e0da81cd..d142b6c0e11 100755 --- a/Controller/Index/Push.php +++ b/Controller/Index/Push.php @@ -192,7 +192,7 @@ public function execute() $quote = $this->quoteRepository->get($transactionId); // create order if it doesn't exists already. - $order = $this->orderHelper->fetchOrder($transactionId); + $order = $this->orderHelper->fetchOrderByQuoteId($transactionId); if ($order === null || $order->isEmpty()) { $transactionData = $this->_paymentHelper->getDataFromResponse($pushResponse); $this->_paymentHelper->saveHeidelpayTransaction($pushResponse, $transactionData, 'PUSH'); diff --git a/Controller/Index/Redirect.php b/Controller/Index/Redirect.php index b2a2447bcb2..c0ee513e661 100755 --- a/Controller/Index/Redirect.php +++ b/Controller/Index/Redirect.php @@ -4,6 +4,7 @@ use Exception; use Heidelpay\Gateway\Controller\HgwAbstract; +use Heidelpay\Gateway\Helper\Order as OrderHelper; use Heidelpay\Gateway\Helper\Payment as HeidelpayHelper; use Heidelpay\Gateway\Model\ResourceModel\Transaction\CollectionFactory; use Heidelpay\Gateway\Model\Transaction as HeidelpayTransaction; @@ -50,6 +51,9 @@ class Redirect extends HgwAbstract /** @var CollectionFactory */ private $transactionCollectionFactory; + /** @var OrderHelper */ + private $orderHelper; + /** * heidelpay Redirect constructor. * @@ -69,6 +73,7 @@ class Redirect extends HgwAbstract * @param Encryptor $encryptor * @param Url $customerUrl * @param CollectionFactory $transactionCollectionFactory + * @param OrderHelper $orderHelper */ public function __construct( Context $context, @@ -86,7 +91,8 @@ public function __construct( OrderCommentSender $orderCommentSender, Encryptor $encryptor, Url $customerUrl, - CollectionFactory $transactionCollectionFactory + CollectionFactory $transactionCollectionFactory, + OrderHelper $orderHelper ) { parent::__construct( $context, @@ -107,6 +113,7 @@ public function __construct( ); $this->transactionCollectionFactory = $transactionCollectionFactory; + $this->orderHelper = $orderHelper; } /** @@ -156,7 +163,8 @@ public function execute() /** @var Order $order */ $order = null; try { - $order = $this->_orderFactory->create()->loadByAttribute('quote_id', $quoteId); + $this->_logger->warning('Load order by QuoteId: ' . $quoteId); + $order = $this->orderHelper->fetchOrderByQuoteId($quoteId); } catch (Exception $e) { $this->_logger->error( 'Heidelpay - Redirect: Cannot receive order.' . $e->getMessage() diff --git a/Helper/Order.php b/Helper/Order.php index a3966665f3d..466df6feac2 100644 --- a/Helper/Order.php +++ b/Helper/Order.php @@ -5,6 +5,8 @@ use Magento\Framework\App\Helper\AbstractHelper; use Magento\Framework\App\Helper\Context; +use Magento\Framework\Data\Collection; +use Magento\Framework\DataObject; use Magento\Sales\Helper\Data as SalesHelper; use Magento\Sales\Model\Order as MagentoOrder; use Magento\Sales\Model\Order\Email\Sender\InvoiceSender; @@ -117,15 +119,31 @@ public function handleOrderMail($order) } /** - * @param $transactionId - * @return MagentoOrder + * Returns the last Order to the quote with the given quoteId or an empty order object. + * + * @param $quoteId + * @return MagentoOrder|DataObject */ - public function fetchOrder($transactionId) + public function fetchOrderByQuoteId($quoteId) { - $criteria = $this->searchCriteriaBuilder->addFilter('quote_id', $transactionId)->create(); + $orderList = $this->fetchOrdersByQuoteId($quoteId); + + return $orderList->getLastItem(); + } + + /** + * @param $quoteId + * @return Collection + */ + protected function fetchOrdersByQuoteId($quoteId): Collection + { + $criteria = $this->searchCriteriaBuilder->addFilter('quote_id', $quoteId)->create(); /** @var Collection $orderList */ $orderList = $this->orderRepository->getList($criteria); + return $orderList; + } + return $orderList->getFirstItem(); } diff --git a/Helper/Payment.php b/Helper/Payment.php index 3c5b6c159a8..1e9b6c532ef 100755 --- a/Helper/Payment.php +++ b/Helper/Payment.php @@ -389,9 +389,10 @@ public function handleOrderCreation($quote, $context = null) $this->lockManager->lock($lockName); try{ /** @var Order $order */ - $order = $this->orderHelper->fetchOrder($quote->getId()); - // Ensure to use the currency of the quote. - if ($order === null || $order->isEmpty()) { + $order = $this->orderHelper->fetchOrderByQuoteId($quote->getId()); + + if ($order === null || $order->isEmpty() || $order->isCanceled()) { + // Ensure to use the currency of the quote. $quote->getStore()->setCurrentCurrencyCode($quote->getQuoteCurrencyCode()); $quote->collectTotals(); // in case of guest checkout, set some customer related data. diff --git a/Test/Integration/Controller/Index/PushHandlingTest.php b/Test/Integration/Controller/Index/PushHandlingTest.php index 937ed4fef18..eaa4f755ace 100644 --- a/Test/Integration/Controller/Index/PushHandlingTest.php +++ b/Test/Integration/Controller/Index/PushHandlingTest.php @@ -114,7 +114,7 @@ public function PushCreatesNewTransaction($paymentCode, $paymentMethod) $this->assertQuoteActive($quote->getId(), false); /** @var Order $order */ - $fetchedOrder = $this->orderHelper->fetchOrder($quote->getId()); + $fetchedOrder = $this->orderHelper->fetchOrderByQuoteId($quote->getId()); $this->assertFalse($fetchedOrder->isEmpty(), 'Order creation failed: Order is empty'); $uniqueId = $xml->Transaction->Identification->UniqueID; @@ -200,7 +200,7 @@ public function CreateNoOrderFromInvalidTransactionTypes($paymentCode, $paymentM $this->assertQuoteActive($quote->getId(), true); /** @var Order $order */ - $fetchedOrder = $this->orderHelper->fetchOrder($quote->getId()); + $fetchedOrder = $this->orderHelper->fetchOrderByQuoteId($quote->getId()); $this->assertTrue($fetchedOrder->isEmpty(), 'No Order should be created here'); // Check Transaction @@ -322,7 +322,7 @@ private function assertMagentoTransactionExists($uniqueId) private function assertQuoteHasNoOrder(Quote $quote) { /** @var Order $fetchedOrder */ - $fetchedOrder = $this->orderHelper->fetchOrder($quote->getId()); + $fetchedOrder = $this->orderHelper->fetchOrderByQuoteId($quote->getId()); $this->assertTrue($fetchedOrder->isEmpty()); $this->assertNotNull($quote); } From 426e244ed23b79fd7ddede4888b7c21452847e85 Mon Sep 17 00:00:00 2001 From: sixer1182 Date: Fri, 8 May 2020 09:04:21 +0200 Subject: [PATCH 3/9] [change] (MAGE2-311) Add measures to avoid unexpected errors due foreign payment type. --- Controller/Index/Redirect.php | 3 ++- Helper/Order.php | 23 +++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Controller/Index/Redirect.php b/Controller/Index/Redirect.php index c0ee513e661..a1ce8da9f6b 100755 --- a/Controller/Index/Redirect.php +++ b/Controller/Index/Redirect.php @@ -172,7 +172,8 @@ public function execute() } // Check whether order was loaded correctly - if($order === null || $order->isEmpty()) { + $hasHeidelpayPayment = $this->orderHelper->hasHeidelpayPayment($order); + if($order === null || $order->isEmpty() || $order->isCanceled() || !$hasHeidelpayPayment) { $this->_logger->error( 'Heidelpay - Redirect: Cannot receive order. Order creation might have failed.' ); diff --git a/Helper/Order.php b/Helper/Order.php index 466df6feac2..9f2d7bb7ace 100644 --- a/Helper/Order.php +++ b/Helper/Order.php @@ -2,7 +2,7 @@ namespace Heidelpay\Gateway\Helper; - +use Heidelpay\Gateway\PaymentMethods\HeidelpayAbstractPaymentMethod; use Magento\Framework\App\Helper\AbstractHelper; use Magento\Framework\App\Helper\Context; use Magento\Framework\Data\Collection; @@ -145,6 +145,25 @@ protected function fetchOrdersByQuoteId($quoteId): Collection } - return $orderList->getFirstItem(); + /** + * Returns true if the payment of the order is part of this payment module. + * + * @param MagentoOrder $order + * @return bool + */ + public function hasHeidelpayPayment(MagentoOrder $order): bool + { + $payment = $order->getPayment(); + $returnVal = true; + + if ($payment === null) { + $this->_logger->error('heidelpay - Empty payment.'); + $returnVal = false; + } elseif (!$payment->getMethodInstance() instanceof HeidelpayAbstractPaymentMethod) { + $this->_logger->error('heidelpay - Not heidelpay payment.'); + $returnVal = false; + } + + return $returnVal; } } \ No newline at end of file From b784bf769aa98c826be5ed90250acf3c3ac7e8dd Mon Sep 17 00:00:00 2001 From: sixer1182 Date: Fri, 8 May 2020 09:06:05 +0200 Subject: [PATCH 4/9] [change] (MAGE2-311) Fix minor style issues and problems. --- Helper/Payment.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Helper/Payment.php b/Helper/Payment.php index 1e9b6c532ef..58c92d69d79 100755 --- a/Helper/Payment.php +++ b/Helper/Payment.php @@ -176,7 +176,7 @@ public function getDataFromResponse(Response $response) $data = []; foreach ($response->toArray() as $parameterKey => $value) { - $data[str_replace('.', '_', $parameterKey)] = $value; + $data[str_replace('.', '_', (string)$parameterKey)] = $value; } return $data; @@ -377,7 +377,7 @@ public function saveHeidelpayTransaction(Response $response, array $data, $sourc } /** - * Create an order by submitting the quote. If Order for that qoute already exist this order will be returned. + * Create an order by submitting the quote. If Order for that quote already exist this order will be returned. * @param Quote $quote * @return AbstractExtensibleModel|OrderInterface|Order|object|null * @throws LocalizedException @@ -403,10 +403,12 @@ public function handleOrderCreation($quote, $context = null) ->setCustomerGroupId(Group::NOT_LOGGED_IN_ID); } $order = $this->_cartManagement->submit($quote); - if($context) { - $order->addStatusHistoryComment('heidelpay - Order created via ' . $context); + + if ($context) { + $order->addCommentToStatusHistory('heidelpay - Order created via ' . $context); } } + } finally { $this->lockManager->unlock($lockName); } @@ -434,7 +436,7 @@ public function getPaymentMethodAndType(Response $response) public function isNewOrderType($paymentMethod, $paymentType) { // Order should be created for incoming payments - if(in_array($paymentType, self::NEW_ORDER_TRANSACTION_TYPE_ARRAY, true)){ + if(\in_array($paymentType, self::NEW_ORDER_TRANSACTION_TYPE_ARRAY, true)){ return true; } // Reservation should only create order if its not online transfer payment method. From 59b05a3ca9dd2bbf87ddbdae15c759c9d73661fd Mon Sep 17 00:00:00 2001 From: sixer1182 Date: Fri, 8 May 2020 10:50:17 +0200 Subject: [PATCH 5/9] [change] (MAGE2-311) Abandon quote if it has an unknown payment method. --- Helper/Payment.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Helper/Payment.php b/Helper/Payment.php index 58c92d69d79..819b2a0f8ff 100755 --- a/Helper/Payment.php +++ b/Helper/Payment.php @@ -381,6 +381,7 @@ public function saveHeidelpayTransaction(Response $response, array $data, $sourc * @param Quote $quote * @return AbstractExtensibleModel|OrderInterface|Order|object|null * @throws LocalizedException + * @throws Exception */ public function handleOrderCreation($quote, $context = null) { @@ -398,15 +399,18 @@ public function handleOrderCreation($quote, $context = null) // in case of guest checkout, set some customer related data. if ($quote->getCustomerId() === null) { $quote->setCustomerId(null) - ->setCustomerEmail($quote->getBillingAddress()->getEmail()) - ->setCustomerIsGuest(true) - ->setCustomerGroupId(Group::NOT_LOGGED_IN_ID); + ->setCustomerEmail($quote->getBillingAddress()->getEmail()) + ->setCustomerIsGuest(true) + ->setCustomerGroupId(Group::NOT_LOGGED_IN_ID); } $order = $this->_cartManagement->submit($quote); if ($context) { $order->addCommentToStatusHistory('heidelpay - Order created via ' . $context); } + } elseif (!$this->orderHelper->hasHeidelpayPayment($order)) { + $quote->setIsActive(false)->save(); + throw new Exception('The basket has been reset because an order already exists.'); } } finally { From d29a35e78e95efa7632bee56594c17286a54fbe7 Mon Sep 17 00:00:00 2001 From: sixer1182 Date: Fri, 8 May 2020 10:51:49 +0200 Subject: [PATCH 6/9] [change] (MAGE2-311) Update CHANGELOG.md. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5a38d4454b..5f63cbf9db4 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ This project does not follow a versioning standard. Versions are crafted after t for secured payment methods and PayPal. - Disable caching for dynamic blocks. - An issue creating orders from Reservations. +- Problem when switching from an unknown payment method to a heidelpay gateway method. ## 20.2.24 ### Added From e594aedc336c035cb6359d9c2b3f63b42d730090 Mon Sep 17 00:00:00 2001 From: sixer1182 Date: Fri, 8 May 2020 12:03:58 +0200 Subject: [PATCH 7/9] [change] (MAGE2-311) Change unnecessary warning to debug. --- Controller/Index/Redirect.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Controller/Index/Redirect.php b/Controller/Index/Redirect.php index a1ce8da9f6b..6663a4ec36d 100755 --- a/Controller/Index/Redirect.php +++ b/Controller/Index/Redirect.php @@ -163,7 +163,7 @@ public function execute() /** @var Order $order */ $order = null; try { - $this->_logger->warning('Load order by QuoteId: ' . $quoteId); + $this->_logger->debug('Load order by QuoteId: ' . $quoteId); $order = $this->orderHelper->fetchOrderByQuoteId($quoteId); } catch (Exception $e) { $this->_logger->error( From 0144e6264f849b424ae52ced1fb59de9325057be Mon Sep 17 00:00:00 2001 From: sixer1182 Date: Fri, 8 May 2020 12:13:39 +0200 Subject: [PATCH 8/9] [change] (MAGE2-311) Add missing line. --- Helper/Order.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Helper/Order.php b/Helper/Order.php index 9f2d7bb7ace..c572cd38bd8 100644 --- a/Helper/Order.php +++ b/Helper/Order.php @@ -144,7 +144,6 @@ protected function fetchOrdersByQuoteId($quoteId): Collection return $orderList; } - /** * Returns true if the payment of the order is part of this payment module. * @@ -166,4 +165,4 @@ public function hasHeidelpayPayment(MagentoOrder $order): bool return $returnVal; } -} \ No newline at end of file +} From 95519815a2c3c720c358e8e6cea8844cd95000b2 Mon Sep 17 00:00:00 2001 From: sixer1182 Date: Fri, 8 May 2020 12:15:24 +0200 Subject: [PATCH 9/9] [change] (MAGE2-311) Fix tabs. --- Helper/Payment.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Helper/Payment.php b/Helper/Payment.php index 819b2a0f8ff..910aa9d26ee 100755 --- a/Helper/Payment.php +++ b/Helper/Payment.php @@ -399,9 +399,9 @@ public function handleOrderCreation($quote, $context = null) // in case of guest checkout, set some customer related data. if ($quote->getCustomerId() === null) { $quote->setCustomerId(null) - ->setCustomerEmail($quote->getBillingAddress()->getEmail()) - ->setCustomerIsGuest(true) - ->setCustomerGroupId(Group::NOT_LOGGED_IN_ID); + ->setCustomerEmail($quote->getBillingAddress()->getEmail()) + ->setCustomerIsGuest(true) + ->setCustomerGroupId(Group::NOT_LOGGED_IN_ID); } $order = $this->_cartManagement->submit($quote);