支付平台签名生成

为保证数据安全和防篡改,所有请求都需要进行签名。 ## 签名步骤 ### 1、取值 获取所有请求的 `POST` 内容,不包括字节类型参数,如文件、字节流,剔除 `sign` 字段,剔除值为空的参数; ### 2、排序 按照第一个字符的键值 ASCII 码递增排序(字母升序排序),如果遇到相同字符则按照第二个字符的键值 ASCII 码递增排序,以此类推; ### 3、拼接 将排序后的参数与其对应值,组合成 `参数=参数值` 的格式,并且把这些参数用 `&` 字符连接起来,此时生成的字符串为 `待签名字符串`。 ### 4、签名 使用 `商户密钥` 对 `待签名字符串` 进行 `HMAC-SHA256` 签名,并对签名结果进行 `Base64` 编码得到签名值。 ## 签名示例 以[订单创建](./Cwwvg4v2)接口为例 ### 1、取值 ```json { "merchant_id": "100001", "method": "fiseng.trade.create", "version": "1.0", "timestamp": "2022-11-16 14:28:08", "biz_content": "{\"fiseng_trade_no\":\"2022111617221196158\",\"fiseng_hmac_key\":\"DTNPFuhEQqJn1XkPoArM38y5KXUH3YDC\",\"area_id\":\"392471\",\"account\":\"test\",\"amount\":8888,\"channel\":\"ALIPAY\",\"client_ip\":\"8.8.8.8\"}", "sign": "" } ``` ### 2、排序 ```json { "biz_content": "{\"fiseng_trade_no\":\"2022111617221196158\",\"fiseng_hmac_key\":\"DTNPFuhEQqJn1XkPoArM38y5KXUH3YDC\",\"area_id\":\"392471\",\"account\":\"test\",\"amount\":8888,\"channel\":\"ALIPAY\",\"client_ip\":\"8.8.8.8\"}", "merchant_id": "100001", "method": "fiseng.trade.create", "sign": "jzTjZXRakOTOUCWwRAvz1Lbf7YWEcXpISpFxlJXNKLE=", "timestamp": "2022-11-16 14:28:08", "version": "1.0" } ``` ### 3、拼接 ```text biz_content={"fiseng_trade_no":"2022111617221196158","fiseng_hmac_key":"DTNPFuhEQqJn1XkPoArM38y5KXUH3YDC","area_id":"392471","account":"test","amount":8888,"channel":"ALIPAY","client_ip":"8.8.8.8"}&merchant_id=100001&method=fiseng.trade.create&timestamp=2022-11-16 14:28:08&version=1.0 ``` ### 4、签名 假设商户密钥为:`lUqkzIzyoZAuaVHE1jLDiefu1ZUWKMKl`,以下为 `PHP` 签名示例代码 ```php <?php $key = 'lUqkzIzyoZAuaVHE1jLDiefu1ZUWKMKl'; $string_to_sign = 'biz_content={"fiseng_trade_no":"2022111617221196158","fiseng_hmac_key":"DTNPFuhEQqJn1XkPoArM38y5KXUH3YDC","area_id":"392471","account":"test","amount":8888,"channel":"ALIPAY","client_ip":"8.8.8.8"}&merchant_id=100001&method=fiseng.trade.create&timestamp=2022-11-16 14:28:08&version=1.0'; // 使用 商户密钥 对 待签名字符串 进行 HMAC-SHA256 签名 $signature = hash_hmac('sha256', $string_to_sign, $key, true); // 对签名结果进行 Base64 编码得到签名值 $signature = base64_encode($signature); ``` 最终生成的签名值为:`JG5rIBV8ioRAr9OnMucR37kbNCyW7Uf5N/KneaQVgKQ=` ## 各语言生成签名代码 ### PHP ```php <?php /** * 生成签名 * @param array $data 数据 * @param string $sign_key 签名密钥 * @return string */ function generate_sign(array $data, string $sign_key): string { unset($data['sign']); ksort($data); $arr = []; foreach ($data as $key => $value) { if (!is_scalar($value) || '' === $value) { continue; } $arr[] = $key . '=' . $value; } $string_to_sign = implode('&', $arr); $signature = base64_encode(hash_hmac('sha256', $string_to_sign, $sign_key, true)); return $signature; } ```