一、请求与应答
1、请求报文
1.1 请求方式:POST
1.2 字符编码:UTF-8
1.3 Headers配置
AppID
= {{appid}}
Content-Type
= application/json;charset=UTF-8
1.4 Body报文结构
{
"coupon_id": "100175",
"order_id": "123456",
"brand_id": "10010001",
"member_id": "100000049",
"send_flag": "2",
"notice_phone": "13800000001",
"verify_code": "123456",
"outer_str": "123456",
"timestamp": 1576127771,
"sign": "93daf319f792332e011a8dc26e8b9e7955fb6ead60855f8672c4e859696a7bd4"
}
PS.timestamp
与sign
为所有接口必传节点,所以API接口文档不再赘述!
1.4 Curl方式请求示例
curl -X POST \
https://xxxxx/api/member/queryPoint \
-H 'AppID: 8888888' \
-H 'Content-Type: application/json;charset=UTF-8' \
-d '{"member_id":"703232323232","timestamp":1570899661,"sign":"b1d4a90dab7e4f1608e22a72aca53eb5f9bec81f80d3948391562b45e73af2b9"}'
2、应答报文结构
2.1 成功返回:code === 0,通常data节点包含数据
{
"code": 0,
"data": {
"verify_code": "23006296189188",
"order_id": "123456",
"seq": "10000320191212120741197848693"
},
"msg": "",
"timestamp": 1576123670,
"sign": "af58c0c9633d6b66eb923733520ae4572a5a84979e219464dbb04cca852e279f"
}
2.2 错误返回:code !== 0,通常data节点无返回
{
"code": 40001,
"data": null,
"msg": "缺少必须的参数",
"timestamp": 1575431387,
"sign": "245b7f43f586ffae3df885ce4a8af38c8673c5014ed8430de70887b3287ff322"
}
PS.所有接口报文结构一致,所以API接口文档不再赘述,仅说明data
以下的节点!
二、签名算法
1、示例参数:
$key = 'B6RluAgaBGHAs8s0WmyRmUUzxfJav48d';//接入密码
$input = [
"company_id" => "THEORY",
"trans_type" => "2",
"order_id" => "221322232422131",
"order_time" => "2019-11-13 18:00:00",
"from_channel" => "POS",
"order_amt" => -100,
"store_id" => "0999",
"member_id" => "100000047",
"currency" => "CNY",
"taobao_nick" => "大树",
"receiver_phone" => "1380000000",
"receiver_address" => "xx路xx号",
"receiver_province" => "福建省",
"receiver_city" => "福州市",
"receiver_name" => "张三",
"receiver_district" => "鼓楼区",
"goods_detail" => [
[
"line_no" => 1,
"barcode" => "190789856223",
"org_order_id" => "2423444321234323266",
"org_line_no" => "33443332",
"unit_price" => 199,
"sale_price" => -50,
"quantity" => 1,
],
[
"line_no" => 2,
"barcode" => "190789856224",
"org_order_id" => "24233123131123266",
"org_line_no" => "4444342",
"unit_price" => 99,
"sale_price" => -50,
"quantity" => 2,
]
]
];
2、筛选参数并排序
首先将数组中的键按字母的ASCII码顺序重新排序 得到如下新的数组(注意:goods_detail里面的不需要排序,只需要排序最外层的字段。外层字段为空的(
""、null、[]、false
)会被忽略不参加排序,因此计算时为空的字段要去掉,goods_detail中为空的不会被忽略,参与计算)
$input = [
"company_id" => "THEORY",
"currency" => "CNY",
"from_channel" => "POS",
"goods_detail" => "[{"line_no":1,"barcode":"190789856223","org_order_id":"2423444321234323266","org_line_no":"33443332","unit_price":199,"sale_price":-50,"quantity":1},{"line_no":2,"barcode":"190789856224","org_order_id":"24233123131123266","org_line_no":"4444342","unit_price":99,"sale_price":-50,"quantity":2}]",
"member_id" => "100000047",
"order_amt" => -100,
"order_id" => "221322232422131",
"order_time" => "2019-11-13 18:00:00",
"receiver_address" => "xx路xx号",
"receiver_city" => "福州市",
"receiver_district" => "鼓楼区",
"receiver_name" => "张三",
"receiver_phone" => "1380000000",
"receiver_province" => "福建省",
"store_id" => "0999",
"taobao_nick" => "大树",
"timestamp" => 1575878166,
"trans_type" => "2"
];
3、拼接参数
将数组的值转换成url参数形式的字符串,并且将结果url_decode得到
待签名字符串($str)
。
$str = "company_id=THEORY¤cy=CNY&from_channel=POS&goods_detail=[{"line_no":1,"barcode":"190789856223","org_order_id":"2423444321234323266","org_line_no":"33443332","unit_price":199,"sale_price":-50,"quantity":1},{"line_no":2,"barcode":"190789856224","org_order_id":"24233123131123266","org_line_no":"4444342","unit_price":99,"sale_price":-50,"quantity":2}]&member_id=100000047&order_amt=-100&order_id=221322232422131&order_time=2019-11-13 18:00:00&receiver_address=xx路xx号&receiver_city=福州市&receiver_district=鼓楼区&receiver_name=张三&receiver_phone=1380000000&receiver_province=福建省&store_id=0999&taobao_nick=大树×tamp=1575878166&trans_type=2";
4、生成摘要
将
待签名字符串($str)
进行sha256哈希加密得到摘要($signStep1)
PHP示例:
$signStep1 = hash('sha256', $str, false);
5、计算签名
将
摘要($signStep1)
首尾拼接接入密钥($appsecret)
后,进行sha256哈希加密
PHP示例:
$newStr = $key . $signStep1 . $key;
$sign = hash('sha256', $newStr, false);
三、附录:
1、采用Postman调试接口
1.1 Headers配置
AppID
= {{appid}}
Content-Type
= application/json
1.2 Body配置:raw
1.3 Pre-request Scripts
【建议】创建一个New Collection
,Edit
,在Pre-request Scripts
填入以下脚本:
//接入参数
const appid = '100003';
const appsecret = '--翼码接入密码--';
////////// 以下代码不可修改 //////////
//剔除空参数
String.prototype.trim = function () {
return this.replace(/(^\s*)|(\s*$)/g, "");
}
//获取当前时间
var timestamp = Math.round(new Date().getTime());
var requestData = request.data.replace('{{timestamp}}', timestamp);
var requestObj = JSON.parse(requestData);
//将sign排除排序
delete requestObj["sign"];
console.log(requestObj);
//根据key经行排序
var keys = Object.keys(requestObj),
i, len = keys.length;
keys.sort();
console.log(keys)
var requestBody = "";
var firstpass = true;
// 构造数据为 key=param&key=param....字符串
for (var index in keys) {
if (!firstpass) {
requestBody += "&";
}
var val = requestObj[keys[index]];
// console.log(keys[index]);
// console.log(Object.prototype.toString.call(val));
// console.log(val);
if (Object.prototype.toString.call(val) === '[object Object]' || Object.prototype.toString.call(val[0]) === '[object Object]') {
requestBody += keys[index] + "=" + JSON.stringify(val);
} else if ("" !== val.toString().trim()) {
requestBody += keys[index] + "=" + val;
}
firstpass = false;
}
console.log(requestBody);
//将数组的值转换成url参数形式的字符串,并且将结果url_decode得到
var encodeURIdata = decodeURIComponent(requestBody);
console.log(encodeURIdata);
//sha256加密生成摘要
var signStep1 = CryptoJS.SHA256(encodeURIdata).toString();
console.log(signStep1);
//前后拼接接入密钥,sha256加密生成签名
var newStr = appsecret + signStep1 + appsecret;
var sign = CryptoJS.SHA256(newStr).toString();
console.log(sign);
//替换变量
postman.setGlobalVariable('appid', appid);
postman.setGlobalVariable('timestamp', timestamp);
postman.setGlobalVariable('sign', sign);