Skip to content
This repository has been archived by the owner on Feb 16, 2022. It is now read-only.

Mage2 108/change/create order from push #116

Merged
merged 30 commits into from
Nov 25, 2019
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f0b2356
(MAGE2-108) change: Create order from push, if it doesn't exists already
Ryouzanpaku Jun 17, 2019
92179f4
(MAGE2-108) change: Create basic integration test for push notification
Ryouzanpaku Jul 2, 2019
00ca178
(MAGE2-108) change: add test cases for different transaction types.
Ryouzanpaku Jul 3, 2019
b1087a7
(MAGE2-108) change: also handle additional payment info in push.
Ryouzanpaku Jul 4, 2019
b025189
(MAGE2-108) change: Create order from push, if it doesn't exists already
Ryouzanpaku Jun 17, 2019
0ff81e6
(MAGE2-108) change: Create basic integration test for push notification
Ryouzanpaku Jul 2, 2019
b8599f6
(MAGE2-108) change: add test cases for different transaction types.
Ryouzanpaku Jul 3, 2019
305e6fb
(MAGE2-108) change: also handle additional payment info in push.
Ryouzanpaku Jul 4, 2019
b72f991
(MAGE2-108) fix style issue
Ryouzanpaku Jul 10, 2019
3dcaa0a
Merge remote-tracking branch 'gitHub/develop' into MAGE2-108/change/c…
Ryouzanpaku Aug 1, 2019
50f5cbd
Merge remote-tracking branch 'gitHub/MAGE2-108/change/create_order_fr…
Ryouzanpaku Aug 1, 2019
9f64974
(MAGE2-108) fix: cleanup code
Ryouzanpaku Aug 1, 2019
7ea1e56
Merge remote-tracking branch 'gitHub/develop' into MAGE2-108/change/c…
Ryouzanpaku Aug 7, 2019
d3ff282
(MAGE2-108) fix merge issues.
Ryouzanpaku Aug 7, 2019
210ecbd
(MAGE2-108) [refactor] cleanup code.
Ryouzanpaku Aug 8, 2019
8c4a010
(MAGE2-108) [change] Test: Add ResponseHelperMock in order to make them
Ryouzanpaku Aug 8, 2019
3ba634d
(MAGE2-108) [change] code style.
Ryouzanpaku Aug 15, 2019
479f95a
Update Controller/Index/Push.php
Ryouzanpaku Oct 24, 2019
b1f0f23
Update Helper/Payment.php
Ryouzanpaku Oct 24, 2019
4dbf96b
(MAGE2-231) [refactor] code style.
Ryouzanpaku Oct 24, 2019
f4d1443
(MAGE2-231) [refactor] correct some file headers.
Ryouzanpaku Oct 24, 2019
fbc9a9e
(MAGE2-231) [refactor] use test annotations for push tests.
Ryouzanpaku Oct 24, 2019
412ecdf
Merge remote-tracking branch 'gitHub/MAGE2-108/change/create_order_fr…
Ryouzanpaku Oct 24, 2019
cbd7151
(MAGE2-231) [fix] composer.json
Ryouzanpaku Oct 28, 2019
10621d1
Merge remote-tracking branch 'gitHub/develop' into MAGE2-108/change/c…
Ryouzanpaku Nov 5, 2019
3bdfc74
(MAGE2-231) [fix] Add missing headers
Ryouzanpaku Nov 12, 2019
4986200
(MAGE2-231) [change] Refactor tests.
Ryouzanpaku Nov 12, 2019
0d82181
(MAGE2-231) [change] cleanup composer.json
Ryouzanpaku Nov 12, 2019
b2b9389
(MAGE2-231) [change] code style.
Ryouzanpaku Nov 15, 2019
151b2c0
(MAGE2-231) [change] code style.
Ryouzanpaku Nov 15, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
259 changes: 156 additions & 103 deletions Controller/Index/Push.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,37 @@

namespace Heidelpay\Gateway\Controller\Index;

