1

I'm working on magento 2.3.3. I've stuck in one place while was doing method that receives callbacks from custom payment gateway via magento web api. The main idea is to redirect customer to my custom gateway (that I've done) and after paying order this custom gateway has to send callback to magento's web api and update the order status. The webapi.xml:

<?xml version="1.0"?>
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
    <route url="/V1/orders/:id/statuses" method="POST">
          <service class="TarlanPay\TarlanPay\Api\Setorderstatus"
          method="status"/>  
    <resources>
        <resource ref="anonymous"/>
    </resources>
     <data>
        <parameter name="orderId" force="true">%reference_id%</parameter>
    </data>
</route>    

The main idea is to redirect customer to my custom gateway (that I've done) and after paying order this custom gateway has to send callback to magento's web api and update the order status. For now I've set web api and wrote the appropriate method to receive callbacks from gateway.

namespace TarlanPay\TarlanPay\Api;
Interface Setorderstatus{
/**
* @api
* @param int $id
* @return string
*/
 public function status($id);
} 

The code above shows my interface that I've set in webapi.xml. The code below shows the class that implements this interface and has method that has to update order status.

namespace TarlanPay\TarlanPay\Model;
use TarlanPay\TarlanPay\Api\Setorderstatus;
use \Magento\Sales\Model\Order;
use \Magento\Sales\Api\OrderRepositoryInterface;
/**
* @api
*/
Class SetorderstatusModel implements Setorderstatus, OrderRepositoryInterface{
    public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria){}
    public function get($id){}
    public function delete(\Magento\Sales\Api\Data\OrderInterface $entity){}
    public function save(\Magento\Sales\Api\Data\OrderInterface $entity){}
    /**
    * @return Model\SetorderstatusModel
    */
public function status($id){
    $tarlanResponse = file_get_contents('php://input');
    $tarlanData = json_decode($tarlanResponse, true);
    if(!empty($tarlanResponse)){
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $order = $objectManager->create('Magento\Sales\Api\Data\OrderInterface')->load($id);
        switch($tarlanData['status']){
            case 0:
            $order->setState(\Magento\Sales\Model\Order::STATE_PENDING)->setStatus(\Magento\Sales\Model\Order::STATE_PENDING);
            $order->save();
            break;
            case 1:
            $order->setState(\Magento\Sales\Model\Order::STATE_COMPLETE)->setStatus(\Magento\Sales\Model\Order::STATE_COMPLETE);
            $order->save();
            break;
            case 3:
            $order->setState(\Magento\Sales\Model\Order::STATE_PROCESSING)->setStatus(\Magento\Sales\Model\Order::STATE_PROCESSING);
            $this->_orderRepository->save($order);
            break;
            case 4:
            $order->setState(\Magento\Sales\Model\Order::STATE_CANCEL)->setStatus(\Magento\Sales\Model\Order::STATE_CANCEL);
            $this->_orderRepository->save($order);
            break;
            case 5:
            $order->setState(\Magento\Sales\Model\Order::STATE_CLOSED)->setStatus(\Magento\Sales\Model\Order::STATE_CLOSED);
            $this->_orderRepository->save($order);
            break;
            case 6:
            $order->setState(\Magento\Sales\Model\Order::STATE_FAIL)->setStatus(\Magento\Sales\Model\Order::STATE_FAIL);
            $this->_orderRepository->save($order);
            break;
            default:
            echo 'something';
            break;
        }
    }
    return true;
}
} 

The problem is, when I try to send some status through the postman, it returns me "400 Bad Request" and "message": "Please provide payment for the order.". Any help will be apreciated.here is Postman's request

2 Answers 2

0

I tried to implement my code in your function I am considering here $id means $orderId

$id = 1;

public function status($id){
    $tarlanResponse = file_get_contents('php://input');
    $tarlanData = json_decode($tarlanResponse, true);
    if(!empty($tarlanResponse)){
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $order = $objectManager->create('\Magento\Sales\Model\Order')->load($id);
        switch($tarlanData['status']){
            case 0:
            $orderState = Order::STATE_PENDING;
            $order->setState($orderState)->setStatus(Order::STATE_PENDING);
            $order->save();
            break;
            case 1:
            $orderState = Order::STATE_COMPLETE;
            $order->setState($orderState)->setStatus(Order::STATE_COMPLETE);
            $order->save();
            break;
            case 3:
            $orderState = Order::STATE_PROCESSING;
            $order->setState($orderState)->setStatus(Order::STATE_PROCESSING);
            $this->_orderRepository->save($order);
            break;
            case 4:
            $orderState = Order::STATE_CANCEL;
            $order->setState($orderState)->setStatus(Order::STATE_CANCEL);
            $this->_orderRepository->save($order);
            break;
            case 5:
            $orderState = Order::STATE_CLOSED;
            $order->setState($orderState)->setStatus(Order::STATE_CLOSED);
            $this->_orderRepository->save($order);
            break;
            case 6:
            $orderState = Order::STATE_FAIL;
            $order->setState($orderState)->setStatus(Order::STATE_FAIL);
            $this->_orderRepository->save($order);
            break;
            default:
            echo 'something';
            break;
        }
    }
    return true;
}
} 

