支付 API
支付订单管理接口,包括创建订单、发起支付、查询订单、订单列表、支付方式和产品价格。
路由前缀:/payment
源码:apps/backend/src/routes/payment.ts
限流:60 秒内最多 10 次请求
认证
所有接口需要 JWT 认证:
Authorization: Bearer <JWT>类型定义
ProductType(产品类型)
| 值 | 说明 |
|---|---|
subscription | 订阅计划 |
credit_pack | 积分包 |
ProviderCode(支付渠道)
| 值 | 说明 |
|---|---|
paddle | Paddle(国际) |
yungouos | YunGouOS(国内) |
stripe | Stripe(国际) |
manual | 手动处理 |
mock | 模拟支付(开发环境) |
PaymentMethod(支付方式)
| 值 | 说明 |
|---|---|
wechat | 微信支付 |
alipay | 支付宝 |
card | 银行卡 |
paypal | PayPal |
bank_transfer | 银行转账 |
Currency(货币)
| 值 | 说明 |
|---|---|
CNY | 人民币 |
USD | 美元 |
OrderStatus(订单状态)
| 值 | 说明 |
|---|---|
created | 已创建,待支付 |
pending | 支付中(已调起支付) |
paid | 已支付,待履约 |
fulfilling | 履约中 |
fulfilled | 已完成 |
fulfill_failed | 履约失败 |
expired | 已过期 |
failed | 支付失败 |
refunded | 已退款 |
端点
1. 创建订单
POST /payment/orders创建支付订单。用户必须属于一个团队才能创建订单。
请求体:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
productType | ProductType | 是 | 产品类型 |
productCode | string | 是 | 产品代码 |
currency | Currency | 否 | 货币类型(默认 CNY) |
metadata | object | 否 | 自定义元数据 |
响应 200 OK:
json
{
"success": true,
"data": {
"orderId": "uuid",
"orderNo": "PO_20260307_ABCD1234",
"amount": 9900,
"currency": "CNY",
"expiresAt": "2026-03-07T10:30:00.000Z"
}
}
amount单位为分(CNY)或 cents(USD)。
错误码:
| HTTP | code | 说明 |
|---|---|---|
| 400 | NO_TEAM | 用户未加入任何团队 |
| 404 | PRODUCT_NOT_FOUND | 产品不存在 |
| 404 | PRICE_NOT_FOUND | 价格未配置 |
| 500 | INTERNAL_ERROR | 服务端错误 |
2. 发起支付
POST /payment/orders/:id/pay对已创建的订单发起支付,返回支付凭据(支付 URL、二维码等)。
路径参数:
| 参数 | 说明 |
|---|---|
id | 订单 ID |
请求体:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
provider | ProviderCode | 是 | 支付渠道 |
paymentMethod | PaymentMethod | 是 | 支付方式 |
returnUrl | string | 否 | 支付完成后的回跳 URL |
响应 200 OK:
json
{
"success": true,
"data": {
"orderId": "uuid",
"orderNo": "PO_20260307_ABCD1234",
"status": "pending",
"providerOrderId": "provider-order-id",
"payUrl": "https://pay.example.com/...",
"qrCode": "weixin://wxpay/...",
"qrCodeUrl": "https://example.com/qr.png",
"checkoutToken": "paddle-checkout-token",
"expiresAt": "2026-03-07T10:30:00.000Z"
}
}不同渠道返回的支付凭据不同:
payUrl(跳转支付)、qrCode(二维码内容)、qrCodeUrl(二维码图片)、checkoutToken(Paddle overlay)。
错误码:
| HTTP | code | 说明 |
|---|---|---|
| 400 | NO_TEAM | 用户未加入任何团队 |
| 400 | ORDER_NOT_PAYABLE | 订单状态不允许支付 |
| 400 | ORDER_EXPIRED | 订单已过期 |
| 400 | PROVIDER_NOT_FOUND | 支付渠道未注册 |
| 404 | ORDER_NOT_FOUND | 订单不存在 |
| 500 | INTERNAL_ERROR | 服务端错误 |
3. 查询订单
GET /payment/orders/:id获取订单详情。仅能查询当前用户所在团队的订单。
路径参数:
| 参数 | 说明 |
|---|---|
id | 订单 ID |
响应 200 OK:
json
{
"success": true,
"data": {
"id": "uuid",
"orderNo": "PO_20260307_ABCD1234",
"productType": "credit_pack",
"product": {
"type": "credit_pack",
"name": "100 积分包",
"credits": 100
},
"amount": 9900,
"currency": "CNY",
"status": "fulfilled",
"provider": "yungouos",
"paymentMethod": "wechat",
"createdAt": "2026-03-07T10:00:00.000Z",
"paidAt": "2026-03-07T10:05:00.000Z",
"fulfilledAt": "2026-03-07T10:05:01.000Z"
}
}错误码:
| HTTP | code | 说明 |
|---|---|---|
| 400 | NO_TEAM | 用户未加入任何团队 |
| 404 | ORDER_NOT_FOUND | 订单不存在(包括无权访问) |
| 500 | INTERNAL_ERROR | 服务端错误 |
4. 订单列表
GET /payment/orders获取当前用户所在团队的订单列表。
查询参数:
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
limit | number | 否 | 20 | 每页数量 |
offset | number | 否 | 0 | 偏移量 |
响应 200 OK:
json
{
"success": true,
"data": [
{
"id": "uuid",
"orderNo": "PO_20260307_ABCD1234",
"productType": "credit_pack",
"amount": 9900,
"currency": "CNY",
"status": "fulfilled",
"createdAt": "2026-03-07T10:00:00.000Z",
"paidAt": "2026-03-07T10:05:00.000Z"
}
]
}错误码:
| HTTP | code | 说明 |
|---|---|---|
| 400 | NO_TEAM | 用户未加入任何团队 |
| 500 | INTERNAL_ERROR | 服务端错误 |
5. 可用支付方式
GET /payment/methods获取当前可用的支付方式列表。
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
currency | Currency | 否 | 按货币类型过滤 |
响应 200 OK:
json
{
"success": true,
"data": [
{
"provider": "yungouos",
"method": "wechat",
"name": "微信支付",
"currencies": ["CNY"]
}
]
}6. 产品价格列表
GET /payment/prices获取所有活跃产品的价格列表。
查询参数:
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
currency | Currency | 否 | CNY | 货币类型 |
响应 200 OK:
json
{
"success": true,
"data": [
{
"id": "uuid",
"productType": "credit_pack",
"productCode": "credits_100",
"name": "100 积分包",
"description": "购买 100 积分",
"amount": 9900,
"currency": "CNY",
"credits": 100,
"billingPeriod": null,
"isFeatured": true
}
]
}错误码:
| HTTP | code | 说明 |
|---|---|---|
| 500 | INTERNAL_ERROR | 服务端错误 |
通用错误格式
支付 API 的错误响应统一格式:
json
{
"success": false,
"error": {
"code": "ORDER_NOT_FOUND",
"message": "订单不存在"
}
}支付系统完整错误码列表见源码 apps/backend/src/domain/payment/errors.ts。