TRX hace 1 año
padre
commit
6b4aeb1fec
Se han modificado 12 ficheros con 224 adiciones y 27 borrados
  1. 29 9
      PaymentClient/src/main/java/com/zhongshu/payment/client/payModel/unionFrictionlessPay/model/UnionUserOpenInfoModel.java
  2. 5 2
      PaymentClient/src/main/java/com/zhongshu/payment/client/payModel/unionFrictionlessPay/paymentModel/SignInParam.java
  3. 24 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/payModel/unionFrictionlessPay/paymentModel/UserRescissionParam.java
  4. 24 0
      PaymentClient/src/main/java/com/zhongshu/payment/client/payModel/unionFrictionlessPay/paymentModel/UserSignQueryParam.java
  5. 27 4
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/controller/unionFrictionlessPay/FrictionlessController.java
  6. 8 0
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/dao/unionFrictionlessPay/UnionUserOpenInfoDao.java
  7. 4 1
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/domain/unionFrictionlessPay/UnionUserOpenInfo.java
  8. 52 3
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/service/pay/impl/unionFrictionlessPay/UnionFrictionlessPayMainService.java
  9. 17 1
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/service/pay/impl/unionFrictionlessPay/UnionNotifyService.java
  10. 4 1
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/service/pay/impl/unionFrictionlessPay/config/UnionPaymentConfig.java
  11. 4 2
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/utils/AesUtils.java
  12. 26 4
      PaymentServer/src/main/java/com/zhongshu/payment/server/core/utils/Test.java

+ 29 - 9
PaymentClient/src/main/java/com/zhongshu/payment/client/payModel/unionFrictionlessPay/model/UnionUserOpenInfoModel.java

@@ -1,7 +1,9 @@
 package com.zhongshu.payment.client.payModel.unionFrictionlessPay.model;
 
+import com.github.microservice.types.unionFrictionlessPayType.ContractState;
 import com.zhongshu.card.client.model.base.SuperModel;
 import com.github.microservice.types.unionFrictionlessPayType.UnionUserOpenType;
