# Webhook 机制
# 介绍
Webhook 是一种消息回调机制,包括:商品、变体、库存、订单等对象改动的消息通知,主要用于实时同步
# 对接步骤
- 1)设置消息监听,参考消息设置接口
- 2)客户端设置监听接口,试例如下(Java 语言)
- 3)测试监听,处理业务逻辑
# Webhook配置要求
# 一、协议要求
- 支持协议: HTTPS
- 加密要求: 建议使用 TLS 1.2 或 TLS 1.3 进行安全传输
- 请求方法: POST
- 内容类型:
Content-Type: application/json
# 二、签名认证
为了确保接收到的 Webhook 消息来自 CJ 官方,建议对请求进行签名验证。
1. 签名算法 签名生成规则如下:
- 准备参数:
openId: 您的 API 账号 ID (String) 从授权接口获取,保存于系统中message: 请求体 JSON 字符串 (String)
- 拼接字符串:将
openId和message作为参数传递给 HMAC-SHA256 算法。 - 计算签名:使用您的
API Key(作为 secret) 对拼接后的数据进行 HMAC-SHA256 加密。 - 编码:将加密后的字节数组进行 Base64 编码,得到最终的签名字符串。
2. 验证步骤
- 获取请求头中的
sign字段。 - 获取请求头中的
openId字段 (如果不在 Header 中,可从 URL 或 Body 中获取)。 - 获取原始请求体 (Body) 的 JSON 字符串。
- 按照上述签名算法自行计算签名。
- 比对计算出的签名与请求头中的
sign是否一致。
3. Java 示例代码
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import com.alibaba.fastjson.JSON;
public class SignUtil {
/**
* 生成签名
* @param openId 用户的 OpenID
* @param apiKey 用户的 API Key (Secret)
* @param param Webhook 请求体对象 (或 JSON 字符串)
* @return 签名字符串
*/
public static String encrypt(Long openId, String apiKey, Object param) {
if (openId == null) {
throw new RuntimeException("openId不能为空");
}
if (param == null) {
throw new RuntimeException("参数对象不能为空");
}
// 注意:实际实现中,openId作为secret的内容进行HMAC运算
// 根据 CallbackClient 和 SignUtil 源码逻辑:
// 1. secret = openId.toString()
// 2. message = JSON.toJSONString(param)
return sign(openId.toString(), JSON.toJSONString(param));
}
private static String sign(String secret, String message) {
String newHmac = "";
try {
String algorithm = "HmacSHA256";
Mac sha256HMAC = Mac.getInstance(algorithm);
// 注意:此处使用 secret (即 openId) 作为密钥
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes(), algorithm);
sha256HMAC.init(secretKey);
byte[] bytes = sha256HMAC.doFinal(message.getBytes());
newHmac = Base64.getEncoder().encodeToString(bytes);
} catch (Exception e) {
e.printStackTrace();
}
return newHmac;
}
}
注意:
- 请求头中包含
sign字段,值为计算出的签名。- 实际验证时,请确保使用请求体原始内容进行计算,避免 JSON 序列化/反序列化导致的字段顺序或格式差异。
- 目前系统实现中,签名的密钥使用的是
openId本身。
# 2. 响应规范
- 成功状态码:
200 OK - 响应超时时间: 3秒
(请避免在接收端执行耗时的业务逻辑,确保快速响应)
# 3. 请求失败处理
- 重试机制: 如果接收端返回非
200 OK状态码,CJ 将在 5 分钟后重试,最多重试 3 次 - 日志记录: 建议在接收端记录请求日志,便于排查问题
- 如果请求失败超过 3 次,CJ 将停止发送该消息,如果整个请求失败率达到 50%,CJ 将暂停发送所有消息,直到接收端恢复正常,且你重新注册Webhook
要求: 请求方法: POST
| 参数名称 | 参数意义 | 参数类型 | 是否必传 | 长度 | 备注 |
|---|---|---|---|---|---|
| code | 状态码 | int | 是 | 成功200 | |
| result | 处理结果 | string | 是 | success=成功, 其他=fail | |
| message | 处理结果消息 | string | 是 | 具体消息内容 |
# 消息列表
# 商品消息
# 接收到的商品消息体
{
"messageId": "ca72a4834cd14b9588e88ce206f614a0",
"type": "PRODUCT",
"messageType": "UPDATE",
"openId": 12312,
"params": {
"categoryId": null,
"categoryName": null,
"pid": "1424608189734850560",
"productDescription": "xxxxxx",
"productImage": null,
"productName": null,
"productNameEn": null,
"productProperty1": null,
"productProperty2": null,
"productProperty3": null,
"productSellPrice": null,
"productSku": null,
"productStatus": null,
"fields" : [
"productDescription"
]
}
}
| 参数名称 | 参数意义 | 参数类型 | 是否必传 | 长度 | 备注 |
|---|---|---|---|---|---|
| messageId | 商品消息 Id | string | Y | 200 | Message Id |
| type | 数据类型 | string | Y | 200 | PRODUCT |
| messageType | 消息类型 | string | Y | 15 | INSERT、UPDATE、DELETE |
| openId | Open Id | number | Y | ||
| params | object | Y | 5 | ||
| - categoryId | 商品品种 Id | string | Y | 200 | |
| - categoryName | 商品品种名称 | string | Y | 200 | |
| - pid | 商品 id | string | Y | 200 | |
| - productDescription | 商品详情 | string | Y | 2000 | |
| - productImage | 商品照片 | string | Y | 200 | |
| - productName | 商品名称 | string | Y | 200 | |
| - productNameEn | 商品名称(英文名) | string | Y | 200 | |
| - productProperty1 | 商品属性1 | string | Y | 200 | |
| - productProperty2 | 商品属性2 | string | Y | 200 | |
| - productProperty3 | 商品属性3 | string | Y | 200 | |
| - productSellPrice | 商品售价 | double | Y | 20 | |
| - productSku | 商品 sku | string | Y | 200 | |
| - productStatus | 商品消息状态 | int | Y | 5 | status:2-未在售, 3-在售 |
| - fields | 修改字段列表 | list | Y | 5 |
| ProductStatus | 说明 |
|---|---|
| 2 | 未在售 |
| 3 | 在售 |
# 接收到的变体消息
{
"messageId": "7cceede817dc47ed9748328b64353c5c",
"type": "VARIANT",
"messageType": "UPDATE",
"openId": 12312,
"params": {
"vid": "1424608152007086080",
"variantName": null,
"variantWeight": null,
"variantLength": null,
"variantWidth": null,
"variantHeight": null,
"variantImage": null,
"variantSku": null,
"variantKey": null,
"variantSellPrice": null,
"variantStatus": null,
"variantValue1": null,
"variantValue2": null,
"variantValue3": null,
"fields" : [
"variantLength"
],
}
}
| 参数名称 | 参数意义 | 参数类型 | 是否必传 | 长度 | 备注 |
|---|---|---|---|---|---|
| messageId | 变体消息 Id | string | Y | 200 | Message Id |
| type | 数据类型 | string | Y | 200 | VARIANT |
| messageType | 消息类型 | string | Y | 15 | INSERT、UPDATE、DELETE |
| openId | Open Id | number | Y | ||
| params | object | Y | 5 | ||
| - vid | 变体 Id | string | Y | 200 | |
| - pid | 商品 id | string | Y | 200 | |
| - variantName | 变体名称 | string | Y | 200 | |
| - variantWeight | 变体重量, 单位:g | int | Y | ||
| - variantLength | 变体长度, 单位:毫米 | int | Y | ||
| - variantWidth | 变体宽度, 单位:毫米 | int | Y | ||
| - variantHeight | 变体高度, 单位:毫米 | int | Y | ||
| - variantImage | 变体图片 | string | Y | 200 | |
| - variantSku | 变体 sku | string | Y | 200 | |
| - variantKey | 变体关键字 | string | Y | 200 | |
| - variantSellPrice | 变体售价 | double | Y | ||
| - variantStatus | 变体状态 | int | Y | 5 | |
| - variantValue1 | 变体属性1 | string | Y | 200 | |
| - variantValue2 | 变体属性2 | string | Y | 200 | |
| - variantValue3 | 变体属性3 | string | Y | 200 | |
| - fields | 修改字段列表 | list | Y | 5 |
| variantStatus | Description |
|---|---|
| 0 | 下架 |
| 1 | 在售 |
# 库存消息
{
"messageId": "ca72a4834cd14b9588e88ce206f614a0",
"type": "STOCK",
"messageType": "UPDATE",
"openId": 12312,
"params": {
"1424608152007086080": [
{
"vid": "1424608152007086080",
"pid": "123890023",
"areaId": "2",
"areaEn": "US Warehouse",
"countryCode": "US",
"storageNum": 12
}
],
"AE7DB9BC-4290-4C85-B8A6-F8957F3DB053": [
{
"vid": "AE7DB9BC-4290-4C85-B8A6-F8957F3DB053",
"pid": "123890023",
"areaId": "2",
"areaEn": "US Warehouse",
"countryCode": "US",
"storageNum": 1
}
]
}
}
# 接收到的物流轨迹变更消息
{
"messageId": "7cceede817dc47ed9748328b64353c5c",
"type": "LOGISTIC",
"messageType": "UPDATE",
"openId": 12312,
"params": {
"orderId": "123",
"trackingNumber": "CJPKL7160102171YQ",
"logisticName": "CJPacket Sensitive",
"trackingStatus": 0,
"logisticsTrackEvents": "[{"activity": "The electronic information of the waybill has been received.", "eventTime": "2021-10-28 21:17:18", "thirdActivity": "运单电子信息已收到", "thirdEventTime": "2021-10-28 21:17:18"}]"
}
}
| 参数名称 | 参数意义 | 参数类型 | 是否必传 | 长度 | 备注 |
|---|---|---|---|---|---|
| messageId | 物流消息 Id | string | Y | 200 | Message Id |
| type | 数据类型 | string | Y | 200 | LOGISTIC |
| messageType | 消息类型 | string | Y | 15 | INSERT、UPDATE、DELETE |
| openId | Open Id | number | Y | ||
| params | object | Y | |||
| - orderId | CJ订单Id | string | Y | 200 | |
| - logisticName | 物流公司名称 | string | Y | 200 | CJPacket Ordinary |
| - trackingNumber | 追踪单号 | string | Y | 200 | |
| - trackingUrl | 追踪号跟踪URL | string | N | 200 | |
| - trackingStatus | 追踪单状态 | integer | Y | 20 | |
| - logisticsTrackEvents | 追踪信息events事件信息 | string | Y | 200 | [{"activity": "The electronic information of the waybill has been received.", "eventTime": "2021-10-28 21:17:18", "thirdActivity": "运单电子信息已收到", "thirdEventTime": "2021-10-28 21:17:18"}] |
# 接收到的纠纷变更消息
{
"messageId": "7cceede817dc47ed9748328b64353c5c",
"type": "DISPUTES",
"messageType": "UPDATE",
"openId": 12312,
"params": {
"orderId": "123",
"status": "1"
}
}
| 参数名称 | 参数意义 | 参数类型 | 是否必传 | 长度 | 备注 |
|---|---|---|---|---|---|
| messageId | 变体消息 Id | string | Y | 200 | Message Id |
| type | 数据类型 | string | Y | 200 | DISPUTES |
| messageType | 消息类型 | string | Y | 15 | INSERT、UPDATE、DELETE |
| openId | Open Id | number | Y | ||
| params | object | Y | 5 | ||
| - orderId | CJ订单 Id | string | Y | 200 | |
| - status | 纠纷状态 | string | Y | 20 |
status状态值
| 参数名称 | 参数意义 |
|---|---|
| 1 | 新增纠纷 |
| 2 | 完成纠纷 |
| 3 | 取消纠纷 |
# 接收到的工单变更消息
{
"messageId": "7cceede817dc47ed9748328b64353c5c",
"type": "TICKET",
"messageType": "UPDATE",
"openId": 12312,
"params": {
"orderId": "123",
"status": "1"
}
}
| 参数名称 | 参数意义 | 参数类型 | 是否必传 | 长度 | 备注 |
|---|---|---|---|---|---|
| messageId | 工单消息 Id | string | Y | 200 | Message Id |
| type | 数据类型 | string | Y | 200 | TICKET |
| messageType | 消息类型 | string | Y | 15 | INSERT、UPDATE、DELETE |
| openId | Open Id | number | Y | ||
| params | object | Y | 5 | ||
| - orderId | CJ订单号 | string | Y | 200 | |
| - status | 工单状态 | string | Y | 20 |
status状态值
| 参数名称 | 参数意义 |
|---|---|
| 1 | 新增 |
| 2 | 已完成 |
| 3 | 已取消 |
# 订单消息
{
"messageId": "7cceede817dc47ed9748328b64353c5c",
"type": "ORDER",
"messageType": "UPDATE",
"openId": 12312,
"params": {
"orderNumber": "api_52f268d40b8d460e82c0683955e63cc9",
"cjOrderId": 210823100016290555,
"orderStatus": "CREATED",
"logisticName": "CJPacket Ordinary",
"trackNumber": null,
"trackingUrl": null,
"createDate": "2021-08-23 11:31:45",
"updateDate": "2021-08-23 11:31:45",
"payDate": null,
"deliveryDate": null,
"completeDate": null,
"orderItems": [
"vid": "1392053744945991680",
"quantity": 1,
"sellPrice": 0.57,
"lineItemId": "2505170958390976500",
"storeLineItemId": "16045188153625",
"productionOrderStatus": 1,
"abnormalType": [
6,
9
]
]
}
}
| 返回字段 | 字段意思 | 字段类型 | 长度 | 备注 |
|---|---|---|---|---|
| messageId | 工单消息 Id | string | 200 | Message Id |
| type | 数据类型 | string | 200 | ORDER |
| messageType | 消息类型 | string | 15 | INSERT、UPDATE、DELETE、ORDER_CONNNECTED:(该类型下特别注意:商品在CJ系统已经重新关联,订单由不完整更新为完整状态,该消息中返回真实CJ订单号) |
| params | object | |||
| - openId | Open Id | number | ||
| - cjOrderId | CJ订单ID | string | 200 | |
| - orderNum | 店铺订单号 | string | 200 | 将废弃,请使用orderNumber |
| - orderNumber | 店铺订单号 | string | 200 | |
| - orderStatus | 订单状态 | string | 200 | 参考订单状态 |
| - logisticName | 物流名称 | string | 200 | |
| - trackNumber | 物流编号 | string | 200 | |
| - trackingUrl | 追踪号跟踪URL | string | 200 | |
| - postage | 运费 | BigDecimal | (18,2) | 单位:$(美元) |
| - updateDate | 更新时间 | string | 200 | |
| - createDate | 创建时间 | string | 200 | |
| - payDate | 支付时间 | string | 200 | |
| - deliveryDate | 发货时间 | string | 200 | |
| - completeDate | 完成时间 | string | 200 | |
| - orderItems | 订单item列表 | List | ||
| -- vid | 变体ID | string | 200 | |
| -- quantity | 数量 | int | 200 | |
| -- sellPrice | 售价 | BigDecimal | (18,2) | 单位:$(美元) |
| -- storeLineItemId | 店铺订单的lineItemId | string | 125 | |
| -- lineItemId | CJ订单item的唯一id | string | 50 | |
| -- productionOrderStatus | 生产状态 | Number | 1 | 1=待排单, 2=待生产, 3=生产中, 4=生产完成, 5=生产异常 |
| -- abnormalType | 异常原因 | int[] | 6=图片链接错误, 9=生产图和效果图对不上, 10=缺少挂环, 11=刀线图和印刷图不匹配, 12=边缘不平整, 13=字母未连接, 14=下单图片缺失 |
# 订单拆单消息
{
"messageId": "7cceede817dc47ed9748328b64353c5c",
"type": "ORDERSPLIT",
"messageType": "UPDATE",
"openId": 12312,
"params": {
"originalOrderId": "原订单",
"splitOrderList": [
{
"createAt":1673490845706,
"orderCode":"SD1613355441583259648-2",
"orderStatus":300,
"productList":[
{
"sku":"CJNSSYLY01043-Claret-S",
"vid":"2547992D-CEE1-4BFD-99AC-9E30354F771F",
"quantity":1,
"productCode":"1613355657229205504"
},
{
"sku":"CJJSAQXF00016-Orange",
"vid":"A9C95BCB-D824-4AA1-A389-E86F3CCB10EF",
"quantity":1,
"productCode":"1613355657229205506"
},
{
"sku":"CJNSSYCS03214-Photo Color-XXL",
"vid":"E5FED43E-F9DE-483F-ADCE-8C95D3380315",
"quantity":1,
"productCode":"1613355657229205507"
}
]
},
{
"createAt":1673490845706,
"orderCode":"SD1613355441583259648-1",
"orderStatus":300,
"productList":[
{
"sku":"CJNSSYLY01043-White-M",
"vid":"0550DFC6-7FF7-4662-AE7D-B4DF0E4EB24A",
"quantity":1,
"productCode":"1613355657229205505"
}
]
}
],
"orderSplitTime": "拆单时间"
}
}
| 返回字段 | 字段意思 | 字段类型 | 长度 | 备注 |
|---|---|---|---|---|
| messageId | 工单消息 Id | string | 200 | Message Id |
| type | 数据类型 | string | 200 | ORDERSPLIT |
| messageType | 消息类型 | string | 15 | INSERT、UPDATE、DELETE |
| openId | Open Id | number | ||
| params | object | |||
| - originalOrderId | 原订单号 | string | 200 | |
| - orderSplitTime | 拆单时间 | string | 200 | |
| - splitOrderList | 拆单列表 | list | ||
| - - orderCode | 拆单后的订单id | string | 200 | |
| - - createAt | 拆单时间 | string | 200 | |
| - - orderStatus | 订单状态 | int | 11 | |
| - - productList | 商品信息列表 | list | 200 | |
| - - - productCode | 商品code | string | 200 | |
| - - - vid | 变体id | string | 200 | |
| - - - quantity | 数量 | int | 10 | |
| - - - sku | sku | string | 200 |
# 纠纷消息
{
"messageId": "7cceede817dc47ed9748328b64353c5c",
"type": "DISPUTE",
"messageType": "UPDATE",
"openId": 12312,
"params": {
"disputeId": "123",
"orderId": "210823100016290555",
"orderNumber": "api_52f268d40b8d460e82c0683955e63cc9",
"status": "",
"refuseReason": "ftdsr",
"refundAmount": "123",
"totalAmount": "123",
"disputeType": "1",
"reissueOrderId": "123",
"trackingNumber": "123",
"lineItems": [
{
"lineItemId": "lineItemId",
"productId": "商品id",
"variantId": "变体id",
"sku": "sku",
"price": 价格,
"quantity": "数量"
}
]
}
}
| 返回字段 | 字段意思 | 字段类型 | 长度 | 备注 |
|---|---|---|---|---|
| messageId | 工单消息 Id | string | 200 | Message Id |
| type | 数据类型 | string | 200 | DISPUTE |
| messageType | 消息类型 | string | 15 | INSERT、UPDATE、DELETE |
| openId | Open Id | number | ||
| params | object | |||
| - orderId | CJ订单ID | string | 200 | |
| - orderNumber | 客户订单号 | string | 200 | |
| - disputeId | 纠纷Id | string | 200 | |
| - shippingProvince | 交易省份 | string | 200 | |
| - status | 状态 | string | 200 | (新增,取消,拒绝,同意退款,同意补发,完成) |
| - refuseReason | 拒绝原因 | string | 500 | |
| - refundAmount | 退款金额 | BigDecimal | (18,2) | 单位:$(美元) |
| - totalAmount | 总金额 | BigDecimal | (18,2) | 单位:$(美元) |
| - disputeType | 纠纷类型 | BigDecimal | (18,2) | 单位:$(美元) |
| - reissueOrderId | 补发单号 | string | 100 | 参考订单状态 |
| - trackingNumber | 补发追踪号 | string | 100 | |
| - productInfoList | 商品信息 | Object[] | ||
| - - productCode | 商品code | string | 200 | |
| - - productId | 商品id | string | 200 | |
| - - variantId | 变体id | string | 200 | |
| - - price | 商品价格 | BigDecimal | (18,2) | 单位:$(美元) |
| - - quantity | 数量 | integer | 100 | |
| - - sku | sku | string | 100 |
| 状态 | 值 |
|---|---|
| 新增纠纷 | 1 |
| 取消纠纷 | 2 |
| 拒绝纠纷 | 3 |
| 同意退款 | 4 |
| 同意补发 | 5 |
| 完成纠纷 | 6 |
# 搜品创建结果消息
{
"messageId": "7cceede817dc47ed9748328b64353c5c",
"type": "SOURCINGCREATE",
"messageType": "UPDATE",
"openId": 12312,
"params": {
"cjProductId":"0550DFC6-7FF7-4662-AE7D-B4DF0E4EB24A",
"cjVariantId":"0550DFC6-7FF7-4662-AE7D-B4DF0E4EB24A",
"cjVariantSku":"CJ123582565212",
"cjSourcingId":"125522",
"status": "completed",
"failReason":"",
"createDate": "2023-02-07 00:00:00"
}
}
| 返回字段 | 字段意思 | 字段类型 | 长度 | 备注 |
|---|---|---|---|---|
| messageId | 工单消息 Id | string | 200 | Message Id |
| type | 数据类型 | string | 200 | SOURCINGCREATE |
| messageType | 消息类型 | string | 15 | INSERT、UPDATE、DELETE |
| openId | Open Id | number | ||
| params | object | |||
| - cjProductId | 商品id | string | 100 | |
| - cjVariantId | 变体id | list | 100 | |
| - cjVariantSku | CJ变体sku | string | 50 | |
| - cjSourcingId | 搜品任务id | string | 50 | |
| - status | 创建结果状态 | string | 20 | |
| - failReason | 失败原因 | string | 20 | |
| - createDate | 创建时间 | String | 50 |
# 物流变更消息
{
"messageId": "7cceede817dc47ed9748328b64353c5c",
"type": "LOGISTIC",
"messageType": "UPDATE",
"openId": 12312,
"params": {
"orderId": 210823100016290555,
"logisticName": "CJPacket Ordinary",
"trackingNumber": "number12345678",
"trackingStatus": 12,
"logisticsTrackEvents": "[{\"status\":12,\"activity\":\" Delivered, PO Box\",\"location\":\" NENANA,AK 99760\",\"eventTime\":\"2024-01-18 07:59:22\",\"statusDesc\":\"Delivered\",\"thirdActivity\":\"Delivered, PO Box\",\"thirdLocation\":\"NENANA,AK 99760\",\"thirdEventTime\":\"2024-01-18 07:59:22\"}]"
}
}
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| messageId | 工单消息 Id | string | 200 | Message Id | |
| type | 数据类型 | string | 200 | LOGISTIC | |
| messageType | 消息类型 | string | 15 | INSERT、UPDATE、DELETE | |
| openId | Open Id | number | |||
| params | object | ||||
| - orderId | CJ订单号 | string | Y | 200 | 210823100016290555 |
| - logisticName | 物流商名称 | string | Y | 200 | CJPacket Ordinary |
| - trackingNumber | 物流追踪号 | string | Y | 200 | number12345678 |
| - trackingUrl | 追踪号跟踪URL | string | N | 200 | |
| - trackingStatus | 追踪状态 | int | Y | 20 | 0=暂无追踪信息, 1=仓库已出库, 2=货代已入库, 3=货代退件, 4=货代出库, 5=头程运输, 6=抵达目的国, 7=开始清关, 8=清关完成, 9=末端提取, 10=派送中, 11=到达待取, 12=已签收, 13=失败/异常, 14=退回 |
| - logisticsTrackEvents | 物流轨迹信息 | string | Y | 200 | [{"status":12,"activity":" Delivered, PO Box","location":" NENANA,AK 99760","eventTime":"2024-01-18 07:59:22","statusDesc":"Delivered","thirdActivity":"Delivered, PO Box","thirdLocation":"NENANA,AK 99760","thirdEventTime":"2024-01-18 07:59:22"}] |
# 示例
# 商品消息接收示例
package com.cj.cn.controller;
import com.alibaba.fastjson.JSON;
import com.cj.cn.constant.callback.domain.CallbackParams;
import com.cj.cn.util.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* CJ webhook 监听示例
*
* @author : kay
*/
@RestController
@RequestMapping("/webhookListener")
@Slf4j
public class TestController {
@PostMapping("/productMessage")
public Result productMessage(@RequestBody @Validated CallbackParams query) {
log.info("product message:{}", JSON.toJSONString(query));
return Result.success(Boolean.TRUE);
}
}
package com.cj.cn.constant.callback.domain;
import lombok.Data;
/**
* @author : kay
*/
@Data
public class CallbackParams {
private String messageId;
private String type;
private Object params;
}
package com.cj.cn.constant.callback.domain;
import lombok.Getter;
import org.springframework.util.StringUtils;
/**
* @author : kay
*/
@Getter
public enum CallbackBusinessTypeEnum {
PRODUCT,
VARIANT,
STOCK;
public static CallbackBusinessTypeEnum create(String name) {
if (!StringUtils.isEmpty(name)) {
for (CallbackBusinessTypeEnum typeEnum: CallbackBusinessTypeEnum.values()) {
if (typeEnum.name().equals(name.toUpperCase())) {
return typeEnum;
}
}
}
return null;
}
}