API 签名组装规则
:::tip[]
连连支付开放接口签名生成算法为 SHA1withRSA
:::caution[]
注意 RSA 常用的有加密和加签两种,加密是为了防止信息泄露,加签是为了防止信息被篡改,连连这里使用的是加签,RSA 加签原理;
:::
一、API 签名说明

说明
- 上图为加签验签的原理,所描述场景为商家服务器发起连连开放接口请求的过程;
- 商家根据 api 签名组装规则和参数签名组装规则,将参数利用商户私钥进行加签生成数字签名;
- 商户自己保存私钥,公钥则通过连连商户站(配置商户公钥)功能保存到连连;
- 连连开放接口的访问,需要签名和参数同时传过来,连连收到请求会利用商户保存到连连的公钥和接收到的明文参数进行签名验证;
- 验证通过后会执行业务逻辑,业务逻辑执行完成返回结果,结果由两部分组成,一部分是业务结果,另一部分则是在返回 head 中的签名参数;
- 返回 head 的签名参数是由业务返回结果构建后利用连连私钥进行加签;
- 商户收到开放返回结果后,利用明文返回参数和连连公钥(获取连连公钥)与返回的签名进行对比验签;
:::info[]
使用 PKCS8 标准 RSA
:::
二、API 签名串组装规则
:::tip[]
在连连开放平台,url 请求的多个参数都要参与签名,构造签名因子就是参与签名所需的参数,下面以“支付取消”接口为例;
:::
接口请求url为:https://gpapi.LianLianpay.com/v3/merchants/<merchant_id>/payments/<merchant_transaction_id>/cancelpay
其中参与验签的参数为merchant_id
和merchant_transaction_id
,GET 类型请求验签参数在 url 中,POST 的验签参数则在 body 的参数模型中
https://gpapi.LianLianpay.com/v3/merchants/202103310000636001/payments/202111121816050188/cancelpay<br/>
签名因子为:merchant_id=202103310000636001, merchant_transaction_id=202111121816050188
合并签名因子
按照字母升序排列,例如有 a=1,b=2 两个参数,则 a 排在前 b 排在后,把前两步的字符串拼起来,得到 a=1&b=2,上述例子中订单取消接口为例则是 merchant_id=202103310000636001&merchant_transaction_id=202111121816050188
对合并后的签名因子执行 RSA 加签算法
得到签名:
eBpZy+QikUaYzFPlCLJbtzJEpmxGQWOVb3M3O19Ydo6B+86OChwH+NWzoijt0gKHCUcv1trhuXYDvqkVH9Z/tqRGVz7PEHn5MGcPgi/QovxNflfmKHL28u3ixzImIKnM2F0xem5qYlBZA9N+1hZUwpFXUQk0oTz61ovklRNthmasU4ByvA58bUdG8os9ibUAeRuNwkSLw9oflZAOIahU8WzWI4zEtE8l8ZhwBicpPkp8i+9hDyeQUwzOKycExY+fPMoHFRh+po1q2sUjgZtCK/LKZnJmYTzmlktQIaVfqkFfrcBLfj89LXLHOaJMhrytT3xgDrcxcnAwIsafHJuaMg==
三、参数签名串组装规则
构造签名因子:拼装的参数
在连连支付,发起创单 url 如下https://gpapi.LianLianpay.com/v3/merchants/<merchant_id>/payments
,这是一个 post 请求,请求参数放在 head body 中,格式为 json,验签因子也就是这些参数,url 中有一个merchant_id
,但是这个参数不是签名因子,这一点需要注意
{
"c": {
"b": "11",
"a": "10"
},
"a": "100",
"b": [
{
"f": "3",
"e": "2",
"d": "1"
},
{
"j": "6",
"i": "5",
"h": "4"
}
]
}
:::info[]
以上 json 一个业务参数例子,这些参数是签名的构造因子,下面我们来说明如何对这些签名因子进行合并;
:::
合并签名因子
先排序最外层参数,以参数名字母正序排序,排序结果如下:
"a":"100"
"b":[{"f":"3","e":"2","d":"1"},{"j":"6","i":"5","h":"4"}]
"c":{"b":"11","a":"10"}
子对象的参数排序;
例如子对象 c
排序前:
{"b":"11","a":"10"}
排序后
{ "a": "10", "b": "11" }
子对象数组类型的排序:
例如子对象 b
排序前:
[{"f":"3","e":"2","d":"1"},{"j":"6","i":"5","h":"4"}]
排序后:
[{ "d": "1", "e": "2", "f": "3"}, { "h": "4", "i": "5", "j": "6" }]
子对象重新排序后整体结果为(注意每层子对象都需如此排列,这是一个递归的过程):
{"a":"100","b":[{"d":"1","e":"2","f":"3"},{"h":"4","i":"5","j":"6"}],"c":{"a":"10","b":"11"}}
关键规则:
- 按照字母正序;
- 按照对象层级分别排序,先以最外层对象排序,然后逐层排序;
- 排序过程 a = "a=100",b= "d=1&e=2&f=3&h=4&i=5&j=6",c= "a=10&b=11"然后再按照 a&b&c 这样的顺序得到了加签字符串"a=100&d=1&e=2&f=3&h=4&i=5&j=6&a=10&b=11";
对合并后的签名因子执行 RSA 加签算法
ot10Q812G3zX9H9kbNPcU9RnZK296C88XtgHGfdcMyS/PqLEPdSSGSJMs4XzfaBDLgNgSbiUTjyzYSfQgGgUUFQ8nSIg813iRj2l0wyEWOfwRochd8SClV3+H9yfkGmh8bl/WJ1wlSah0giDDEpM12ArU6ygRgYpxrGAZwFewuB0yGSVAVuWWIk8E4UfDPETX4BXhshojF+HxEH2+pF4MHQvF30tdkM8FAaf9KxpIRFmU5X5gK34N+wJWygHpDjucQEPho5Lr3sftBOoA56LkF0AzaZcaVfJlBJCpIrlXG6rrr+qT6JSbrhpw466kio/2AXbtEewnmaD9wLklvXkQg==
四、常见问题
:::info[]
验签不通过常见原因:
- 金额字段精度为小数后两位,请保持参与签名的金额精度和上送的金额精度一致;
- 业务字段为NULL时不参与签名,业务字段为空字符时参与签名;
:::