跳到主要内容

EIOTCLUB Claude Analysis Material

这份文档是给 Claude 做进一步分析用的精简材料,只保留本轮明确需要的三部分:

  1. 签名算法(Signature Algorithm)
  2. Webhook 回调配置页对应的关键结构
  3. 单卡信息查询接口的完整参数和响应示例

来源主要整理自:

  • docs/integrations/eiotclub-apifox-export.md
  • openapi/eiotclub-apifox-openapi.json

1. 签名算法

来源页:API接口 -> 签名(sign)算法

  • 文档索引链接:https://s.apifox.cn/166a9792-0aaf-4d87-a524-2279ef4788bd/2084440m0.md
  • 生产 base URL:https://oapi.eiotclub.com

系统级参数

所有 API 请求都带这些系统参数:

参数类型必填说明
appkeystring应用身份标识
timestamplong10 位时间戳
nonceinteger5 位随机正整数
signstring签名结果

API 请求签名规则

  1. 将所有非空请求参数按参数名 ASCII 升序排列。
  2. 拼接成 key=value&key=value... 的字符串,记为 StringParm
  3. 在字符串末尾拼接 secret,形成 StringParmSign
  4. StringParmSignsha1 运算。
  5. 将结果转为大写,得到最终 sign

关键注意事项

  • secret 不参与排序。
  • secret 不直接作为请求字段传给 API,只用于签名。
  • API 调用签名需要包含 appkey
  • 回调通知签名计算不需要加入 appkey,这一点非常关键。

文档中的签名示例

假设系统参数和业务参数如下:

系统级参数业务级参数
appkey000001userNamewx
timestamp1556595508age24
nonce24523sex1

按 ASCII 升序拼接后:

age=24&appkey=000001&nonce=24523&sex=1&timestamp=1556595508&userName=wx

假设 secret = a1b1c1d1,则参与签名的字符串为:

age=24&appkey=000001&nonce=24523&sex=1&timestamp=1556595508&userName=wx&secret=a1b1c1d1

sha1 并转大写后示例结果:

963A56BAEBED746F2746E4D9B3B77BE0F2E171E7

请求示例

POST https://oapi.eiotclub.com/api/v3/xxx/xxx
Content-Type: application/json;charset=utf-8

{
"appkey": "000001",
"timestamp": 1556595508,
"nonce": 24523,
"sign": "963A56BAEBED746F2746E4D9B3B77BE0F2E171E7",
"userName": "wx",
"age": "24",
"sex": "1"
}

2. Webhook 回调配置相关内容

这里对应 EIOTCLUB Apifox 中的异步通知页面。当前这轮优先整理一个最典型、信息最完整的 webhook:订购通知-详细版

来源页:API接口 -> 异步通知 -> 订购通知-详细版

  • 文档索引链接:https://s.apifox.cn/166a9792-0aaf-4d87-a524-2279ef4788bd/124594751e0.md
  • 路径:POST /customerNotifyUrl
  • 含义:客户提供接收异步通知的地址(HTTP/HTTPS)

Webhook 请求体字段

字段类型必填说明
timestampinteger10 位时间戳
nonceinteger5 位随机正整数
signstring通知签名
idstring请求唯一标识
eventstring通知类型,例如 SubPkgList
dataarray<object>订购套餐数据

data[] 内字段

字段类型必填说明
iccidstringICCID
orderIdnumber套餐订单号
packageNamestring套餐名称
packageCodestring套餐编码
stateinteger套餐状态:0 待使用,1 使用中,2 已完成
gzhPackageNamestring商品套餐名称
packageTypeinteger套餐类型:2 限量流量包,3 限时流量包,4 限时限速包
createDatestring订购时间
outTradeNostringAPI 调用方传入的唯一订单号标识,最大 32 位
fromIccidstring转移套餐来源卡号
fromOrderIdinteger转移套餐来源订单号
salesChannelstring销售渠道,如 USERSYSTEMTRANSFERPLATFORMAPI
customDatastring客户白名单登录用户唯一标识,最大 125 位

Webhook 请求示例

{
"data": [
{
"iccid": "89423053323291099364",
"orderId": 10004728,
"packageName": "A-TM-50M-1天",
"packageCode": "A-TM-50M-1D-A-CN-TEST-2024052489FC722C",
"state": 0,
"gzhPackageName": "",
"createDate": "2024-05-28 09:34:47",
"packageType": 3,
"outTradeNo": "6300001983111426769635"
}
],
"event": "SubPkgList",
"id": "ue5Y0qNC8QQIRtUR3UgV4xzg",
"nonce": 40604,
"sign": "F0D19FA6945B21C0D61BDEFD4DCC41B64B29272B",
"timestamp": 1716860340
}

Webhook 成功响应

{
"status": "SUCCESS"
}

给 Claude 的注意点

  • EIOTCLUB webhook 验签规则和 API 请求签名不同:回调不带 appkey 参与签名
  • id 可以优先作为事件幂等键。
  • event 是本地路由事件处理器的重要分发字段。
  • 这个页面只代表一个典型 webhook,其他通知页(套餐生效、退款通知、达量到期、锁卡/解锁等)结构类似,但 data 字段内容会不同。

