密钥(Authentication)
签名生成规则
统一签名生成规则:
将
Map中的所有键值对按字典顺序(不区分大小写)排序,并将它们连接成查询字符串格式。具体来说,每个键值对将被连接为key=value&,形成一个连接字符串。连接字符串后,将 HiPay 后端的
商户私钥(key)附加到字符串末尾。对最终拼接好的字符串执行 MD5 加密,得到签名字符串(sign)。
TIP
签名空值:
连接字符串中,“值”为“空”的字段不要参与签名。
参数示例值
| 参数名称 | 类型 | 示例值 |
|---|---|---|
| mchNo | String | M1735112701 |
| appId | String | 676bb7fefb715596544e2210 |
| mchOrderNo | String | PAYIN_TEST_0003 |
| amount | Number | 1000 |
| subject | String | test |
| body | String | test |
| notifyUrl | String | http://domain.com |
| successUrl | String | http://domain.com |
| failUrl | String | http://domain.com |
| cancelUrl | String | http://domain.com |
| expiredTime | Number | 600 |
| userName | String | test |
| userEmail | String | test@gmail.com |
| userPhone | String | 0899998888 |
| userAddress | String | test |
| reqTime | Number | 1739413509 |
字符串拼接示例
将上述参数按字典序排序后进行拼接,并在最后追加 key。
示例拼接字符串:
mchNo=M1735112701&appId=676bb7fefb715596544e2210&mchOrderNo=PAYIN_TEST_0003&amount=1000&subject=test&body=test¬ifyUrl=http://domain.com&successUrl=http://domain.com&failUrl=http://domain.com&cancelUrl=http://domain.com&expiredTime=600&userName=test&userEmail=test@gmail.com&userPhone=0899998888&userAddress=test&reqTime=1739413509&key=your_private_key
签名计算
使用商户私钥对拼接字符串进行MD5加密,得到最终的签名值。
最终签名为:sign = MD5(concatenated string).toUpperCase()
代码示例
1. 获取拼接字符串
java
public static String getStrSort(Map<String, String> map) {
ArrayList<String> list = new ArrayList<>();
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
if (entry.getValue() != null && !entry.getValue().isEmpty()) {
list.add(entry.getKey() + "=" + entry.getValue() + "&");
}
}
String[] arrayToSort = list.toArray(new String[0]);
Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
StringBuilder sb = new StringBuilder();
for (String s : arrayToSort) {
sb.append(s);
}
return sb.toString();
}2. 使用映射参数和私钥计算签名
java
public static String getSign(Map<String, String> map, String key) {
String result = getStrSort(map);
result = result + "key=" + key;
if (_log.isDebugEnabled()) {
_log.debug("signStr: {}", result);
}
result = md5(result, encodingCharset).toUpperCase();
if (_log.isDebugEnabled()) {
_log.debug("signValue: {}", result);
}
return result;
}3、MD5加密方式
java
public static String md5(String value, String charset) {
MessageDigest md = null;
try {
byte data[] = value.getBytes(charset);
md = MessageDigest.getInstance("MD5");
byte digestData[] = md.digest(data);
return toHex(digestData);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}