use Heidelpay\Gateway\Controller\HgwAbstract;
use Heidelpay\Gateway\Helper\Order as orderHelper;
use Heidelpay\Gateway\Helper\Payment as PaymentHelper;
use Heidelpay\Gateway\PaymentMethods\HeidelpayAbstractPaymentMethod;
use Heidelpay\PhpPaymentApi\Exceptions\XmlResponseParserException;
use Heidelpay\PhpPaymentApi\Push as heidelpayPush;
use Magento\Checkout\Model\Session as CheckoutSession;
use Magento\Customer\Model\Session as CustomerSession;
use Magento\Customer\Model\Url;
use Heidelpay\Gateway\Helper\Response as ResponseHelper;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\Request\Http;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\Encryption\Encryptor;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Url\Helper\Data;
use Magento\Framework\View\Result\PageFactory;
use Magento\Quote\Api\CartManagementInterface;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\QuoteRepository;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Email\Sender\InvoiceSender;
use Magento\Sales\Model\Order\Email\Sender\OrderCommentSender;
use Magento\Sales\Model\Order\Email\Sender\OrderSender;
use Magento\Sales\Model\Order\Payment\Transaction;
use Magento\Sales\Model\Order\Invoice;
use Magento\Sales\Model\Order\Payment\Transaction;
use Magento\Sales\Model\OrderFactory;
use Magento\Sales\Model\OrderRepository;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\ResourceModel\Order\Collection;
use Heidelpay\Gateway\PaymentMethods\HeidelpayAbstractPaymentMethod;
use Psr\Log\LoggerInterface;