Try this.

Sign up to request clarification or add additional context in comments.

6 Comments

It doesn't work. Maybe I use that in wrong way? Where exactly should I put this code? Since, my payment gateway sends custom statuses from 0 to 6 and I should connect them with magento statuses. For example when payment gateway sends status 1 it means success. When it sends status 6 means fail. But In your code the only state is processing. I also tried replace to STATE_COMPLETE, but still nothing...
Please check my updated solution, I have tried to implement my solution in your function. Try it.
One more suggestion for you that uses your code in a try-catch block so if there is any error occurs so, you can get an idea about the error.
Still the same issue. "message": "Please provide payment for the order."
$payment = $order->getPayment(); $method = $payment->getMethodInstance(); $methodTitle = $method->getTitle(); Check this it's giving you any payment method or not?
|
0

I still have no idead why it asked me to provide payment for the order. But now it's gone. And also I've faced another issue. When I tried to update status to complete it didn't work. Now I solved this one as well. It was because magento didn't register my order as invoiced order, thus it couldn't be as completed order. This is final code:

namespace TarlanPay\TarlanPay\Model;
 use TarlanPay\TarlanPay\Api\Setorderstatus;
 use \Magento\Sales\Model\Order;
 use \Magento\Sales\Api\OrderRepositoryInterface;
 use \Magento\Checkout\Model\Session;
 use \Magento\Sales\Model\Service\InvoiceService;

/**
* @api
*/

Class SetorderstatusModel implements Setorderstatus, OrderRepositoryInterface{

public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria){}
public function get($id){}
public function delete(\Magento\Sales\Api\Data\OrderInterface $entity){}
public function save(\Magento\Sales\Api\Data\OrderInterface $entity){}
  /**
  * @return Model\SetorderstatusModel
  */
public function status($id){
$tarlanResponse = file_get_contents('php://input');
$tarlanData = json_decode($tarlanResponse, true);
if(!empty($tarlanResponse)){
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $invoice = $objectManager->create('\Magento\Sales\Model\Service\InvoiceService');
    $order = $objectManager->create('\Magento\Sales\Model\Order')->load($id); // This is to correctly pass an argument that has been set in web api's url. For example my url looks like this - magento2/rest/V1/orders/12/statuses. Where 12 is order entity id.
    $invoice = $invoice->prepareInvoice($order); //this invoice is to update your status to complete
    $invoice->setRequestedCaptureCase(\Magento\Sales\Model\Order\Invoice::CAPTURE_ONLINE); //this invoice is to update your status to complete
    $invoice->register(); //this invoice is to update your status to complete
    switch($tarlanData['status']){
        case 0:
        $orderState = Order::STATE_PENDING_PAYMENT;
        $order->setState($orderState)->setStatus(Order::STATE_PENDING_PAYMENT);
        $order->save();
        break;
        case 1:
        $orderState = Order::STATE_COMPLETE;
        $order->setState($orderState)->setStatus(Order::STATE_COMPLETE);
        $order->save();
        break;
        case 2:
        $orderState = Order::STATE_PROCESSING;
        $order->setState($orderState)->setStatus(Order::STATE_PROCESSING);
        $order->save();
        break;
        case 3:
        $orderState = Order::STATE_PROCESSING;
        $order->setState($orderState)->setStatus(Order::STATE_PROCESSING);
        $order->save();
        break;
        case 4:
        $orderState = Order::STATE_CANCELED;
        $order->setState($orderState)->setStatus(Order::STATE_CANCELED);
        $order->save();
        break;
        case 5:
        $orderState = Order::STATE_CLOSED;
        $order->setState($orderState)->setStatus(Order::STATE_CLOSED);
        $this->_orderRepository->save($order);
        break;
        case 6:
        $orderState = Order::STATE_CANCELED;
        $order->setState($orderState)->setStatus(Order::STATE_CANCELED);
        $order->save();
        break;
        default:
        echo 'something';
        break;
    }
}
  return true;
 }
 }                                                                             

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.