微信支付 APIv3 要求使用商户证书进行身份验证和敏感信息加解密,配置流程比 APIv2 复杂不少。本文整理从申请到后端集成的完整步骤。
证书体系概述
微信支付 APIv3 涉及两类证书:
| 证书类型 | 作用 | 来源 |
|---|
| 商户 API 证书 | 请求签名,证明你的商户身份 | 商户平台自行申请 |
| 平台证书 | 验证微信支付回调签名,加密敏感数据 | 微信侧提供,需程序自动下载更新 |
简单来说:你发请求用商户证书,收回调验平台证书。
步骤一:申请商户 API 证书
- 登录 微信支付商户平台
- 进入 账户中心 → API安全 → API证书
- 点击「申请证书」,按提示下载证书生成工具
- 使用工具生成 CSR 文件并提交
- 获取证书文件,通常包含:
apiclient_key.pem — 商户私钥apiclient_cert.pem — 商户证书
步骤二:设置 APIv3 密钥
APIv3 需要一个 32 位密钥用于平台证书解密和回调验签:
- 进入 账户中心 → API安全 → APIv3密钥
- 点击「设置」,生成或填写 32 位随机字符串
- 妥善保存此密钥,丢失后无法找回,只能重置
步骤三:后端集成
安装依赖
以 Node.js 为例:
1
| npm install wechatpay-node-v3
|
基础配置
1 2 3 4 5 6 7 8 9 10 11
| import WechatPay from 'wechatpay-node-v3'; import fs from 'fs';
const wechatPay = new WechatPay({ appid: 'wx1234567890', mchid: '1234567890', publicKey: fs.readFileSync('/path/to/apiclient_cert.pem'), privateKey: fs.readFileSync('/path/to/apiclient_key.pem'), secretKey: 'your-32-char-api-v3-key', });
|
发起支付请求示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const result = await wechatPay.transactions_jsapi({ description: '98潮玩 - 游戏礼包', out_trade_no: 'ORDER20240718001', notify_url: 'https://yyimg.com/api/wxpay/notify', amount: { total: 1, currency: 'CNY', }, payer: { openid: 'oUpF8xxxxxxxxxxxx', }, });
console.log(result.prepay_id);
|
回调验签
收到微信支付的异步通知时,必须验证签名:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import { Controller, Post, Body, Headers } from '@midwayjs/core';
@Controller('/api/wxpay') export class WxPayController {
@Post('/notify') async notify( @Headers('wechatpay-signature') signature: string, @Headers('wechatpay-timestamp') timestamp: string, @Headers('wechatpay-nonce') nonce: string, @Headers('wechatpay-serial') serial: string, @Body() body: any ) { const verified = wechatPay.verifySignature(signature, timestamp, nonce, body); if (!verified) { return { code: 'FAIL', message: '签名验证失败' }; }
const resource = body.resource; const decrypted = wechatPay.decipher(resource.ciphertext, resource.associated_data, resource.nonce);
console.log('支付成功:', decrypted);
return { code: 'SUCCESS', message: 'OK' }; } }
|
平台证书自动更新
平台证书有有效期(通常 1 年),到期前需要更新。务必在代码中实现自动下载:
1 2 3 4 5 6 7 8 9 10 11 12
| await wechatPay.initPlatformCertificate();
setInterval(async () => { try { await wechatPay.initPlatformCertificate(); console.log('平台证书已刷新'); } catch (err) { console.error('平台证书刷新失败:', err); } }, 12 * 60 * 60 * 1000);
|
常见问题
1. 证书路径在服务器上找不到
生产环境建议用环境变量配置路径,避免硬编码:
1 2 3 4 5
| const wechatPay = new WechatPay({ privateKey: fs.readFileSync(path.join(__dirname, process.env.WXPAY_KEY_PATH || '')), publicKey: fs.readFileSync(path.join(__dirname, process.env.WXPAY_CERT_PATH || '')), });
|
2. 回调验签失败
常见原因:
- 平台证书过期,检查
wechatpay-serial 请求头中的序列号 - POST body 被中间件解析后变成对象,验签前需转为原始 JSON 字符串
- 使用了错误的 APIv3 密钥
3. APIv2 迁移到 APIv3
如果你还在用 APIv2:
- APIv3 不再需要证书文件进行签名,改用私钥签名
- 敏感信息(如用户手机号)从明文改为密文,需要解密
- 回调通知格式完全不同,数据结构是加密的 JSON
4. 环境隔离
正式环境和沙箱环境的证书独立,不要混用:
1 2 3 4 5 6 7 8
| const isProd = process.env.NODE_ENV === 'production'; const config = isProd ? { mchid: '真实商户号', } : { mchid: '沙箱商户号', };
|
总结
微信支付 APIv3 证书配置的核心步骤:
- 商户平台申请 API 证书(apiclient_cert.pem + apiclient_key.pem)
- 设置 32 位 APIv3 密钥
- 后端集成 SDK,实现签名和验签
- 实现平台证书自动更新,避免过期导致回调失败
- 做好环境隔离和错误处理
搞定这些,微信支付的证书问题基本不会再困扰你。