Pārlūkot izejas kodu

feat(支付): 重构通联支付SDK为统一支付接口

- 将H5支付接口升级为支持多种支付方式的统一支付接口
- 更新生产环境URL为vsp.allinpay.com
- 修改签名验签逻辑使用Base64和UTF-8编码
- 增加支付方式、用户标识等可选参数支持
- 更新测试用例适配新接口
skyfffire 1 nedēļu atpakaļ
vecāks
revīzija
aa6a05213a
1 mainītis faili ar 42 papildinājumiem un 28 dzēšanām
  1. 42 28
      src/main/java/common/utils/tl/AllinpaySDK.java

+ 42 - 28
src/main/java/common/utils/tl/AllinpaySDK.java

@@ -7,7 +7,9 @@ import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.jfinal.kit.HttpKit;
 import com.jfinal.kit.StrKit;
+import java.nio.charset.StandardCharsets;
 import java.util.*;
+import java.util.Base64;
 
 /**
  * 通联支付SDK
@@ -19,9 +21,9 @@ import java.util.*;
 public class AllinpaySDK {
     
     // 生产环境配置
-    private static final String BASE_URL = "https://syb.allinpay.com";
-    private static final String H5_PAY_URL = BASE_URL + "/apiweb/h5unionpay/unionorder";
-    private static final String QUERY_URL = BASE_URL + "/apiweb/unitorder/query";
+    private static final String BASE_URL = "https://vsp.allinpay.com";
+    private static final String UNIFIED_PAY_URL = BASE_URL + "/apiweb/unitorder/pay";
+    private static final String QUERY_URL = "https://syb.allinpay.com/apiweb/unitorder/query";
     
     // 商户配置信息(测试用静态配置)
     private static final String APP_ID = "00000051";
@@ -38,44 +40,56 @@ public class AllinpaySDK {
     private static final SM2 sm2 = SmUtil.sm2(SM2_PRIVATE_KEY, ALLINPAY_PUBLIC_KEY);
     
     /**
-     * H5收银台支付
-     * 
-     * @param trxamt 交易金额(分)
-     * @param reqsn 商户交易单号
-     * @param body 商品描述
-     * @param remark 备注
-     * @param notify_url 异步通知地址
-     * @param return_url 同步跳转地址
+     * 统一支付接口
+     *
+     * @param trxamt      交易金额(分)
+     * @param reqsn       商户交易单号
+     * @param paytype     交易方式
+     * @param body        订单标题
+     * @param remark      备注
+     * @param acct        支付平台用户标识
+     * @param notify_url  交易结果通知地址
+     * @param limit_pay   支付限制
+     * @param idno        证件号
+     * @param truename    付款人真实姓名
+     * @param sub_appid   微信子appid
      * @return 支付结果
      */
-    public static PaymentResult h5Pay(Long trxamt, String reqsn, String body, String remark, 
-                                     String notify_url, String return_url) {
+    public static PaymentResult unifiedPay(Long trxamt, String reqsn, String paytype, String body, String remark,
+                                           String acct, String notify_url, String limit_pay, String idno,
+                                           String truename, String sub_appid) {
         try {
             // 1. 构建请求参数
             Map<String, String> params = new TreeMap<>();
             params.put("appid", APP_ID);
             params.put("cusid", CUS_ID);
-            params.put("version", "12");
+            params.put("version", VERSION);
             params.put("signtype", SIGN_TYPE);
             params.put("randomstr", RandomUtil.randomString(8));
             params.put("trxamt", String.valueOf(trxamt));
             params.put("reqsn", reqsn);
+            params.put("paytype", paytype);
             params.put("body", body);
             params.put("remark", remark);
             params.put("notify_url", notify_url);
-            params.put("return_url", return_url);
-            params.put("charset", "UTF-8");
-            
+
+            // 添加可选参数
+            if (StrKit.notBlank(acct)) params.put("acct", acct);
+            if (StrKit.notBlank(limit_pay)) params.put("limit_pay", limit_pay);
+            if (StrKit.notBlank(idno)) params.put("idno", idno);
+            if (StrKit.notBlank(truename)) params.put("truename", truename);
+            if (StrKit.notBlank(sub_appid)) params.put("sub_appid", sub_appid);
+
             // 2. 生成签名
             String sign = generateSign(params);
             params.put("sign", sign);
-            
+
             // 3. 发送请求
-            String response = sendPostRequest(H5_PAY_URL, params);
-            
+            String response = sendPostRequest(UNIFIED_PAY_URL, params);
+
             // 4. 解析响应
             return parsePaymentResponse(response);
-            
+
         } catch (Exception e) {
             e.printStackTrace();
             return PaymentResult.error("支付请求失败: " + e.getMessage());
@@ -143,7 +157,7 @@ public class AllinpaySDK {
             System.out.println("通知验签字符串: " + signString);
             
             // 使用通联公钥验签
-            boolean verifyResult = sm2.verifyHex(signString, sign);
+            boolean verifyResult = sm2.verify(signString.getBytes(StandardCharsets.UTF_8), sign.getBytes(StandardCharsets.UTF_8), APP_ID.getBytes(StandardCharsets.UTF_8));
             
             if (!verifyResult) {
                 return NotifyResult.error("签名验证失败");
@@ -172,7 +186,8 @@ public class AllinpaySDK {
         System.out.println("签名字符串: " + signString);
         
         // 2. 使用SM2私钥签名
-        String sign = sm2.signHex(signString);
+        byte[] signBytes = sm2.sign(signString.getBytes(StandardCharsets.UTF_8), APP_ID.getBytes(StandardCharsets.UTF_8));
+        String sign = Base64.getEncoder().encodeToString(signBytes);
         
         System.out.println("生成的签名: " + sign);
         return sign;
@@ -319,7 +334,7 @@ public class AllinpaySDK {
             System.out.println("验签字符串: " + signString);
             
             // 使用通联公钥验签
-            boolean result = sm2.verifyHex(signString, sign);
+            boolean result = sm2.verify(signString.getBytes(StandardCharsets.UTF_8), Base64.getDecoder().decode(sign), APP_ID.getBytes(StandardCharsets.UTF_8));
             
             System.out.println("验签结果: " + result);
             return result;
@@ -485,14 +500,13 @@ public class AllinpaySDK {
         String body = "测试商品";
         String remark = "SDK测试订单";
         String notify_url = "https://your-domain.com/api/payment/callback";
-        String return_url = "https://your-domain.com/payment-result";
         
         System.out.println("测试订单号: " + reqsn);
         System.out.println("交易金额: " + trxamt + "分");
         
-        // 测试1: H5支付
-        System.out.println("\n=== 测试H5支付 ===");
-        PaymentResult payResult = h5Pay(trxamt, reqsn, body, remark, notify_url, return_url);
+        // 测试1: 统一支付
+        System.out.println("\n=== 测试统一支付 ===");
+        PaymentResult payResult = unifiedPay(trxamt, reqsn, "W02", body, remark, "o9o43wz9sV5x8P-MA2b02mtYw4Co", notify_url, null, null, null, null);
         System.out.println("支付结果: " + payResult);
         
         if (payResult.isSuccess()) {