# 8 消息
# 1 设置
# Webhook配置要求
# 一、协议要求
- 支持协议: HTTPS
- 加密要求: 建议使用 TLS 1.2 或 TLS 1.3 进行安全传输
- 请求方法: POST
- 内容类型:
Content-Type: application/json
# 二、响应规范
- 成功状态码:
200 OK - 响应超时时间: 3秒
(请避免在接收端执行耗时的业务逻辑,确保快速响应) - 地址校验: 监听地址必须使用公网
HTTPS地址,不能使用localhost、127.0.0.1等本地地址 - 失败信息: 当地址校验失败时,
message会直接返回具体失败原因,便于排查
# 1.1 监听设置(POST)
消息监听,监听设置
# URL
https://developers.cjdropshipping.com/api2.0/v1/webhook/set
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/webhook/set' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"product": {
"type": "ENABLE",
"callbackUrls": [
"https://your-host/api2.0/"
]
},
"stock": {
"type": "ENABLE",
"callbackUrls": [
"https://your-host/api2.0/"
]
},
"order": {
"type": "ENABLE",
"callbackUrls": [
"https://your-host/api2.0/"
]
},
"logistics": {
"type": "ENABLE",
"callbackUrls": [
"https://your-host/api2.0/"
]
},
"makeup": {
"type": "ENABLE",
"callbackUrls": [
"https://your-host/api2.0/"
]
},
"privateOrder": {
"type": "ENABLE",
"callbackUrls": [
"https://your-host/api2.0/"
]
}
}'
| 参数名称 | 参数意义 | 参数类型 | 是否必传 | 长度 | 备注 |
|---|---|---|---|---|---|
| product | 商品消息 | object | 是 | 200 | 商品消息设置 |
| - type | 监听类型 | string | 是 | 200 | ENABLE-启用,CANCEL-取消 |
| - callbackUrls | 监听接口 | string[] | 是 | 只支持单个监听,且必须为可访问的公网 HTTPS 地址 | |
| stock | 库存消息 | object | 是 | 200 | 库存消息设置 |
| - type | 监听类型 | string | 是 | 200 | ENABLE-启用,CANCEL-取消 |
| - callbackUrls | 监听接口 | string[] | 是 | 只支持单个监听,且必须为可访问的公网 HTTPS 地址 | |
| order | 订单消息 | object | 是 | 200 | 订单消息设置 |
| - type | 监听类型 | string | 是 | 200 | ENABLE-启用,CANCEL-取消 |
| - callbackUrls | 监听接口 | string[] | 是 | 只支持单个监听,且必须为可访问的公网 HTTPS 地址 | |
| logistics | 物流轨迹消息 | object | 是 | 200 | 物流消息设置 |
| - type | 监听类型 | string | 是 | 200 | ENABLE-启用,CANCEL-取消 |
| - callbackUrls | 监听接口 | string[] | 是 | 只支持单个监听,且必须为可访问的公网 HTTPS 地址 | |
| makeup | 补款单消息 | object | 否 | 200 | 补款单消息设置(添加/取消/支付成功通知) |
| - type | 监听类型 | string | 是 | 200 | ENABLE-启用,CANCEL-取消 |
| - callbackUrls | 监听接口 | string[] | 是 | 只支持单个监听,且必须为可访问的公网 HTTPS 地址 | |
| privateOrder | 私有订单消息 | object | 否 | 200 | 私有订单(SY单/私有库存单)消息设置(状态变更通知) |
| - type | 监听类型 | string | 是 | 200 | ENABLE-启用,CANCEL-取消 |
| - callbackUrls | 监听接口 | string[] | 是 | 只支持单个监听,且必须为可访问的公网 HTTPS 地址 |
# 返回
success
{
"code": 200,
"result": true,
"message": "Success",
"data": true,
"requestId": "97367e0f-cf3a-4c9b-acea-a36fb56f81b8",
"success": true
}
| 返回字段 | 字段意思 | 字段类型 | 长度 | 备注 |
|---|---|---|---|---|
| code | 错误码 | int | 20 | 返回错误码标准表 |
| result | 是否正常返回 | boolean | 1 | |
| message | 返回信息 | string | 200 | |
| data | 是否设置成功 | boolean | 1 | 接口数据返回 |
| requestId | 请求Id | string | 48 | 用于日志查询错误 |
| success | 是否调用成功 | boolean | 1 | true-成功,false-失败 |
error
{
"code": 1607001,
"result": false,
"message": "Please do not use domain names such as localhost, 127.0.0.1",
"data": null,
"requestId": "a18c9793-7c99-42f9-970b-790eecdceba2",
"success": false
}
| 返回字段 | 字段意思 | 字段类型 | 长度 | 备注 |
|---|---|---|---|---|
| code | 错误码 | int | 20 | 返回错误码标准表 |
| result | 是否正常返回 | boolean | 1 | |
| message | 返回信息 | string | 200 | |
| data | 接口数据返回 | |||
| requestId | 请求Id | string | 48 | 用于日志查询错误 |
| success | 是否调用成功 | boolean | 1 | true-成功,false-失败 |
# 2 商品订阅
# 2.1 订阅商品(POST)
订阅指定商品或开启全部商品订阅,用于商品/变体/库存的webhook通知。
注意:订阅指定商品和订阅全部商品互斥。
- 如果传入
productIds,则只订阅指定商品,系统会自动取消全部商品订阅。- 如果只传
subscribeAll=true(不传productIds),则历史订阅的指定商品将被清空。
subscribeAll 限制
- 2026年7月份之前,仅 2026年6月份之前注册 的用户可以订阅所有商品(
subscribeAll=true) - 2026年7月份之后,所有用户均不可订阅所有商品,必须指定具体商品 ID 进行订阅
# URL
https://developers.cjdropshipping.com/api2.0/v1/webhook/product/subscribe
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/webhook/product/subscribe' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"productIds": ["1952652478987366401", "1952652478987366402"],
"subscribeAll": false
}'
| 参数名称 | 参数意义 | 参数类型 | 是否必传 | 长度 | 备注 |
|---|---|---|---|---|---|
| productIds | 商品ID列表 | string[] | 否 | 最大100 | 要订阅的商品ID,不能超过用户等级对应的订阅上限 |
| subscribeAll | 订阅全部商品 | boolean | 否 | true=开启全部商品订阅,false=关闭。与productIds互斥 |
# 返回
success
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"successProductIds": ["1952652478987366401"],
"failProductIds": ["1952652478987366402"],
"subscribeAll": false
},
"requestId": "97367e0f-cf3a-4c9b-acea-a36fb56f81b8",
"success": true
}
| 返回字段 | 字段意思 | 字段类型 | 长度 | 备注 |
|---|---|---|---|---|
| code | 错误码 | int | 20 | 返回错误码标准表 |
| result | 是否正常返回 | boolean | 1 | |
| message | 返回信息 | string | 200 | |
| data | 返回数据 | object | ||
| - successProductIds | 订阅成功的商品ID列表 | string[] | ||
| - failProductIds | 订阅失败的商品ID列表(已订阅、不存在等原因) | string[] | ||
| - subscribeAll | 是否开启全量订阅 | boolean | 仅当请求中subscribeAll有值时返回 | |
| requestId | 请求Id | string | 48 | 用于日志查询错误 |
| success | 是否调用成功 | boolean | 1 | true-成功,false-失败 |
error
{
"code": 1606010,
"result": false,
"message": "Product webhook is not enabled",
"data": null,
"requestId": "a18c9793-7c99-42f9-970b-790eecdceba2",
"success": false
}
错误码说明:
| 错误码 | 说明 |
|---|---|
| 1606010 | 商品webhook未开启 |
| 1606011 | 超过订阅上限 |
| 1606012 | 商品不可订阅 |
| 1606013 | 商品订阅失败 |
各等级订阅上限:
| 等级 | 最大订阅数 |
|---|---|
| lv1 | 100 |
| lv2 | 1000 |
| lv3 | 2000 |
| lv4 | 5000 |
| lv5 | 10000 |
# 2.2 取消订阅商品(POST)
从订阅列表中移除指定商品。
# URL
https://developers.cjdropshipping.com/api2.0/v1/webhook/product/unsubscribe
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/webhook/product/unsubscribe' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"productIds": ["1952652478987366401", "1952652478987366402"]
}'
| 参数名称 | 参数意义 | 参数类型 | 是否必传 | 长度 | 备注 |
|---|---|---|---|---|---|
| productIds | 商品ID列表 | string[] | 是 | 最大100 | 要取消订阅的商品ID |
# 返回
success
{
"code": 200,
"result": true,
"message": "Success",
"data": true,
"requestId": "97367e0f-cf3a-4c9b-acea-a36fb56f81b8",
"success": true
}
| 返回字段 | 字段意思 | 字段类型 | 长度 | 备注 |
|---|---|---|---|---|
| code | 错误码 | int | 20 | 返回错误码标准表 |
| result | 是否正常返回 | boolean | 1 | |
| message | 返回信息 | string | 200 | |
| data | 是否成功 | boolean | 1 | true=成功 |
| requestId | 请求Id | string | 48 | 用于日志查询错误 |
| success | 是否调用成功 | boolean | 1 | true-成功,false-失败 |
# 2.3 查询已订阅商品(GET)
分页查询当前用户已订阅的商品列表。
# URL
https://developers.cjdropshipping.com/api2.0/v1/webhook/product/subscribe/list
# CURL
curl --location --request GET 'https://developers.cjdropshipping.com/api2.0/v1/webhook/product/subscribe/list?pageNum=1&pageSize=20&sku=CJJJJTJT00784&shopId=123456' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxx'
| 参数名称 | 参数意义 | 参数类型 | 是否必传 | 长度 | 备注 |
|---|---|---|---|---|---|
| pageNum | 页码 | int | 否 | 默认:1,最小:1 | |
| pageSize | 每页条数 | int | 否 | 默认:20,最小:1,最大:200 | |
| sku | 商品SPU | string | 否 | 21 | 可选,按SPU搜索 |
| productId | 商品ID | string | 否 | 50 | 可选,按商品ID筛选 |
| shopId | 店铺ID | string | 是 | 用于授权验证 |
# 返回
success
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"pageSize": 20,
"pageNumber": 1,
"totalRecords": 50,
"totalPages": 3,
"content": [
{
"productId": "1952652478987366401",
"sku": "CJJJJTJT00784",
"productName": "Wireless Bluetooth Headphone",
"productImage": "https://cdn.cjdropshipping.com/xxx.jpg",
"status": true,
"reason": null,
"createAt": "2026-04-01 10:30:00"
}
]
},
"requestId": "97367e0f-cf3a-4c9b-acea-a36fb56f81b8",
"success": true
}
| 返回字段 | 字段意思 | 字段类型 | 长度 | 备注 |
|---|---|---|---|---|
| code | 错误码 | int | 20 | 返回错误码标准表 |
| result | 是否正常返回 | boolean | 1 | |
| message | 返回信息 | string | 200 | |
| data | 返回数据 | object | 分页包装对象 | |
| - pageSize | 每页条数 | int | ||
| - pageNumber | 当前页码 | int | ||
| - totalRecords | 总记录数 | int | ||
| - totalPages | 总页数 | int | ||
| - content | 商品列表 | array | ||
| -- productId | 商品ID | string | 50 | |
| -- sku | 商品SPU | string | 21 | |
| -- productName | 商品名称 | string | ||
| -- productImage | 商品图片URL | string | ||
| -- status | 订阅状态 | boolean | true=生效,false=失效 | |
| -- reason | 失效原因 | string | 255 | 如 "Product delisted" |
| -- createAt | 订阅时间 | string | 格式:yyyy-MM-dd HH:mm:ss | |
| requestId | 请求Id | string | 48 | 用于日志查询错误 |
| success | 是否调用成功 | boolean | 1 | true-成功,false-失败 |
# 3 通知规则
# 3.1 商品/变体通知过滤
当商品或变体发生变更时,webhook通知根据用户的订阅配置进行过滤:
- 用户开启了
subscribeAllProducts=true→ 发送通知 - 用户订阅了该具体商品 → 发送通知
- 以上均不满足 → 跳过通知
# 3.2 库存通知过滤
库存变更通知遵循相同的商品订阅过滤规则。只有订阅了对应商品的用户才会收到库存变更通知。
# 3.3 自动关闭机制
- 每个Topic的webhook推送成功/失败次数按小时维度记录
- 如果前2个完整小时内,每个小时区间的成功率都低于80%(可配置),则该Topic的webhook将被自动关闭
- 被自动关闭的webhook需要手动重新激活
- 关闭原因会记录在系统中
# 3.4 私有库存出库单通知
私有库存出库单复用「订单消息(ORDER)」主题推送,开通订单 webhook 后即可收到,无需单独订阅:
- 创建私有库存出库单时即推送一条
messageType=INSERT消息(普通订单创建不推送 INSERT); - 后续状态/支付/发货等变更与普通订单一致按
UPDATE推送; - 消息体在订单消息
params中带privateOutboundOrder=true标识,普通订单为false; - 订单消息体字段详见入门-Webhook 机制 订单消息。
# 4 补款单消息(Makeup)
订阅后,补款单发生以下变化时推送到已注册的 makeup 回调地址:
| messageType | 触发时机 | params.status |
|---|---|---|
INSERT | 补款单创建(添加) | CREATED |
CANCEL | 补款单取消 | CANCELED |
PAID | 补款单支付成功(完成) | PAID |
# 4.1 消息体示例
{
"messageId": "f3c2a1d09e8b4c5da6b7c8d9e0f1a2b3",
"type": "MAKEUP",
"messageType": "PAID",
"params": {
"orderId": "BT2606061320024499900",
"relationOrderId": "SD2606060858539645300",
"payOrderId": "2605260000000001",
"amount": 12.35,
"reason": "Postage difference",
"type": 1,
"diffUseType": 0,
"status": "PAID",
"createDate": "2026-06-04 10:00:00",
"paymentDate": "2026-06-04 12:00:00"
}
}
单号说明:
orderId为补款单号,统一以BT开头(示例BT2606061320024499900),与补款列表orderCode一致;relationOrderId为本次补款关联的原 CJ 订单号(被补款的订单),类型随原订单而定(如私有库存出库单SD…、代发/直发订单等),可用其在订单查询接口反查原订单详情。
| 字段 | 类型 | 说明 |
|---|---|---|
| messageId | string | 消息唯一ID(重试时不变,可用于幂等去重) |
| type | string | 业务类型,补款单固定 MAKEUP |
| messageType | string | INSERT-添加 / CANCEL-取消 / PAID-支付成功 |
| params.orderId | string | 补款单号,BT 开头,与补款列表 orderCode 一致,示例 BT2606061320024499900 |
| params.relationOrderId | string | 关联的原 CJ 订单号(被补款订单),类型随原订单而定:私有库存出库单 SD…、代发/直发订单等,示例 SD2606060858539645300 |
| params.payOrderId | string | 补款支付单号(支付后返回) |
| params.amount | number | 补款金额,单位 USD |
| params.reason | string | 补款原因(英文) |
| params.type | int | 1=补款 |
| params.diffUseType | int | 0=订单补款 1=Balance Top-up 2=Repayment 3=Transfer Shipping Fee |
| params.status | string | CREATED / CANCELED / PAID |
| params.createDate | string | 创建时间 yyyy-MM-dd HH:mm:ss |
| params.paymentDate | string | 支付时间(PAID 时返回) |
# 4.2 验签
请求头携带 sign,算法:sign = Base64( HmacSHA256( secret = openId字符串, message = 请求体JSON原文 ) )。接收端用自己的 openId 作为密钥对原始请求体计算 HmacSHA256 并 Base64 编码,与 sign 头比对一致即为合法请求。
# 4.3 响应要求
与其他主题一致:3 秒内返回 200 OK;推送失败会重试(最多3次),持续失败将触发自动关闭机制(见 3.3)。
# 5 私有订单消息(PrivateOrder)
订阅 privateOrder 主题后,私有订单(SY单/私有库存单,订单号以 SY 开头)发生状态变更时推送到已注册的回调地址。仅推送 SY 单,不含直发/押金等其它单据。
| messageType | 触发时机 |
|---|---|
UPDATE | SY 单状态发生变化(如待支付→已付款→待发货→已发货→已完成/已取消) |
# 5.1 消息体示例
{
"messageId": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"type": "PRIVATE_ORDER",
"messageType": "UPDATE",
"params": {
"orderId": "SY2606061320024499900",
"orderNumber": "shop_order_123",
"status": "SHIPPED",
"orderType": 2,
"createDate": "2026-06-04 10:00:00",
"paymentDate": "2026-06-04 12:00:00",
"deliveryDate": "2026-06-05 09:00:00",
"completeDate": null
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
| messageId | string | 消息唯一ID(重试时不变,可用于幂等去重) |
| type | string | 业务类型,私有订单固定 PRIVATE_ORDER |
| messageType | string | UPDATE-状态变更 |
| params.orderId | string | 私有订单号,单号规则:固定 SY 前缀 + 19 位数字(雪花ID),示例 SY2606061320024499900 |
| params.orderNumber | string | 店铺订单号 |
| params.status | string | 订单状态名称,见 5.2 状态表 |
| params.orderType | int | 订单类型:2=备货(私有库存单/SY单)。私有订单 webhook 目前仅推送 SY 单,orderType 固定为 2 |
| params.createDate | string | 创建时间 yyyy-MM-dd HH:mm:ss |
| params.paymentDate | string | 支付时间(已支付时返回) |
| params.deliveryDate | string | 发货(出库)时间(已发货时返回) |
| params.completeDate | string | 完成时间(完成时返回) |
# 5.2 status 状态值
| status | 说明 |
|---|---|
| WAIT_PAY | 待支付 |
| PAYMENT_INCOMING | 支付中 |
| PAID | 已付款待处理 |
| WAIT_SHIPMENT | 待发货 |
| INTERCEPTING / INTERCEPT | 拦截中 / 已拦截 |
| SHIPPED | 已发货 |
| COMPLETED | 已完成 |
| OVER | 已结束/关闭 |
| CANCELLED | 已取消 |
| REFUND_COMPLETE | 纠纷退款完成 |
| RESEND_OVER | 纠纷补发完成 |
# 5.3 验签与响应
验签算法与其它主题一致:sign = Base64( HmacSHA256( secret = openId字符串, message = 请求体JSON原文 ) );接收端 3 秒内返回 200 OK,推送失败重试(最多3次),持续失败触发自动关闭机制(见 3.3)。