签名

1. 签名说明

1.1. 更新历史

版本号日期撰写人说明

1.0.0

2024-04-10

-

基本信息以及签名方式

1.2. 基本信息

1.1.1. API基本信息

  • API Key、secretKey

接口需要商户的API Key,请联系商务进行申请,申请成功后,会同时创建用户的secretKey,用于接口签名。本平台不保留secretKey, 需要商户自己妥善保存。

  • 本文档,所有接口的请求、响应的数据格式全部采用JSON格式;

  • 本文档,所有接口的测试环境格式 https://baseUrl/webhook/global/bizType

    • 其中bizType为资源信息,请参考权限说明。

    • baseUrl 为请求的域名或IP,请联系运营人员提供

  • 所有时间,包括请求、响应,均为时间戳(UNIX时间),单位为毫秒

  • 测试环境地址:https://pre-api-test.cmfbl.com/webhook

  • 正式环境地址:https://api.multimarkets.org/webhook

1.1.2. HTTP响应状态码

  • HTTP 4XX 错误码用于指示错误的请求内容、行为、格式。问题在于请求者。

  • HTTP 403 错误码表示违反WAF限制(Web应用程序防火墙)。

  • HTTP 429 错误码表示警告访问频次超限,即将被封IP。

  • HTTP 418 表示收到429后继续访问,IP被封。

  • HTTP 5XX 错误码用于指示本平台服务侧的问题。

1.1.3. 访问限制

  • 目前单个API-KEY 1分钟访问次数不超过100次,否则将返回429

  • 如果返回429后继续访问,即返回418

  • 首次返回418时,会被禁用5分钟,再次访问会被禁用10分钟,以此类推。

1.2. 请求方式与鉴权

1.2.1 请求头

请求相关通用参数需要放在http请求头,请求头参数如下:

请求头说明参数说明:

参数名称说明数据类型是否必填

apiKey

通过平台申请的api_key

字符串

必填

recvWindow

时间空窗,含义见下文《请求时间安全限制》

整数

非必填

timestamp

请求发送的时间(时间戳格式,毫秒)

整数

必填

signature

签名,签名计算方法见下文《签名》。

字符串

必填

companyId

公司ID

整数

必填

trace

全局链路唯一标志

字符串

必填

version

资源版本号

字符串

非必填

group

资源分组

字符串

非必填

lang

语言信息,默认zh-CN

字符串

非必填

注意: API-keys 与 secretKey 是大小写敏感的; 签名,是大小写敏感的

1.2.2 签名

签名使用SHA1WithRSA算法. secretKey作为 SHA1WithRSA 的密钥,param中对应的参数 + timestamp 作为SHA1WithRSA的操作对象,得到的输出即为签名。 具体计算方法,见本章节的《示例》。

1.2.3 请求时间安全限制

  • 服务器收到请求时,会判断请求参数timestamp,与服务器当前时间比较,如果是5000毫秒(这个时间,称为时间空窗,默认值5000)之前发出的,则拒绝请求。

  • 这个时间空窗值,可以通过发送可选参数 recvWindow来自定义。

逻辑伪代码如下:

if (timestamp < (serverTime ) && (serverTime - timestamp) <= recvWindow){
 // process request
}else{
 // reject request
}

1.2.4. 签名示例

Api KeysecretKey

companyId:439
apiKey:1710e1f6b4b54c15bea72e8669966591
secretKey:MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAI5WJjsBgtiuQQZDs5qe8LBDUm2ZSa4gTBJ+ztq6HkY5P88MqPJuQA8GJ3ZJqAzS8xfFsSfdVDpbFiAjtZYzIbQM0g8e5bER55uGjxLaC2c1BdiHi49KfUdJHwZ1HWoKOtO6NRnNMWo94oBiYSPz4CJSzS2XPDHmGbfo/wOj/IQRAgMBAAECgYAFJAlnciuGpeyFTGatO/ZXd2b/vFyT5Gi69keEUNqNEL5EPSHQ97hqkn9UX16pb+kFv8chOHY1UVrgOEnzrc8Wws6bDb4JbniapUuT4kXZLlA13tO1MNwIxSZoEfajMZ4LUTx7TgDcCYgFhMJrk6dgQQEAsPMNlFy4YWxEV3A9TQJBANPiyCYujM1LN6lITX7HORne12Ns1cHuzZJMu1zMALR5xrktGSmP3kc5gVfmrEgI9YU0dw/I2hSnPcNzW5VogqMCQQCr+HxA88wRV5d28FYwynVA9r982guPj+vnlGfS6jc7cm4YhboSCc12YiZuvloHc676qz2CnH4PR1oCbwVs7v27AkEAqFOhbbPNZ8o5jeJCrlTWqBbARdxQdKCh73fF4RKv/LBBjxqkwr/odezZNFuswg1b/1aOv5twpLe3+W3LdAZywQJBAKVO6XIuaN3Ky0iD4vZnx6q5Bn1nxHEuMeCcoej3SDyW1QoxkhnA3oaL9tHBnR1IsM05SpmBARSCzB1Gx3pdif0CQQCygtbpkypR+dbuj+P9x0ei49IMJZCSB7wlehJtWlRjvK3IFeOaG0lN0ioO9/jET33eo1ekCwvGZDB72FKgcYb/

实际业务请求参数如下

{"companyId":1,"lang":"zh-CN","customerNo":"86001308"}

计算签名:

第一步,获取body里的请求参数,参数按字母排序之后,组成下面的字符串:

{"companyId":1,"customerNo":"86001308","lang":"zh-CN"}

说明:

  • “参数按字母排序”的排序方式为,按照字母从小到大排序,从第一个字母开始比较,一样则比较第二个字母,再一样则比较第三个字母,依此类推。

  • 双引号全部去除,无论是字段名,还是字段值的双引号;

  • 中间不能有空格;

  • 如果字段为null,不参与签名

第二步,获取请求头的timestamp的参数,拼接在第一步的结果后面:

{companyId:1,customerNo:86001308,lang:zh-CN}1650361143685

第三步,使用secretKey 通过SHA1WithRSA 对第二步结果进行签名,结果如下 :

Dihl6oOt5UkaHo9sEouquP3EqbukLX2dAOoKTSGicYryTvH1m9r6vtSLHGutZn7u34/06gjhdpbXRFPdjb51GVHvG75qWXZ1P/boL89xtuja6eTEy9q/aS8R270Q1A+m/MOTxdiifCy0IByrSpCs4VJKaj2d8jlJo2GHznsH+q0=

附: java 版本 demo.

1.2.5 响应格式

采用JSON格式。

所有响应,统一格式:

{
    "msg": "描述",
    "fail": true,
    "trace": "请求唯一标识",
    "code": "响应码",
    "data": {},
    "bizCode": "业务代码",
    "tm": 0,
    "msgParams": "异常参数",
    "ok": true
}

说明:

  • code:依据code判断是否响应成功,code为“0”表示成功;其它均为错误码,见《响应错误码》。

  • message: 为code对应的描述信息,比如“请求成功”。

  • data 响应的业务数据部分。具体见各个接口。

1.3. 通用错误码

编码描述

00012001

验证签名失败

00012002

请求已超出时间空窗

00012003

请求的API_KEY不存在

00012004

当前没有对该API的请求权限

00012005

请求过于频繁

00012006

API已过期

00012007

非法IP地址

说明:具体业务接口错误码参见具体接口说明文档

Last updated