支付平台签名生成
为保证数据安全和防篡改,所有请求都需要进行签名。
## 签名步骤
### 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×tamp=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×tamp=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;
}
```