# 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] | ✅ | ## 示例 ### 请求体 ```json { "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" } } ``` ### 响应体 ```json { "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 代码中引入依赖: ```xml commons-codec commons-codec 1.15 ``` ### 生成签名 从请求参数中依次组合 `merchant_id`、`timestamp` 和请求体 `requestBody` 内容,拼接为字符串后,使用您的私钥进行 SHA256withRSA 算法生成签名: ```java 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); ``` ### 设置请求头 1. 将签名设置到请求头 `signature` 中,并确保请求体和签名参数 `requestBody` 完全一致 2. 设置请求头 `type` 为 `RSA256`,表示使用的签名方式 3. 设置请求头 `version` 为 `v1.2`,表示使用的 API 版本 ### 请求示例 ```bash 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 公钥 ```java 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)); ```