3

I am unable to set payment transaction id after successful payment processing...

I have got payment confirmation transaction details by payment gateway on my controller action. Now I need to save the payment transaction id in \Magento\Payment\Model\InfoInterface $payment by using setTransactionId method of above interface.

But unable to use the \Magento\Payment\Model\InfoInterface

Using code

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$payment = $objectManager->get('\Magento\Payment\Model\InfoInterface');
$payment->setTransactionId(htmlentities($transaction_result->id))
                ->setIsTransactionClosed(0);

Getting error as: Cannot instantiate interface Magento\Payment\Model\InfoInterface

Please suggest way to get payment instance for save/update order transaction in custom method of model.

I am in return url page of payment

As I have redirected payment gateways after payment done or failed at payment on a controller action.

On the url's at controller, I need to get current order/payment and then update truncation id to that order/payment object.

I have just tried below solution:

protected $_checkoutSession;
public function __construct(
   ...
    \Magento\Checkout\Model\Session $checkoutSession,
    .....
) {
    $this->_checkoutSession = $checkoutSession;
}

 public function execute(){
    $order = $this->_checkoutSession->getLastRealOrder();
    $payment = $order->getPayment();
    $payment->setTransactionId(htmlentities($transaction_result->id));
    $payment->setIsTransactionClosed(0)
            ->setTransactionAdditionalInfo(
                    "some text",
                    htmlentities($transaction_result->id)
                );    
}

But $this->_checkoutSession comes with empty array... It means after coming back from payment gateway session get flushed... but how and why.. then how to get order object?

I have got order Increment id... Now how to get order object with order increment id?

I have also used below links:

Magento 2.1.1 How to load Order with Increment ID using OrderRepository object

https://github.com/magento/magento2/issues/3534#issuecomment-227413082

for get order object by order increment id but don't found order object yet for get payment object.

Update:

When i am coming back from payment gateway as redirect url on my module controller execute function i am not getting object manager or session object or order object... I dont know much about dependency injection... please elaborate if i have to create and put any code in the di file in etc folder...

below code are not working in my module controller execute function:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$payment = $objectManager->get('\Magento\Payment\Model\InfoInterface');

It return null/empty

And if I am using below code:

protected $_checkoutSession;
public function __construct(
   ...
    \Magento\Checkout\Model\Session $checkoutSession,
    .....
) {
    $this->_checkoutSession = $checkoutSession;
}

 public function execute(){
    $order = $this->_checkoutSession->getLastRealOrder();
    $payment = $order->getPayment();
    $payment->setTransactionId(htmlentities($transaction_result->id));
    $payment->setIsTransactionClosed(0)
            ->setTransactionAdditionalInfo(
                    "some text",
                    htmlentities($transaction_result->id)
                );    
}

then this also not working...

Please help to resolve the issue...

