维护说明:本文档已并入本站直接维护(单仓重构后原
backend/docs/*.md、前端docs/*.md不再随仓库发布)。 实现细节以 pay-unify 源码 为准,页面与源码的对应关系见相关资源。
https://<your-domain>/api/v2(示例;本地为 http://localhost:8097/api/v2)POST /oauth/token 换取 Bearer,见 认证体系)| 支付方式 | PayWay 值 | 说明 |
|---|---|---|
| 支付宝 | alipay |
支持PC网页支付、手机网页支付 |
| 微信支付 | wechat |
支持Native扫码支付、H5支付 |
| PayPal | paypal |
支持多币种国际支付 |
| 状态码 | 说明 |
|---|---|
| 1 | 待支付 |
| 2 | 已扫码(未支付) |
| 101 | 支付失败 |
| 201 | 已支付 |
| 300 | 已关闭 |
| 400 | 已退款 |
前端映射常量见
frontend/src/constants/options.ts。
Pay-Unify 开放 API(/api/v2/*)使用 OAuth2 Client Credentials:
接口:POST /oauth/token(公开;同时接受 JSON 与 application/x-www-form-urlencoded)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| grant_type | string | 是 | 固定 client_credentials |
| client_id | string | 是 | 控制台「API 应用管理」创建的应用 ID |
| client_secret | string | 是 | 应用密钥(仅创建 / 轮换时展示一次,bcrypt 存储) |
响应:
所有 /api/v2/* 请求携带:
令牌按应用的 scope 授权(payment:write 下单、payment:read 查单等),admin scope 通过所有检查。
scope 全集见 API 总览。
POST /oauth/token 失败返回 invalid_client(RFC 6749 不区分“应用不存在”与“密钥错误”):
/api/v1/api-apps 管理员会话)创建一个;invalid_client / 403。⚠️ 旧版 GoAuth HMAC(
X-App-Id / X-Timestamp / X-Nonce / X-Sign)认证已全面下线, 若在历史资料中看到这些请求头,请忽略并改用 Bearer。管理员 JWT(/api/v1/*,HttpOnly Cookie + CSRF) 仅用于控制台,详见 认证体系。
POST /api/v2/payment/payapplication/json| 参数名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| subject | string | 是 | 商品标题/订单描述 | VIP会员30天 |
| amount | float64 | 是 | 支付金额(元) | 99.00 |
| payWay | string | 是 | 支付方式:alipay/wechat/paypal | alipay |
| orderType | string | 否 | 订单类型 | vip/product |
| userId | string | 否 | 用户ID | user_123456 |
| extra | string | 否 | 额外信息(JSON字符串) | {"coupon":"NEW2024"} |
| currency | string | 否 | 货币代码(PayPal专用) | USD |
| brandName | string | 否 | 品牌名称(PayPal专用) | My Store |
| cancelUrl | string | 否 | 取消支付URL(PayPal专用) | https://... |
订单类型说明:
subscription/vip/member/membership: 订阅类订单,支付成功后自动为用户增加30天VIPproduct: 普通商品订单| 参数名 | 类型 | 说明 |
|---|---|---|
| code | int | 状态码,200表示成功 |
| message | string | 响应消息 |
| data | object | 响应数据 |
| data.payUrl | string | 支付链接 |
| data.payWay | string | 支付方式 |
| data.amount | float64 | 支付金额 |
| data.orderNo | string | 订单号 |
| data.orderId | string | PayPal订单ID(仅PayPal支付) |
| data.currency | string | 货币代码(仅PayPal支付) |
GET /api/v2/payment/query/{outTradeNo}| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| outTradeNo | path | string | 是 | 商户订单号 |
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | int | 状态码 |
| message | string | 响应消息 |
| data | object | 订单详情 |
| data.orderNo | string | 订单号 |
| data.subject | string | 订单标题 |
| data.amount | float64 | 订单金额 |
| data.status | int | 订单状态:1-未支付,2-已支付,201-已关闭,202-已退款 |
| data.payWay | string | 支付方式 |
| data.tradeNo | string | 第三方交易号 |
| data.payTime | int64 | 支付时间(Unix时间戳) |
| data.createdAt | int64 | 创建时间(Unix时间戳) |
GET /api/v2/payment/orders| 参数名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| userId | string | 否 | 用户ID | user_123456 |
| status | string | 否 | 订单状态 | 1/2/201/202 |
| payWay | string | 否 | 支付方式 | alipay/wechat/paypal |
| page | int | 否 | 页码,默认1 | 1 |
| pageSize | int | 否 | 每页数量,默认10,最大100 | 20 |
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | int | 状态码 |
| message | string | 响应消息 |
| data | object | 响应数据 |
| data.list | array | 订单列表 |
| data.total | int64 | 总记录数 |
| data.page | int | 当前页码 |
| data.pageSize | int | 每页数量 |
POST /api/v2/payment/close/{outTradeNo}| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| outTradeNo | path | string | 是 | 商户订单号 |
POST /api/v2/payment/cancel/{outTradeNo}| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| outTradeNo | path | string | 是 | 商户订单号 |
| cancelReason | body | string | 否 | 取消原因 |
POST /api/v2/payment/refund| 参数名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| outTradeNo | string | 是 | 商户订单号 | 202512311234567890 |
| refundAmount | float64 | 是 | 退款金额(元),不能超过订单金额 | 99.00 |
| refundReason | string | 否 | 退款原因 | 用户申请退款 |
支付成功后,支付平台(支付宝/微信/PayPal)会向您配置的回调地址发送异步通知。您需要在收到通知后:
| 支付方式 | 回调地址 |
|---|---|
| 支付宝 | POST /api/v2/payment/notify/alipay |
| 微信支付 | POST /api/v2/payment/notify/wechat |
| PayPal | POST /api/v2/payment/notify/paypal |
您有两种方式获取支付结果:
平台已自动处理支付回调,您只需要通过轮询查询或实现自己的 Webhook 来监听订单状态变化。
如果您的系统需要实时接收支付通知,建议实现以下流程:
| 状态码 | 说明 |
|---|---|
| 200 | 请求成功 |
| 400 | 请求参数错误 |
| 401 | 认证失败 |
| 403 | 无权限访问 |
| 404 | 资源不存在 |
| 429 | 请求频率超限 |
| 500 | 服务器内部错误 |
响应中的 code 字段:
| 错误码 | 说明 |
|---|---|
| 200 | 成功 |
| 400 | 参数错误 |
| 401 | 认证失败 |
| 403 | 无权限 |
| 404 | 资源不存在 |
| 500 | 系统错误 |
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
| "认证失败" | 签名错误或应用信息不正确 | 检查 AppId、AppSecret 和签名算法 |
| "时间戳已过期" | 请求时间戳超出允许范围 | 检查系统时间,确保在±5分钟内 |
| "支付金额必须大于0" | amount 参数 ≤ 0 | 检查金额参数 |
| "不支持的支付方式" | payWay 参数不在允许范围内 | 使用 alipay/wechat/paypal |
| "订单不存在或无权限操作" | 订单号不存在或不属于当前应用 | 检查订单号和应用权限 |
| "订单已支付,无法关闭" | 尝试关闭已支付的订单 | 只能关闭未支付的订单 |
官方未提供 SDK 包,以下为最小 OAuth2 接入示例(以 Go / Python / Node.js 演示)。
生产环境务必使用 HTTPS;令牌默认 1 小时过期,请实现自动刷新。
https://test.your-domain.comtest-app-001test-secret-key-12345678901234567890注意事项: