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

如何创建基于mVISA的WooCommerce动态二维码支付网关插件?

搭建WooCommerce mVISA动态二维码支付网关插件指南

嘿,我之前做过类似的支付网关插件,咱们一步步来把银行提供的mVISA资源整合到WooCommerce里,让客户能扫码完成付款——踩过的坑我都给你标出来了。

一、先搭好插件的基础框架

WooCommerce的支付网关必须遵循它的扩展规范,先把最基础的文件结构搞定:

  • 新建一个文件夹,比如woocommerce-mvisa-qr-payment
  • 里面放主插件文件woocommerce-mvisa-qr-payment.php(初期单文件就能搞定,后期复杂了再拆分)

主插件文件的头部注释(必须)

这是WordPress识别插件的关键,复制后修改成你的信息:

<?php
/*
Plugin Name: WooCommerce mVISA QR Payment Gateway
Plugin URI: 你的插件地址(可选)
Description: 基于mVISA的动态二维码支付网关,客户扫描结账页面的二维码完成支付
Version: 1.0.0
Author: 你的名字
Author URI: 你的个人地址(可选)
License: GPLv2 or later
Text Domain: woocommerce-mvisa-qr-payment
*/

// 防止直接访问插件文件
if (!defined('ABSPATH')) {
    exit;
}

二、把网关注册到WooCommerce

接下来要告诉WooCommerce咱们的支付网关存在,用官方提供的钩子:

// 注册支付网关
add_filter('woocommerce_payment_gateways', 'add_mvisa_qr_payment_gateway');
function add_mvisa_qr_payment_gateway($gateways) {
    $gateways[] = 'WC_MVISA_QR_Payment_Gateway';
    return $gateways;
}

// 加载网关类
add_action('plugins_loaded', 'init_mvisa_qr_payment_gateway');
function init_mvisa_qr_payment_gateway() {
    class WC_MVISA_QR_Payment_Gateway extends WC_Payment_Gateway {
        // 核心功能都在这个类里实现
    }
}

三、实现网关类的核心功能

咱们把类里的关键方法一个个填进去:

1. 初始化网关基本信息

在类的__construct方法里设置网关的基础属性:

public function __construct() {
    $this->id = 'mvisa_qr_payment'; // 唯一ID,不能和其他网关重复
    $this->icon = ''; // 可以加个mVISA官方图标URL
    $this->has_fields = false; // 不需要额外表单字段
    $this->method_title = 'mVISA 二维码支付';
    $this->method_description = '客户扫描二维码,通过移动应用完成支付';

    // 加载后台配置选项
    $this->init_form_fields();
    $this->init_settings();

    // 保存配置的钩子
    add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));

    // 处理银行回调的钩子
    add_action('init', array($this, 'handle_mvisa_callback'));
}

2. 配置后台选项(管理银行参数)

把银行给的请求代码、回调URL做成后台可配置项,方便后期修改:

public function init_form_fields() {
    $this->form_fields = array(
        'enabled' => array(
            'title' => '启用/禁用',
            'type' => 'checkbox',
            'label' => '启用mVISA二维码支付',
            'default' => 'yes'
        ),
        'title' => array(
            'title' => '支付方式名称',
            'type' => 'text',
            'default' => 'mVISA 扫码支付'
        ),
        'bank_request_code' => array(
            'title' => '银行请求代码',
            'type' => 'text',
            'description' => '银行提供的专属请求代码',
            'default' => ''
        ),
        'callback_url' => array(
            'title' => '回调URL',
            'type' => 'text',
            'description' => '银行回调地址(自动生成:' . home_url('?mvisa_callback=1') . ')',
            'default' => home_url('?mvisa_callback=1')
        ),
        'bank_api_url' => array(
            'title' => 'mVISA API地址',
            'type' => 'text',
            'description' => '银行提供的生成二维码的API接口',
            'default' => ''
        ),
        'api_secret' => array(
            'title' => 'API签名密钥',
            'type' => 'password',
            'description' => '银行提供的签名验证密钥(必填,防止伪造请求)',
            'default' => ''
        )
    );
}

3. 生成动态二维码并展示

当用户选择这个支付方式提交订单后,我们需要调用银行API生成二维码,再展示给用户:

// WooCommerce核心支付处理方法
public function process_payment($order_id) {
    $order = wc_get_order($order_id);

    // 调用银行API生成二维码数据
    $qr_data = $this->generate_mvisa_qr($order);

    if (!$qr_data) {
        wc_add_notice('生成二维码失败,请稍后重试', 'error');
        return array(
            'result' => 'failure',
            'redirect' => wc_get_checkout_url()
        );
    }

    // 把二维码数据存在订单元数据里
    $order->update_meta_data('_mvisa_qr_data', $qr_data);
    $order->save();

    // 标记订单为待支付
    $order->update_status('pending', '等待客户扫码支付');

    // 跳转到订单详情页展示二维码
    return array(
        'result' => 'success',
        'redirect' => $this->get_return_url($order)
    );
}

