签名生成
<p><strong>签名规则:</strong></p>
<ol>
<li>
<p>将接口API中参与签名的所有参数(为空的参数不需参与)按照ASCII码从小到大排序,拼接成形如:param1=a&param2=b&param3=c
有的参数值是JSON对象,这时请将JSON对象转为JSON字符串。
sign参数本身不参与签名!</p>
</li>
<li>
<p>在末尾拼接分配的密钥:&key=xxxxxxx。拼接后格式:param1=a&param2=b&param3=c&key=xxxxxxx
密钥在后台 -> 设置 -> API 对接 中查看。</p>
</li>
<li>对拼接后的字符串进行MD5并转成小写,即得到签名sign。</li>
</ol>
<p><strong>注意事项</strong>
不同的编程语言内置的排序算法排序的结果可能有差异(指对驼峰的排序)。
若系统提示签名不正确,建议首先检查第二步得到的字符串参数顺序是否和下面举例的一致:</p>
<pre><code class="language-ts">amount=xxx&amp;notifyUrl=xxx&amp;outOrderNo=xxx&amp;payMethod=accountBook&amp;payeeInfo={&quot;acctName&quot;:&quot;xx&quot;,&quot;account&quot;:&quot;xxx&quot;}&amp;transferMethod=bankcard&amp;userId=xxxxx&amp;key=xxx</code></pre>
<p>若不一致,建议您更换排序算法,或手动拼接字符串确保顺序一致。</p>
<p>服务端验证签名验证的具体实现是这样的:</p>
<pre><code>public generateSign(data: Record&lt;string, any&gt;, apiKey: string) {
const temp: Record&lt;string, string&gt; = {}
Object.keys(data)
.sort()
.forEach((k) =&gt; {
// skip sign key
if (k === 'sign') return
// skip empty value
if (data[k] === '' || data[k] === null || data[k] === undefined) return
// handle JSON value
if (typeof data[k] === 'object') {
temp[k] = JSON.stringify(data[k])
} else {
temp[k] = data[k]
}
})
const params = new URLSearchParams(temp)
params.sort()
params.append('key', apiKey)
return md5(decodeURIComponent(params.toString()))
}</code></pre>