Files
jczxw-pc/docs/payment-integration.md
2026-04-23 16:30:57 +08:00

388 lines
8.2 KiB
Markdown
Raw 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.

# 支付与订单闭环实现指南
## 📦 已完成的前端实现
### 1. 支付 API 模块 (`app/api/payment/index.ts`)
提供统一的支付接口封装:
```typescript
import {
createWechatJsapiPay, // 微信 JSAPI 支付
createWechatH5Pay, // 微信 H5 支付
createWechatNativePay, // 微信 Native 扫码支付
createAlipayPay, // 支付宝网页支付
queryPayStatus, // 查询支付状态
detectPayEnvironment, // 检测支付环境
isWechatBrowser, // 检测微信浏览器
isAlipayBrowser // 检测支付宝浏览器
} from '@/api/payment'
```
### 2. 支付组件 (`app/components/payment/PaymentModal.vue`)
开箱即用的支付弹窗组件,支持:
- **微信 JSAPI** - 微信内置浏览器调起微信支付
- **微信 H5** - 非微信浏览器跳转微信H5支付页面
- **微信 Native** - 扫码支付,显示二维码
- **支付宝 WAP** - 跳转支付宝支付页面
- **余额支付** - 平台余额直接扣款
使用方式:
```vue
<template>
<PaymentModal
v-model:visible="payModalVisible"
:order-no="order.orderNo"
:order-id="order.orderId"
:pay-price="order.payPrice"
:available-methods="{ wechat: true, alipay: true, balance: false }"
@success="onPaySuccess"
/>
</template>
<script setup>
import PaymentModal from '@/components/payment/PaymentModal.vue'
const payModalVisible = ref(false)
function openPay(order) {
payModalVisible.value = true
}
function onPaySuccess(result) {
console.log('支付成功', result)
// 刷新订单列表等操作
}
</script>
```
### 3. 订单页面集成 (`app/pages/orders.vue`)
已完善 `goPay()``applyRefund()``cancelOrder()` 功能:
- 点击"去支付"打开支付弹窗
- 点击"申请退款"弹出确认框
- 点击"取消订单"弹出确认框
---
## 🔧 后端需要实现的接口
### 1. 微信 JSAPI 支付
```
POST /api/system/wx-jsapi-pay/unified-order
```
**请求参数:**
```json
{
"orderNo": "订单号",
"openId": "用户 OpenId",
"subject": "商品描述",
"body": "商品详情",
"totalAmount": 100, // 金额(分)
"returnUrl": "支付完成跳转URL"
}
```
**返回参数:**
```json
{
"code": 0,
"data": {
"prepayId": "预支付交易会话标识",
"codeUrl": "公众号 AppId",
"mwebUrl": "H5支付链接"
}
}
```
### 2. 微信 H5 支付
```
POST /api/system/wx-h5-pay/unified-order
```
**请求参数:** 同 JSAPI
**返回参数:**
```json
{
"code": 0,
"data": {
"mwebUrl": "https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?..."
}
}
```
### 3. 微信 Native 支付
```
POST /api/system/wx-native-pay/unified-order
```
**返回参数:**
```json
{
"code": 0,
"data": {
"codeUrl": "weixin://wxpay/bizpayurl?..."
}
}
```
### 4. 支付宝网页支付
```
POST /api/system/alipay/unified-order
```
**请求参数:**
```json
{
"orderNo": "订单号",
"subject": "商品标题",
"body": "商品描述",
"totalAmount": 100, // 金额(元)
"returnUrl": "支付完成跳转URL"
}
```
**返回参数:**
```json
{
"code": 0,
"data": {
"paymentUrl": "https://openapi.alipay.com/gateway.do?..."
}
}
```
### 5. 查询支付状态
```
GET /api/system/payment/query-status?orderNo=xxx
```
**返回参数:**
```json
{
"code": 0,
"data": {
"paid": true,
"payStatus": 1,
"orderStatus": 1,
"payTime": "2024-01-01 12:00:00",
"transactionId": "微信/支付宝交易号"
}
}
```
### 6. 取消订单
```
POST /api/system/order/cancel
```
**请求参数:**
```json
{
"orderId": 123
}
```
### 7. 申请退款
```
POST /api/system/order/refund
```
**请求参数:**
```json
{
"orderId": 123,
"reason": "退款原因"
}
```
---
## 🔐 微信支付配置
### 1. 微信商户平台配置
登录 [微信商户平台](https://pay.weixin.qq.com),获取以下信息:
| 配置项 | 说明 |
|--------|------|
| AppID | 公众号应用ID |
| MchID | 商户号 |
| API Key | APIv2 密钥 |
| APIv3 Key | APIv3 密钥 |
| 证书 | 商户证书(用于退款等敏感操作) |
| AppSecret | 公众号应用密钥 |
### 2. 后端配置示例
```yaml
# application.yml
wechat:
pay:
app-id: wx1234567890abcdef
mch-id: 1234567890
api-key: xxxxxxxx
api-v3-key: xxxxxxxx
notify-url: https://your-domain.com/api/payment/notify
refund-url: https://your-domain.com/api/payment/refund-notify
cert-path: /path/to/apiclient_cert.p12
```
### 3. JSAPI 支付配置
需要在微信公众平台配置:
- **JS接口安全域名** - 发起支付的页面域名
- **网页授权域名** - 用于获取 OpenId
---
## 🔐 支付宝配置
### 1. 支付宝开放平台配置
登录 [支付宝开放平台](https://open.alipay.com),创建应用并获取:
| 配置项 | 说明 |
|--------|------|
| AppID | 应用ID |
| PrivateKey | 应用私钥 |
| AlipayPublicKey | 支付宝公钥 |
### 2. 后端配置示例
```yaml
# application.yml
alipay:
app-id: 2021000000000000
private-key: xxxxxxxx
alipay-public-key: xxxxxxxx
notify-url: https://your-domain.com/api/payment/alipay-notify
return-url: https://your-domain.com/api/payment/alipay-return
```
---
## 📋 支付流程
### 微信 JSAPI 支付流程
```
┌─────────────┐
│ 用户下单 │
└──────┬──────┘
┌─────────────┐
│ 后端创建订单 │
└──────┬──────┘
┌─────────────────────────────────────┐
│ 前端调用 createWechatJsapiPay │
│ (传入 openId、订单信息) │
└──────┬────────────────────────────┘
┌─────────────┐
│ 后端统一下单 │
│ 返回 prepayId │
└──────┬──────┘
┌─────────────┐
│ 前端调起 │
│ WeixinJSBridge │
└──────┬──────┘
┌─────────────┐
│ 用户输入密码 │
│ 完成支付 │
└──────┬──────┘
┌─────────────────────────────────────┐
│ 微信回调后端 + 前端轮询 queryPayStatus │
└──────┬────────────────────────────┘
┌─────────────┐
│ 显示支付成功 │
└─────────────┘
```
### 支付结果通知
后端需要实现支付结果回调:
```
POST /api/system/payment/notify (微信)
POST /api/system/payment/alipay-notify (支付宝)
```
收到回调后:
1. 验证签名
2. 更新订单状态
3. 返回 success 给支付方
---
## 🎯 快速开始
### 1. 完成后端接口
按照"后端需要实现的接口"章节实现各个支付接口。
### 2. 配置密钥
在微信商户平台和支付宝开放平台完成配置,获取必要的密钥。
### 3. 更新 API 路径
如果后端接口路径与设计不同,更新 `app/api/payment/index.ts` 中的接口路径。
### 4. 测试支付
1. 启动前端:`pnpm dev`
2. 登录后进入订单页面
3. 点击"去支付"测试支付流程
---
## 📝 注意事项
### 1. 金额单位
- **前端传给后端**保留2位小数或 分(整数)
- **微信/支付宝**:通常使用**分**
- 建议前端统一传元,后端转为分
### 2. 订单号
- 建议使用业务方生成的唯一订单号
- 避免重复支付
- 建议格式:`PAY + 时间戳 + 随机数`
### 3. 回调通知
- 必须实现支付结果回调
- 回调地址需要公网可访问
- 注意防止重复处理
### 4. 安全建议
- 所有支付相关接口需要登录验证
- 金额计算在后端完成
- 签名验证在前端不做,后端完成
---
## 🔗 相关资源
- [微信支付开发文档](https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml)
- [支付宝支付文档](https://opendocs.alipay.com/open/270)
- [JSSDK 使用说明](https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html)