Ashish Raj
  • 1,325
  • 2
  • 15
  • 32
  • You can read Magento payment dev guide, it describes how you can use response handler to store transaction details http://devdocs.magento.com/guides/v2.1/payments-integrations/payment-gateway/response-handler.html – joni jones Feb 09 '17 at 09:13
  • I need payment object in return url page controller action of payment – Ashish Raj Feb 09 '17 at 10:12
  • You should not write any logic in controllers, they should be 'thin', you can call some service or gateway command instead and process all logic in response handlers. – joni jones Feb 09 '17 at 11:08
  • yes I try to call my model function of my module but getting same problem .. need payment/order object/instance for save transaction id ... – Ashish Raj Feb 09 '17 at 11:10
  • 1
    @AshishRaj, You can try with $order = $this->_checkoutSession->getLastRealOrderId(); to get order id instead of getLastRealOrder(); – Rakesh Jesadiya Feb 15 '17 at 06:18
  • I have the order incremented Id which i had pass to payment gateway and they giving me in response... What i need is a order object... for save payment transaction id in order... please help – Ashish Raj Feb 15 '17 at 06:24
  • Try with, public function __construct( \Magento\Framework\App\Action\Context $context, \Magento\Checkout\Model\Session $checkoutSession, \Magento\Sales\Model\OrderFactory $orderFactory, ) { $this->_checkoutSession = $checkoutSession; $this->_orderFactory = $orderFactory; parent::__construct($context); } $order = $this->_orderFactory->create()->loadByIncrementId($this->_checkoutSession->getLastRealOrderId()); – Rakesh Jesadiya Feb 15 '17 at 07:14
  • $order = $this->_orderFactory->create()->loadByIncrementId($this->_ch‌​eckoutSession->getLa‌​stRealOrderId()); is returning null... i am not able to create order object in my controller while coming back from payment gateway as return url... infact... not even order object but session object is also coming empty ... dont know why... – Ashish Raj Feb 15 '17 at 09:19
  • You cant get last order id in controller after order placed because after place order checkout session is flushed out. so you cant get last order id from checkout session – Rakesh Jesadiya Feb 15 '17 at 09:52
  • I have the order id and transaction id and order is just placessed but not finished... i am just get back from payment gateway and want to save order id and transaction id in order respectively... I need to get order object with my order id which i have already... but unable to get or create object in my controller action of redirect url of my payment gateway – Ashish Raj Feb 15 '17 at 10:30

4 Answers4

3

I was unable to save/update payment gateway transaction id in my order while coming back from payment gateway after successful payment but was getting in return url controller action..

I have solved my problem by adding another method in payment model and save transaction id with respect to order id in db and get that in capture method of payment model....

As I was unable to create/get object manger and session data variable in my controller and was unable to get transaction id in capture function of payment module which is already extending \Magento\Payment\Model\Method\Cc because of use of curl.

Transaction id is coming on redirect url controller action and then we are coming after curl excution line of code where i was needed to save transaction id in the order and payment.

As I am using CURL method in my payment capture function for call payment gateway and passing order id and order detail to payment gateway with a return url. Payment gateway successfully coming back on the return url controller action. So I call my payment model new function captureNew and pass transaction detail as a argument. Then go in payment module captureNew function and save transaction id with order id in a database custom table and after the execution of captureNew function...

Then it return back in capture method under the curl execution line and there I get the transaction id by the order id from db and save in the order and payment object by below code

$payment->setParentTransactionId(null);
$payment->setTransactionId($order_transactionId)->setIsTransactionClosed(0);
$order->save();
Ashish Raj
  • 1,325
  • 2
  • 15
  • 32
2

First, $payment object should be taken from order object.

So. You need change

$payment = $objectManager->get('\Magento\Payment\Model\InfoInterface');

to

  $payment = $orderObject->getPayment();
  $payment->setTransactionId(htmlentities($transaction_result->id));
        $payment->setIsTransactionClosed(0)
          ->setTransactionAdditionalInfo(
                            "some text",
                            htmlentities($transaction_result->id)
                        );    

Modify code in return url page of payment

As you have redirect to our customer at payment gateways then there should be a page in magento where our customer will be redirect after payment done or failed at payment.

On that url's at controller, you need to get current order from checkout session \Magento\Checkout\Model\Session .then you need to update truncation id to that order object.

At controller class. You need inject some class from which you can get Order object \Magento\Checkout\Model\Session

protected $_checkoutSession;
public function __construct(
   ...
    \Magento\Checkout\Model\Session $checkoutSession,
    .....
) {
    $this->_checkoutSession = $checkoutSession;
}

 public function execute(){
    $order = $this->_checkoutSession->getLastRealOrder();
    $payment = $order->getPayment();
    $payment->setTransactionId(htmlentities($transaction_result->id));
    $payment->setIsTransactionClosed(0)
            ->setTransactionAdditionalInfo(
                    "some text",
                    htmlentities($transaction_result->id)
                );    
}
Amit Bera
  • 77,456
  • 20
  • 123
  • 237
