前言
为WooCommerce商店集成微信支付,可以显著提升中国用户的购物体验和支付成功率。本教程将指导你使用微信支付官方PHP SDK,以最稳妥的方式完成集成,避免重复造轮子。
准备工作
在开始编码前,你需要完成以下配置:
- 微信商户平台账号:申请并开通微信支付商户号。
- API密钥:登录商户平台,在【账户中心】->【API安全】中设置API密钥(需安装操作证书)。
- AppID与商户号:记录你的公众号AppID(或小程序AppID、移动应用AppID)和商户号(MCHID)。
- 服务器配置:确保你的WordPress网站服务器IP已添加到商户平台的IP白名单中,并准备好一个可通过公网访问的域名(用于接收支付结果通知)。
安装微信支付官方PHP SDK
推荐使用Composer进行安装,这是最规范的方式。
composer require wechatpay/wechatpay
如果你的环境不支持Composer,也可以从GitHub下载SDK源码并手动引入。
创建WooCommerce支付网关插件
我们将创建一个简单的插件来添加微信支付网关。在WordPress的 wp-content/plugins 目录下创建一个新文件夹,例如 wechatpay-for-woocommerce,然后创建主文件。
主插件文件:wechatpay-for-woocommerce.php
<?php
/**
* Plugin Name: WooCommerce WeChat Pay Gateway
* Description: 集成微信支付官方SDK的WooCommerce支付网关
* Version: 1.0.0
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 确保WooCommerce激活
add_action('plugins_loaded', 'init_wechatpay_gateway');
function init_wechatpay_gateway() {
if (!class_exists('WC_Payment_Gateway')) {
return;
}
// 引入Composer自动加载(假设SDK通过Composer安装在插件目录下的vendor文件夹)
$autoloader = plugin_dir_path(__FILE__) . 'vendor/autoload.php';
if (file_exists($autoloader)) {
require_once $autoloader;
}
// 定义支付网关类
class WC_Gateway_WeChatPay extends WC_Payment_Gateway {
// 类定义将在下文展开
}
// 将网关添加到WooCommerce
add_filter('woocommerce_payment_gateways', 'add_wechatpay_gateway');
function add_wechatpay_gateway($gateways) {
$gateways[] = 'WC_Gateway_WeChatPay';
return $gateways;
}
}
实现支付网关类
接下来,在同一个文件内,完善 WC_Gateway_WeChatPay 类的核心方法。
1. 构造函数与基本设置
public function __construct() {
$this->id = 'wechatpay';
$this->icon = ''; // 可选项:支付图标URL
$this->has_fields = false;
$this->method_title = '微信支付';
$this->method_description = '通过微信支付官方SDK接收付款';
// 加载设置字段
$this->init_form_fields();
$this->init_settings();
// 获取用户设置
$this->title = $this->get_option('title');
$this->description = $this->get_option('description');
$this->enabled = $this->get_option('enabled');
$this->appid = $this->get_option('appid');
$this->mchid = $this->get_option('mchid');
$this->api_key = $this->get_option('api_key');
$this->notify_url = home_url('/wc-api/wc_gateway_wechatpay/'); // 通知端点
// 保存设置
add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options'));
// 注册支付结果回调处理
add_action('woocommerce_api_wc_gateway_wechatpay', array($this, 'handle_notify'));
}
2. 管理后台设置字段
public function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => '启用/禁用',
'type' => 'checkbox',
'label' => '启用微信支付',
'default' => 'no'
),
'title' => array(
'title' => '标题',
'type' => 'text',
'description' => '客户在结账时看到的支付方式标题。',
'default' => '微信支付',
'desc_tip' => true
),
'description' => array(
'title' => '描述',
'type' => 'textarea',
'description' => '支付方式的描述信息。',
'default' => '使用微信扫码支付。'
),
'appid' => array(
'title' => 'AppID',
'type' => 'text',
'description' => '微信公众号或小程序的AppID。',
'default' => ''
),
'mchid' => array(
'title' => '商户号 (MCHID)',
'type' => 'text',
'description' => '微信支付商户号。',
'default' => ''
),
'api_key' => array(
'title' => 'API密钥',
'type' => 'password',
'description' => '商户平台设置的API密钥。',
'default' => ''
)
);
}
3. 处理支付请求(核心)
当用户下单并选择微信支付后,此方法被调用,用于创建微信支付订单并返回支付参数(如二维码链接)。
public function process_payment($order_id) {
$order = wc_get_order($order_id);
// 1. 初始化微信支付客户端
$wechatpay = $this->init_wechatpay_client();
// 2. 构建请求参数(以Native支付为例,生成二维码)
$requestData = [
'mchid' => $this->mchid,
'out_trade_no' => $order->get_order_number(),
'appid' => $this->appid,
'description' => '订单:' . $order->get_order_number(),
'notify_url' => $this->notify_url,
'amount' => [
'total' => intval($order->get_total() * 100), // 转换为分
'currency' => 'CNY'
]
];
try {
// 3. 调用SDK创建订单
$resp = $wechatpay->chain('v3/pay/transactions/native')->post(['json' => $requestData]);
$result = json_decode($resp->getBody(), true);
// 4. 获取二维码链接(code_url)
$code_url = $result['code_url'];
// 5. 将订单状态设为“等待支付”并存储二维码URL(临时方案)
$order->update_status('pending', '等待客户微信扫码支付。');
// 实际应用中,应将code_url与订单关联存储,例如使用订单元数据
update_post_meta($order_id, '_wechatpay_qrcode_url', $code_url);
// 6. 重定向到自定义的“展示二维码”页面
return array(
'result' => 'success',
'redirect' => $order->get_checkout_payment_url(true) // 将触发支付页面
);
} catch (Exception $e) {
wc_add_notice('支付请求创建失败:' . $e->getMessage(), 'error');
return array('result' => 'failure');
}
}
// 辅助函数:初始化SDK客户端
private function init_wechatpay_client() {
// 商户API私钥(此处假设你已下载并妥善保存私钥文件,例如apiclient_key.pem)
$merchantPrivateKeyFilePath = plugin_dir_path(__FILE__) . 'cert/apiclient_key.pem';
$merchantPrivateKey = file_get_contents($merchantPrivateKeyFilePath);
// 微信支付平台证书(SDK支持自动下载和缓存,此处简化处理)
// 强烈建议在生产环境中实现平台证书的自动更新机制
$merchantId = $this->mchid;
$merchantSerialNumber = '你的商户证书序列号'; // 从商户平台获取
$wechatpay = WeChatPayBuilder::factory([
'mchid' => $merchantId,
'serial' => $merchantSerialNumber,
'privateKey' => $merchantPrivateKey,
'certs' => [
// 此处应放置平台证书,示例中省略了自动获取逻辑
],
'secret' => $this->api_key, // API v3密钥
'merchantCerts' => [$merchantPrivateKey],
]);
return $wechatpay;
}
4. 处理支付结果异步通知
微信支付服务器会向你的通知地址发送POST请求,告知支付结果。你必须正确验证并处理。
public function handle_notify() {
$body = file_get_contents('php://input');
$headers = getallheaders();
// 注意:getallheaders()可能在某些环境下不可用,需调整
try {
$wechatpay = $this->init_wechatpay_client();
// SDK内置了通知验签和解密工具,此处为简化示例逻辑
// 实际应使用 $inWechatpay->decrypt($headers, $body) 进行验证和解密
$data = json_decode($body, true);
$out_trade_no = $data['out_trade_no'];
$order = wc_get_order(wc_get_order_id_by_order_key($out_trade_no)); // 需根据你的订单号匹配逻辑调整
if ($order && $data['trade_state'] === 'SUCCESS') {
// 支付成功
$order->payment_complete();
$order->add_order_note('微信支付成功。交易单号:' . $data['transaction_id']);
// 返回成功响应给微信支付
header('HTTP/1.1 200 OK');
echo json_encode(['code' => 'SUCCESS', 'message' => '成功']);
} else {
// 支付失败或其他状态
header('HTTP/1.1 500 Internal Server Error');
}
} catch (Exception $e) {
header('HTTP/1.1 500 Internal Server Error');
error_log('微信支付通知处理错误:' . $e->getMessage());
}
exit;
}
前端展示支付二维码
你需要在主题中创建一个页面模板或使用钩子,在订单支付页面展示从 process_payment 步骤获取的二维码。一个简单的示例:
// 在支付页面(例如 checkout/payment 页面)添加短代码或自定义模板
// 从订单元数据获取二维码URL并生成img标签
$qrcode_url = get_post_meta($order_id, '_wechatpay_qrcode_url', true);
echo '<div class="wechatpay-qrcode"><img src="' . esc_url($qrcode_url) . '" alt="微信支付二维码" /></div>';
重要注意事项与安全建议
- 证书管理:商户私钥必须妥善保管,严禁提交到代码仓库。平台证书应实现自动更新。
- 通知验证:必须验证微信支付通知的签名,确保请求来源合法,防止伪造支付成功。
- 订单状态:仅以异步通知(
handle_notify)的结果为准来更新订单状态,不要依赖前端回调。 - 错误处理:在生产环境中,应完善所有异常捕获,并记录日志以便排查。
- 测试:务必在微信支付沙箱环境或使用真实小额交易进行充分测试。
总结
通过以上步骤,你已成功为WooCommerce集成了微信支付官方SDK。本教程提供了从插件创建、SDK初始化、支付下单到结果通知处理的完整流程和示例代码。请根据你的具体业务场景(如公众号支付、小程序支付)调整接口和参数,并严格遵守微信支付的官方文档和安全规范。