+import com.zhongshu.card.client.model.org.UserCountModel;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
@@ -14,9 +16,36 @@ public class UnionUserOpenInfoModel extends SuperModel {
     @Schema(description = "签约类型")
     private UnionUserOpenType unionUserOpenType;
 
+    private String unionUserOpenTypeName;
+
+    public String getUnionUserOpenTypeName() {
+        if (unionUserOpenType != null) {
+            return unionUserOpenType.getName();
+        }
+        return "";
+    }
+
+    @Schema(description = "签约状态")
+    private ContractState contractState;
+
+    private String contractStateName;
+
+    public String getContractStateName() {
+        if (contractState != null) {
+            return contractState.getName();
+        }
+        return "";
+    }
+
     @Schema(description = "用户ID")
     private String userId;
 
+    @Schema(description = "用户名称")
+    private String userName;
+
+    @Schema(description = "用户信息")
+    private UserCountModel userCount;
+
     @Schema(description = "商户代码")
     private String mid;
 
@@ -29,9 +58,6 @@ public class UnionUserOpenInfoModel extends SuperModel {
     @Schema(description = "银商免密支付签约协议号")
     private String contractId;
 
-    @Schema(description = "签约状态,通知商户,必传。UNSIGNED-未签约 SIGNED-已签约 RESCISSION-已解约 ELETING_CONTRACT-解约中 UNKNOWN-未知")
-    private String contractState;
-
     @Schema(description = "签约时间")
     private Long signedTime;
 
@@ -43,10 +69,4 @@ public class UnionUserOpenInfoModel extends SuperModel {
 
     @Schema(description = "签约订单过期时间")
     private Long expiredTime;
-
-    @Schema(description = "签约参数")
-    private Object param;
-
-    @Schema(description = "签约返回参数")
-    private Object result;
 }

+ 5 - 2
PaymentClient/src/main/java/com/zhongshu/payment/client/payModel/unionFrictionlessPay/model/SignInParam.java → PaymentClient/src/main/java/com/zhongshu/payment/client/payModel/unionFrictionlessPay/paymentModel/SignInParam.java

@@ -1,6 +1,7 @@
-package com.zhongshu.payment.client.payModel.unionFrictionlessPay.model;
+package com.zhongshu.payment.client.payModel.unionFrictionlessPay.paymentModel;
 
 import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
 import lombok.Data;
 
 /**
@@ -10,14 +11,16 @@ import lombok.Data;
  * @date 2024/8/27
  */
 @Data
-public class SignInParam  {
+public class SignInParam {
 
     @Schema(description = "商户ID")
     private String shopOid;
 
     @Schema(description = "商户微信小程序id, 交易发起场景03:小程序,必传用于签约完成/失败/取消后跳转")
+    @NotEmpty(message = "mchntWxMpAppId不能为空")
     private String mchntWxMpAppId;
 
     @Schema(description = "商户微信小程序path, 交易发起场景03:小程序,必传用于签约完成/失败/取消后跳转")
+    @NotEmpty(message = "mchntWxMpPath不能为空")
     private String mchntWxMpPath;
 }

+ 24 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/payModel/unionFrictionlessPay/paymentModel/UserRescissionParam.java

@@ -0,0 +1,24 @@
+package com.zhongshu.payment.client.payModel.unionFrictionlessPay.paymentModel;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.internal.build.AllowPrintStacktrace;
+
+/**
+ * 用户解约的参数
+ *
+ * @author TRX
+ * @date 2024/9/2
+ */
+@Data
+@AllowPrintStacktrace
+@NoArgsConstructor
+public class UserRescissionParam {
+
+    @Schema(description = "用户ID", hidden = true)
+    private String userId;
+
+    @Schema(description = "签约协议号")
+    private String contractId;
+}

+ 24 - 0
PaymentClient/src/main/java/com/zhongshu/payment/client/payModel/unionFrictionlessPay/paymentModel/UserSignQueryParam.java

@@ -0,0 +1,24 @@
+package com.zhongshu.payment.client.payModel.unionFrictionlessPay.paymentModel;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import org.checkerframework.common.aliasing.qual.NonLeaked;
+import org.hibernate.internal.build.AllowPrintStacktrace;
+
+/**
+ * 用户签约状态查询参数
+ *
+ * @author TRX
+ * @date 2024/9/2
+ */
+@Data
+@AllowPrintStacktrace
+@NonLeaked
+public class UserSignQueryParam {
+
+    @Schema(description = "用户ID", hidden = true)
+    private String userId;
+
+    @Schema(description = "关联的商户ID")
+    private String shopId;
+}

+ 27 - 4
PaymentServer/src/main/java/com/zhongshu/payment/server/core/controller/unionFrictionlessPay/FrictionlessController.java

@@ -1,21 +1,23 @@
 package com.zhongshu.payment.server.core.controller.unionFrictionlessPay;
 
 import com.github.microservice.auth.security.annotations.ResourceAuth;
+import com.github.microservice.auth.security.helper.AuthHelper;
 import com.github.microservice.auth.security.type.AuthType;
 import com.github.microservice.net.ResultContent;
-import com.zhongshu.payment.client.payModel.unionFrictionlessPay.model.SignInParam;
-import com.zhongshu.payment.client.payModel.unionFrictionlessPay.model.SignParam;
+import com.zhongshu.payment.client.payModel.unionFrictionlessPay.paymentModel.SignInParam;
+import com.zhongshu.payment.client.payModel.unionFrictionlessPay.model.UnionUserOpenInfoModel;
+import com.zhongshu.payment.client.payModel.unionFrictionlessPay.paymentModel.UserRescissionParam;
+import com.zhongshu.payment.client.payModel.unionFrictionlessPay.paymentModel.UserSignQueryParam;
 import com.zhongshu.payment.server.core.service.pay.impl.unionFrictionlessPay.UnionFrictionlessPayMainService;
-import com.zhongshu.payment.server.core.service.pay.impl.unionFrictionlessPay.UnionNotifyService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
-import jakarta.servlet.http.HttpServletRequest;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
+import java.util.List;
 
 /**
  * 无感支付
@@ -32,6 +34,9 @@ public class FrictionlessController {
     @Autowired
     UnionFrictionlessPayMainService unionFrictionlessPayMainService;
 
+    @Autowired
+    AuthHelper authHelper;
+
     //---------------------------通知 start-----------------------------
     @Operation(summary = "无感支付开始签约")
     @ResourceAuth(value = "user", type = AuthType.User)
@@ -40,4 +45,22 @@ public class FrictionlessController {
         return unionFrictionlessPayMainService.sign(param);
     }
 
+    @Operation(summary = "查询用户签约信息")
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @PostMapping(value = "getUserSign", consumes = MediaType.APPLICATION_JSON_VALUE)
+    public ResultContent<List<UnionUserOpenInfoModel>> getUserSign(@RequestBody @Valid UserSignQueryParam param) {
+        param.setUserId(authHelper.getCurrentUser().getUserId());
+        return unionFrictionlessPayMainService.getUserSign(param);
+    }
+
+    @Operation(summary = "解约")
+    @ResourceAuth(value = "user", type = AuthType.User)
+    @PostMapping(value = "rescission", consumes = MediaType.APPLICATION_JSON_VALUE)
+    public ResultContent<List<UnionUserOpenInfoModel>> rescission(
+            @RequestBody UserRescissionParam param) {
+        param.setUserId(authHelper.getCurrentUser().getUserId());
+        return unionFrictionlessPayMainService.rescission(param);
+    }
+
+
 }

+ 8 - 0
PaymentServer/src/main/java/com/zhongshu/payment/server/core/dao/unionFrictionlessPay/UnionUserOpenInfoDao.java

@@ -4,6 +4,8 @@ import com.github.microservice.components.data.mongo.mongo.dao.MongoDao;
 import com.zhongshu.payment.server.core.dao.unionFrictionlessPay.extend.UnionUserOpenInfoDaoExtend;
 import com.zhongshu.payment.server.core.domain.unionFrictionlessPay.UnionUserOpenInfo;
 
+import java.util.List;
+
 /**
  * 卡
  *
@@ -14,6 +16,12 @@ public interface UnionUserOpenInfoDao extends MongoDao<UnionUserOpenInfo>, Union
 
     UnionUserOpenInfo findTopById(String id);
 
+    List<UnionUserOpenInfo> findByUserId(String userId);
+
     UnionUserOpenInfo findTopByUserId(String userId);
 
+    UnionUserOpenInfo findTopByContractNo(String contractNo);
+
+    UnionUserOpenInfo findTopByContractId(String contractId);
+
 }

+ 4 - 1
PaymentServer/src/main/java/com/zhongshu/payment/server/core/domain/unionFrictionlessPay/UnionUserOpenInfo.java

@@ -60,6 +60,9 @@ public class UnionUserOpenInfo extends SuperMain {
     @Schema(description = "签约参数")
     private Object param;
 
-    @Schema(description = "签约返回参数")
+    @Schema(description = "签约请求返回参数")
     private Object result;
+
+    @Schema(description = "签约回调数据")
+    private Object signResult;
 }

+ 52 - 3
PaymentServer/src/main/java/com/zhongshu/payment/server/core/service/pay/impl/unionFrictionlessPay/UnionFrictionlessPayMainService.java

@@ -1,5 +1,6 @@
 package com.zhongshu.payment.server.core.service.pay.impl.unionFrictionlessPay;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.github.microservice.app.stream.StreamHelper;
@@ -21,6 +22,9 @@ import com.zhongshu.payment.client.payModel.commn.PayOrderParam;
 import com.zhongshu.payment.client.payModel.unionFrictionlessPay.model.*;
 import com.github.microservice.types.unionFrictionlessPayType.ContractState;
 import com.github.microservice.types.unionFrictionlessPayType.UnionUserOpenType;
+import com.zhongshu.payment.client.payModel.unionFrictionlessPay.paymentModel.SignInParam;
+import com.zhongshu.payment.client.payModel.unionFrictionlessPay.paymentModel.UserRescissionParam;
+import com.zhongshu.payment.client.payModel.unionFrictionlessPay.paymentModel.UserSignQueryParam;
 import com.zhongshu.payment.server.core.dao.unionFrictionlessPay.UnionUserOpenInfoDao;
 import com.zhongshu.payment.server.core.domain.unionFrictionlessPay.UnionUserOpenInfo;
 import com.zhongshu.payment.server.core.service.org.CollectionIdService;
@@ -35,7 +39,10 @@ import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
 import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * 银联无感支付服务
@@ -133,17 +140,32 @@ public class UnionFrictionlessPayMainService extends SuperPayService {
         }
         SignResponse response = (SignResponse) requestAPI;
         log.info("response: {}", JSONUtil.toJsonStr(response));
+        unionUserOpenInfo.setResult(response);
+
         unionUserOpenInfoDao.save(unionUserOpenInfo);
         return ResultContent.buildSuccess(response);
     }
 
     /**
-     * 商户解约
+     * 解约
      *
-     * @param param
+     * @param
      * @return
      */
-    public ResultContent rescission(SignInParam param) {
+    public ResultContent rescission(UserRescissionParam param) {
+        String userId = param.getUserId();
+        if (StringUtils.isEmpty(userId)) {
+            return ResultContent.buildFail("userId不能为空");
+        }
+        UnionUserOpenInfo unionUserOpenInfo = unionUserOpenInfoDao.findTopByContractId(param.getContractId());
+        if (ObjectUtils.isEmpty(unionUserOpenInfo)) {
+            return ResultContent.buildFail(String.format("签约信息不存在:%s", param.getContractId()));
+        }
+        ContractState contractState = unionUserOpenInfo.getContractState();
+        if (contractState != ContractState.SIGNED) {
+            return ResultContent.buildFail("该用户未签约");
+        }
+
         RescissionParam rescissionParam = new RescissionParam();
         rescissionParam.setRequestTimestamp(DateUtils.paresTime(System.currentTimeMillis(), DateUtils.FORMAT_LONG));
         String url = payApiConfig.getUrl(UnionFrictionlessPayApiConfig.rescission);
@@ -318,4 +340,31 @@ public class UnionFrictionlessPayMainService extends SuperPayService {
         return ResultContent.buildFail("暂未实现");
     }
 
+    /**
+     * 查询签约的信息
+     *
+     * @return
+     */
+    public ResultContent<List<UnionUserOpenInfoModel>> getUserSign(UserSignQueryParam param) {
+        String userId = param.getUserId();
+        if (StringUtils.isEmpty(userId)) {
+            return ResultContent.buildFail("userId 为空");
+        }
+        List<UnionUserOpenInfo> list = unionUserOpenInfoDao.findByUserId(userId);
+        List<UnionUserOpenInfoModel> models = new ArrayList<>();
+        if (ObjectUtils.isNotEmpty(list)) {
+            models = list.stream().map(this::toModel).collect(Collectors.toList());
+        }
+        return ResultContent.buildSuccess(models);
+    }
+
+    public UnionUserOpenInfoModel toModel(UnionUserOpenInfo entity) {
+        UnionUserOpenInfoModel model = null;
+        if (ObjectUtils.isNotEmpty(entity)) {
+            model = new UnionUserOpenInfoModel();
+            BeanUtil.copyProperties(entity, model);
+        }
+        return model;
+    }
+
 }

+ 17 - 1
PaymentServer/src/main/java/com/zhongshu/payment/server/core/service/pay/impl/unionFrictionlessPay/UnionNotifyService.java

@@ -7,16 +7,21 @@ import com.github.microservice.core.helper.JsonHelper;
 import com.github.microservice.net.ResultContent;
 import com.github.microservice.stream.PaymentStreamType;
 import com.github.microservice.stream.model.SignModel;
+import com.github.microservice.types.unionFrictionlessPayType.ContractState;
 import com.zhongshu.card.client.service.feign.OperationLogsFeignService;
 import com.zhongshu.payment.client.payModel.unionFrictionlessPay.model.PayNotifyResponse;
 import com.zhongshu.payment.client.payModel.unionFrictionlessPay.model.SignNotifyParam;
+import com.zhongshu.payment.server.core.dao.unionFrictionlessPay.UnionUserOpenInfoDao;
+import com.zhongshu.payment.server.core.domain.unionFrictionlessPay.UnionUserOpenInfo;
 import com.zhongshu.payment.server.core.service.base.SuperService;
 import com.zhongshu.payment.server.core.service.pay.impl.unionFrictionlessPay.config.UnionPaymentConfig;
 import com.zhongshu.payment.server.core.utils.AesUtils;
+import com.zhongshu.payment.server.core.utils.CommonUtil;
 import jakarta.servlet.ServletInputStream;
 import jakarta.servlet.http.HttpServletRequest;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
 import org.bouncycastle.jce.ECNamedCurveTable;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
@@ -49,6 +54,9 @@ public class UnionNotifyService extends SuperService {
     @Autowired
     OperationLogsFeignService operationLogsFeignService;
 
+    @Autowired
+    UnionUserOpenInfoDao unionUserOpenInfoDao;
+
     /**
      * 无感支付签约回调 (解约也调用该接口)
      *
@@ -85,6 +93,14 @@ public class UnionNotifyService extends SuperService {
             paramMap.put(key, values[0]);
         });
 
+        String contractState = paramMap.get("contractState");
+        UnionUserOpenInfo unionUserOpenInfo = unionUserOpenInfoDao.findTopByContractNo(contractNo);
+        if (ObjectUtils.isNotEmpty(unionUserOpenInfo)) {
+            unionUserOpenInfo.setContractState(CommonUtil.getEnumByName(ContractState.class, contractState));
+        }
+        unionUserOpenInfo.setSignResult(paramMap);
+        unionUserOpenInfoDao.save(unionUserOpenInfo);
+
         Security.addProvider(new BouncyCastleProvider());
         KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
                 "EC",
@@ -105,7 +121,7 @@ public class UnionNotifyService extends SuperService {
         log.info("签约通知字符串:{} {}", contractNo, paramMap);
 
         PublicKey publicKey = AesUtils.initializeSM3WithSM2PublicKey(
-                UnionPaymentConfig.notifySecret.getBytes());
+                UnionPaymentConfig.notifySecret);
         // 创建 Signature 对象,指定验签算法为 SM3withSM2
         Signature signature1 = Signature.getInstance("SM3withSM2");
         // 初始化 Signature 对象,使用公钥进行验签

+ 4 - 1
PaymentServer/src/main/java/com/zhongshu/payment/server/core/service/pay/impl/unionFrictionlessPay/config/UnionPaymentConfig.java

@@ -8,8 +8,9 @@ package com.zhongshu.payment.server.core.service.pay.impl.unionFrictionlessPay.c
  */
 public class UnionPaymentConfig {
 
-    // 无感支付 秘钥
+    // 无感支付 秘钥 测试环境通知加密密钥
     public static final String notifySecret = "GAhPWQ8D4hXanneneaydaHYHiwn64p7y3A46Jpss87aKWsy5";
+
     //
     public static final String appId = "10037e6f803bc8ab01805fd07db4000d";
 
@@ -24,8 +25,10 @@ public class UnionPaymentConfig {
     // 银联无感支付签约模板ID
     public static final String planId = "d2041b5c28474a2c9bb8b70128d71160";
 
+    // 来源编号
     public static final String msgSrcId = "103A";
 
+    // 签约状态发生变化回调地址
     public static final String notifyUrl = "https://api.dev.qk.zonelife.cn/paymentserver-trx/frictionless/notify/signNotify";
 
     // 过期时间

+ 4 - 2
PaymentServer/src/main/java/com/zhongshu/payment/server/core/utils/AesUtils.java

@@ -1,5 +1,6 @@
 package com.zhongshu.payment.server.core.utils;
 
+import cn.hutool.core.codec.Base64Decoder;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
@@ -7,6 +8,7 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider;
 
 import javax.crypto.Mac;
 import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
 import java.security.KeyFactory;
 import java.security.MessageDigest;
 import java.security.PublicKey;
@@ -86,10 +88,10 @@ public class AesUtils {
         return str;
     }
 
-    public static PublicKey initializeSM3WithSM2PublicKey(byte[] publicKeyBytes) throws Exception {
+    public static PublicKey initializeSM3WithSM2PublicKey(String publicKeyStr) throws Exception {
         // 将字节转换为PublicKey
         Security.addProvider(new BouncyCastleProvider());
-        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
+        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(base64Decode(publicKeyStr).getBytes(StandardCharsets.UTF_8));
         KeyFactory keyFactory = KeyFactory.getInstance("ECDSA", "BC");
         PublicKey publicKey = keyFactory.generatePublic(keySpec);
         return publicKey;

+ 26 - 4
PaymentServer/src/main/java/com/zhongshu/payment/server/core/utils/Test.java

@@ -1,15 +1,16 @@
 package com.zhongshu.payment.server.core.utils;
 
+import com.zhongshu.payment.server.core.service.pay.impl.unionFrictionlessPay.config.UnionPaymentConfig;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.bouncycastle.jce.ECNamedCurveTable;
 import org.bouncycastle.jce.provider.BouncyCastleProvider;
 import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
 
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.Security;
-import java.security.Signature;
+import java.security.*;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Arrays;
+import java.util.Base64;
 
 /**
  * @author TRX
@@ -27,16 +28,37 @@ public class Test {
         ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("sm2p256v1");
         keyPairGenerator.initialize(ecSpec);
         KeyPair keyPair = keyPairGenerator.generateKeyPair();
+        String pub1 = new String(keyPair.getPublic().getEncoded());
+        String publicKeyBase64 = Base64.getEncoder().encodeToString(pub1.getBytes());
+        log.info("publicKeyBase64: {}", publicKeyBase64);
+        PublicKey publicKey1 = keyPair.getPublic();
+        log.info("pub1: {}", keyPair.getPublic().getFormat());
+
+//        PublicKey publicKey = AesUtils.initializeSM3WithSM2PublicKey(UnionPaymentConfig.notifySecret);
+//        log.info("public: {} {}", publicKey, publicKeyBase64);
+        KeyPairGenerator keyPairGenerator1 = KeyPairGenerator.getInstance("SM2");
+        keyPairGenerator1.initialize(256, new SecureRandom());
+        // 生成密钥对
+        KeyPair keyPair1 = keyPairGenerator1.generateKeyPair();
+        log.info("A: {}", keyPair1.getPublic());
 
         // Sign
         Signature signature = Signature.getInstance("SM3withSM2", "BC");
         signature.initSign(keyPair.getPrivate());
         signature.update("Hello, SM2".getBytes());
         byte[] sig = signature.sign();
+        log.info("sig: {}", new String(sig));
 
         // Verify
         signature.initVerify(keyPair.getPublic());
         signature.update("Hello, SM2".getBytes());
         System.out.println("Signature verified: " + signature.verify(sig));
+
+
+        String publicKeyString = UnionPaymentConfig.notifySecret;
+        byte[] keyBytes = Base64.getDecoder().decode(publicKeyString);
+        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
+        KeyFactory keyFactory = KeyFactory.getInstance("ECDSA", "BC");
+        PublicKey publicKey = keyFactory.generatePublic(spec);
     }
 }