cancel
Showing results for 
Search instead for 
Did you mean: 

on successfull transaction(Paytabs) change status to Processing instead of complete

on successfull transaction(Paytabs) change status to Processing instead of complete

We have different kind of order buttons like processing,packaging,shipment and finally complete.

Problem is on successful transaction pay-tabs gateway changing status directly to complete so we are unable to perform further processes like processing,packaging,shipment.

 

I am sharing paytabs responce controller code. Please suggest me what can i change in the code so status should go for processing.

<?php

// declare(strict_types=1);

namespace Paytabs\Paytabexpress\Controller\Ipn;

use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\View\Result\Page;
use Magento\Framework\View\Result\PageFactory;
use Magento\Sales\Model\Order;

/**
 * Class Index
 */
class Response extends Action
{
    /**
     * @var PageFactory
     */
    private $pageFactory;

    /**
     * @var Magento\Sales\Model\Order\Email\Sender\OrderSender
     */
    private $_orderSender;

    // protected $resultRedirect;
    private $paytabs;

    /**
     * @var \Psr\Log\LoggerInterface
     */
    protected $_logger;


    /**
     * @param Context $context
     * @param PageFactory $pageFactory
     */
    public function __construct(
        Context $context,
        PageFactory $pageFactory,
        \Magento\Sales\Model\Order\Email\Sender\OrderSender $orderSender,
        \Psr\Log\LoggerInterface $logger
    ) {
        parent::__construct($context);

        $this->pageFactory = $pageFactory;
        $this->_orderSender = $orderSender;
        $this->_logger = $logger;
        // $this->resultRedirect = $context->getResultFactory();

        $this->paytabs = new \Paytabs\Paytabexpress\Gateway\Api;
    }

    /**
     * @return ResponseInterface|ResultInterface|Page
     */
    public function execute()
    {
        if (!$this->getRequest()->isPost()) {
            $this->_logger->addError("Paytabs: no post back data received in callback");
            return;
        }

        // Get the params that were passed from our Router
        $orderId = $this->getRequest()->getParam('order_id', null);
        $transactionId = $this->getRequest()->getParam('transaction_id', null);

        $resultRedirect = $this->resultRedirectFactory->create();

        //

        if (!$orderId || !$transactionId) {
            $this->_logger->addError("Paytabs: OrderId/TransactionId data did not receive in callback");
            return;
        }

        //

        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $order = $objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId($orderId);

        if (!$order) {
            $this->_logger->addError("Paytabs: Order is missing, Order param = [{$orderId}]");
            return;
        }

        $payment = $order->getPayment();
        $paymentMethod = $payment->getMethodInstance();

        $paymentSuccess = $paymentMethod->getConfigData('order_success_status');
        if (!$paymentSuccess) $paymentSuccess = Order::STATE_PROCESSING;
        $paymentFailed = $paymentMethod->getConfigData('order_failed_status');
        if (!$paymentFailed) $paymentFailed = Order::STATE_CANCELED;

        $secretsign = $paymentMethod->getConfigData('secretsign');
        $sendInvoice = $paymentMethod->getConfigData('send_invoice');
        if (!$sendInvoice) $sendInvoice = false;

        //

        $secured = $this->verifySecure($this->getRequest()->getParams(), $secretsign);
        if (!$secured) {
            $this->_logger->addError("Paytabs Response signature did not match, Order param = [{$orderId}] ");

            $order->addStatusToHistory(Order::STATE_CANCELED, "Paytabs Response signature does not match. You might have received tampered data");
            $order->cancel()->save();
            $resultRedirect->setPath('checkout/onepage/failure');
            return $resultRedirect;
        }

        //

        $ptApi = $this->paytabs->pt($paymentMethod);

        $verify_response = $ptApi->verify_payment($transactionId, $orderId);
        if (!$verify_response) {
            $this->_logger->addError("Paytabs Response: verify payload is empty, Order param = [{$orderId}] ");
            return;
        }

        // $orderId = $verify_response->reference_no;
        if ($orderId != $verify_response->order_id) {
            $this->_logger->addError("Paytabs Response: Order reference number is mismatch, Order = [{$orderId}], ReferenceId = [{$verify_response->reference_no}] ");
            $this->messageManager->addWarningMessage('Order reference number is mismatch');
            $resultRedirect->setPath('checkout/onepage/failure');
            return $resultRedirect;
        }

        //if get response successful
        $success = ($verify_response->response_code == 100);
        $res_msg = $verify_response->result;

        $verifyPayment = $success;

        if ($verifyPayment) {
            // PayTabs "Transaction ID"
            $txnId = $transactionId;
            $paymentAmount = $verify_response->amount;
            $paymentCurrency = $verify_response->currency;

            $payment
                ->setTransactionId($txnId)
                ->setLastTransId($txnId)
                ->setCcTransId($txnId)
                ->setIsTransactionClosed(false)
                ->setShouldCloseParentTransaction(true)
                ->setAdditionalInformation("Payment amount", $paymentAmount)
                ->setAdditionalInformation("Payment currency", $paymentCurrency)
                ->save();

            if ($sendInvoice) {
                $payment->registerCaptureNotification($paymentAmount, true)->save();

                $invoice = $payment->getCreatedInvoice();
                if ($invoice && !$order->getEmailSent()) {
                    $this->_orderSender->send($order);
                    $order->addStatusHistoryComment(
                        __('You notified customer about invoice #%1.', $invoice->getIncrementId())
                    )
                        ->setIsCustomerNotified(true)
                        ->save();
                }
            }

            $transType = \Magento\Sales\Model\Order\Payment\Transaction::TYPE_CAPTURE;
            $transaction = $payment->addTransaction($transType, null, false);
            $transaction
                ->setIsClosed(true)
                ->setParentTxnId(null)
                ->save();


            $orderState = Order::STATE_PROCESSING; //$paymentSuccess
            $this->setNewStatus($order, $orderState);

            $this->messageManager->addSuccessMessage($res_msg);
            $resultRedirect->setPath('checkout/onepage/success');
        } else {
            $this->_logger->addError("Paytabs Response: Payment verify failed [$res_msg] for Order {$orderId}");
            $payment->setIsTransactionPending(true);
            $payment->setIsFraudDetected(true);

            // $orderState = Order::STATE_CANCELED;
            $this->setNewStatus($order, $paymentFailed);

            $this->messageManager->addErrorMessage($res_msg);
            // $resultRedirect->setPath('checkout/onepage/failure');
        }

        return $resultRedirect;

        // return $this->pageFactory->create();
    }

