You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenCart Theme Journal订单完成前自动跳转支付站点异常问题

问题与解决方案:OpenCart Journal主题下Moyasar3支付插件跳转异常

问题现象

在OpenCart搭配Journal主题使用Moyasar3支付插件时,出现订单流程异常:用户尚未填写姓名、地址等必填结账字段,就被自动跳转至Moyasar支付站点。尝试在代码中添加return $this->load->view('extension/payment/moyasar3', $data);后问题仍未解决,相关核心代码如下:

public function index()
{
    $this->load->language('extension/payment/moyasar3');
    $this->load->model('extension/payment/moyasar3');
    $this->load->model('checkout/order');

    $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);

    $amount = $this->currency->format(
        $order_info['total'],
        $order_info['currency_code'],
        $order_info['currency_value'],
        false
    );

    $amount *= 100;

    $invoice = [
        'amount' => round($amount),
        'description' => 'Order id #' . $this->session->data['order_id'],
        'currency' => $order_info['currency_code'],
        'success_url' => $this->url->link('extension/payment/moyasar3/callback', '', true),
        'back_url' => $this->url->link('checkout/cart'),
        'metadata' => [
            'order_id' => $this->session->data['order_id'],
            'firstname' => $order_info['firstname'],
            'lastname' => $order_info['lastname'],
            'telephone' => $order_info['telephone'],
            'email' => $order_info['email'],
            'shipping_address_1' => $order_info['shipping_address_1'],
            'shipping_address_2' => $order_info['shipping_address_2'],
            'shipping_city' => $order_info['shipping_city'],
            'shipping_zone' => $order_info['shipping_zone'],
            'shipping_postcode' => $order_info['shipping_postcode'],
            'orderdate' => $order_info['date_added']
        ]
    ];

    try {
        $response = (new QuickHttp)
            ->basic_auth($this->config->get('payment_moyasar3_api_secret_key'))
            ->post('https://api.moyasar.com/v1/invoices', $invoice)
            ->json();
    } catch (QuickHttpException $error) {
        $message = 'Could not created invoice, un-expected error';

        if ($error->response->isJson()) {
            $body = $error->response->json();
            $message = $body['message'];
        }

        $this->log->write('Could not create invoice for order ' . $this->session->data['order_id']);
        $this->log->write("Server returned with $message");
        $this->log->write('Server status' . $error->response->status());

        echo '<b>' . $message . '</b>';
        die;
    }
 
    $url = preg_replace('?lang=en', '', $response['url']);

    ?>
        <script>
            window.location.href = '<?php echo $url; ?>';
        </script>
    <?php

    die;
}

问题根源

  1. 缺少必填字段校验:代码直接从Session获取订单ID并调用支付接口生成跳转链接,完全未检查订单信息中的必填字段是否填写完整,导致未完成结账流程的用户被强制跳转。
  2. 正则表达式语法错误:preg_replace('?lang=en', '', $response['url'])中的正则缺少分隔符,会导致匹配失败,可能引发后续跳转异常。
  3. 跳转逻辑不符合OpenCart流程:直接输出JS脚本并终止程序,绕过了OpenCart的表单验证和页面渲染流程,无法触发结账页面的错误提示。

修复方案

1. 添加必填字段校验逻辑

在获取order_info后,立即检查关键必填字段是否为空,若为空则跳转回结账页面并提示错误。

2. 修复正则表达式

将preg_replace的正则改为合法格式,正确匹配URL中的?lang=en参数。

3. 调整跳转逻辑

遵循OpenCart的响应流程,使用官方重定向方法跳转,避免直接输出脚本终止程序。

修改后的完整代码如下:

public function index()
{
    $this->load->language('extension/payment/moyasar3');
    $this->load->model('extension/payment/moyasar3');
    $this->load->model('checkout/order');

    // 检查Session中是否存在订单ID
    if (!isset($this->session->data['order_id'])) {
        $this->response->redirect($this->url->link('checkout/checkout'));
    }

    $order_info = $this->model_checkout_order->getOrder($this->session->data['order_id']);

    // 校验必填结账字段
    $required_fields = [
        'firstname', 'lastname', 'telephone', 'email',
        'shipping_address_1', 'shipping_city', 'shipping_postcode'
    ];
    
    foreach ($required_fields as $field) {
        if (empty($order_info[$field])) {
            $this->session->data['error'] = $this->language->get('error_required_fields');
            $this->response->redirect($this->url->link('checkout/checkout'));
        }
    }

    $amount = $this->currency->format(
        $order_info['total'],
        $order_info['currency_code'],
        $order_info['currency_value'],
        false
    );

    $amount *= 100;

    $invoice = [
        'amount' => round($amount),
        'description' => 'Order id #' . $this->session->data['order_id'],
        'currency' => $order_info['currency_code'],
        'success_url' => $this->url->link('extension/payment/moyasar3/callback', '', true),
        'back_url' => $this->url->link('checkout/cart'),
        'metadata' => [
            'order_id' => $this->session->data['order_id'],
            'firstname' => $order_info['firstname'],
            'lastname' => $order_info['lastname'],
            'telephone' => $order_info['telephone'],
            'email' => $order_info['email'],
            'shipping_address_1' => $order_info['shipping_address_1'],
            'shipping_address_2' => $order_info['shipping_address_2'],
            'shipping_city' => $order_info['shipping_city'],
            'shipping_zone' => $order_info['shipping_zone'],
            'shipping_postcode' => $order_info['shipping_postcode'],
            'orderdate' => $order_info['date_added']
        ]
    ];

    try {
        $response = (new QuickHttp)
            ->basic_auth($this->config->get('payment_moyasar3_api_secret_key'))
            ->post('https://api.moyasar.com/v1/invoices', $invoice)
            ->json();
    } catch (QuickHttpException $error) {
        $message = 'Could not created invoice, un-expected error';

        if ($error->response->isJson()) {
            $body = $error->response->json();
            $message = $body['message'];
        }

        $this->log->write('Could not create invoice for order ' . $this->session->data['order_id']);
        $this->log->write("Server returned with $message");
        $this->log->write('Server status' . $error->response->status());

        $this->session->data['error'] = $message;
        $this->response->redirect($this->url->link('checkout/checkout'));
    }
 
    // 修复正则表达式,正确移除lang=en参数
    $url = preg_replace('/\?lang=en/', '', $response['url']);
    // 可选:更严谨的URL参数处理方式,适配多语言场景
    /*
    $parsed_url = parse_url($response['url']);
    parse_str($parsed_url['query'] ?? '', $query_params);
    unset($query_params['lang']);
    $new_query = empty($query_params) ? '' : '?' . http_build_query($query_params);
    $url = $parsed_url['scheme'] . '://' . $parsed_url['host'] . $parsed_url['path'] . $new_query;
    */

    // 使用OpenCart官方重定向方法跳转
    $this->response->redirect($url);
}

额外说明

  • 需在插件的语言文件中添加error_required_fields对应的提示文本,例如:$_['error_required_fields'] = '请填写所有必填结账字段';
  • 若使用注释中的URL参数处理方式,兼容性更强,可适配更多语言参数场景。

内容的提问来源于stack exchange,提问作者ahmed mohamed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 01:02:32