Skip to content

HTTP 请求 / 响应规范

适用于所有 /openapi/v1/* 接口。请求与响应风格全部接口统一,渠道按本规范实现一次即可适用所有接口,无需为每个接口定制解析逻辑。

一、请求

1.1 URL 与方法

约定
Base URL沙箱 https://test-api.cxh.me / 生产 https://api.cxh.me
路径前缀/openapi/v1/
HTTP 方法所有业务接口一律使用 POST(查询接口同样使用 POST)
Content-Typeapplication/json;charset=UTF-8
编码UTF-8
Body 大小不超过 1 MB

查询接口的过滤条件以 JSON body 传递,不使用 query string;此约定使所有接口可统一应用幂等头部。

1.2 必传请求头

Header必填含义 / 示例
Content-Typeapplication/json;charset=UTF-8
X-CXH-App-Id渠道唯一标识,如 test_xxxxxxx
X-CXH-Timestamp请求构造时刻的 Unix 毫秒数,如 1714003200123。与 CXH 时差超过 5 分钟将被拒(401003)
X-CXH-Nonce32 位 hex 随机串,10 分钟内不可重复(401004)
X-CXH-Request-Id渠道生成的请求追踪 ID,建议使用 UUID;同值会原样返回在响应中
X-CXH-SignatureHMAC-SHA256 base64 签名,详见 签名 + 字段加密
Authorization业务接口必填Bearer <accessToken>;auth/token 接口无需携带
Idempotency-Key写接口建议UUID;同 key 与不同 body 组合将触发 409001

签名头的拼装与 HMAC 计算公式见 签名 + 字段加密 § 1.1

1.3 Body 字段类型约定

类型序列化形式说明
字符串JSON "..."默认明文;敏感字段需 AES 加密(详见 字段级加密)
整数JSON 数字 / 字符串所有 64 位整型 ID 字段(orderNo / userId / channelId 等)统一使用 JSON 字符串,以规避 JavaScript Number.MAX_SAFE_INTEGER(2^53) 精度限制
金额JSON 数字(整型)单位为分(cent),Long 类型;100 表示 1.00 元;不使用浮点
时间"yyyy-MM-dd HH:mm:ss"UTC+8 时区;响应中所有时间字段一律此格式
布尔JSON true / false
枚举大写下划线字符串BIND_SUCCESS / PAY_FAIL,完整取值见 字段约定

1.4 完整请求示例

POST /openapi/v1/auth/token(获取访问令牌,无需 Authorization):

http
POST /openapi/v1/auth/token HTTP/1.1
Host: test-api.cxh.me
Content-Type: application/json;charset=UTF-8
X-CXH-App-Id: test_xxxxxxx
X-CXH-Timestamp: 1714003200123
X-CXH-Nonce: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4
X-CXH-Request-Id: 7f8a9b1c-2d3e-4f5a-6b7c-8d9e0f1a2b3c
X-CXH-Signature: ab12CDef34GHij56KLmn78OPqr90STuv...
Idempotency-Key: 7f8a9b1c-2d3e-4f5a-6b7c-8d9e0f1a2b3c

{"grantType":"client_credentials","appId":"test_xxxxxxx"}

二、响应

2.1 HTTP 状态码

状态码含义
200业务成功与业务失败均使用 200,具体结果以响应 body 中的 code 字段为准
401鉴权层错误(签名 / 时间戳 / nonce / accessToken 失效)。响应 body 仍遵循统一结构,code 形如 401xxx
429限流。响应 body 仍遵循统一结构,code 形如 429xxx
5xxCXH 异常,渠道应自动重试(指数退避,最多 3 次)

渠道判断业务结果时应先核对 HTTP 状态码,200 时再核对 body 中 code == "0";此两层条件同时满足才表示业务成功。

2.2 Body 包装结构

所有响应 body 一律采用以下结构:

json
{
  "code": "0",
  "message": "success",
  "data": { ... },
  "requestId": "7f8a9b1c-2d3e-4f5a-6b7c-8d9e0f1a2b3c",
  "timestamp": "2026-04-28 18:30:45",
  "success": true
}
字段类型说明
codestring"0" 表示业务成功;非 "0" 表示业务失败,完整取值见 错误码
messagestring人类可读描述;渠道仅用于日志与展示,不应基于此字段做分支判断
dataobject | array | null业务数据;失败时为 null
requestIdstring与请求头 X-CXH-Request-Id 一致(便于日志关联);若请求未携带,由 CXH 生成
timestampstringCXH 生成响应的时间(yyyy-MM-dd HH:mm:ss,UTC+8)
successbooleancode == "0" 时为 true;为冗余字段,部分 SDK 用于快捷判断

2.3 成功响应示例

json
{
  "code": "0",
  "message": "success",
  "data": {
    "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6...",
    "expiresIn": "7200",
    "expiresAt": "2026-04-28 20:30:45"
  },
  "requestId": "7f8a9b1c-2d3e-4f5a-6b7c-8d9e0f1a2b3c",
  "timestamp": "2026-04-28 18:30:45",
  "success": true
}

2.4 失败响应示例

json
{
  "code": "401002",
  "message": "签名错误",
  "data": null,
  "requestId": "7f8a9b1c-2d3e-4f5a-6b7c-8d9e0f1a2b3c",
  "timestamp": "2026-04-28 18:30:45",
  "success": false
}

完整业务失败码清单见 错误码

2.5 渠道解析建议

python
resp = requests.post(url, headers=headers, json=body)
if resp.status_code >= 500:
    # CXH 异常,应自动重试(指数退避)
    retry_with_backoff()
elif resp.status_code != 200:
    # 401 / 429 等鉴权或限流错误,根据 body 区分
    payload = resp.json()
    raise ApiError(payload['code'], payload['message'])
else:
    payload = resp.json()
    if payload['code'] != '0':
        raise BusinessError(payload['code'], payload['message'])
    data = payload['data']  # 业务成功,继续处理

三、通用约定

3.1 幂等

  • 所有写接口(orders/create / agreements/bind-confirm / agreements/replace 等)支持 Idempotency-Key 头幂等
  • CXH 在 7 天内对同一 (appId, idempotencyKey) 的请求返回首次响应
  • 同 key + 同 body:直接返回首次响应(无副作用)
  • 同 key + 异 body:返回 409001 IDEMPOTENCY_CONFLICT,渠道应排查请求构造逻辑
  • 业务唯一约束(如 externalOrderNo)由 CXH 全局唯一性校验兜底,与头部幂等独立生效

3.2 请求追踪

  • 渠道传入 X-CXH-Request-Id,CXH 日志全链路记录该 ID;问题排查时提供此 ID 可快速定位 CXH 侧日志
  • 响应 body 中 requestId 字段始终等于请求头 X-CXH-Request-Id,可用于渠道侧日志关联
  • 异常上报或客服工单建议附带此 ID

3.3 时区与时间格式

  • 响应中所有时间字段一律为 yyyy-MM-dd HH:mm:ss 格式,UTC+8(Asia/Shanghai)
  • 请求头 X-CXH-Timestamp 为例外,使用 Unix 毫秒数(用于签名时差校验)
  • 渠道传入时间字符串时建议遵循同样格式;2026-04-28T18:30:45+08:00 等 ISO 8601 形式同样接受,响应统一转换为前者返回

3.4 ID 与金额精度

  • 所有 64 位 ID(orderNo / userId / channelId / paymentOrderNo 等)以 JSON 字符串返回,渠道亦应以字符串接收与存储
  • JavaScript 渠道应使用 String / BigInt 处理,不应使用 Number.parseInt,以免精度丢失
  • 所有金额字段为 Long 类型整型分,无浮点;100 表示 1.00

3.5 重试与超时

场景渠道建议
HTTP 5xx指数退避重试 3 次(间隔 1s / 3s / 9s)
HTTP 200 且 code=429xxx等待 1 分钟后再重试,不应立即重发
HTTP 200 且 code=0业务成功,不应重试(避免重复创单)
HTTP 200 且其他 code业务失败,应先依据 错误码 判断是否可重试,而非直接重试
网络超时 / 连接重置使用同一 Idempotency-Key 重发,CXH 返回首次结果

建议请求超时配置:connect 5s / read 15s。

3.6 字段大小限制

上限
单个字符串字段1024 字符(接口文档另有说明者除外)
整个 JSON body1 MB
单次列表查询返回100 条(超出请使用分页参数 page / size)

四、相关文档

对接咨询 · bd@cxh.me / tech@cxh.me