383 lines
7.8 KiB
Markdown
383 lines
7.8 KiB
Markdown
|
|
# 通用支付模块 API 接口定义 (Universal Payment API) v4.0
|
|||
|
|
|
|||
|
|
> 无论后端使用何种语言(Python/Node/Go/Java/PHP),请严格实现以下 RESTful 接口
|
|||
|
|
|
|||
|
|
## 🎯 设计原则
|
|||
|
|
|
|||
|
|
1. **RESTful 风格**: 资源命名统一,动词语义清晰
|
|||
|
|
2. **统一响应格式**: 所有接口返回 `{code, message, data}` 结构
|
|||
|
|
3. **幂等性**: 重复请求不产生副作用
|
|||
|
|
4. **安全性**: 敏感操作需签名验证
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📦 统一响应格式
|
|||
|
|
|
|||
|
|
### 成功响应
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"message": "success",
|
|||
|
|
"data": { ... }
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 错误响应
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 400,
|
|||
|
|
"message": "参数错误:order_sn 不能为空",
|
|||
|
|
"data": null
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 常用错误码
|
|||
|
|
| Code | 含义 |
|
|||
|
|
|:---|:---|
|
|||
|
|
| 200 | 成功 |
|
|||
|
|
| 400 | 请求参数错误 |
|
|||
|
|
| 401 | 未授权/登录过期 |
|
|||
|
|
| 403 | 无权限 |
|
|||
|
|
| 404 | 资源不存在 |
|
|||
|
|
| 409 | 状态冲突 (如重复支付) |
|
|||
|
|
| 500 | 服务器内部错误 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. 核心交易接口 (Core Transaction)
|
|||
|
|
|
|||
|
|
### 1.1 创建订单
|
|||
|
|
业务系统调用,创建一个待支付订单。
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
POST /api/payment/create_order
|
|||
|
|
Content-Type: application/json
|
|||
|
|
Authorization: Bearer {token}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Request Body**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"user_id": "u1001", // [必填] 用户ID
|
|||
|
|
"title": "VIP会员月卡", // [必填] 订单标题 (≤30字符)
|
|||
|
|
"amount": 99.00, // [必填] 金额 (单位: 元)
|
|||
|
|
"currency": "CNY", // [可选] 币种,默认 CNY
|
|||
|
|
"product_id": "vip_monthly", // [可选] 商品ID
|
|||
|
|
"product_type": "membership", // [可选] 商品类型
|
|||
|
|
"extra_params": { // [可选] 扩展参数 (会透传到回调)
|
|||
|
|
"coupon_id": "C001",
|
|||
|
|
"referrer": "user_123"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Response**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"message": "success",
|
|||
|
|
"data": {
|
|||
|
|
"order_sn": "202401170001", // 系统生成的订单号
|
|||
|
|
"status": "created", // 订单状态
|
|||
|
|
"amount": 99.00,
|
|||
|
|
"expire_at": "2024-01-17T11:30:00Z" // 订单过期时间
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 1.2 发起支付 (收银台)
|
|||
|
|
用户选择支付方式后,获取支付参数。
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
POST /api/payment/checkout
|
|||
|
|
Content-Type: application/json
|
|||
|
|
Authorization: Bearer {token}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Request Body**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"order_sn": "202401170001", // [必填] 订单号
|
|||
|
|
"gateway": "wechat_jsapi", // [必填] 支付网关 (见下方枚举)
|
|||
|
|
"return_url": "https://...", // [可选] 支付成功后跳转地址
|
|||
|
|
"openid": "oXxx...", // [条件] 微信JSAPI必填
|
|||
|
|
"coin_amount": 0 // [可选] 使用虚拟币抵扣金额
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Gateway 支付网关枚举**:
|
|||
|
|
| Gateway | 说明 | 返回类型 |
|
|||
|
|
|:---|:---|:---|
|
|||
|
|
| `alipay_web` | 支付宝PC网页 | url (跳转) |
|
|||
|
|
| `alipay_wap` | 支付宝H5 | url (跳转) |
|
|||
|
|
| `alipay_qr` | 支付宝扫码 | qrcode |
|
|||
|
|
| `wechat_native` | 微信扫码 | qrcode |
|
|||
|
|
| `wechat_jsapi` | 微信公众号/小程序 | json (SDK参数) |
|
|||
|
|
| `wechat_h5` | 微信H5 | url (跳转) |
|
|||
|
|
| `wechat_app` | 微信APP | json (SDK参数) |
|
|||
|
|
| `paypal` | PayPal | url (跳转) |
|
|||
|
|
| `stripe` | Stripe | url (Checkout Session) |
|
|||
|
|
| `usdt` | USDT-TRC20 | address (钱包地址) |
|
|||
|
|
| `coin` | 纯虚拟币支付 | direct (直接完成) |
|
|||
|
|
|
|||
|
|
**Response**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"message": "success",
|
|||
|
|
"data": {
|
|||
|
|
"trade_sn": "T20240117100001", // 交易流水号
|
|||
|
|
"type": "qrcode", // 响应类型: url/qrcode/json/address/direct
|
|||
|
|
"payload": "weixin://wxpay/...",// 支付数据 (根据type不同)
|
|||
|
|
"expiration": 1800, // 过期时间 (秒)
|
|||
|
|
"amount": 99.00, // 实际支付金额 (扣除抵扣后)
|
|||
|
|
"coin_deducted": 0 // 虚拟币抵扣金额
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**不同 type 的 payload 格式**:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// type: "url" - 跳转链接
|
|||
|
|
payload: "https://openapi.alipay.com/gateway.do?..."
|
|||
|
|
|
|||
|
|
// type: "qrcode" - 二维码内容
|
|||
|
|
payload: "weixin://wxpay/bizpayurl?pr=xxx"
|
|||
|
|
|
|||
|
|
// type: "json" - SDK调起参数 (微信JSAPI)
|
|||
|
|
payload: {
|
|||
|
|
"appId": "wx...",
|
|||
|
|
"timeStamp": "1705470600",
|
|||
|
|
"nonceStr": "xxx",
|
|||
|
|
"package": "prepay_id=wx...",
|
|||
|
|
"signType": "RSA",
|
|||
|
|
"paySign": "xxx"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// type: "address" - 加密货币地址
|
|||
|
|
payload: {
|
|||
|
|
"address": "TXxx...",
|
|||
|
|
"amount_usdt": 13.88,
|
|||
|
|
"memo": "202401170001"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// type: "direct" - 直接完成 (纯虚拟币支付)
|
|||
|
|
payload: { "status": "paid" }
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 1.3 查询订单状态
|
|||
|
|
前端轮询使用,判断支付是否完成。
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
GET /api/payment/status/{order_sn}
|
|||
|
|
Authorization: Bearer {token}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Response**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"message": "success",
|
|||
|
|
"data": {
|
|||
|
|
"order_sn": "202401170001",
|
|||
|
|
"status": "paid", // created/paying/paid/closed/refunded
|
|||
|
|
"paid_amount": 99.00,
|
|||
|
|
"paid_at": "2024-01-17T10:05:00Z",
|
|||
|
|
"payment_method": "wechat_jsapi",
|
|||
|
|
"trade_sn": "T20240117100001"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**订单状态机**:
|
|||
|
|
```
|
|||
|
|
created → paying → paid → (refunded)
|
|||
|
|
↓ ↓
|
|||
|
|
closed closed
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 1.4 关闭订单
|
|||
|
|
主动关闭未支付的订单。
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
POST /api/payment/close/{order_sn}
|
|||
|
|
Authorization: Bearer {token}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Response**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"message": "success",
|
|||
|
|
"data": {
|
|||
|
|
"order_sn": "202401170001",
|
|||
|
|
"status": "closed",
|
|||
|
|
"closed_at": "2024-01-17T10:10:00Z"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. 回调通知接口 (Webhook)
|
|||
|
|
|
|||
|
|
### 2.1 统一回调入口
|
|||
|
|
接收第三方支付平台的异步通知。
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
POST /api/payment/notify/{gateway}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Path Params**:
|
|||
|
|
- `gateway`: `alipay` / `wechat` / `paypal` / `stripe` / `nowpayments`
|
|||
|
|
|
|||
|
|
**处理逻辑**:
|
|||
|
|
1. 根据 gateway 加载对应驱动
|
|||
|
|
2. 验签 (Verify Signature)
|
|||
|
|
3. 幂等性检查 (防重复处理)
|
|||
|
|
4. 更新订单状态
|
|||
|
|
5. 触发业务回调 (发货/开通权限等)
|
|||
|
|
6. 返回平台所需响应
|
|||
|
|
|
|||
|
|
**返回格式**:
|
|||
|
|
```
|
|||
|
|
# 支付宝
|
|||
|
|
success
|
|||
|
|
|
|||
|
|
# 微信
|
|||
|
|
<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>
|
|||
|
|
|
|||
|
|
# Stripe
|
|||
|
|
HTTP 200 OK
|
|||
|
|
|
|||
|
|
# PayPal
|
|||
|
|
HTTP 200 OK
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 2.2 同步返回 (Return)
|
|||
|
|
用户支付完成后的页面跳转。
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
GET /api/payment/return/{gateway}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Query Params**: 各平台不同,由平台自动附加
|
|||
|
|
|
|||
|
|
**处理逻辑**:
|
|||
|
|
1. 解析回传参数
|
|||
|
|
2. 验签
|
|||
|
|
3. 重定向到成功页面
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. 辅助接口
|
|||
|
|
|
|||
|
|
### 3.1 获取可用支付方式
|
|||
|
|
```http
|
|||
|
|
GET /api/payment/methods
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Response**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"data": {
|
|||
|
|
"methods": [
|
|||
|
|
{
|
|||
|
|
"gateway": "wechat_jsapi",
|
|||
|
|
"name": "微信支付",
|
|||
|
|
"icon": "/icons/wechat.png",
|
|||
|
|
"enabled": true,
|
|||
|
|
"available": true // 当前环境是否可用 (如微信内)
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"gateway": "alipay_wap",
|
|||
|
|
"name": "支付宝",
|
|||
|
|
"icon": "/icons/alipay.png",
|
|||
|
|
"enabled": true,
|
|||
|
|
"available": true
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3.2 获取汇率
|
|||
|
|
```http
|
|||
|
|
GET /api/payment/exchange_rate?from=CNY&to=USD
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Response**:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"data": {
|
|||
|
|
"from": "CNY",
|
|||
|
|
"to": "USD",
|
|||
|
|
"rate": 0.139,
|
|||
|
|
"updated_at": "2024-01-17T00:00:00Z"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. 管理接口 (Admin)
|
|||
|
|
|
|||
|
|
### 4.1 订单列表
|
|||
|
|
```http
|
|||
|
|
GET /api/admin/payment/orders?page=1&limit=20&status=paid
|
|||
|
|
Authorization: Bearer {admin_token}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.2 交易流水列表
|
|||
|
|
```http
|
|||
|
|
GET /api/admin/payment/trades?page=1&limit=20
|
|||
|
|
Authorization: Bearer {admin_token}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.3 发起退款
|
|||
|
|
```http
|
|||
|
|
POST /api/admin/payment/refund
|
|||
|
|
Authorization: Bearer {admin_token}
|
|||
|
|
Content-Type: application/json
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
"trade_sn": "T20240117100001",
|
|||
|
|
"amount": 99.00,
|
|||
|
|
"reason": "用户申请退款"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. 接口签名规范 (可选)
|
|||
|
|
|
|||
|
|
对于安全要求高的场景,可启用接口签名:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 请求头
|
|||
|
|
X-Sign: sha256(timestamp + nonce + body + secret)
|
|||
|
|
X-Timestamp: 1705470600
|
|||
|
|
X-Nonce: abc123
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📌 注意事项
|
|||
|
|
|
|||
|
|
1. **金额单位**: 所有金额均以**元**为单位,小数点后2位
|
|||
|
|
2. **时间格式**: ISO 8601 格式 `YYYY-MM-DDTHH:mm:ssZ`
|
|||
|
|
3. **字符编码**: UTF-8
|
|||
|
|
4. **HTTPS**: 生产环境必须使用 HTTPS
|
|||
|
|
5. **幂等性**: 相同订单号重复请求返回相同结果
|