API 认证
🔐 重要提示:请严格按照本文档说明进行 API 认证与签名,确保安全通信。
必要头部参数
请求头参数
参数名 | 含义描述 | 类型 | 必填 |
---|---|---|---|
signature | 请求签名 | String[1,500] | ✅ |
type | 签名类型,固定传 RSA256 | String[1,10] | ✅ |
version | 版本号,固定传 v1.2 | String[1,10] | ✅ |
响应头参数
参数名 | 含义描述 | 类型 | 必填 |
---|---|---|---|
signature | 响应签名 | String[1,500] | ✅ |
type | 签名类型,固定传 RSA256 | String[1,10] | ✅ |
version | 版本号,固定传 v1.2 | String[1,10] | ✅ |
示例
请求体
{
"merchant_id": "18356675194960",
"payment_type": "PURCHASE",
"authorisation_type": "FINAL_AUTH",
"capture_method": "AUTOMATIC",
"trans_id": "t202311081113",
"timestamp": 1700805506000,
"amount": 445,
"currency": "EUR",
"notify_url": "https://www.baidu.com/notifyUrl",
"return_url": "https://www.baidu.com/returnUrl",
"payment": {
"payment_method": "BankCard",
"store_payment_method": false,
"token_usage": "CARD_ON_FILE",
"shopper_reference": "user1234567890",
"encrypted_card_no": "string",
"encrypted_exp_year": "string",
"encrypted_exp_month": "string",
"encrypted_cvv": "string"
}
}
响应体
{
"ret_code": "000000",
"ret_msg": "Success",
"data": {
"merchant_id": "18356675194960",
"trans_id": "t202311081113",
"order_id": "GW20598371023658327",
"status": "AUTHORIZED",
"authorisation_type": "FINAL_AUTH",
"capture_method": "AUTOMATIC",
"amount": 445,
"currency": "EUR",
"payment": {
"payment_method": "BANKCARD"
},
"card_info": {
"bin": "424242",
"last4": "4242",
"card_brand": "VISA"
},
"balances": {
"authed_amount": 445,
"captured_amount": 0,
"able_to_capture_amount": 445,
"voided_amount": 0,
"able_to_void_amount": 445,
"refunded_amount": 0,
"able_to_refund_amount": 0
}
}
}
计算签名
添加依赖
在您的 Java 代码中引入依赖:
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
生成签名
从请求参数中依次组合 merchant_id
、timestamp
和请求体 requestBody
内容,拼接为字符串后,使用您的私钥进行 SHA256withRSA 算法生成签名:
private static final String FORMAT = "merchantId=%s×tamp=%s&requestBody=%s";
String content = String.format(FORMAT, merchantId, timestamp, requestBody);
Signature signature = Signature.getInstance("SHA256withRSA");
byte[] privateKeys = Base64Utils.decodeFromString(privateKey);
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKeys);
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(pkcs8EncodedKeySpec);
signature.initSign(priKey);
signature.update(content.getBytes(StandardCharsets.UTF_8));
byte[] signed = signature.sign();
String result = Base64Utils.encodeToString(signed);
String sign = URLEncoder.encode(result);
log.info("生成签名:{}", sign);
设置请求头
- 将签名设置到请求头
signature
中,并确保请求体和签名参数requestBody
完全一致 - 设置请求头
type
为RSA256
,表示使用的签名方式 - 设置请求头
version
为v1.2
,表示使用的 API 版本
请求示例
curl 'https://sandbox.aq.paykka.com/payments' -X POST \
-H 'Content-Type: application/json'\
-H 'type: RSA256'\
-H 'version: v1.2'\
-H 'signature: SOjw%2FOwcMM2jCB7xxxxxxxxxOtFyY%2BvWE%2FFXefazBA%3D%3D'\
-d '{"merchant_id": "18356675194960"}'
验证签名
⚠️ 注意: 验证签名时使用的公钥是 PayKKa 公钥
String content = String.format(FORMAT, merchantId, timestamp, requestBody);
Signature signature = Signature.getInstance("SHA256withRSA");
byte[] publicKeys = Base64Utils.decodeFromString(publicKey);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKeys);
PublicKey pubKey = KeyFactory.getInstance("RSA").generatePublic(x509EncodedKeySpec);
signature.initVerify(pubKey);
signature.update(content.getBytes(StandardCharsets.UTF_8));
String channelSignature = URLDecoder.decode("signatureDataFromPayKKa", StandardCharsets.UTF_8);
boolean verified = signature.verify(Base64Utils.decodeFromString(channelSignature));