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; }
问题根源
- 缺少必填字段校验:代码直接从Session获取订单ID并调用支付接口生成跳转链接,完全未检查订单信息中的必填字段是否填写完整,导致未完成结账流程的用户被强制跳转。
- 正则表达式语法错误:
preg_replace('?lang=en', '', $response['url'])中的正则缺少分隔符,会导致匹配失败,可能引发后续跳转异常。 - 跳转逻辑不符合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
相关产品推荐
相关产品推荐