    //

    public function setNewStatus($order, $newStatus)
    {
        if ($newStatus == Order::STATE_CANCELED) {
            $order->cancel();
        } else {
            $order->setState($newStatus)->setStatus($newStatus);
            $order->addStatusToHistory($newStatus, "Order was set to '$newStatus' as in the admin's configuration.");
        }
        $order->save();
    }

    function verifySecure($pdata, $secretsign)
    {
        $params = array(
            'order_id' => $pdata['order_id'],
            'response_code' => $pdata['response_code'],
            'customer_name' => $pdata['customer_name'],
            'transaction_currency' => $pdata['transaction_currency'],
            'last_4_digits' => $pdata['last_4_digits'],
            'customer_email' => $pdata['customer_email']
        );
        $calSignature = $this->create_secure_hash($params, $secretsign);

        $signature = $pdata['secure_sign'];

        if ($calSignature != "" && strcmp($signature, $calSignature) != 0) {
            return false;
        }
        return true;
    }

    protected function create_secure_hash($params = array(), $shain_phrase)
    {
        $string = ''; // SHA phrase
        ksort($params); // Sorting the params
        foreach ($params as $keys => $values) {
            $string .= strtoupper($keys) . '=' . $values . $shain_phrase;
            // Combining the field values in one string
        }
        // SHA Converting here
        $secure_sign = sha1($string); // Converting the values to SHA1 format
        return $secure_sign;
    }
}

/**
 * move CRSF verification to Plugin
 * compitable with old Magento version >=2.0 && <2.3
 * compitable with PHP version 5.6
 */

 

 

 

1 REPLY 1

Re: on successfull transaction(Paytabs) change status to Processing instead of complete

Hello @tippanna_pawar ,

 

The above shared code doesn't have code where the status is changing to Complete. Either this file is not being called or there is some other piece of code for ex: plugin, which is changing the status.
Try to find STATE_SUCCESS keyword in your module to know where it is changing status.

Problem Solved ? Click on 'Kudos' & Accept as Solution ! Smiley Happy