# 支付功能使用指南 ## 📋 概述 本项目已完整接入**微信支付**和**支付宝支付**,支持内容购买、账户充值等支付场景。 --- ## 一、配置信息 ### 1.1 微信支付配置 位置:`src/main/resources/application-dev.yml` 和 `src/main/resources/application-prod.yml` ```yaml payment: wechat: appId: wx7d13d99de5be3bfa # 微信应用 ID mchId: 1673321732 # 商户号 mchKey: UDuZXDcmy5Eb6o0nTNZhu6ek4DDh4K8B # 商户密钥 mchSerialNo: 5EFC47D3AA59BFD1AAE548F96B5E19E1C60F067D # 商户证书序列号 privateKeyPath: apiclient_key.pem # 商户私钥文件路径 domain: https://api.mch.weixin.qq.com # 微信服务器地址 notifyUrl: http://127.0.0.1:19001/api/pay/wx/notify # 支付回调地址 returnUrl: http://127.0.0.1:19001/api/pay/success # 支付成功跳转地址 ``` ### 1.2 支付宝支付配置 ```yaml payment: alipay: appId: 2021004138642603 # 支付宝应用 ID publicKey: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnakP04nUmsoFoveIvOhbLqkA1xQuYtvkrqq2AVvTsbtqpsEOTm9G095e2rBYLp89oDcf6L6BhtJPwdrhnA+qifUyVmACI9sprrsGeRYQgndK7y4c6spQcSnsnakSxlIp22j7pvBXNAZuqud2hQV+TOLKEUh1W3izTgMj/Ejoh3ZsCjgDRtTVgaytzSdHYrhNku+pIrl15/xVGJED99RYXkR8GHawxuK+vWVmxU0tiTCwTsqLz43v6TtCZ+/UfLL/luwp9B4ZvB+0qon82LILYr6oxs10kE2IAvryuDToAc1s/v/36jgt+7DXwqzfUDksHhVLHdJHChyc4ax5HmMsBwIDAQAB" # 支付宝公钥 privateKey: "" # 商户私钥(需配置) notifyUrl: http://127.0.0.1:19001/api/pay/alipay/trade/notify # 支付回调地址 returnUrl: https://shuziren.xueai.art/alipay-success # 支付成功跳转地址 signType: RSA2 # 签名类型 charset: UTF-8 # 字符编码 gatewayUrl: https://openapi.alipay.com/gateway.do # 支付宝网关 ``` --- ## 二、API 接口说明 ### 2.1 创建微信支付订单 **接口地址:** `POST /api/pay/wx/create` **请求参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | orderNo | String | 否 | 订单号(不传则自动生成) | | userId | Long | 是 | 用户 ID | | userName | String | 是 | 用户名 | | amount | BigDecimal | 是 | 支付金额(单位:元) | | productName | String | 是 | 商品名称 | | productDesc | String | 否 | 商品描述 | | businessId | Long | 是 | 关联业务 ID | | businessType | String | 是 | 业务类型:recharge(充值)/purchase_content(购买内容) | **请求示例:** ```bash curl -X POST http://localhost:19001/api/pay/wx/create \ -H "Content-Type: application/json" \ -d '{ "userId": 123, "userName": "张三", "amount": 0.01, "productName": "测试商品", "productDesc": "商品描述", "businessId": 456, "businessType": "purchase_content" }' ``` **响应示例:** ```json { "code": 200, "message": "success", "data": { "code_url": "weixin://wxpay/bizpayurl?pr=xxx", "order_no": "ORDER_20260331_001" } } ``` **字段说明:** - `code_url`: 微信支付二维码链接,前端可使用此链接生成二维码 - `order_no`: 支付订单号,用于后续查询订单状态 --- ### 2.2 创建支付宝支付订单 **接口地址:** `POST /api/pay/alipay/create` **请求参数:** 与微信支付相同 **请求示例:** ```bash curl -X POST http://localhost:19001/api/pay/alipay/create \ -H "Content-Type: application/json" \ -d '{ "userId": 123, "userName": "张三", "amount": 0.01, "productName": "测试商品", "businessId": 456, "businessType": "purchase_content" }' ``` **响应示例:** ```json { "code": 200, "message": "success", "data": "
...
" } ``` **使用说明:** - 返回的是 HTML 表单字符串 - 前端将此外壳写入页面后会自动提交跳转到支付宝支付页面 --- ### 2.3 支付回调接口(系统自动处理) #### 微信支付回调 **接口地址:** `POST /api/pay/wx/notify` **说明:** - 由微信支付服务器自动调用 - 处理支付结果并更新订单状态 - 返回 XML 格式响应给微信服务器 #### 支付宝支付回调 **异步回调:** `POST /api/pay/alipay/trade/notify` **同步回调:** `GET /api/pay/alipay/trade/return` **说明:** - 异步回调由支付宝服务器自动调用 - 同步回调用于用户支付完成后跳转回指定页面 --- ## 三、使用场景示例 ### 3.1 场景 1:购买付费内容 **业务流程:** 1. 用户点击购买按钮 2. 创建购买记录(待支付状态) 3. 创建支付订单 4. 用户扫码或跳转支付 5. 支付成功后更新订单和购买记录状态 **前端调用示例:** ```javascript // 步骤 1:创建购买记录 const purchaseResponse = await fetch('/api/content/purchase', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId: 123, contentId: 456, payType: 3 // 3=微信支付,4=支付宝支付 }) }); const purchaseResult = await purchaseResponse.json(); // 步骤 2:创建支付订单 const payResponse = await fetch('/api/pay/wx/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId: 123, amount: 9.99, productName: 'AI 技能教程', productDesc: '高级 AI 技能培训内容', businessId: 456, businessType: 'purchase_content' }) }); const payResult = await payResponse.json(); if (payResult.code === 200) { // 步骤 3:显示支付二维码 const codeUrl = payResult.data.code_url; // 使用 QRCode 库生成二维码 new QRCode(document.getElementById('qrcode'), { text: codeUrl, width: 200, height: 200 }); // 步骤 4:轮询查询订单状态 const checkOrderStatus = setInterval(async () => { const statusResponse = await fetch(`/api/pay/order/query?orderNo=${payResult.data.order_no}`); const statusResult = await statusResponse.json(); if (statusResult.data.status === 2) { // 2=已支付 clearInterval(checkOrderStatus); alert('支付成功!'); window.location.reload(); } }, 3000); // 每 3 秒查询一次 // 设置超时(15 分钟后停止查询) setTimeout(() => { clearInterval(checkOrderStatus); alert('支付超时,请重新下单'); }, 900000); } ``` --- ### 3.2 场景 2:账户充值 **业务流程:** ```javascript // 创建充值订单 const rechargeResponse = await fetch('/api/pay/wx/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId: 123, amount: 100.00, // 充值 100 元 productName: '账户充值', businessId: 123, businessType: 'recharge' // 充值业务类型 }) }); const result = await rechargeResponse.json(); if (result.code === 200) { // 显示支付二维码 showQRCode(result.data.code_url); } ``` **说明:** - 支付成功后,系统会自动通过回调将充值金额添加到用户账户余额 --- ### 3.3 场景 3:支付宝网页支付 ```javascript // 创建支付宝订单 const aliPayResponse = await fetch('/api/pay/alipay/create', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId: 123, amount: 0.01, productName: '测试商品', businessId: 456, businessType: 'purchase_content' }) }); const result = await aliPayResponse.json(); if (result.code === 200) { // 将返回的 HTML 表单写入页面 document.body.innerHTML = result.data; // 表单会自动提交,跳转到支付宝支付页面 } ``` --- ## 四、前端集成完整示例 ### 4.1 微信支付页面 ```html 微信支付

