通讯模式
接口如无特殊要求均采用HTTP POST方式提交。
接口地址
参数说明
参数类型 | 简称 | 参数说明 |
---|---|---|
整数 | I | 整数,十亿以内,简称是大写INT的首字母 |
日期 | D | 使用yyyyMMdd(如20210315)的格式 |
日期时间 | T | 使用yyyyMMddHHmmss(如20210315155012)的格式 |
字符串 | S | 任意合法的字符串,如S(16),表示字符串长度不超过16位 |
枚举值 | E | 见具体参数描述 |
浮点数 | F | 不超过10亿,小数点后最多7位 |
复合类型 | C | 数组内部嵌套键值对 |
布尔类型 | B | 布尔类型,true:是,false:否 |
签名和验签
- 所有请求和返回报文都包含签名参数,接收方务必检查签名的正确性,以保证业务数据合法安全。
- 签名和验签支持国密(SM2)和RSA两种方式,签名结果需要转换成16进制字符串。
- RSA签名使用标准签名算法”SHA256withRSA”,密钥长度2048位。
- RSA签名步骤:明文转json字符串->RSA->HEX(16)->密文(signStr)
敏感字段解密
手机号等敏感字段要求加密的需使用3DES解密,其中包含获取3DES密钥,之后才能用3des进行解密
- 获取3DES密钥,需使用商户私钥解密数字信封字段(dgtlEnvlp)获取密钥
- 3DES解密:使用获取的密钥进行3DES解密
幂等支持
本文档中部分接口支持幂等,当同一个商户订单号outTradeNo多次调用时,遵循如下:
- 同一个outTradeNo代表同一笔交易,outTradeNo需保证全局唯一
- 如之前已经返回成功,再次调用仍然会返回成功,不会重复处理交易
- outTradeNo只能包含字母、数字、下划线 _
特殊说明
本文档中部分接口字段名前包含中划线(-),当出现中划线时,表示该字段为上一级字段的叶子字段,即代表父字段为一个集合字段(JSON数组或JSON格式)
3DES解密说明
需使用商户私钥解密数字信封(dgtlEnvlp)字段得到3DES解密的密钥key
- 解密前需对加密数据和密钥key转为btye[]数组,java和php参考以下解密示例
JAVA
public static byte[] hex2Bytes(String source) {
byte[] sourceBytes = new byte[source.length() / 2];
for (int i = 0; i < sourceBytes.length; i++) {
sourceBytes[i] = (byte) Integer.parseInt(source.substring(i * 2, i * 2 + 2), 16);
}
return sourceBytes;
}
public static String threeDesDecrypt(String data, String keyStr) throws Exception {
try {
byte[] src = hex2Bytes(data);
byte[] keybyte = hex2Bytes(keyStr);
// 生成密钥
byte[] key = new byte[24];
if (keybyte.length < key.length) {
System.arraycopy(keybyte, 0, key, 0, keybyte.length);
} else {
System.arraycopy(keybyte, 0, key, 0, key.length);
}
SecretKey deskey = new SecretKeySpec(key, "DESede");
// 解密
Cipher c1 = Cipher.getInstance("DESede/ECB/PKCS5Padding");
c1.init(Cipher.DECRYPT_MODE, deskey);
byte[] decryptByte = c1.doFinal(src);
return new String(decryptByte);
} catch (Exception e) {
throw new Exception("3DES解密发生错误", e);
}
}
PHP
<?php
class TripleDES
{
private const CIPHER_METHOD = 'DES-EDE3';
private $key;
public function __construct($key)
{
// 3DES密钥需要24字节(192位),确保密钥为48个十六进制字符(24字节)
$this->key = hex2bin($key);
if ($this->key === false || strlen($this->key) !== 24) {
throw new InvalidArgumentException('Invalid 3DES key provided. Key must be 48 hexadecimal characters.');
}
}
public function encrypt($data)
{
// 使用3DES ECB模式进行加密,PKCS5Padding填充
$paddedData = $this->pkcs5_pad($data);
$encrypted = openssl_encrypt($paddedData, self::CIPHER_METHOD, $this->key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING);
return bin2hex($encrypted);
}
public function decrypt($data)
{
$data = hex2bin($data);
if ($data === false) {
throw new InvalidArgumentException('Invalid encrypted data provided.');
}
// 使用3DES ECB模式进行解密
$decrypted = openssl_decrypt($data, self::CIPHER_METHOD, $this->key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING);
return $this->pkcs5_unpad($decrypted);
}
private function pkcs5_pad($text, $blocksize = 8)
{
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
private function pkcs5_unpad($text)
{
$pad = ord($text[strlen($text) - 1]);
if ($pad > strlen($text) || strspn($text, chr($pad), strlen($text) - $pad) !== $pad) {
return false;
}
return substr($text, 0, -1 * $pad);
}
}
// 测试示例
try {
$key = "8c5dd9b9235180a77c9298f273fe67e08c5dd9b9235180a7";
$tripleDES = new TripleDES($key);
$originalData = "This is a secret message.";
$encryptedData = $tripleDES->encrypt($originalData);
$decryptedData = $tripleDES->decrypt($encryptedData);
echo "原始数据: " . $originalData . PHP_EOL . "<br>";
echo "加密数据: " . $encryptedData . PHP_EOL . "<br>";
echo "解密数据: " . $decryptedData . PHP_EOL . "<br>";
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
?>
作者:xiaofeng 创建时间:2025-03-25 16:45
最后编辑:xiaofeng 更新时间:2025-04-24 15:18
最后编辑:xiaofeng 更新时间:2025-04-24 15:18