// 调用银行API生成二维码的私有方法
private function generate_mvisa_qr($order) {
    $bank_api_url = $this->get_option('bank_api_url');
    $request_code = $this->get_option('bank_request_code');
    $callback_url = $this->get_option('callback_url');

    // 构造API请求参数(完全按照银行提供的文档来,这里是示例)
    $params = array(
        'request_code' => $request_code,
        'order_id' => $order->get_id(),
        'amount' => $order->get_total(),
        'currency' => $order->get_currency(),
        'callback_url' => $callback_url
    );

    // 发送POST请求到银行API
    $response = wp_remote_post($bank_api_url, array(
        'headers' => array('Content-Type' => 'application/json'),
        'body' => json_encode($params),
        'timeout' => 15
    ));

    if (is_wp_error($response)) {
        error_log('mVISA API请求失败: ' . $response->get_error_message());
        return false;
    }

    $body = json_decode(wp_remote_retrieve_body($response), true);

    // 根据银行的响应代码判断是否成功
    if ($body['response_code'] == 'SUCCESS') {
        return $body['qr_code_content']; // 银行返回的二维码字符串
    } else {
        error_log('mVISA API返回错误: ' . $body['response_message']);
        return false;
    }
}

然后在订单详情页显示二维码(用前端JS生成,减少服务器压力):

// 在订单页面添加二维码显示
add_action('woocommerce_order_details_after_order_table', 'display_mvisa_qr_on_order_page');
function display_mvisa_qr_on_order_page($order) {
    $gateway = new WC_MVISA_QR_Payment_Gateway();
    if ($order->get_payment_method() != $gateway->id) {
        return;
    }

    $qr_data = $order->get_meta('_mvisa_qr_data');
    if (!$qr_data) {
        echo '<p>二维码生成失败,请联系客服</p>';
        return;
    }

    // 用QRCode.js生成二维码
    echo '<div class="mvisa-qr-container">
            <h3>请扫描下方二维码完成支付</h3>
            <div id="mvisa-qr-code"></div>
            <script>
                // 加载QRCode库
                const script = document.createElement("script");
                script.src = "https://cdn.jsdelivr.net/npm/qrcode@1.5.1/build/qrcode.min.js";
                script.onload = function() {
                    QRCode.toCanvas(document.getElementById("mvisa-qr-code"), "' . esc_js($qr_data) . '", {
                        width: 200,
                        color: { dark: "#000", light: "#fff" }
                    }, (error) => error && console.error(error));
                };
                document.body.appendChild(script);
          </div>';
}

4. 处理银行的回调请求

用户支付完成后,银行会调用你提供的回调URL,咱们需要验证请求合法性并更新订单状态:

public function handle_mvisa_callback() {
    if (!isset($_GET['mvisa_callback']) || $_GET['mvisa_callback'] != '1') {
        return;
    }

    // 获取银行回调参数(按银行文档来,这里是示例)
    $order_id = $_POST['order_id'];
    $payment_status = $_POST['payment_status'];
    $response_code = $_POST['response_code'];
    $signature = $_POST['signature'];

    // 验证签名(非常重要!防止恶意篡改订单)
    $api_secret = $this->get_option('api_secret');
    $expected_signature = hash('sha256', $order_id . $payment_status . $api_secret);
    if ($signature != $expected_signature) {
        wp_die('无效的请求签名');
    }

    $order = wc_get_order($order_id);
    if (!$order) {
        wp_die('订单不存在');
    }

    // 根据银行响应更新订单状态
    if ($response_code == 'SUCCESS' && $payment_status == 'COMPLETED') {
        $order->update_status('completed', '支付成功,订单已完成');
        $order->payment_complete(); // 标记订单为已支付
    } else {
        $order->update_status('failed', '支付失败,响应代码:' . $response_code);
    }

    // 给银行返回成功响应(按银行要求的格式)
    echo json_encode(array('status' => 'OK'));
    exit;
}

四、关键注意事项

  • 签名验证:一定要严格实现银行要求的签名验证逻辑,这是防止恶意请求的核心。
  • HTTPS加密:确保你的网站和银行API接口都用HTTPS,避免敏感数据明文传输。
  • 错误日志:把API请求和回调的错误记录到WordPress日志里,方便调试。
  • 测试环境:先在银行的测试环境跑通所有流程(生成二维码、支付成功/失败回调),再上线。
  • 超时处理:可以加个定时任务,比如30分钟后自动取消未支付的订单。

五、安装启用

把整个插件文件夹压缩成ZIP包,在WordPress后台「插件-安装插件-上传插件」里上传启用,之后去WooCommerce「设置-支付」里找到「mVISA二维码支付」,配置好银行提供的参数就可以用了。

内容的提问来源于stack exchange,提问作者Dyton Marshall A

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:25:34