OpenAPI 开发者文档更新记录 OpenAPI Developer Documentation Changelog
版本更新历史 Revision History
| 版本号Version | 更新时间Date | 变更类型Type | 更新内容说明Change Description |
|---|---|---|---|
| v1.4.0 | 2026-09-18 | 优化 / 完善Enhancement |
1. 回调通知增加 12 次阶梯重试机制,明确重试间隔(10秒至24小时)。 2. 回调请求 Header 中强调签名使用专门的回调密钥计算。 3. 精简单账号充值说明,对齐并标准化各状态查询接口描述。 1. Added a 12-attempt exponential backoff retry policy for Webhooks (10s up to 24h). 2. Specified that Webhook signature calculation uses the dedicated Callback Secret. 3. Streamlined single recharge descriptions and aligned all query endpoints. |
| v1.3.0 | 2026-09-18 | 新增能力Feature |
1. 新增「充值状态变更回调通知 (Webhook)」文档,支持充值终态的主动异步推送。 2. 规范化定义回调 Header(包含 X-Event-Id、X-Signature)及事件 Body 结构。
1. Added Webhook Notification specification for asynchronous final status delivery.2. Defined Webhook Headers (including X-Event-Id, X-Signature) and payload schema.
|
| v1.2.0 | 2026-09-17 | 安全修正Security Fix |
1. 修正签名验证算法:明确 6 行规范化结构拼接规则,引入 rawQuery 参与验签。2. 统一全平台各 API 请求 Header 参数定义,输出标准 Base64 签名串。 3. 补充基于标准 JDK 原生库的 Java 签名生成实现与 NodeJS 代码示例。 1. Corrected HMAC-SHA256 signature algorithm to 6-line canonical format including rawQuery.2. Standardized Base64 encoded output for all API request headers. 3. Added standard Java (pure JDK) and Node.js signature code examples. |
| v1.1.0 | 2026-09-15 | 新增接口Feature |
1. 扩充「批量账号充值提交」及「按批次业务号查询整批充值状态」接口。 2. 增加针对单笔充值按订单号和业务请求号的多维度状态查询能力。 1. Added Batch Account Recharge submission and batch status query endpoints. 2. Provided single recharge query by both client request number and platform order number. |
| v1.0.0 | 2026-09-08 | 初始发布Initial Release |
1. 发布开放平台基础 API 规范与签名鉴权规则。 2. 开放单账号充值提交基础接口。 1. Published platform baseline OpenAPI specifications and authentication rules. 2. Released single account recharge submission endpoint. |
接口与文档模块概览 Modules & Endpoints Index
| 模块名称Module | 类型 / 方法Type / Method | 接口路径 / 说明Path / Description | 操作Action |
|---|---|---|---|
| API 签名验证规则API Signature Rules | DOC | 公共 Header 参数、HMAC-SHA256 签名算法及代码示例Common Headers, HMAC-SHA256 algorithm & code samples | 查看规则 →View Doc → |
| 单账号充值提交Single Account Recharge | POST | /v1/recharges |
查看接口 →View API → |
| 按请求号查询状态Query by Request No | GET | /v1/recharges/by-client-request-no/{clientRequestNo} |
查看接口 →View API → |
| 按平台单号查询状态Query by Order No | GET | /v1/recharges/{orderNo} |
查看接口 →View API → |
| 批量账号充值提交Batch Account Recharge | POST | /v1/recharges/batch |
查看接口 →View API → |
| 按批次号查询整批状态Query Batch Status | GET | /v1/recharges/batch/{batchNo} |
查看接口 →View API → |
| 充值状态变更回调通知Webhook Notification | DOC | Webhook 异步推送充值终态与验签机制Asynchronous Webhook event push & verification | 查看通知 →View Doc → |
API 签名验证规则 API Signature Authentication Rules
1. 公共请求头参数 (Headers) 1. Common Request Headers
每次调用接口时,客户端必须在 Request Header 中包含以下字段: The client must include the following headers on every API invocation:
| 请求头 (Header)Header | 描述Description | 示例 / 说明Example / Note |
|---|---|---|
| X-App-Key | 开发者分配的 App KeyAssigned Developer App Key | your_app_key_here |
| X-Timestamp | 当前时间的 Unix 时间戳(秒级别)Unix epoch timestamp in seconds | 1678888888 |
| X-Nonce | 随机字符串(建议 32 位 Hex 字符)Random string (32-character hex recommended) | 1eaf4cbb81d947e69d140a65415d0f71 |
| X-Signature | 根据下方规则计算得出的签名值 (Base64)HMAC-SHA256 signature (Base64) | 详见下方计算规则See calculation rules below |
注意:Notice: 必须妥善保管与 App Key 对应的 App Secret,绝对不要将其放在请求中传输。App Secret 仅用于在本地计算签名。 Keep your App Secret confidential. Never transmit it over HTTP/HTTPS. It is used strictly for local signature generation.
2. 签名计算规则 2. Signature Calculation Process
签名的生成依赖于 HMAC-SHA256 算法,最终输出为 Base64 编码字符串,分为以下三个步骤: The signature is generated using HMAC-SHA256 and encoded in Base64, structured in three steps:
步骤一:计算 Body Hash Step 1: Compute Body Hash
将 HTTP 请求体 (Body) 的原始字符串数据(UTF-8 编码),使用 SHA256 算法进行哈希计算,并将结果转换为十六进制小写字符串 (Hex)。
Hash the raw HTTP Body (UTF-8 encoded) with SHA256 and convert the digest to lowercase hexadecimal string.
注意:如果当前请求没有 Body(如 GET 请求或 Body 为空),则对空字符串 "" 进行 SHA256 计算得出 Hex。
Note: For requests without body (e.g. GET requests), compute SHA256 on empty string "".
步骤二:构建规范化请求字符串 (Canonical Request) Step 2: Build Canonical Request String
将请求的 6 项关键要素严格按以下顺序拼接,各项之间使用换行符
进行分隔。格式如下:
Join the 6 elements strictly in order using newline character
:
HTTP_METHOD + "
" +
REQUEST_PATH + "
" +
RAW_QUERY + "
" +
X_TIMESTAMP + "
" +
X_NONCE + "
" +
BODY_HASH
步骤三:计算最终签名 (Signature) Step 3: Generate Base64 Signature
使用分配的 App Secret 作为秘钥,对步骤二生成的规范化字符串进行 HMAC-SHA256 运算,并将输出转换为 Base64 字符串:
Calculate HMAC-SHA256 using App Secret as the key over the canonical string and encode as Base64:
Signature = Base64(HMAC_SHA256(CanonicalRequest, AppSecret))
3. 代码示例 3. Code Samples
Java (Pure JDK javax.crypto)
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;
public class SignUtil {
public static String sha256Hex(String data) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest((data == null ? "" : data).getBytes(StandardCharsets.UTF_8));
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String hmacSha256Base64(String data, String secret) {
try {
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec keySpec = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
mac.init(keySpec);
return Base64.getEncoder().encodeToString(mac.doFinal(data.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static String generateSignature(String method, String path, String rawQuery,
String timestamp, String nonce, String body, String secret) {
String bodyHash = sha256Hex(body == null ? "" : body);
String canonicalRequest = String.join("
",
method.toUpperCase(), path, rawQuery == null ? "" : rawQuery,
timestamp, nonce, bodyHash);
return hmacSha256Base64(canonicalRequest, secret);
}
}
JavaScript (CryptoJS / Node.js)
const CryptoJS = require("crypto-js");
function generateSignature({ method, path, rawQuery = "", timestamp, nonce, body = "", secret }) {
const bodyHash = CryptoJS.SHA256(CryptoJS.enc.Utf8.parse(body)).toString(CryptoJS.enc.Hex);
const canonicalRequest = [
method.toUpperCase(), path, rawQuery, timestamp, nonce, bodyHash
].join("
");
return CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA256(canonicalRequest, secret));
}
单账号充值提交 Single Account Recharge Submission
接口说明 Endpoint Overview
-
异步受理模式:Asynchronous Processing:
本接口为异步受理模式,调用返回
202 Accepted表示平台已成功接收并持久化充值请求,后续充值状态请通过查询接口获取。 This endpoint operates asynchronously. A202 Acceptedresponse confirms persistence. Call query endpoints for final execution status. -
幂等与重试规范:Idempotency & Retries:
平台不提供自动重试机制;调用方发起网络重试时,必须复用相同的业务请求号
clientRequestNo,并重新生成当前时间戳、随机数nonce及对应的签名值。 When retrying due to timeouts, reuse the sameclientRequestNo, but regenerateX-Timestamp,X-Nonce, andX-Signature.
请求 Header 参数 Request Headers
| 参数名Header | 类型Type | 必填Required | 说明与示例Description & Example |
|---|---|---|---|
| X-App-Key | string | 必填Yes | 调用凭证 AppKeyAssigned AppKey |
| X-Timestamp | integer | 必填Yes | 当前时间戳(秒)Current timestamp (seconds) |
| X-Nonce | string | 必填Yes | 防重放随机字符串Anti-replay random string |
| X-Signature | string | 必填Yes | HMAC-SHA256 签名串 (Base64)HMAC-SHA256 signature (Base64) |
| Content-Type | string | 必填Yes | application/json |
请求 Body (application/json) Request Body (application/json)
| 参数名Field | 类型Type | 必填Required | 说明与示例Description & Example |
|---|---|---|---|
| clientRequestNo | string | 必填Yes | 调用方业务请求号,示例: APIFOX-20260915-0005Client unique request number |
| accountId | string | 必填Yes | 充值账号 ID,示例: 333333Recharge target account ID |
| amount | number | 必填Yes | 充值金额,示例: 27Recharge amount |
{
"clientRequestNo": "APIFOX-20260915-0005",
"accountId": "333333",
"amount": 27
}
返回响应 (202 Accepted) Response (202 Accepted)
{
"success": true,
"message": "充值请求已受理",
"code": 202,
"result": {
"orderNo": "RC202609070001",
"clientRequestNo": "APIFOX-20260907-0001",
"status": "PROCESSING"
},
"timestamp": 1788786000000
}
按调用方业务请求号查询状态 Query Recharge by Client Request No
接口说明 Endpoint Overview
- 查询维度:Lookup Scope: 调用方使用发起充值时提交的业务请求号
clientRequestNo查询该订单的处理状态与执行明细。Query execution status using your original client request number. - 状态流转:Status Flow: 充值受理后状态为
PROCESSING(处理中),终态包括SUCCESS(充值成功)与FAILED(充值失败)。Status transitions fromPROCESSINGto final stateSUCCESSorFAILED. - 轮询建议:Polling: 建议调用方采用指数退避或合理时间间隔(如 1~3 秒)进行轮询,以避免高频无效请求。Polling interval of 1-3 seconds is recommended.
请求 Header 参数 Request Headers
| 参数名Header | 类型Type | 必填Required | 说明与示例Description & Example |
|---|---|---|---|
| X-App-Key | string | 必填Yes | 调用凭证 AppKeyAssigned AppKey |
| X-Timestamp | integer | 必填Yes | 当前时间戳(秒)Current timestamp (seconds) |
| X-Nonce | string | 必填Yes | 防重放随机字符串Anti-replay random string |
| X-Signature | string | 必填Yes | HMAC-SHA256 签名串 (Base64)HMAC-SHA256 signature (Base64) |
路径参数 (Path Parameters) Path Parameters
| 参数名Field | 类型Type | 必填Required | 说明Description |
|---|---|---|---|
| clientRequestNo | string | 必填Yes | 调用方提交充值时的原始请求号Original client request number |
返回响应示例 (200 OK) Response Example (200 OK)
{
"success": true,
"code": 200,
"message": "查询成功",
"result": {
"orderNo": "RC202609070001",
"clientRequestNo": "APIFOX-20260915-0005",
"accountId": "333333",
"amount": 27,
"status": "SUCCESS",
"failReason": null,
"finishTime": "2026-09-15 10:20:30"
},
"timestamp": 1788786050000
}
按平台充值单号查询状态 Query Recharge by Platform Order No
接口说明 Endpoint Overview
- 查询维度:Lookup Scope: 调用方使用充值受理成功后返回的平台充值单号
orderNo查询该订单的处理状态与执行明细。Query execution status using the platform-issued order number. - 状态流转:Status Flow: 充值受理后状态为
PROCESSING(处理中),终态包括SUCCESS(充值成功)与FAILED(充值失败)。Status transitions fromPROCESSINGto final stateSUCCESSorFAILED. - 轮询建议:Polling: 建议调用方采用指数退避或合理时间间隔(如 1~3 秒)进行轮询,以避免高频无效请求。Polling interval of 1-3 seconds is recommended.
请求 Header 参数 Request Headers
| 参数名Header | 类型Type | 必填Required | 说明与示例Description & Example |
|---|---|---|---|
| X-App-Key | string | 必填Yes | 调用凭证 AppKeyAssigned AppKey |
| X-Timestamp | integer | 必填Yes | 当前时间戳(秒)Current timestamp (seconds) |
| X-Nonce | string | 必填Yes | 防重放随机字符串Anti-replay random string |
| X-Signature | string | 必填Yes | HMAC-SHA256 签名串 (Base64)HMAC-SHA256 signature (Base64) |
路径参数 (Path Parameters) Path Parameters
| 参数名Field | 类型Type | 必填Required | 说明Description |
|---|---|---|---|
| orderNo | string | 必填Yes | 平台充值订单号,如 RC202609070001Platform recharge order number |
返回响应示例 (200 OK) Response Example (200 OK)
{
"success": true,
"code": 200,
"message": "查询成功",
"result": {
"orderNo": "RC202609070001",
"clientRequestNo": "APIFOX-20260915-0005",
"accountId": "333333",
"amount": 27,
"status": "SUCCESS",
"finishTime": "2026-09-15 10:20:30"
},
"timestamp": 1788786050000
}
批量账号充值提交 Batch Account Recharge Submission
接口说明 Endpoint Overview
- 批量提交与拆解:Batch Splitting: 支持一次性提交多个充值账户的充值指令。平台成功持久化受理后返回
202 Accepted,后台将自动拆解并并发执行各个子充值单。Submit multiple recharge items in one batch. Handled asynchronously with202 Accepted. - 批次幂等:Batch Idempotency: 批次重试需严格复用相同的业务批次号
batchNo。当遇到网络超时或不确定响应时,请勿更换批次号重试。Reuse the samebatchNowhen retrying a batch. - 子单独立性:Sub-order Isolation: 批次内各子单独立执行,部分子单失败不会影响其余子单的正常充值。Sub-orders are executed independently; failure in one item does not affect others.
请求 Header 参数 Request Headers
| 参数名Header | 类型Type | 必填Required | 说明与示例Description & Example |
|---|---|---|---|
| X-App-Key | string | 必填Yes | 调用凭证 AppKeyAssigned AppKey |
| X-Timestamp | integer | 必填Yes | 当前时间戳(秒)Current timestamp (seconds) |
| X-Nonce | string | 必填Yes | 防重放随机字符串Anti-replay random string |
| X-Signature | string | 必填Yes | HMAC-SHA256 签名串 (Base64)HMAC-SHA256 signature (Base64) |
| Content-Type | string | 必填Yes | application/json |
请求 Body (application/json) Request Body (application/json)
| 参数名Field | 类型Type | 必填Required | 说明Description |
|---|---|---|---|
| batchNo | string | 必填Yes | 批次业务请求号(调用方生成)Client-generated batch number |
| items | array | 必填Yes | 充值子项明细列表Recharge item details array |
| └─ subRequestNo | string | 必填Yes | 子单调用方请求号Sub-order request number |
| └─ accountId | string | 必填Yes | 充值账户 IDAccount ID |
| └─ amount | number | 必填Yes | 充值金额Amount |
{
"batchNo": "BATCH-20260915-001",
"items": [
{
"subRequestNo": "REQ-001",
"accountId": "333333",
"amount": 50
},
{
"subRequestNo": "REQ-002",
"accountId": "444444",
"amount": 100
}
]
}
返回响应 (202 Accepted) Response (202 Accepted)
{
"success": true,
"message": "批量充值已持久化受理",
"code": 202,
"result": {
"platformBatchNo": "BAT20260915000001",
"batchNo": "BATCH-20260915-001",
"totalCount": 2,
"status": "PROCESSING"
},
"timestamp": 1788786100000
}
按批次业务号查询整批充值状态 Query Batch Recharge Status
接口说明 Endpoint Overview
- 批次状态聚合:Aggregation: 根据批量提交时传入的业务批次号
batchNo查询整批明细的处理进度,包括总笔数、成功笔数、失败笔数及整批终态。Query total, success, and failed counts along with batch final state. - 子单明细列表:Sub-orders Details: 返回结果中的
details数组包含每个子请求号对应的平台单号、充值账户、充值金额以及各自的执行状态。Thedetailsarray provides the status of every sub-item.
请求 Header 参数 Request Headers
| 参数名Header | 类型Type | 必填Required | 说明与示例Description & Example |
|---|---|---|---|
| X-App-Key | string | 必填Yes | 调用凭证 AppKeyAssigned AppKey |
| X-Timestamp | integer | 必填Yes | 当前时间戳(秒)Current timestamp (seconds) |
| X-Nonce | string | 必填Yes | 防重放随机字符串Anti-replay random string |
| X-Signature | string | 必填Yes | HMAC-SHA256 签名串 (Base64)HMAC-SHA256 signature (Base64) |
路径参数 (Path Parameters) Path Parameters
| 参数名Field | 类型Type | 必填Required | 说明Description |
|---|---|---|---|
| batchNo | string | 必填Yes | 批量充值提交的业务批次号Batch number |
返回响应示例 (200 OK) Response Example (200 OK)
{
"success": true,
"code": 200,
"message": "查询成功",
"result": {
"batchNo": "BATCH-20260915-001",
"platformBatchNo": "BAT20260915000001",
"totalCount": 2,
"successCount": 2,
"failCount": 0,
"status": "COMPLETED",
"details": [
{
"subRequestNo": "REQ-001",
"orderNo": "RC202609150001",
"accountId": "333333",
"amount": 50,
"status": "SUCCESS"
},
{
"subRequestNo": "REQ-002",
"orderNo": "RC202609150002",
"accountId": "444444",
"amount": 100,
"status": "SUCCESS"
}
]
},
"timestamp": 1788786200000
}
充值状态变更回调通知 (Webhook) Recharge Status Webhook Notification
接口说明 Endpoint Overview
- 触发机制:Trigger Mechanism: 当充值订单状态发生变更(成功或失败)时,平台将主动向调用方配置的回调地址发起 HTTP POST 请求,推送充值终态数据及签名认证信息。 When a recharge order reaches a final state (SUCCESS or FAILED), the platform sends an HTTP POST push to your configured callback endpoint.
-
重试机制:Retry Policy:
回调通知共重试 12 次。第 1 次为即时推送;若响应非 2xx 或网络超时,后续各次重试的延迟时间间隔依次为:
10秒、30秒、1分钟、5分钟、15分钟、30分钟、1小时、3小时、6小时、12小时、24小时。若 12 次重试均失败,则后续不会再发起推送。 Webhook notifications retry up to 12 times. 1st attempt is immediate. If non-2xx response or timeout occurs, subsequent retry delays are:10s, 30s, 1m, 5m, 15m, 30m, 1h, 3h, 6h, 12h, 24h. If all 12 attempts fail, no further push will be made.
请求 Header 参数 Request Headers
| 请求头 (Header)Header | 类型Type | 必填Required | 说明与示例Description & Example |
|---|---|---|---|
| Content-Type | string | 必填Yes | application/json; charset=utf-8 |
| X-App-Key | string | 必填Yes | 调用方分配的 App KeyClient App Key |
| X-Timestamp | integer | 必填Yes | 推送请求时间戳(秒)Push timestamp (seconds) |
| X-Nonce | string | 必填Yes | 防重放随机字符串Anti-replay random string |
| X-Event-Id | string | 必填Yes | 回调事件唯一标识 ID,示例: evt_2100831915776983042_SUCCESSUnique event ID for deduplication |
| X-Signature | string | 必填Yes | HMAC-SHA256 签名串 (Base64)。签名生成规则与 API 签名生成规则一致,但 secret 使用回调密钥 HMAC-SHA256 signature (Base64). Same canonical calculation rules as API requests, but signed with the dedicated Callback Secret. |
请求 Body (application/json) Request Body (application/json)
| 参数名Field | 类型Type | 必填Required | 说明与示例Description & Example |
|---|---|---|---|
| eventId | string | 必填Yes | 回调事件唯一 IDUnique event ID |
| eventType | string | 必填Yes | RECHARGE_STATUS_CHANGED |
| appKey | string | 必填Yes | 接收方的 App KeyReceiver App Key |
| customerId | string | 必填Yes | 客户编号Customer / Merchant ID |
| orderNo | string | 必填Yes | 平台充值订单号Platform recharge order number |
| clientRequestNo | string | 必填Yes | 调用方提交充值时的原始请求号Original client request number |
| accountId | string | 必填Yes | 充值目标账户 IDTarget account ID |
| amount | number | 必填Yes | 实际充值金额Recharge amount |
| status | string | 必填Yes | SUCCESS / FAILED |
| failureCode | string | 可空Nullable | 失败错误码(成功时为 null)Failure error code (null on success) |
| failureReason | string | 可空Nullable | 失败原因描述(成功时为 null)Failure description (null on success) |
| occurredAt | string | 必填Yes | 状态变更时间(ISO-8601)Event timestamp (ISO-8601) |
Body JSON Sample:
{
"eventId": "evt_2100831915776983042_SUCCESS",
"eventType": "RECHARGE_STATUS_CHANGED",
"appKey": "meta_E-HNGb7FfzM916trGCWiA9dB",
"customerId": "93",
"orderNo": "2100831915776983042",
"clientRequestNo": "APIFOX-20260908-00874",
"accountId": "c9dabd2aa2a311f1b5b60242c0a80002",
"amount": 1,
"status": "SUCCESS",
"failureCode": null,
"failureReason": null,
"occurredAt": "2026-09-18T14:23:48.777+08:00"
}