Files
2026-01-30 17:25:30 +08:00

676 lines
14 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 微信集成功能验证指南
本文档提供微信公众号 OAuth 认证和微信支付功能的完整验证流程。
## 目录
- [前置准备](#前置准备)
- [配置验证](#配置验证)
- [功能测试](#功能测试)
- [1. 微信 OAuth 登录](#1-微信-oauth-登录)
- [2. 微信账号绑定](#2-微信账号绑定)
- [3. 微信 JSAPI 支付](#3-微信-jsapi-支付)
- [4. 微信 H5 支付](#4-微信-h5-支付)
- [5. 支付回调验证](#5-支付回调验证)
- [常见问题排查](#常见问题排查)
---
## 前置准备
### 1. 微信配置准备
确保已获取以下信息:
**公众号配置**
- [ ] AppID
- [ ] AppSecret
- [ ] OAuth 回调域名已配置(在公众号后台)
**支付配置**
- [ ] 商户号
- [ ] APIv3 密钥32位
- [ ] 商户证书文件apiclient_cert.pem
- [ ] 商户私钥文件apiclient_key.pem
- [ ] 证书序列号
- [ ] 支付回调 URL 已配置(在商户平台)
### 2. 环境准备
```bash
# 创建证书目录
mkdir -p /app/certs
# 复制证书文件
cp apiclient_cert.pem /app/certs/
cp apiclient_key.pem /app/certs/
# 设置文件权限
chmod 600 /app/certs/*
# 加载环境变量
source .env.local
```
### 3. 启动服务
```bash
# 编译并启动
go run cmd/api/main.go
# 或使用 Docker
docker-compose up -d api
```
---
## 配置验证
### 自动验证脚本
运行配置验证脚本:
```bash
# 加载环境变量
source .env.local
# 运行验证脚本
bash scripts/verify-wechat.sh
```
**预期输出**(所有检查通过):
```
========================================
微信配置验证脚本
========================================
1. 检查微信公众号配置
----------------------------------------
✓ JUNHONG_WECHAT_OFFICIAL_ACCOUNT_APP_ID
✓ JUNHONG_WECHAT_OFFICIAL_ACCOUNT_APP_SECRET
✓ JUNHONG_WECHAT_OFFICIAL_ACCOUNT_TOKEN
✓ JUNHONG_WECHAT_OFFICIAL_ACCOUNT_AES_KEY
✓ JUNHONG_WECHAT_OFFICIAL_ACCOUNT_OAUTH_REDIRECT_URL
2. 检查微信支付配置
----------------------------------------
✓ JUNHONG_WECHAT_PAYMENT_APP_ID
✓ JUNHONG_WECHAT_PAYMENT_MCH_ID
✓ JUNHONG_WECHAT_PAYMENT_API_V3_KEY
✓ JUNHONG_WECHAT_PAYMENT_CERT_PATH
✓ JUNHONG_WECHAT_PAYMENT_KEY_PATH
✓ JUNHONG_WECHAT_PAYMENT_SERIAL_NO
✓ JUNHONG_WECHAT_PAYMENT_NOTIFY_URL
3. 检查证书文件
----------------------------------------
✓ 文件存在: /app/certs/apiclient_cert.pem
✓ 文件存在: /app/certs/apiclient_key.pem
4. 验证配置格式
----------------------------------------
✓ 支付回调 URL 使用 HTTPS
5. 检查证书有效性(可选)
----------------------------------------
✓ 证书有效期至: Jan 30 12:00:00 2026 GMT
✓ 证书序列号匹配
========================================
验证结果
========================================
错误: 0
警告: 0
✅ 配置验证通过,所有配置正确
```
### 查看服务启动日志
```bash
# 查看实时日志
tail -f logs/app.log
# 或使用 Docker
docker logs -f junhong-api
```
**预期日志**(成功初始化):
```json
{
"level": "info",
"ts": "2025-01-30T12:00:00.000+0800",
"msg": "微信公众号服务初始化成功"
}
{
"level": "info",
"ts": "2025-01-30T12:00:00.001+0800",
"msg": "微信支付服务初始化成功"
}
{
"level": "info",
"ts": "2025-01-30T12:00:00.002+0800",
"msg": "服务启动成功",
"address": ":3000"
}
```
**错误日志**(配置问题):
```json
{
"level": "fatal",
"ts": "2025-01-30T12:00:00.000+0800",
"msg": "微信配置不完整或无效",
"error": "证书文件不存在: /app/certs/apiclient_cert.pem"
}
```
---
## 功能测试
### 1. 微信 OAuth 登录
#### 前端测试步骤
**步骤 1构造授权 URL**
```javascript
const appId = 'wxabcdef1234567890';
const redirectUri = encodeURIComponent('https://your-domain.com/wechat-callback');
const state = Math.random().toString(36).substring(7);
const authUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_userinfo&state=${state}#wechat_redirect`;
// 跳转到微信授权页面
window.location.href = authUrl;
```
**步骤 2处理回调**
在回调页面(`https://your-domain.com/wechat-callback`
```javascript
// 获取 URL 参数中的 code
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const state = urlParams.get('state');
if (!code) {
alert('授权失败:未获取到授权码');
return;
}
// 调用后端 OAuth 登录接口
fetch('https://api.your-domain.com/api/c/v1/wechat/auth', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code })
})
.then(res => res.json())
.then(data => {
if (data.code === 0) {
console.log('登录成功', data.data);
localStorage.setItem('token', data.data.token);
// 跳转到主页
window.location.href = '/';
} else {
alert(`登录失败: ${data.msg}`);
}
})
.catch(err => {
console.error('请求失败', err);
alert('登录失败,请重试');
});
```
#### 后端日志验证
```bash
# 查看 OAuth 请求日志
tail -f logs/app.log | grep -i oauth
```
**成功日志**
```json
{
"level": "debug",
"ts": "2025-01-30T12:00:00.000+0800",
"msg": "微信 OAuth 授权成功",
"open_id": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M",
"union_id": "oGfRjwX..."
}
{
"level": "info",
"ts": "2025-01-30T12:00:00.001+0800",
"msg": "个人客户创建成功",
"customer_id": 123
}
```
**失败日志**
```json
{
"level": "error",
"ts": "2025-01-30T12:00:00.000+0800",
"msg": "微信 OAuth 授权失败",
"code": "071abc123...",
"error": "invalid code"
}
```
#### 使用 curl 测试
```bash
# 替换为真实的授权码5分钟有效
CODE="071abc123456789def"
curl -X POST http://localhost:3000/api/c/v1/wechat/auth \
-H "Content-Type: application/json" \
-d "{\"code\":\"$CODE\"}"
```
**成功响应**
```json
{
"code": 0,
"msg": "登录成功",
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"customer_id": 123,
"phone": "",
"nickname": "微信用户",
"is_new_user": true
},
"timestamp": "2025-01-30T12:00:00+08:00"
}
```
---
### 2. 微信账号绑定
#### 前提条件
- 已有个人客户账号
- 已获取 JWT Token
#### 测试步骤
```bash
# 替换为真实的 Token 和授权码
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
CODE="071abc123456789def"
curl -X POST http://localhost:3000/api/c/v1/bind-wechat \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"code\":\"$CODE\"}"
```
**成功响应**
```json
{
"code": 0,
"msg": "绑定成功",
"timestamp": "2025-01-30T12:00:00+08:00"
}
```
**失败响应**(微信号已被绑定):
```json
{
"code": 1020,
"msg": "该微信号已被其他账号绑定",
"timestamp": "2025-01-30T12:00:00+08:00"
}
```
---
### 3. 微信 JSAPI 支付
#### 前提条件
- 已创建订单(状态为"待支付"
- 在微信内网页中调用
- 已获取用户 OpenID
#### 测试步骤
**步骤 1创建支付订单**
```bash
# 替换为真实的 Token、订单ID 和 OpenID
H5_TOKEN="your_h5_token_here"
ORDER_ID=1
OPEN_ID="o6_bmjrPTlm6_2sgVt7hMZOPfL2M"
curl -X POST "http://localhost:3000/api/h5/orders/$ORDER_ID/wechat-pay/jsapi" \
-H "Authorization: Bearer $H5_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"open_id\":\"$OPEN_ID\"}"
```
**成功响应**
```json
{
"code": 0,
"msg": "支付订单创建成功",
"data": {
"prepay_id": "wx30123456789012345678901234567890",
"pay_config": {
"appId": "wxabcdef1234567890",
"timeStamp": "1706606400",
"nonceStr": "5K8264ILTKCH16CQ2502SI8ZNMTM67VS",
"package": "prepay_id=wx30123456789012345678901234567890",
"signType": "RSA",
"paySign": "oR9d8PuhnIc+YZ8cBHFCwfgpaK9gd..."
}
},
"timestamp": "2025-01-30T12:00:00+08:00"
}
```
**步骤 2前端唤起支付**
```javascript
// 获取支付配置后,调用微信 JSAPI
wx.chooseWXPay({
...payConfig,
success: function(res) {
console.log('支付成功', res);
alert('支付成功');
// 跳转到订单详情页
window.location.href = `/orders/${orderId}`;
},
fail: function(res) {
console.error('支付失败', res);
alert('支付失败:' + res.err_msg);
}
});
```
#### 后端日志验证
```bash
# 查看支付请求日志
tail -f logs/app.log | grep -i jsapi
```
**成功日志**
```json
{
"level": "info",
"ts": "2025-01-30T12:00:00.000+0800",
"msg": "创建 JSAPI 支付订单成功",
"order_no": "ORDER_20250130_001",
"prepay_id": "wx30123456789012345678901234567890"
}
```
---
### 4. 微信 H5 支付
#### 前提条件
- 已创建订单(状态为"待支付"
- 在浏览器中调用(微信外)
#### 测试步骤
**步骤 1创建 H5 支付订单**
```bash
# 替换为真实的 Token 和订单ID
H5_TOKEN="your_h5_token_here"
ORDER_ID=1
curl -X POST "http://localhost:3000/api/h5/orders/$ORDER_ID/wechat-pay/h5" \
-H "Authorization: Bearer $H5_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"scene_info": {
"payer_client_ip": "123.12.12.123",
"h5_type": "Wap"
}
}'
```
**成功响应**
```json
{
"code": 0,
"msg": "H5 支付订单创建成功",
"data": {
"h5_url": "https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx30123456789012345678901234567890&package=3583359058"
},
"timestamp": "2025-01-30T12:00:00+08:00"
}
```
**步骤 2前端跳转支付**
```javascript
// 跳转到微信 H5 支付页面
const returnUrl = encodeURIComponent(`https://your-domain.com/orders/${orderId}`);
window.location.href = `${h5Url}&redirect_url=${returnUrl}`;
```
#### 后端日志验证
```bash
# 查看 H5 支付日志
tail -f logs/app.log | grep -i "h5"
```
**成功日志**
```json
{
"level": "info",
"ts": "2025-01-30T12:00:00.000+0800",
"msg": "创建 H5 支付订单成功",
"order_no": "ORDER_20250130_001",
"h5_url": "https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?..."
}
```
---
### 5. 支付回调验证
#### 验证方法1查看日志
支付成功后,微信会自动调用回调接口。查看日志验证:
```bash
# 查看支付回调日志
tail -f logs/app.log | grep -i "支付通知"
```
**成功日志**
```json
{
"level": "info",
"ts": "2025-01-30T12:00:00.000+0800",
"msg": "支付通知处理成功",
"out_trade_no": "ORDER_20250130_001",
"transaction_id": "4200001234202501301234567890"
}
```
#### 验证方法2查询订单状态
```bash
# 查询订单状态(使用数据库或 API
curl -X GET "http://localhost:3000/api/h5/orders/$ORDER_ID" \
-H "Authorization: Bearer $H5_TOKEN"
```
**预期响应**(订单已支付):
```json
{
"code": 0,
"data": {
"id": 1,
"order_no": "ORDER_20250130_001",
"status": "paid",
"total_amount": 100,
"paid_amount": 100,
"paid_at": "2025-01-30T12:00:00+08:00",
"payment_method": "wechat"
}
}
```
#### 验证方法3使用 Postman 模拟回调
**注意**:真实环境中由微信服务器调用,本地测试需要跳过签名验证。
```bash
# 模拟支付回调(仅测试环境)
curl -X POST http://localhost:3000/api/callback/wechat-pay \
-H "Content-Type: application/json" \
-d '{
"id": "test_id",
"create_time": "2025-01-30T12:00:00+08:00",
"resource_type": "encrypt-resource",
"event_type": "TRANSACTION.SUCCESS",
"summary": "支付成功",
"resource": {
"ciphertext": "...",
"nonce": "...",
"associated_data": "..."
}
}'
```
---
## 常见问题排查
### 1. 配置验证失败
**问题**:脚本报错 "缺失必填配置"
**解决方法**
```bash
# 检查环境变量是否加载
env | grep JUNHONG_WECHAT
# 重新加载环境变量
source .env.local
# 重新运行验证脚本
bash scripts/verify-wechat.sh
```
### 2. 服务启动失败
**问题**:日志显示 "微信配置不完整或无效"
**解决方法**
1. 查看详细错误日志
2. 检查证书文件路径是否正确
3. 验证证书文件权限600 或 644
4. 确认 APIv3 密钥长度为 32 位
### 3. OAuth 授权失败
**问题**:返回错误码 1044
**可能原因**
- 授权码已过期5分钟有效期
- 授权码已被使用过
- AppID 或 AppSecret 配置错误
- 回调域名未在公众号后台配置
**解决方法**
1. 重新发起授权流程获取新 code
2. 检查公众号配置
3. 查看详细日志:`tail -f logs/app.log | grep -i oauth`
### 4. 支付订单创建失败
**问题**:返回错误码 1046
**可能原因**
- 商户号配置错误
- 证书文件无效或过期
- APIv3 密钥错误
- 订单金额为0或负数
**解决方法**
1. 验证商户号和密钥
2. 检查证书有效期:`openssl x509 -in /app/certs/apiclient_cert.pem -noout -dates`
3. 确认证书序列号匹配
4. 查看详细日志:`tail -f logs/app.log | grep -i payment`
### 5. 支付回调签名验证失败
**问题**:日志显示 "支付回调签名验证失败"
**可能原因**
- 证书配置错误
- 证书序列号不匹配
- 证书已过期
**解决方法**
1. 重新下载最新的商户证书
2. 更新证书序列号配置
3. 确保证书文件路径正确
4. 验证证书:`bash scripts/verify-wechat.sh`
### 6. 启用调试日志
如需查看详细的 HTTP 请求日志:
```bash
# 设置环境变量
export JUNHONG_WECHAT_PAYMENT_HTTP_DEBUG=true
# 重启服务
go run cmd/api/main.go
# 查看调试日志
tail -f logs/app.log | grep -i wechat
```
---
## 验证清单
完成以下清单后,微信集成功能验证完成:
- [ ] 配置验证脚本通过0 错误)
- [ ] 服务启动成功,微信服务初始化日志正常
- [ ] 微信 OAuth 登录成功,返回 Token
- [ ] 微信账号绑定成功
- [ ] JSAPI 支付订单创建成功,返回支付配置
- [ ] H5 支付订单创建成功,返回支付 URL
- [ ] 支付回调处理成功,订单状态更新为"已支付"
- [ ] 日志中无错误或警告信息
---
## 相关文档
- [使用指南](./使用指南.md) - 详细的配置和部署说明
- [API 文档](./API文档.md) - 接口说明和示例
- [环境变量配置](../environment-variables.md) - 所有环境变量说明