3. 单卡信息查询接口

来源页:API接口 -> 卡业务接口 -> 单卡信息查询

  • 文档索引链接:https://s.apifox.cn/166a9792-0aaf-4d87-a524-2279ef4788bd/63600559e0.md
  • OpenAPI 路径:POST /api/v3/card/getCardsInfo
  • 作用:根据卡号,获取单卡信息及流量使用信息。

完整请求参数

字段类型必填说明
appkeystring应用身份标识
timestampinteger当前时间戳,10 位
nonceinteger5 位随机正整数
signstring请求签名
iccidstring卡片 ICCID

请求示例

{
"appkey": "{{APPKEY}}",
"timestamp": "{{TIMESTAMP}}",
"nonce": 67958,
"sign": "{{SIGN}}",
"iccid": "89000123456789013802"
}

响应顶层结构

字段类型说明
codestring200 表示成功,其他表示失败
messagestring成功或失败原因
dataobject单卡详情

data 字段完整列表

字段类型说明
iccidstringICCID 卡号
imsistringIMSI 号
activateDatestring卡片激活时间
cardStatusstring卡状态,如 ACTIVATION_READY_NAMENON_ACTIVATED_NAMEACTIVATED_NAMEDEACTIVATED_NAME
isRealNameinteger是否实名:0 未实名,1 已实名
monthRemainFlownumber当前套餐剩余流量,单位 MB
monthUseFlownumber当前套餐已用流量,单位 MB
remainFlowTypenumber剩余流量类型:0 套餐流量,1 池剩余流量
productCodestring产品编码
packageEndDatestring当前套餐到期时间
dataFlownumber卡片总流量(包括未使用套餐),单位 MB
remainFlownumber卡片总剩余流量(包括未使用套餐),单位 MB
expectedEndDatestring卡片预计到期时间
imeiPoolStatusintegerIMEI 池锁状态:0 未锁,1 锁住暂停卡
imeiPoolUnlockCountintegerIMEI 池已解锁次数
isIMEIPoolinteger是否归属池:0 不归属,1 归属池,2 临时归属池
networkstring当前网络
totalUseFlownumber卡片已使用总流量,文档注明“暂时不精准”
packageCodestring当前使用系统套餐简码
packageKindinteger套餐类型:0 限量套餐,1 限时套餐,2 限时限速套餐
eidstringeSIM 卡号
remarkstring当前客户备注

整理后的响应示例

下面这个示例不是 EIOTCLUB 页面原样 mock,而是根据 OpenAPI 字段整理成更适合 Claude 理解的实际结构示例:

{
"code": "200",
"message": "Success",
"data": {
"iccid": "89000123456789013802",
"eid": "89049032000000000000012345678901",
"imsi": "460011234567890",
"activateDate": "2025-02-25 10:12:00",
"cardStatus": "ACTIVATED_NAME",
"isRealName": 1,
"monthRemainFlow": 73.0,
"monthUseFlow": 27.0,
"remainFlowType": 0,
"productCode": "PROD_CN_4G_001",
"packageEndDate": "2025-06-04 23:59:59",
"dataFlow": 1024.0,
"remainFlow": 512.0,
"expectedEndDate": "2025-08-04 23:59:59",
"imeiPoolStatus": 0,
"imeiPoolUnlockCount": 0,
"isIMEIPool": 0,
"network": "CMCC",
"totalUseFlow": 2048.0,
"packageCode": "PKG-1GB-30D",
"packageKind": 0,
"remark": "AOVIS test device"
}
}

给 Claude 的注意点

  • 这是单卡查询接口,不是分页列表接口。
  • 入参核心业务字段只有 iccid,其余四个是系统签名参数。
  • totalUseFlow 在文档里被注明“暂时不精准”,不要把它当绝对可信口径。
  • 流量类字段存在“当前套餐口径”和“卡片总口径”两套,需要在本地模型里区分:
    • 当前套餐:monthRemainFlowmonthUseFlow
    • 卡片累计/总量:dataFlowremainFlowtotalUseFlow

4. 可直接发给 Claude 的提示词

请基于这份 EIOTCLUB 分析材料,重点分析三件事:
1. 如何正确实现 API 请求签名与 webhook 验签,并避免把 appkey 错误加入 webhook 签名。
2. 如何为 /api/v3/card/getCardsInfo 设计一个稳定的服务层封装、返回字段映射和错误处理。
3. 如何为 EIOTCLUB webhook(尤其是订购通知-详细版)设计幂等处理、事件类型分发和本地订单/卡状态同步策略。

要求:
- 输出推荐的 TypeScript 服务层结构。
- 给出 sign 生成函数和 webhook sign 验签函数的伪代码或正式代码。
- 说明单卡查询接口的本地 DTO / schema 应该如何定义。
- 说明 webhook payload 的关键字段如何映射到本地事件模型。