话单推送
呼叫终态话单的 Webhook 推送协议、事件报文与 X-CALLBACK-ID 签名验证。
话单推送
呼叫到达终态后,平台将话单结果以 HTTP POST 推送到你配置的 Webhook 回调地址,是「发送记录查询」接口主动拉取之外的另一种话单获取方式。
前置配置:在 InnoPaas Console 配置 Webhook 回调(事件类型:话单状态推送 cdr_status_push);可选配置签名凭据(用户名与密钥),配置后推送将携带签名头,见下文签名验证。
推送协议
- 方法:
POST,请求体application/json; charset=utf-8 - 你的接收服务应在超时内返回 2xx 状态码,其他视为推送失败
-
当前版本推送失败不会自动重试:请保障接收服务稳定,并按
eventId做幂等处理(eventId即呼叫标识callId)。
事件报文
{
"eventCode": "cdr_status_push",
"eventId": "YYYX931******64224",
"eventTime": "2026-11-09 10:00:41",
"data": {
"callId": "YYYX931******64224",
"mobile": "8613800138000",
"callStatus": 2,
"callDesc": "200",
"callDescMsg": "呼叫成功",
"callTime": "2026-11-09 10:00:05",
"startTime": "2026-11-09 10:00:07",
"answerTime": "2026-11-09 10:00:11",
"byeTime": "2026-11-09 10:00:35",
"ringTime": "2026-11-09 10:00:09",
"invokeTime": "2026-11-09 10:00:00",
"batchNo": "B20261109***",
"templateId": "Tpl_0001",
"recordUrl": "https://example.com/rec/xxx.mp3"
}
}data 字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
| callId | String | 呼叫唯一标识(同发送接口返回的 callId) |
| mobile | String | 被叫号码 |
| callStatus | Integer | 呼叫状态码(数值,以实际推送为准) |
| callDesc | String | 结束码 |
| callDescMsg | String | 结束码说明 |
| callTime | String | 呼叫时间 |
| startTime | String | 本次呼叫拨出时间 |
| answerTime | String | 接通时间(未接通为空) |
| byeTime | String | 挂断时间 |
| ringTime | String | 振铃时间 |
| invokeTime | String | 任务发起时间 |
| batchNo | String | 批次号 |
| templateId | String | 模板 ID |
| recordUrl | String | 录音文件地址(无录音为空) |
签名验证
配置了签名凭据时,每次推送携带 X-CALLBACK-ID 请求头,格式:
timestamp=<毫秒时间戳>;nonce=<32位随机串>;username=<配置的用户名>;signature=<签名>signature 的计算方式:
- 签名原文 =
timestamp + nonce + username三段按顺序直接拼接(无任何分隔符) - 算法 =
HMAC-SHA256,密钥为配置的密钥(secret) - 输出为小写十六进制字符串
验签示例(Java):
String header = request.getHeader("X-CALLBACK-ID"); // timestamp=...;nonce=...;username=...;signature=...
Map<String, String> kv = new LinkedHashMap<>();
for (String pair : header.split(";")) {
int i = pair.indexOf('=');
kv.put(pair.substring(0, i), pair.substring(i + 1));
}
String expected = hmacSha256Hex(SECRET,
kv.get("timestamp") + kv.get("nonce") + kv.get("username"));
if (!expected.equals(kv.get("signature"))) {
// 验签失败,拒绝处理
}未配置签名凭据(用户名与密钥均为空)时,推送不携带 X-CALLBACK-ID 头,仅做普通 POST。
注意事项
- 回调地址需公网可达;接收端响应 2xx 即视为成功
- 按
eventId(=callId)幂等处理,避免重复入库 - 推送与话单查询接口字段语义一致,可组合使用:Webhook 实时接收 + 查询接口兜底对账
最后更新于