2

You need to put below code in the success action of your code when responce came after successfull payment.

$order = $this->getOrder();
$payment = $order->getPayment();

$trans_id = 'Transection id returned from Brantree Payment';            
$payment->setLastTransId($trans_id);
$payment->setTransactionId($trans_id);
$payment->setAdditionalInformation(
      [\Magento\Sales\Model\Order\Payment\Transaction::RAW_DETAILS => (array)$payment->getAdditionalInformation()]
);
$formatedPrice = $order->getBaseCurrency()->formatTxt(
                $order->getGrandTotal()
            );

$message = __('The Captured amount is %1.', $formatedPrice);
//get the object of builder class Magento\Sales\Model\Order\Payment\Transaction\Builder
$trans = $this->_transactionBuilder;
$transaction = $trans->setPayment($payment)
->setOrder($order)
            ->setTransactionId($trans_id)
            ->setAdditionalInformation(
                [\Magento\Sales\Model\Order\Payment\Transaction::RAW_DETAILS => (array)$payment->getAdditionalInformation()]
            )
            ->setFailSafe(true)
            //build method creates the transaction and returns the object
            ->build(\Magento\Sales\Model\Order\Payment\Transaction::TYPE_CAPTURE);

            $payment->addTransactionCommentsToOrder(
                $transaction,
                $message
            );
            $payment->setParentTransactionId(null);

            $payment->save();
            $order->save();
            $transaction->save();

Thanks

Sanjay Jethva
  • 1,399
  • 4
  • 18
  • 40
  • i was unable to get transaction id in capture method of payment model but was getting in return url controller action.. I have solved my problem by adding another method in payment model and save transaction id with respect to order id in db and get that in capture method of payment model...

    Thanks for your answer...

    – Ashish Raj Feb 21 '17 at 10:46
0

I have the same problem, but this only happens when I try to generate invoices in Loop. The first transaction creates an invoice & transaction in DB but when I attempt to capture payment ( ONLINE ) in the loop for second order, the system generates invoices correctly. Still, when I save the order to Generate a Capture Transaction in Db, the system gives me an error.

{"error":"Set order for existing transactions not allowed"}

private function processNewInvoice(Order $order, array $items, $amount, $pendingInvoice, $id): Invoice|bool { try { $this->_logger->info('Invoice Creation', ['invoice' => $pendingInvoice . '-' . $order->getEntityId()]);

    $newInvoice = $order->prepareInvoice($items);

    $newInvoice->setGrandTotal($amount);

    $newInvoice->setData('ora_invoice_number', $pendingInvoice);

    $newInvoice->setBaseGrandTotal($amount);

    $this->_logger->info('Invoice to be processed', ['invoice' => $newInvoice->getData()]);

    if (!$newInvoice->getTotalQty()) {
        $this->_logger->debug('Cannot create an invoice without products for order ' . $order->getIncrementId());
        throw new LocalizedException(__('Cannot create an invoice without products'));
    }

    $newInvoice->setRequestedCaptureCase(Invoice::CAPTURE_ONLINE);

    $newInvoice->register();

    $newInvoice->getOrder()->setIsInProcess(true);

    $newInvoice->save();

    //Create Transaction
    $transaction = $this->transactionFactory->create()
        ->addObject($newInvoice)
        ->addObject($order);
    $transaction->save();

    $comment = 'Amount of $' . number_format($newInvoice->getGrandTotal(), 2) . '. Transaction ID: "' . $newInvoice->getTransactionId() . '"';
    $order->addCommentToStatusHistory($comment)->save();

} catch (\Exception $exception) {
    $this->_logger->critical('Cannot create invoice', ['error' => $exception->getMessage()]);
}

$this->_logger->info('Invoice Saved and captured', ['invoice' => $newInvoice->getId()]);

return $newInvoice;

}