主题
签名算法
所有请求需携带 signature 参数,由以下步骤生成。
生成步骤
- 移除
signature参数(如果存在) - 处理数组参数,将数组 / 对象转换为 JSON 字符串(不进行键排序)
- 按键名升序排序所有参数
- 拼接参数为
key=value&格式(跳过空值) - 在末尾追加
&api_secret=你的商户密钥 - 对完整字符串进行 MD5 加密并转为大写
最终签名
签名结果为大写的 32 位 MD5 字符串,例如 D866A542EB56BBD26857B552C432E9D6。
代码示例
php
function generateSignature($params, $apiSecret) {
// 1. 移除 signature 参数
unset($params['signature']);
// 2. 处理数组参数
$processedParams = [];
foreach ($params as $key => $value) {
if (is_array($value)) {
$processedParams[$key] = json_encode($value, JSON_UNESCAPED_UNICODE);
} else {
$processedParams[$key] = $value;
}
}
// 3. 按键名排序
ksort($processedParams);
// 4. 拼接参数
$stringToSign = '';
foreach ($processedParams as $key => $value) {
if ($value !== '' && $value !== null) {
$stringToSign .= $key . '=' . $value . '&';
}
}
// 5. 移除最后的 & 并追加 api_secret
$stringToSign = rtrim($stringToSign, '&') . '&api_secret=' . $apiSecret;
// 6. 生成 MD5 签名并转为大写
return strtoupper(md5($stringToSign));
}
// 使用示例
$params = [
'api_key' => 'your_api_key',
'timestamp' => time(),
'nonce' => 'random_string_16',
'order_type' => 1,
'cny_amount' => 1000.00
];
$apiSecret = 'your_api_secret';
$signature = generateSignature($params, $apiSecret);
$params['signature'] = $signature;javascript
// 完整的 MD5 + generateSignature 实现 见文档站源码
// 这里给出调用示例
import { generateSignature } from './md5.js'
const params = {
api_key: 'your_api_key',
timestamp: Math.floor(Date.now() / 1000),
nonce: Math.random().toString(36).substring(2, 18),
order_type: 1,
cny_amount: 1000.00
}
const apiSecret = 'your_api_secret'
params.signature = generateSignature(params, apiSecret)python
import hashlib
import json
import time
import random
import string
def generate_signature(params, api_secret):
# 1. 移除 signature
params = {k: v for k, v in params.items() if k != 'signature'}
# 2. 处理数组参数
processed = {}
for k, v in params.items():
if isinstance(v, (dict, list)):
processed[k] = json.dumps(v, ensure_ascii=False)
else:
processed[k] = v
# 3 & 4. 按键名排序并拼接参数
parts = []
for k in sorted(processed.keys()):
v = processed[k]
if v != '' and v is not None:
parts.append(f'{k}={v}')
# 5. 追加 api_secret
string_to_sign = '&'.join(parts) + '&api_secret=' + api_secret
# 6. MD5 大写
return hashlib.md5(string_to_sign.encode('utf-8')).hexdigest().upper()
# 使用示例
params = {
'api_key': 'your_api_key',
'timestamp': str(int(time.time())),
'nonce': ''.join(random.choices(string.ascii_letters + string.digits, k=16)),
'order_type': 1,
'cny_amount': 1000.00
}
api_secret = 'your_api_secret'
params['signature'] = generate_signature(params, api_secret)验签失败常见原因
- 参数值被 URL 编码(如中文未解码就参与签名)
api_secret填写错误- 空值参数未过滤
- 数组参数未按
json_encode序列化(卖单 payment_method)
