状态机与错误码
订单状态机(PaymentIntent)
REQUIRES_PAYMENT_METHOD ──► PROCESSING ──► SUCCEEDED ──► PARTIALLY_REFUNDED ──► REFUNDED
│ │
├──► CANCELED ├──► FAILED
├──► EXPIRED ├──► EXPIRED
└──► FAILED └──► CANCELED- SUCCEEDED 只能由可信 Provider 事件(验签通过的回调或主动查询结果)触发;浏览器跳转/前端请求无法改变订单状态
FAILED / EXPIRED / CANCELED / REFUNDED为终态;迟到的成功事件会留档并进入对账差异,不会翻转终态订单- 重复回调由
(通道, 事件ID)唯一约束去重,不会重复入账
退款状态机(Refund)
PENDING ──► PROCESSING ──► SUCCEEDED │ └────────► FAILED(释放已占用的退款额度) └──► FAILED
- 支持部分退款与多次退款;创建即预留额度,累计退款不可能超过实付金额(并发安全)
- 手续费策略由商户配置:默认不退手续费(余额可能为负,即敞口);PROPORTIONAL 按比例退还
HTTP 状态与错误码
错误响应统一结构:{ "code": "...", "message": "...", "request_id": "..." }
| HTTP | code | 说明 |
|---|---|---|
| 400 | VALIDATION_FAILED | 参数校验失败(附字段级 errors) |
| 400 | AMOUNT_OUT_OF_RANGE / PRODUCT_NOT_AVAILABLE | 金额区间 / 产品未绑定或未启用 |
| 400 | REFUND_EXCEEDS_PAID_AMOUNT | 退款总额超过实付 |
| 400 | IDEMPOTENCY_KEY_REQUIRED / INVALID_NOTIFY_URL | 缺少幂等键 / 回调地址不安全 |
| 401 | MISSING_AUTH_HEADERS / INVALID_API_KEY / INVALID_SIGNATURE | 鉴权失败 |
| 401 | TIMESTAMP_EXPIRED / NONCE_REPLAYED | 时间戳越界 / 防重放拒绝 |
| 403 | MERCHANT_NOT_ACTIVE / IP_NOT_ALLOWED / RISK_BLOCKED | 商户状态 / IP 白名单 / 风控拦截 |
| 404 | PAYMENT_INTENT_NOT_FOUND / REFUND_NOT_FOUND | 资源不存在(含跨商户访问) |
| 409 | DUPLICATE_MERCHANT_ORDER_NO / DUPLICATE_MERCHANT_REFUND_NO | 单号重复 |
| 409 | IDEMPOTENCY_CONFLICT / IDEMPOTENCY_IN_PROGRESS | 幂等冲突 / 处理中 |
| 409 | NOT_CANCELABLE / INVALID_STATE_TRANSITION | 状态机拒绝 |
金额与时间约定
- API 层金额为元字符串(最多两位小数);响应同时附
amount_minor(分,字符串) - 内部记账一律整数分,手续费 HALF_UP 舍入;费率以下单时快照,后续调价不影响已建订单
- 日报/日切按业务时区
Asia/Shanghai;API 时间字段为 UTC ISO 8601