/**
* heidelpay Push Controller
Expand All @@ -27,59 +47,65 @@
*
* @package heidelpay\magento2\controllers
*/
class Push extends \Heidelpay\Gateway\Controller\HgwAbstract
class Push extends HgwAbstract
{
/** @var OrderRepository $orderRepository */
private $orderRepository;

/** @var \Heidelpay\PhpPaymentApi\Push */
/** @var heidelpayPush */
private $heidelpayPush;

/** @var SearchCriteriaBuilder */
private $searchCriteriaBuilder;
/** @var QuoteRepository */
private $quoteRepository;
/** @var orderHelper */
private $orderHelper;

/** @var ResponseHelper */
private $repsonseHelper;

/**
* @param \Magento\Framework\App\Action\Context $context
* @param \Magento\Customer\Model\Session $customerSession
* @param \Magento\Checkout\Model\Session $checkoutSession
* @param \Magento\Sales\Model\OrderFactory $orderFactory
* @param \Magento\Framework\Url\Helper\Data $urlHelper
* @param \Psr\Log\LoggerInterface $logger
* @param \Magento\Quote\Api\CartManagementInterface $cartManagement
* @param \Magento\Quote\Api\CartRepositoryInterface $quoteObject
* @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
* @param \Heidelpay\Gateway\Helper\Payment $paymentHelper
* @param Context $context
* @param CustomerSession $customerSession
* @param CheckoutSession $checkoutSession
* @param OrderFactory $orderFactory
* @param Data $urlHelper
* @param LoggerInterface $logger
* @param CartManagementInterface $cartManagement
* @param CartRepositoryInterface $quoteObject
* @param PageFactory $resultPageFactory
* @param PaymentHelper $paymentHelper
* @param OrderSender $orderSender
* @param InvoiceSender $invoiceSender
* @param OrderCommentSender $orderCommentSender
* @param \Magento\Framework\Encryption\Encryptor $encryptor
* @param \Magento\Customer\Model\Url $customerUrl
* @param Encryptor $encryptor
* @param Url $customerUrl
* @param OrderRepository $orderRepository
* @param \Heidelpay\PhpPaymentApi\Push $heidelpayPush
* @param heidelpayPush $heidelpayPush
* @param SearchCriteriaBuilder $searchCriteriaBuilder
* @param QuoteRepository $quoteRepository
* @param orderHelper $orderHelper
* @param ResponseHelper $repsonseHelper
*/
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Customer\Model\Session $customerSession,
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Sales\Model\OrderFactory $orderFactory,
\Magento\Framework\Url\Helper\Data $urlHelper,
\Psr\Log\LoggerInterface $logger,
\Magento\Quote\Api\CartManagementInterface $cartManagement,
\Magento\Quote\Api\CartRepositoryInterface $quoteObject,
\Magento\Framework\View\Result\PageFactory $resultPageFactory,
\Heidelpay\Gateway\Helper\Payment $paymentHelper,
Context $context,
CustomerSession $customerSession,
CheckoutSession $checkoutSession,
OrderFactory $orderFactory,
Data $urlHelper,
LoggerInterface $logger,
CartManagementInterface $cartManagement,
CartRepositoryInterface $quoteObject,
PageFactory $resultPageFactory,
PaymentHelper $paymentHelper,
OrderSender $orderSender,
InvoiceSender $invoiceSender,
OrderCommentSender $orderCommentSender,
\Magento\Framework\Encryption\Encryptor $encryptor,
\Magento\Customer\Model\Url $customerUrl,
Encryptor $encryptor,
Url $customerUrl,
OrderRepository $orderRepository,
\Heidelpay\PhpPaymentApi\Push $heidelpayPush,
heidelpayPush $heidelpayPush,
QuoteRepository $quoteRepository,
orderHelper $orderHelper,
SearchCriteriaBuilder $searchCriteriaBuilder,
ResponseHelper $repsonseHelper
) {
Expand All @@ -103,25 +129,28 @@ public function __construct(

$this->orderRepository = $orderRepository;
$this->heidelpayPush = $heidelpayPush;
$this->quoteRepository = $quoteRepository;
$this->orderHelper = $orderHelper;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->repsonseHelper = $repsonseHelper;
}

/**
* @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface|void
* @throws \Heidelpay\PhpPaymentApi\Exceptions\XmlResponseParserException
* @return ResponseInterface|ResultInterface|void
* @throws XmlResponseParserException
* @throws NoSuchEntityException
*/
public function execute()
{
/** @var \Magento\Framework\App\Request\Http $request */
/** @var Http $request */
$request = $this->getRequest();

if (!$request->isPost()) {
$this->_logger->debug('Heidelpay - Push: Response is not post.');
return;
}

if ($request->getHeader('Content-Type') != 'application/xml') {
if ($request->getHeader('Content-Type') !== 'application/xml') {
$this->_logger->debug('Heidelpay - Push: Content-Type is not "application/xml"');
}

Expand Down Expand Up @@ -153,80 +182,104 @@ public function execute()
$pushResponse->getPayment()->getCode()
);

// in case of receipts, we process the push message for receipts.
if ($this->_paymentHelper->isReceiptAble($paymentMethod, $paymentType) && $pushResponse->isSuccess()) {
// load the referenced order to receive the order information.
$criteria = $this->searchCriteriaBuilder
->addFilter(
'quote_id',
$pushResponse->getIdentification()->getTransactionId()
)->create();

/** @var Collection $orderList */
$orderList = $this->orderRepository->getList($criteria);

/** @var Order $order */
$order = $orderList->getFirstItem();
$payment = $order->getPayment();

/** @var HeidelpayAbstractPaymentMethod $methodInstance */
$methodInstance = $payment->getMethodInstance();
$transactionID = $pushResponse->getPaymentReferenceId();

/** @var bool $transactionExists Flag to identify new Transaction*/
$transactionExists = $methodInstance->heidelpayTransactionExists($transactionID);

// If Transaction already exists, push wont be processed.
if ($transactionExists) {
$this->_logger->debug('heidelpay - Push Response: ' . $transactionID . ' already exists');
return;
}
// Only process transactions that might potentially create new order, this includes receipts.
if ($pushResponse->isSuccess() && $this->_paymentHelper->isNewOrderType($paymentType)) {

$transactionId = $pushResponse->getIdentification()->getTransactionId();
$order = $this->orderHelper->fetchOrder($transactionId);
$quote = $this->quoteRepository->get($transactionId);

$paidAmount = (float)$pushResponse->getPresentation()->getAmount();
$dueLeft = $order->getTotalDue() - $paidAmount;
// create order if it doesn't exists already.
if ($order === null || $order->isEmpty()) {
$transactionData = $this->_paymentHelper->getDataFromResponse($pushResponse);
$this->_paymentHelper->saveHeidelpayTransaction($pushResponse, $transactionData, 'PUSH');
$this->_logger->debug('heidelpay Push - Order does not exist for transaction. heidelpay transaction id: '
. $transactionId);

$state = Order::STATE_PROCESSING;
$comment = 'heidelpay - Purchase Complete';
try {
$order = $this->_paymentHelper->createOrderFromQuote($quote);
if ($order === null || $order->isEmpty())
{
$this->_logger->error('Heidelpay - Response: Cannot submit the Quote. ' . $e->getMessage());
return;
}
} catch (Exception $e) {
$this->_logger->error('Heidelpay - Response: Cannot submit the Quote. ' . $e->getMessage());
return;
}

// if payment is not complete
if ($dueLeft > 0.00) {
$state = Order::STATE_PAYMENT_REVIEW;
$comment = 'heidelpay - Partly Paid ('
. $this->_paymentHelper->format(
$pushResponse->getPresentation()->getAmount()
)
. ' ' . $pushResponse->getPresentation()->getCurrency() . ')';
$this->_paymentHelper->mapStatus($transactionData, $order);
Ryouzanpaku marked this conversation as resolved.
Show resolved Hide resolved
$this->_logger->debug('order status: ' . $order->getStatus());
$this->orderHelper->handleOrderMail($order);
$this->orderHelper->handleInvoiceMails($order);
$this->orderRepository->save($order);
}
$this->_paymentHelper->handleAdditionalPaymentInformation($quote);


if ($this->_paymentHelper->isReceiptAble($paymentMethod, $paymentType)) {
Ryouzanpaku marked this conversation as resolved.
Show resolved Hide resolved
// load the referenced order to receive the order information.
$payment = $order->getPayment();

/** @var HeidelpayAbstractPaymentMethod $methodInstance */
$methodInstance = $payment->getMethodInstance();
$uniqueId = $pushResponse->getPaymentReferenceId();

// set the invoice states to 'paid', if no due is left.
if ($dueLeft <= 0.00) {
/** @var \Magento\Sales\Model\Order\Invoice $invoice */
foreach ($order->getInvoiceCollection() as $invoice) {
$invoice->setState(Invoice::STATE_PAID)->save();
/** @var bool $transactionExists Flag to identify new Transaction */
$transactionExists = $methodInstance->heidelpayTransactionExists($uniqueId);

// If Transaction already exists, push wont be processed.
if ($transactionExists) {
$this->_logger->debug('heidelpay - Push Response: ' . $uniqueId . ' already exists');
return;
}
}

$order->setTotalPaid($order->getTotalPaid() + $paidAmount)
->setBaseTotalPaid($order->getBaseTotalPaid() + $paidAmount)
->setState($state)
->addStatusHistoryComment($comment, $state);

// create a heidelpay Transaction.
$methodInstance->saveHeidelpayTransaction(
$pushResponse,
$paymentMethod,
$paymentType,
'PUSH',
[]
);
$paidAmount = (float)$pushResponse->getPresentation()->getAmount();
$dueLeft = $order->getTotalDue() - $paidAmount;

// create a child transaction.
$payment->setTransactionId($transactionID)
->setParentTransactionId($pushResponse->getIdentification()->getReferenceId())
->setIsTransactionClosed(true)
->addTransaction(Transaction::TYPE_CAPTURE, null, true);
$state = Order::STATE_PROCESSING;
$comment = 'heidelpay - Purchase Complete';

$this->orderRepository->save($order);
// if payment is not complete
if ($dueLeft > 0.00) {
$state = Order::STATE_PAYMENT_REVIEW;
$comment = 'heidelpay - Partly Paid ('
. $this->_paymentHelper->format(
$pushResponse->getPresentation()->getAmount()
)
. ' ' . $pushResponse->getPresentation()->getCurrency() . ')';
}

// set the invoice states to 'paid', if no due is left.
if ($dueLeft <= 0.00) {
/** @var Invoice $invoice */
foreach ($order->getInvoiceCollection() as $invoice) {
$invoice->setState(Invoice::STATE_PAID)->save();
}
}

$order->setTotalPaid($order->getTotalPaid() + $paidAmount)
->setBaseTotalPaid($order->getBaseTotalPaid() + $paidAmount)
->setState($state)
->addStatusHistoryComment($comment, $state);

// create a heidelpay Transaction.
$methodInstance->saveHeidelpayTransaction(
Ryouzanpaku marked this conversation as resolved.
Show resolved Hide resolved
$pushResponse,
$paymentMethod,
$paymentType,
'PUSH',
[]
);

// create a child transaction.
$payment->setTransactionId($uniqueId)
->setParentTransactionId($pushResponse->getIdentification()->getReferenceId())
->setIsTransactionClosed(true)
->addTransaction(Transaction::TYPE_CAPTURE, null, true);

$this->orderRepository->save($order);
}
}
}
}
5 changes: 3 additions & 2 deletions Controller/Index/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ public function execute()
$this->orderRepository->save($order);
}

$this->handleAdditionalPaymentInformation($quote);
$this->_paymentHelper->handleAdditionalPaymentInformation($quote);
$this->_logger->debug('Heidelpay - Response: redirectUrl is ' . $redirectUrl);

// return the heidelpay response url as raw response instead of echoing it out.
Expand All @@ -281,12 +281,13 @@ public function execute()

/**
* Send order confirmation to the customer
* @param $order
* @param Order $order
*/
protected function handleOrderMail($order)
{
try {
if ($order && $order->getId()) {
$this->_logger->debug('heidelpay Response - sending mail for order ' . $order->getIncrementId());
$this->_orderSender->send($order);
}
} catch (Exception $e) {
Expand Down
2 changes: 1 addition & 1 deletion Gateway/Config/HgwMainConfigInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* This class provides the interface to the HgwMainConfiguration getters.
*
* @license Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
* @copyright Copyright © 2016-present Heidelberger Payment GmbH. All rights reserved.
* @copyright Copyright © 2016-present heidelpay GmbH. All rights reserved.
*
* @author Simon Gabriel <development@heidelpay.com>
*
Expand Down
2 changes: 1 addition & 1 deletion Helper/BasketHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* The payment helper is a collection of function to prepare an send
*
* @license Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
* @copyright Copyright © 2016-present Heidelberger Payment GmbH. All rights reserved.
* @copyright Copyright © 2016-present heidelpay GmbH. All rights reserved.
*
* @link https://dev.heidelpay.de/magento
*
Expand Down
Loading