feat: 完整重构小程序匹配功能 + 修复UI对齐 + 文章数据API
主要更新: 1. 按H5网页端完全重构匹配功能(match页面) - 4种匹配类型: 创业合伙/资源对接/导师顾问/团队招募 - 资源对接等类型弹出手机号/微信号输入框 - 去掉重新匹配按钮,改为返回按钮 2. 修复所有卡片对齐和宽度问题 - 目录页附录卡片居中 - 首页阅读进度卡片满宽度 - 我的页面菜单卡片对齐 - 推广中心分享卡片统一宽度 3. 修复目录页图标和文字对齐 - section-icon固定40rpx宽高 - section-title与图标垂直居中 4. 更新真实完整文章标题(62篇) - 从book目录读取真实markdown文件名 - 替换之前的简化标题 5. 新增文章数据API - /api/db/chapters - 获取完整书籍结构 - 支持按ID获取单篇文章内容
This commit is contained in:
382
addons/Universal_Payment_Module copy/1_核心设计_通用协议/API接口定义.md
Normal file
382
addons/Universal_Payment_Module copy/1_核心设计_通用协议/API接口定义.md
Normal file
@@ -0,0 +1,382 @@
|
||||
# 通用支付模块 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. **幂等性**: 相同订单号重复请求返回相同结果
|
||||
396
addons/Universal_Payment_Module copy/1_核心设计_通用协议/业务逻辑与模型.md
Normal file
396
addons/Universal_Payment_Module copy/1_核心设计_通用协议/业务逻辑与模型.md
Normal file
@@ -0,0 +1,396 @@
|
||||
# 业务逻辑与数据模型 (Business Logic & Data Model) v4.0
|
||||
|
||||
> 定义支付系统的核心数据结构和业务流程
|
||||
|
||||
## 📊 数据库表结构
|
||||
|
||||
### 1. 订单表 (orders)
|
||||
|
||||
存储业务订单信息,与支付解耦。
|
||||
|
||||
```sql
|
||||
CREATE TABLE `orders` (
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`sn` VARCHAR(32) NOT NULL COMMENT '订单号 (业务唯一)',
|
||||
`user_id` VARCHAR(64) NOT NULL COMMENT '用户ID',
|
||||
`title` VARCHAR(128) NOT NULL COMMENT '订单标题',
|
||||
`price_amount` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '订单原价 (分)',
|
||||
`pay_amount` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '应付金额 (分)',
|
||||
`currency` VARCHAR(8) NOT NULL DEFAULT 'CNY' COMMENT '货币类型',
|
||||
`status` VARCHAR(20) NOT NULL DEFAULT 'created' COMMENT '状态: created/paying/paid/closed/refunded',
|
||||
`product_id` VARCHAR(64) DEFAULT NULL COMMENT '商品ID',
|
||||
`product_type` VARCHAR(32) DEFAULT NULL COMMENT '商品类型',
|
||||
`extra_data` JSON DEFAULT NULL COMMENT '扩展数据',
|
||||
`paid_at` DATETIME DEFAULT NULL COMMENT '支付时间',
|
||||
`closed_at` DATETIME DEFAULT NULL COMMENT '关闭时间',
|
||||
`expired_at` DATETIME DEFAULT NULL COMMENT '过期时间',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_sn` (`sn`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_created_at` (`created_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表';
|
||||
```
|
||||
|
||||
### 2. 交易流水表 (pay_trades)
|
||||
|
||||
记录每一次支付尝试,一个订单可能有多次交易。
|
||||
|
||||
```sql
|
||||
CREATE TABLE `pay_trades` (
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`trade_sn` VARCHAR(32) NOT NULL COMMENT '交易流水号 (系统生成)',
|
||||
`order_sn` VARCHAR(32) NOT NULL COMMENT '关联订单号',
|
||||
`user_id` VARCHAR(64) NOT NULL COMMENT '用户ID',
|
||||
`title` VARCHAR(128) NOT NULL COMMENT '交易标题',
|
||||
`amount` BIGINT UNSIGNED NOT NULL COMMENT '交易金额 (分)',
|
||||
`cash_amount` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '现金支付金额 (分)',
|
||||
`coin_amount` BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '虚拟币抵扣金额',
|
||||
`currency` VARCHAR(8) NOT NULL DEFAULT 'CNY' COMMENT '货币类型',
|
||||
`platform` VARCHAR(32) NOT NULL COMMENT '支付平台: alipay/wechat/paypal/stripe/usdt/coin',
|
||||
`platform_type` VARCHAR(32) DEFAULT NULL COMMENT '平台子类型: web/wap/jsapi/native/h5/app',
|
||||
`platform_sn` VARCHAR(64) DEFAULT NULL COMMENT '平台交易号',
|
||||
`platform_created_params` JSON DEFAULT NULL COMMENT '发送给平台的参数',
|
||||
`platform_created_result` JSON DEFAULT NULL COMMENT '平台返回的结果',
|
||||
`status` VARCHAR(20) NOT NULL DEFAULT 'paying' COMMENT '状态: paying/paid/closed/refunded',
|
||||
`type` VARCHAR(20) NOT NULL DEFAULT 'purchase' COMMENT '类型: purchase(购买)/recharge(充值)',
|
||||
`pay_time` DATETIME DEFAULT NULL COMMENT '支付时间',
|
||||
`notify_data` JSON DEFAULT NULL COMMENT '回调原始数据',
|
||||
`seller_id` VARCHAR(64) DEFAULT NULL COMMENT '卖家ID (多商户场景)',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_trade_sn` (`trade_sn`),
|
||||
KEY `idx_order_sn` (`order_sn`),
|
||||
KEY `idx_platform_sn` (`platform_sn`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_created_at` (`created_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='交易流水表';
|
||||
```
|
||||
|
||||
### 3. 资金流水表 (cashflows)
|
||||
|
||||
记录账户资金变动(可选,用于虚拟币/钱包场景)。
|
||||
|
||||
```sql
|
||||
CREATE TABLE `cashflows` (
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`sn` VARCHAR(32) NOT NULL COMMENT '流水号',
|
||||
`user_id` VARCHAR(64) NOT NULL COMMENT '用户ID',
|
||||
`type` VARCHAR(20) NOT NULL COMMENT '类型: inflow(入账)/outflow(出账)',
|
||||
`action` VARCHAR(32) NOT NULL COMMENT '动作: recharge/purchase/refund/transfer',
|
||||
`amount` BIGINT NOT NULL COMMENT '金额 (分,正数入账负数出账)',
|
||||
`currency` VARCHAR(8) NOT NULL DEFAULT 'CNY',
|
||||
`balance_before` BIGINT NOT NULL DEFAULT 0 COMMENT '变动前余额',
|
||||
`balance_after` BIGINT NOT NULL DEFAULT 0 COMMENT '变动后余额',
|
||||
`trade_sn` VARCHAR(32) DEFAULT NULL COMMENT '关联交易流水号',
|
||||
`order_sn` VARCHAR(32) DEFAULT NULL COMMENT '关联订单号',
|
||||
`remark` VARCHAR(256) DEFAULT NULL COMMENT '备注',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_sn` (`sn`),
|
||||
KEY `idx_user_id` (`user_id`),
|
||||
KEY `idx_trade_sn` (`trade_sn`),
|
||||
KEY `idx_created_at` (`created_at`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='资金流水表';
|
||||
```
|
||||
|
||||
### 4. 退款记录表 (refunds)
|
||||
|
||||
```sql
|
||||
CREATE TABLE `refunds` (
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`refund_sn` VARCHAR(32) NOT NULL COMMENT '退款单号',
|
||||
`trade_sn` VARCHAR(32) NOT NULL COMMENT '原交易流水号',
|
||||
`order_sn` VARCHAR(32) NOT NULL COMMENT '原订单号',
|
||||
`amount` BIGINT UNSIGNED NOT NULL COMMENT '退款金额 (分)',
|
||||
`reason` VARCHAR(256) DEFAULT NULL COMMENT '退款原因',
|
||||
`status` VARCHAR(20) NOT NULL DEFAULT 'pending' COMMENT '状态: pending/processing/success/failed',
|
||||
`platform_refund_sn` VARCHAR(64) DEFAULT NULL COMMENT '平台退款单号',
|
||||
`refunded_at` DATETIME DEFAULT NULL COMMENT '退款完成时间',
|
||||
`operator_id` VARCHAR(64) DEFAULT NULL COMMENT '操作人ID',
|
||||
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_refund_sn` (`refund_sn`),
|
||||
KEY `idx_trade_sn` (`trade_sn`),
|
||||
KEY `idx_order_sn` (`order_sn`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='退款记录表';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 状态机定义
|
||||
|
||||
### 订单状态 (Order Status)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ created │
|
||||
│ │ │
|
||||
│ ┌───────────┼───────────┐ │
|
||||
│ ▼ │ ▼ │
|
||||
│ paying ────────┼───────► closed │
|
||||
│ │ │ │
|
||||
│ ▼ │ │
|
||||
│ paid ─────────┼───────► refunded │
|
||||
│ │ │
|
||||
└─────────────────────────────────────────────────┘
|
||||
|
||||
状态说明:
|
||||
- created: 订单已创建,等待支付
|
||||
- paying: 支付中 (已发起支付请求)
|
||||
- paid: 已支付
|
||||
- closed: 已关闭 (超时/主动取消)
|
||||
- refunded: 已退款
|
||||
```
|
||||
|
||||
### 交易状态 (Trade Status)
|
||||
|
||||
```
|
||||
paying → paid
|
||||
↓ ↓
|
||||
closed refunded
|
||||
|
||||
状态说明:
|
||||
- paying: 支付中
|
||||
- paid: 支付成功
|
||||
- closed: 交易关闭
|
||||
- refunded: 已退款
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔢 编号规则
|
||||
|
||||
### 订单号 (order_sn)
|
||||
```
|
||||
格式: YYYYMMDD + 6位随机数
|
||||
示例: 202401170001
|
||||
|
||||
生成规则:
|
||||
1. 日期前缀保证每日唯一空间
|
||||
2. 随机数使用分布式ID生成器
|
||||
3. 支持前缀自定义 (如区分业务线)
|
||||
```
|
||||
|
||||
### 交易流水号 (trade_sn)
|
||||
```
|
||||
格式: T + YYYYMMDD + HHmmss + 5位随机数
|
||||
示例: T20240117100530123456
|
||||
|
||||
生成规则:
|
||||
1. 前缀 T 标识交易类型
|
||||
2. 精确到秒的时间戳
|
||||
3. 5位随机数防碰撞
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 核心业务流程
|
||||
|
||||
### 1. 标准支付流程
|
||||
|
||||
```sequence
|
||||
用户 -> 业务系统: 1. 提交订单
|
||||
业务系统 -> 支付模块: 2. 创建订单 (create_order)
|
||||
支付模块 -> 业务系统: 3. 返回 order_sn
|
||||
|
||||
用户 -> 支付模块: 4. 选择支付方式并支付 (checkout)
|
||||
支付模块 -> 支付平台: 5. 创建平台交易
|
||||
支付平台 -> 支付模块: 6. 返回支付参数
|
||||
支付模块 -> 用户: 7. 返回支付数据 (二维码/跳转链接)
|
||||
|
||||
用户 -> 支付平台: 8. 完成支付
|
||||
支付平台 -> 支付模块: 9. 异步回调 (notify)
|
||||
支付模块 -> 支付模块: 10. 验签 + 更新状态
|
||||
支付模块 -> 业务系统: 11. 触发业务回调 (发货/开通)
|
||||
```
|
||||
|
||||
### 2. 支付回调处理流程
|
||||
|
||||
```python
|
||||
def handle_notify(gateway, data):
|
||||
# 1. 加载对应的支付网关驱动
|
||||
driver = PaymentFactory.create(gateway)
|
||||
|
||||
# 2. 验证签名
|
||||
if not driver.verify_sign(data):
|
||||
raise SignatureError("签名验证失败")
|
||||
|
||||
# 3. 解析回调数据
|
||||
parsed = driver.parse_notify(data)
|
||||
trade_sn = parsed['trade_sn']
|
||||
|
||||
# 4. 幂等性检查
|
||||
trade = Trade.get_by_sn(trade_sn)
|
||||
if trade.status == 'paid':
|
||||
return driver.success_response() # 已处理过,直接返回成功
|
||||
|
||||
# 5. 金额校验
|
||||
if parsed['amount'] != trade.cash_amount:
|
||||
raise AmountMismatchError("金额不匹配")
|
||||
|
||||
# 6. 更新交易状态
|
||||
trade.update({
|
||||
'status': 'paid',
|
||||
'platform_sn': parsed['platform_sn'],
|
||||
'pay_time': parsed['pay_time'],
|
||||
'notify_data': data
|
||||
})
|
||||
|
||||
# 7. 更新订单状态
|
||||
order = Order.get_by_sn(trade.order_sn)
|
||||
order.update({'status': 'paid', 'paid_at': now()})
|
||||
|
||||
# 8. 触发业务回调
|
||||
dispatch_event('order.paid', order)
|
||||
|
||||
# 9. 返回成功响应
|
||||
return driver.success_response()
|
||||
```
|
||||
|
||||
### 3. 退款流程
|
||||
|
||||
```python
|
||||
def apply_refund(trade_sn, amount, reason):
|
||||
trade = Trade.get_by_sn(trade_sn)
|
||||
|
||||
# 1. 状态检查
|
||||
if trade.status != 'paid':
|
||||
raise InvalidStatusError("只有已支付的交易可以退款")
|
||||
|
||||
# 2. 创建退款记录
|
||||
refund = Refund.create({
|
||||
'refund_sn': generate_refund_sn(),
|
||||
'trade_sn': trade_sn,
|
||||
'amount': amount,
|
||||
'reason': reason,
|
||||
'status': 'pending'
|
||||
})
|
||||
|
||||
# 3. 调用平台退款接口
|
||||
driver = PaymentFactory.create(trade.platform)
|
||||
result = driver.refund({
|
||||
'trade_sn': trade_sn,
|
||||
'refund_sn': refund.refund_sn,
|
||||
'amount': amount
|
||||
})
|
||||
|
||||
# 4. 更新状态
|
||||
if result.success:
|
||||
refund.update({'status': 'success', 'refunded_at': now()})
|
||||
trade.update({'status': 'refunded'})
|
||||
else:
|
||||
refund.update({'status': 'failed'})
|
||||
|
||||
return refund
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏭 工厂模式设计
|
||||
|
||||
```python
|
||||
class PaymentFactory:
|
||||
"""支付网关工厂"""
|
||||
|
||||
_drivers = {
|
||||
'alipay': AlipayGateway,
|
||||
'wechat': WechatGateway,
|
||||
'paypal': PayPalGateway,
|
||||
'stripe': StripeGateway,
|
||||
'usdt': USDTGateway,
|
||||
'coin': CoinGateway,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def create(cls, gateway: str) -> AbstractGateway:
|
||||
gateway_name = gateway.split('_')[0] # wechat_jsapi -> wechat
|
||||
|
||||
if gateway_name not in cls._drivers:
|
||||
raise ValueError(f"不支持的支付网关: {gateway}")
|
||||
|
||||
driver_class = cls._drivers[gateway_name]
|
||||
return driver_class(config=get_payment_config(gateway_name))
|
||||
```
|
||||
|
||||
```python
|
||||
class AbstractGateway(ABC):
|
||||
"""支付网关抽象基类"""
|
||||
|
||||
@abstractmethod
|
||||
def create_trade(self, data: dict) -> dict:
|
||||
"""创建交易"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def verify_sign(self, data: dict) -> bool:
|
||||
"""验证签名"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def parse_notify(self, data: dict) -> dict:
|
||||
"""解析回调数据"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def refund(self, data: dict) -> RefundResult:
|
||||
"""发起退款"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def query_trade(self, trade_sn: str) -> dict:
|
||||
"""查询交易"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def close_trade(self, trade_sn: str) -> bool:
|
||||
"""关闭交易"""
|
||||
pass
|
||||
|
||||
def success_response(self) -> str:
|
||||
"""回调成功响应"""
|
||||
return "success"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💰 金额处理规范
|
||||
|
||||
### 1. 存储规则
|
||||
- 数据库统一使用**分**为单位 (BIGINT)
|
||||
- 避免浮点数精度问题
|
||||
|
||||
### 2. 接口规则
|
||||
- API 输入输出统一使用**元**为单位
|
||||
- 内部转换: `分 = 元 × 100`
|
||||
|
||||
### 3. 转换示例
|
||||
```python
|
||||
# 元转分 (API输入 -> 数据库)
|
||||
def yuan_to_fen(yuan: float) -> int:
|
||||
return int(round(yuan * 100))
|
||||
|
||||
# 分转元 (数据库 -> API输出)
|
||||
def fen_to_yuan(fen: int) -> float:
|
||||
return round(fen / 100, 2)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔐 幂等性设计
|
||||
|
||||
### 1. 订单创建幂等
|
||||
- 使用 `(user_id, product_id, created_date)` 组合判断
|
||||
- 或使用客户端传入的幂等键 `idempotency_key`
|
||||
|
||||
### 2. 支付回调幂等
|
||||
- 检查交易状态,已支付则直接返回成功
|
||||
- 使用数据库事务 + 行锁保证并发安全
|
||||
|
||||
### 3. 退款幂等
|
||||
- 同一笔交易只能退款一次 (或限制总退款金额)
|
||||
383
addons/Universal_Payment_Module copy/1_核心设计_通用协议/安全与合规.md
Normal file
383
addons/Universal_Payment_Module copy/1_核心设计_通用协议/安全与合规.md
Normal file
@@ -0,0 +1,383 @@
|
||||
# 支付安全与合规指南 (Security & Compliance) v4.0
|
||||
|
||||
> 支付系统安全最佳实践,保护你的资金和用户数据
|
||||
|
||||
## 🔐 密钥安全
|
||||
|
||||
### 1. 密钥存储原则
|
||||
|
||||
```
|
||||
❌ 错误做法:
|
||||
- 将密钥硬编码在代码中
|
||||
- 将密钥提交到 Git 仓库
|
||||
- 通过即时通讯工具传输密钥
|
||||
- 使用弱密码作为 API Key
|
||||
|
||||
✅ 正确做法:
|
||||
- 使用环境变量存储密钥
|
||||
- 使用专业密钥管理服务 (AWS KMS, HashiCorp Vault)
|
||||
- 定期轮换密钥
|
||||
- 最小权限原则
|
||||
```
|
||||
|
||||
### 2. .gitignore 必须包含
|
||||
|
||||
```gitignore
|
||||
# 支付密钥相关
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
*.pem
|
||||
*.key
|
||||
cert/
|
||||
config/payment.yml
|
||||
secrets/
|
||||
```
|
||||
|
||||
### 3. 密钥轮换
|
||||
|
||||
- 定期更换 API 密钥 (建议每 90 天)
|
||||
- 发现泄露立即作废并重新生成
|
||||
- 保留旧密钥短暂过渡期
|
||||
|
||||
---
|
||||
|
||||
## 🔒 通信安全
|
||||
|
||||
### 1. HTTPS 强制
|
||||
|
||||
```nginx
|
||||
# Nginx 配置示例
|
||||
server {
|
||||
listen 80;
|
||||
server_name your-domain.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name your-domain.com;
|
||||
|
||||
ssl_certificate /path/to/fullchain.pem;
|
||||
ssl_certificate_key /path/to/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
|
||||
|
||||
# HSTS
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 证书管理
|
||||
|
||||
- 使用受信任的 CA 签发证书
|
||||
- 定期检查证书有效期
|
||||
- 推荐 Let's Encrypt 自动续期
|
||||
|
||||
---
|
||||
|
||||
## ✅ 签名验证
|
||||
|
||||
### 1. 支付宝签名验证
|
||||
|
||||
```python
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.Signature import PKCS1_v1_5
|
||||
from Crypto.Hash import SHA256
|
||||
import base64
|
||||
|
||||
def verify_alipay_sign(params: dict, sign: str, public_key: str) -> bool:
|
||||
"""验证支付宝签名"""
|
||||
# 1. 参数排序
|
||||
sorted_params = sorted([(k, v) for k, v in params.items() if k != 'sign' and v])
|
||||
|
||||
# 2. 拼接待签名字符串
|
||||
sign_str = '&'.join([f'{k}={v}' for k, v in sorted_params])
|
||||
|
||||
# 3. RSA2 验签
|
||||
key = RSA.import_key(f"-----BEGIN PUBLIC KEY-----\n{public_key}\n-----END PUBLIC KEY-----")
|
||||
verifier = PKCS1_v1_5.new(key)
|
||||
hash_obj = SHA256.new(sign_str.encode('utf-8'))
|
||||
|
||||
try:
|
||||
verifier.verify(hash_obj, base64.b64decode(sign))
|
||||
return True
|
||||
except (ValueError, TypeError):
|
||||
return False
|
||||
```
|
||||
|
||||
### 2. 微信签名验证
|
||||
|
||||
```python
|
||||
import hashlib
|
||||
|
||||
def verify_wechat_sign(params: dict, sign: str, api_key: str) -> bool:
|
||||
"""验证微信支付签名"""
|
||||
# 1. 参数排序
|
||||
sorted_params = sorted([(k, v) for k, v in params.items() if k != 'sign' and v])
|
||||
|
||||
# 2. 拼接待签名字符串
|
||||
sign_str = '&'.join([f'{k}={v}' for k, v in sorted_params])
|
||||
sign_str += f'&key={api_key}'
|
||||
|
||||
# 3. MD5 签名
|
||||
calculated_sign = hashlib.md5(sign_str.encode('utf-8')).hexdigest().upper()
|
||||
|
||||
return calculated_sign == sign
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💰 金额校验
|
||||
|
||||
### 1. 回调金额必须验证
|
||||
|
||||
```python
|
||||
def handle_payment_notify(trade_sn: str, paid_amount: int):
|
||||
"""处理支付回调时必须验证金额"""
|
||||
trade = get_trade_by_sn(trade_sn)
|
||||
|
||||
# 金额必须严格匹配
|
||||
if paid_amount != trade.cash_amount:
|
||||
log.error(f"金额不匹配! 订单:{trade.cash_amount}, 回调:{paid_amount}")
|
||||
raise AmountMismatchError()
|
||||
|
||||
# 继续处理...
|
||||
```
|
||||
|
||||
### 2. 防止金额篡改
|
||||
|
||||
```python
|
||||
# 前端传入的金额仅用于展示,实际金额从后端订单读取
|
||||
def checkout(order_sn: str, gateway: str):
|
||||
order = get_order(order_sn)
|
||||
|
||||
# 金额从数据库读取,不信任前端
|
||||
amount = order.pay_amount
|
||||
|
||||
return create_trade(order_sn, amount, gateway)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🛡️ 回调安全
|
||||
|
||||
### 1. IP 白名单
|
||||
|
||||
```python
|
||||
# 支付平台回调 IP 白名单
|
||||
PAYMENT_IP_WHITELIST = {
|
||||
'alipay': [
|
||||
'110.75.0.0/16',
|
||||
'203.209.0.0/16'
|
||||
],
|
||||
'wechat': [
|
||||
'101.226.0.0/16',
|
||||
'140.207.0.0/16'
|
||||
]
|
||||
}
|
||||
|
||||
def verify_callback_ip(gateway: str, client_ip: str) -> bool:
|
||||
"""验证回调来源 IP"""
|
||||
import ipaddress
|
||||
|
||||
whitelist = PAYMENT_IP_WHITELIST.get(gateway, [])
|
||||
client = ipaddress.ip_address(client_ip)
|
||||
|
||||
for cidr in whitelist:
|
||||
if client in ipaddress.ip_network(cidr):
|
||||
return True
|
||||
|
||||
return False
|
||||
```
|
||||
|
||||
### 2. 防重放攻击
|
||||
|
||||
```python
|
||||
import time
|
||||
|
||||
def check_notify_timestamp(timestamp: int) -> bool:
|
||||
"""检查回调时间戳,防止重放攻击"""
|
||||
now = int(time.time())
|
||||
|
||||
# 允许 5 分钟的时间差
|
||||
if abs(now - timestamp) > 300:
|
||||
log.warning(f"回调时间戳异常: {timestamp}")
|
||||
return False
|
||||
|
||||
return True
|
||||
```
|
||||
|
||||
### 3. 幂等性处理
|
||||
|
||||
```python
|
||||
def process_notify_idempotent(trade_sn: str, notify_data: dict):
|
||||
"""幂等性处理回调"""
|
||||
|
||||
# 使用分布式锁
|
||||
lock_key = f"payment_notify:{trade_sn}"
|
||||
|
||||
with redis_lock(lock_key, timeout=10):
|
||||
trade = get_trade_by_sn(trade_sn)
|
||||
|
||||
# 已处理过,直接返回成功
|
||||
if trade.status == 'paid':
|
||||
return success_response()
|
||||
|
||||
# 处理支付成功逻辑
|
||||
update_trade_to_paid(trade, notify_data)
|
||||
|
||||
return success_response()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 日志审计
|
||||
|
||||
### 1. 必须记录的日志
|
||||
|
||||
```python
|
||||
import logging
|
||||
|
||||
payment_logger = logging.getLogger('payment')
|
||||
|
||||
# 创建交易日志
|
||||
payment_logger.info(f"创建交易 | trade_sn={trade_sn} | order_sn={order_sn} | amount={amount} | gateway={gateway}")
|
||||
|
||||
# 回调日志
|
||||
payment_logger.info(f"收到回调 | gateway={gateway} | trade_sn={trade_sn} | raw_data={raw_data[:500]}")
|
||||
|
||||
# 签名验证日志
|
||||
payment_logger.info(f"签名验证 | trade_sn={trade_sn} | result={verify_result}")
|
||||
|
||||
# 状态变更日志
|
||||
payment_logger.info(f"状态变更 | trade_sn={trade_sn} | from={old_status} | to={new_status}")
|
||||
|
||||
# 退款日志
|
||||
payment_logger.info(f"发起退款 | refund_sn={refund_sn} | trade_sn={trade_sn} | amount={amount}")
|
||||
```
|
||||
|
||||
### 2. 敏感信息脱敏
|
||||
|
||||
```python
|
||||
def mask_sensitive(data: dict) -> dict:
|
||||
"""敏感信息脱敏"""
|
||||
sensitive_keys = ['card_no', 'id_card', 'phone', 'bank_account']
|
||||
|
||||
masked = data.copy()
|
||||
for key in sensitive_keys:
|
||||
if key in masked:
|
||||
value = str(masked[key])
|
||||
if len(value) > 4:
|
||||
masked[key] = value[:2] + '*' * (len(value) - 4) + value[-2:]
|
||||
|
||||
return masked
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚨 异常处理
|
||||
|
||||
### 1. 支付异常分类
|
||||
|
||||
```python
|
||||
class PaymentError(Exception):
|
||||
"""支付基础异常"""
|
||||
pass
|
||||
|
||||
class SignatureError(PaymentError):
|
||||
"""签名验证失败"""
|
||||
pass
|
||||
|
||||
class AmountMismatchError(PaymentError):
|
||||
"""金额不匹配"""
|
||||
pass
|
||||
|
||||
class OrderExpiredError(PaymentError):
|
||||
"""订单已过期"""
|
||||
pass
|
||||
|
||||
class DuplicatePaymentError(PaymentError):
|
||||
"""重复支付"""
|
||||
pass
|
||||
|
||||
class RefundError(PaymentError):
|
||||
"""退款失败"""
|
||||
pass
|
||||
```
|
||||
|
||||
### 2. 统一异常处理
|
||||
|
||||
```python
|
||||
@app.exception_handler(PaymentError)
|
||||
async def payment_exception_handler(request, exc):
|
||||
return JSONResponse(
|
||||
status_code=400,
|
||||
content={
|
||||
"code": 400,
|
||||
"message": str(exc),
|
||||
"data": None
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ 合规要求
|
||||
|
||||
### 1. PCI DSS 合规 (信用卡)
|
||||
|
||||
- 不存储完整卡号、CVV、PIN
|
||||
- 使用 Stripe/PayPal 等符合 PCI DSS 的支付网关
|
||||
- 定期安全评估
|
||||
|
||||
### 2. GDPR 合规 (欧盟用户)
|
||||
|
||||
- 明确告知用户数据用途
|
||||
- 提供数据删除功能
|
||||
- 用户同意授权
|
||||
|
||||
### 3. 中国支付合规
|
||||
|
||||
- 接入持牌支付机构
|
||||
- 实名认证
|
||||
- 交易限额管理
|
||||
|
||||
---
|
||||
|
||||
## 📋 安全检查清单
|
||||
|
||||
```markdown
|
||||
## 上线前安全检查
|
||||
|
||||
### 密钥管理
|
||||
- [ ] 所有密钥通过环境变量配置
|
||||
- [ ] 密钥未提交到代码仓库
|
||||
- [ ] 生产环境密钥与测试环境隔离
|
||||
|
||||
### 通信安全
|
||||
- [ ] 启用 HTTPS
|
||||
- [ ] 证书有效且受信任
|
||||
- [ ] 启用 HSTS
|
||||
|
||||
### 签名验证
|
||||
- [ ] 所有回调验签
|
||||
- [ ] 验签失败拒绝处理
|
||||
|
||||
### 金额校验
|
||||
- [ ] 回调金额与订单金额比对
|
||||
- [ ] 金额从后端读取
|
||||
|
||||
### 日志审计
|
||||
- [ ] 关键操作有日志
|
||||
- [ ] 敏感信息脱敏
|
||||
|
||||
### 异常处理
|
||||
- [ ] 异常不泄露敏感信息
|
||||
- [ ] 有统一异常处理
|
||||
|
||||
### 回调安全
|
||||
- [ ] IP 白名单验证 (可选)
|
||||
- [ ] 幂等性处理
|
||||
- [ ] 防重放攻击
|
||||
```
|
||||
133
addons/Universal_Payment_Module copy/1_核心设计_通用协议/标准配置模板.yaml
Normal file
133
addons/Universal_Payment_Module copy/1_核心设计_通用协议/标准配置模板.yaml
Normal file
@@ -0,0 +1,133 @@
|
||||
# ============================================================================
|
||||
# 全球支付模块标准配置模板 (Universal Payment Config Template) v4.0
|
||||
# ============================================================================
|
||||
# 适用于: Python, Node.js, Go, Java, PHP 等任意后端语言
|
||||
# 使用方法: 将此配置映射到你项目的环境变量 (.env, config.py, application.yml)
|
||||
# ============================================================================
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# 1. 基础环境 (Environment)
|
||||
# ----------------------------------------------------------------------------
|
||||
APP_ENV: "production" # development / staging / production
|
||||
APP_NAME: "MyApp" # 应用名称 (用于日志/标题)
|
||||
APP_URL: "https://your-site.com" # 你的网站域名 (用于回调地址生成)
|
||||
APP_CURRENCY: "CNY" # 默认货币: CNY, USD, EUR
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# 2. 数据库 (Database) - 存储订单和交易流水
|
||||
# ----------------------------------------------------------------------------
|
||||
DB_CONNECTION: "mysql" # mysql / postgres / mongodb / sqlite
|
||||
DB_HOST: "127.0.0.1"
|
||||
DB_PORT: "3306"
|
||||
DB_DATABASE: "payment_db"
|
||||
DB_USERNAME: "root"
|
||||
DB_PASSWORD: "your_password"
|
||||
|
||||
# 自动创建的表:
|
||||
# - orders (订单表)
|
||||
# - pay_trades (交易流水表)
|
||||
# - cashflows (资金流水表)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# 3. 支付宝 (Alipay) - 中国市场
|
||||
# ----------------------------------------------------------------------------
|
||||
ALIPAY_ENABLED: true
|
||||
ALIPAY_MODE: "production" # sandbox / production
|
||||
ALIPAY_APP_ID: "" # 开放平台应用 AppID
|
||||
ALIPAY_PID: "" # 商户 PID (合作伙伴ID)
|
||||
ALIPAY_SELLER_EMAIL: "" # 收款支付宝账号
|
||||
ALIPAY_PRIVATE_KEY: "" # 商户私钥 (RSA2)
|
||||
ALIPAY_PUBLIC_KEY: "" # 支付宝公钥
|
||||
ALIPAY_MD5_KEY: "" # MD5 密钥 (旧版接口)
|
||||
|
||||
# 回调地址 (系统自动拼接 APP_URL)
|
||||
# 同步回调: ${APP_URL}/api/payment/return/alipay
|
||||
# 异步回调: ${APP_URL}/api/payment/notify/alipay
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# 4. 微信支付 (Wechat Pay) - 中国市场
|
||||
# ----------------------------------------------------------------------------
|
||||
WECHAT_ENABLED: true
|
||||
WECHAT_MODE: "production" # sandbox / production
|
||||
|
||||
# 公众号/网站支付
|
||||
WECHAT_APPID: "" # 公众号/网站 AppID
|
||||
WECHAT_APP_SECRET: "" # AppSecret
|
||||
|
||||
# 服务号 (如果有独立服务号)
|
||||
WECHAT_SERVICE_APPID: "" # 服务号 AppID
|
||||
WECHAT_SERVICE_SECRET: "" # 服务号 AppSecret
|
||||
|
||||
# 商户信息
|
||||
WECHAT_MCH_ID: "" # 商户号
|
||||
WECHAT_MCH_KEY: "" # 商户平台 API 密钥 (32位)
|
||||
WECHAT_MCH_KEY_V3: "" # APIv3 密钥 (如使用v3接口)
|
||||
|
||||
# 证书路径 (相对于项目根目录)
|
||||
WECHAT_CERT_PATH: "./cert/wechat/apiclient_cert.pem"
|
||||
WECHAT_KEY_PATH: "./cert/wechat/apiclient_key.pem"
|
||||
WECHAT_CERT_SERIAL: "" # 证书序列号 (v3接口需要)
|
||||
|
||||
# 小程序 (如果有)
|
||||
WECHAT_MINI_APPID: "" # 小程序 AppID
|
||||
WECHAT_MINI_SECRET: "" # 小程序 AppSecret
|
||||
|
||||
# 回调地址
|
||||
# 异步回调: ${APP_URL}/api/payment/notify/wechat
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# 5. PayPal - 全球市场
|
||||
# ----------------------------------------------------------------------------
|
||||
PAYPAL_ENABLED: true
|
||||
PAYPAL_MODE: "live" # sandbox / live
|
||||
PAYPAL_CLIENT_ID: "" # Client ID
|
||||
PAYPAL_CLIENT_SECRET: "" # Client Secret
|
||||
PAYPAL_WEBHOOK_ID: "" # Webhook ID (用于验证回调)
|
||||
|
||||
# 回调地址: ${APP_URL}/api/payment/notify/paypal
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# 6. Stripe - 全球市场
|
||||
# ----------------------------------------------------------------------------
|
||||
STRIPE_ENABLED: true
|
||||
STRIPE_MODE: "live" # test / live
|
||||
STRIPE_PUBLIC_KEY: "" # pk_live_xxx 或 pk_test_xxx
|
||||
STRIPE_SECRET_KEY: "" # sk_live_xxx 或 sk_test_xxx
|
||||
STRIPE_WEBHOOK_SECRET: "" # whsec_xxx
|
||||
|
||||
# 回调地址: ${APP_URL}/api/payment/notify/stripe
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# 7. USDT (加密货币) - Web3 / 抗审查支付
|
||||
# ----------------------------------------------------------------------------
|
||||
USDT_ENABLED: false
|
||||
USDT_GATEWAY_TYPE: "nowpayments" # nowpayments / native
|
||||
|
||||
# 选项 A: NOWPayments (第三方托管)
|
||||
NOWPAYMENTS_API_KEY: ""
|
||||
NOWPAYMENTS_IPN_SECRET: ""
|
||||
|
||||
# 选项 B: Native (原生 TRC20 监听)
|
||||
TRON_NODE_API: "https://api.trongrid.io"
|
||||
TRON_WALLET_ADDRESS: "" # 你的 USDT-TRC20 收款地址
|
||||
TRON_API_KEY: "" # TronGrid API Key
|
||||
TRON_CHECK_INTERVAL: 60 # 轮询间隔 (秒)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# 8. 高级配置 (Advanced)
|
||||
# ----------------------------------------------------------------------------
|
||||
# 虚拟币/积分系统
|
||||
COIN_ENABLED: false # 是否启用虚拟币抵扣
|
||||
COIN_RATE: 100 # 1元 = 100虚拟币
|
||||
|
||||
# 订单配置
|
||||
ORDER_EXPIRE_MINUTES: 30 # 订单过期时间 (分钟)
|
||||
TRADE_SN_PREFIX: "T" # 交易流水号前缀
|
||||
|
||||
# 日志配置
|
||||
PAYMENT_LOG_LEVEL: "info" # debug / info / warning / error
|
||||
PAYMENT_LOG_PATH: "./logs/payment.log"
|
||||
|
||||
# 安全配置
|
||||
PAYMENT_IP_WHITELIST: "" # 回调IP白名单 (逗号分隔)
|
||||
PAYMENT_SIGN_TYPE: "RSA2" # 签名类型: RSA2, MD5
|
||||
Reference in New Issue
Block a user