Magento无法跳转至结账成功页问题咨询与解决方法
关于Magento支付回调跳转成功页的问题
场景与问题
我正在开发一个Magento支付模块,流程是:用户点击下单后,系统调用外部API获取唯一ID,把Magento订单ID和这个API唯一ID存到自定义表,然后构造带唯一ID的URL跳转到外部支付页面;支付完成后,用户会被重定向回Magento的指定回调控制器。
现在遇到的问题是:回调控制器里跳转到购物车页的代码能正常运行,但跳转到checkout/onepage/success成功页时,会自动跳回购物车页。
相关代码
回调控制器代码如下:
<?php namespace Namespace\Payment\Controller\Redirect; use Magento\Framework\App\ActionInterface; use Magento\Framework\App\RequestInterface; use Magento\Framework\App\ResponseInterface; use Magento\Framework\Controller\Result\RedirectFactory; use Namespace\Payment\Helper\Data as Helper; use Namespace\Payment\Model\MyOrder; class Callback implements ActionInterface { protected $request; protected $response; protected $helper; protected $redirectFactory; protected MyOrder $myOrder; public function __construct( RequestInterface $request, ResponseInterface $response, Helper $helper, MyOrder $myOrder, RedirectFactory $redirectFactory ) { $this->request = $request; $this->response = $response; $this->helper = $helper; $this->myOrder= $myOrder; $this->redirectFactory = $redirectFactory; } /** * {@inheritdoc} */ public function execute() { $orderId = '000000003'; // 这段代码无法正常跳转成功页 return $this->response->setRedirect( $this->helper->getSuccessUrl($orderId) )->sendResponse(); // 这段代码可以正常跳转购物车页 return $this->response->setRedirect( $this->helper->getCartUrl() )->sendResponse(); } }
助手类返回的成功页URL是https://whatever-ngrok-domain.app/checkout/onepage/success/?order_id=000000003,购物车页URL是https://whatever-ngrok-domain.app/checkout/cart/,且订单000000003确实存在。
排查发现的问题
深入查看Magento源码后,发现成功页控制器的isValid方法会验证会话数据,因为checkoutSession里没有填充LastSuccessQuoteId等数据,导致验证失败,自动跳回购物车:
public function isValid() { if (!$this->checkoutSession->getLastSuccessQuoteId()) { return false; } if (!$this->checkoutSession->getLastQuoteId() || !$this->checkoutSession->getLastOrderId()) { return false; } return true; }
解决方案
只要拿到对应的$order对象,就能把缺失的会话数据填充到checkoutSession里,具体操作如下:
- 在回调控制器的构造函数中注入
Magento\Checkout\Model\Session、Magento\Sales\Api\OrderRepositoryInterface和Magento\Quote\Model\QuoteRepository; - 在
execute方法中,通过订单ID获取完整的订单对象; - 从订单对象中取出关联的报价(Quote)ID,然后把需要的会话数据设置到
checkoutSession中; - 可选:清空当前用户的购物车,和正常下单流程保持一致;
- 最后再跳转到成功页。
修改后的控制器代码示例:
<?php namespace Namespace\Payment\Controller\Redirect; use Magento\Framework\App\ActionInterface; use Magento\Framework\App\RequestInterface; use Magento\Framework\App\ResponseInterface; use Magento\Framework\Controller\Result\RedirectFactory; use Namespace\Payment\Helper\Data as Helper; use Namespace\Payment\Model\MyOrder; use Magento\Checkout\Model\Session as CheckoutSession; use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Quote\Model\QuoteRepository; class Callback implements ActionInterface { protected $request; protected $response; protected $helper; protected $redirectFactory; protected MyOrder $myOrder; protected CheckoutSession $checkoutSession; protected OrderRepositoryInterface $orderRepository; protected QuoteRepository $quoteRepository; public function __construct( RequestInterface $request, ResponseInterface $response, Helper $helper, MyOrder $myOrder, RedirectFactory $redirectFactory, CheckoutSession $checkoutSession, OrderRepositoryInterface $orderRepository, QuoteRepository $quoteRepository ) { $this->request = $request; $this->response = $response; $this->helper = $helper; $this->myOrder= $myOrder; $this->redirectFactory = $redirectFactory; $this->checkoutSession = $checkoutSession; $this->orderRepository = $orderRepository; $this->quoteRepository = $quoteRepository; } /** * {@inheritdoc} */ public function execute() { $orderIncrementId = '000000003'; try { // 通过订单增量ID获取订单对象 $order = $this->orderRepository->get($orderIncrementId); // 获取关联的报价对象 $quote = $this->quoteRepository->get($order->getQuoteId()); // 填充checkoutSession所需的关键数据 $this->checkoutSession->setLastQuoteId($quote->getId()); $this->checkoutSession->setLastSuccessQuoteId($quote->getId()); $this->checkoutSession->setLastOrderId($order->getId()); $this->checkoutSession->setLastRealOrderId($order->getIncrementId()); // 清空购物车(可选,和正常下单流程保持一致) $quote->setIsActive(false)->save(); // 跳转到成功页 return $this->response->setRedirect( $this->helper->getSuccessUrl($orderIncrementId) )->sendResponse(); } catch (\Exception $e) { // 异常处理,比如跳转到错误页或者购物车 return $this->response->setRedirect( $this->helper->getCartUrl() )->sendResponse(); } } }
内容的提问来源于stack exchange,提问作者vkal
相关产品推荐
相关产品推荐