微信支付

请使用微信扫码支付

等待支付...

``` ### 4.2 支付宝支付页面 ```html 支付宝支付

正在跳转到支付宝支付页面...

请稍候

``` --- ## 五、核心代码文件 | 文件路径 | 说明 | |---------|------| | `src/main/java/com/kexue/skills/controller/PayController.java` | 支付接口控制器 | | `src/main/java/com/kexue/skills/service/PayService.java` | 支付服务接口 | | `src/main/java/com/kexue/skills/service/impl/PayServiceImpl.java` | 支付服务实现类 | | `src/main/java/com/kexue/skills/config/PaymentConfig.java` | 支付配置类 | | `src/main/java/com/kexue/skills/entity/PaymentOrder.java` | 支付订单实体类 | | `src/main/java/com/kexue/skills/service/PaymentOrderService.java` | 支付订单服务接口 | | `src/main/java/com/kexue/skills/service/impl/PaymentOrderServiceImpl.java` | 支付订单服务实现类 | --- ## 六、注意事项 ### 6.1 开发环境测试 ⚠️ **重要提示:** 本地开发环境下,微信和支付宝无法直接访问到你的 localhost 回调地址。 **解决方案:** 1. **使用内网穿透工具**(推荐) ```bash # 使用 ngrok ngrok http 19001 # 将生成的域名配置到回调地址 # 例如:https://abc123.ngrok.io/api/pay/wx/notify ``` 2. **部署到测试服务器** - 直接部署到具有公网 IP 的服务器进行测试 3. **修改配置文件** ```yaml payment: wechat: notifyUrl: https://your-domain.ngrok.io/api/pay/wx/notify alipay: notifyUrl: https://your-domain.ngrok.io/api/pay/alipay/trade/notify ``` ### 6.2 金额单位 - 前端传入金额单位:**元** - 微信支付内部转换:**分**(代码自动处理) - 建议最小金额:0.01 元 ### 6.3 业务类型说明 | 业务类型 | 说明 | 支付成功后操作 | |---------|------|--------------| | `recharge` | 账户充值 | 增加用户账户余额 | | `purchase_content` | 购买内容 | 更新内容购买记录状态 | ### 6.4 支付状态码 | 状态码 | 说明 | |-------|------| | 1 | 待支付 | | 2 | 已支付 | | 3 | 支付失败 | | 4 | 已取消 | | 5 | 已退款 | ### 6.5 安全建议 1. **权限验证**:所有支付接口都应添加权限验证(已部分实现) 2. **签名验证**:确保支付回调的签名验证正确 3. **幂等性处理**:支付回调应支持重复通知(已实现) 4. **日志记录**:完整的支付日志便于问题排查 --- ## 七、常见问题 ### Q1: 如何查询订单状态? ```java // 通过订单号查询 PaymentOrder order = paymentOrderService.queryByOrderNo(orderNo); // 或通过主键查询 PaymentOrder order = paymentOrderService.queryById(orderId); ``` ### Q2: 如何处理支付回调失败? 系统已实现幂等性处理,同一订单多次回调不会重复处理。如果回调失败,微信/支付宝会按一定频率重试。 ### Q3: 如何申请退款? 当前版本暂未实现退款功能,如需退款,需要: 1. 调用微信/支付宝退款 API 2. 更新支付订单状态为已退款(5) 3. 恢复用户余额或购买权限 ### Q4: 测试时使用真实资金吗? 是的,对接的是正式环境。如需测试环境,需要: - 微信:申请沙箱环境 - 支付宝:使用测试账号 --- ## 八、技术支持 如遇问题,请检查以下内容: 1. ✅ 配置文件中的商户号、密钥是否正确 2. ✅ 回调地址是否可被外网访问 3. ✅ 商户私钥文件是否存在且路径正确 4. ✅ 查看日志文件中的详细错误信息 5. ✅ 确认微信/支付宝商户号状态正常 --- **文档版本:** v1.0 **更新时间:** 2026-03-31 **维护人员:** 系统开发团队