Эх сурвалжийг харах

feat:订单支付方式:微信支付,退款demo

wrj 1 жил өмнө
parent
commit
69c94d2941

+ 109 - 7
nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/PayController.java

@@ -17,6 +17,7 @@ import com.ijpay.core.kit.PayKit;
 import com.ijpay.core.kit.WxPayKit;
 import com.ijpay.core.utils.DateTimeZoneUtil;
 import com.ijpay.wxpay.WxPayApi;
+import com.ijpay.wxpay.WxPayApiConfigKit;
 import com.ijpay.wxpay.enums.WxDomainEnum;
 import com.ijpay.wxpay.enums.v3.BasePayApiEnum;
 import com.ijpay.wxpay.enums.v3.CertAlgorithmTypeEnum;
@@ -25,6 +26,8 @@ import com.ijpay.wxpay.model.v3.*;
 import com.ylx.common.config.WxPayConfig;
 import com.ylx.common.core.domain.R;
 import com.ylx.massage.domain.TRecharge;
+import com.ylx.massage.enums.BillTypeEnum;
+import com.ylx.massage.service.TOrderService;
 import com.ylx.massage.service.TRechargeService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -39,10 +42,7 @@ import java.io.ByteArrayInputStream;
 import java.math.BigDecimal;
 import java.nio.charset.StandardCharsets;
 import java.security.cert.X509Certificate;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 import static com.ylx.common.constant.HttpStatus.SUCCESS;
 
@@ -64,6 +64,9 @@ public class PayController {
     @Resource
     private TRechargeService rechargeService;
 
+    @Resource
+    private TOrderService orderService;
+
     String serialNo;
     String platSerialNo;
 
@@ -74,10 +77,10 @@ public class PayController {
     @ApiOperation("AIPV3微信支付充值")
     public R createUnifiedOrder(@RequestBody TRecharge recharge) throws Exception {
         TRecharge rechargeResp = rechargeService.recharge(recharge);
-        return getStringR(rechargeResp.getRechargeNo(),recharge.getdMoney(), recharge.getcOpenId(),"充值");
+        return rechargeService.getPay(rechargeResp.getRechargeNo(),recharge.getdMoney(), recharge.getcOpenId(),BillTypeEnum.RECHARGE.getInfo(), BillTypeEnum.RECHARGE.getCode().toString());
     }
 
-    public R<String> getStringR(String setOutTradeNo, BigDecimal amount, String openId,String description) throws Exception {
+    public R<String> getPay(String setOutTradeNo, BigDecimal amount, String openId,String description) throws Exception {
         String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3);
         UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
                 .setAppid(wxPayProperties.getAppId())
@@ -178,7 +181,12 @@ public class PayController {
                 map.put("message", "SUCCESS");
                 // 处理业务逻辑
                 JSONObject jsonObject = new JSONObject(plainText);
-                TRecharge outTradeNo = rechargeService.increaseAmount(jsonObject.get("out_trade_no").toString());
+                if (jsonObject.get("attach").equals(BillTypeEnum.WX_PAY.getCode().toString())) {
+                    // 订单支付成功
+                    orderService.payNotifyOrder(jsonObject.get("out_trade_no").toString());
+                }else{
+                    TRecharge outTradeNo = rechargeService.increaseAmount(jsonObject.get("out_trade_no").toString());
+                }
             } else {
                 response.setStatus(500);
                 map.put("code", "ERROR");
@@ -327,6 +335,100 @@ public class PayController {
         }
     }
 
+    @RequestMapping("/refund")
+    @ResponseBody
+    public String refund(@RequestParam(required = false) String transactionId, @RequestParam(required = false) String outTradeNo) {
+        try {
+            String outRefundNo = "wrj2024051101";
+            outTradeNo = "RECHAR2024050800001";
+            log.info("商户退款单号: {}", outRefundNo);
+
+            //退款商品
+            List<RefundGoodsDetail> list = new ArrayList<>();
+            RefundGoodsDetail refundGoodsDetail = new RefundGoodsDetail()
+                    //商户侧商品编码
+                    .setMerchant_goods_id("123")
+                    //商品名称
+                    .setGoods_name("IJPay 测试")
+                    //商品单价
+                    .setUnit_price(1)
+                    //商品退款金额
+                    .setRefund_amount(1)
+                    //商品退货数量
+                    .setRefund_quantity(1);
+            list.add(refundGoodsDetail);
+
+            RefundModel refundModel = new RefundModel()
+                    //商户退款单号
+                    .setOut_refund_no(outRefundNo)
+                    //退款原因
+                    .setReason("IJPay 测试退款")
+                    //回调地址
+                    .setNotify_url(wxPayProperties.getRefundNotify())
+                    //金额信息
+                    .setAmount(new RefundAmount().setRefund(1).setTotal(1).setCurrency("CNY"))
+                    //退款商品
+                    .setGoods_detail(list);
+
+            //商户订单号
+            if (StrUtil.isNotEmpty(transactionId)) {
+                refundModel.setTransaction_id(transactionId);
+            }
+            if (StrUtil.isNotEmpty(outTradeNo)) {
+                refundModel.setOut_trade_no(outTradeNo);
+            }
+            log.info("退款参数 {}", JSONUtil.toJsonStr(refundModel));
+            IJPayHttpResponse response = WxPayApi.v3(
+                    RequestMethodEnum.POST,
+                    WxDomainEnum.CHINA.toString(),
+                    BasePayApiEnum.REFUND.toString(),
+                    wxPayProperties.getMchId(),
+                    getSerialNumber(),
+                    null,
+                    wxPayProperties.getCertKeyPath(),
+                    JSONUtil.toJsonStr(refundModel)
+            );
+            // 根据证书序列号查询对应的证书来验证签名结果
+            boolean verifySignature = WxPayKit.verifySignature(response, wxPayProperties.getPlatFormPath());
+            log.info("verifySignature: {}", verifySignature);
+            log.info("退款响应 {}", response);
+
+            if (verifySignature) {
+                return response.getBody();
+            }
+        } catch (Exception e) {
+            log.error("系统异常", e);
+            return e.getMessage();
+        }
+        return null;
+    }
+
+    /**
+     * 退款通知
+     */
+    @RequestMapping(value = "/refundNotify", method = {RequestMethod.POST, RequestMethod.GET})
+    @ResponseBody
+    @ApiOperation("微信退款回调接口")
+    public String refundNotify(HttpServletRequest request) {
+        String xmlMsg = HttpKit.readData(request);
+        log.info("退款通知=" + xmlMsg);
+        Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
+
+        String returnCode = params.get("return_code");
+        // 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
+        if (WxPayKit.codeIsOk(returnCode)) {
+            String reqInfo = params.get("req_info");
+            String decryptData = WxPayKit.decryptData(reqInfo, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey());
+            log.info("退款通知解密后的数据=" + decryptData);
+            // 更新订单信息
+            // 发送通知等
+            Map<String, String> xml = new HashMap<String, String>(2);
+            xml.put("return_code", "SUCCESS");
+            xml.put("return_msg", "OK");
+            return WxPayKit.toXml(xml);
+        }
+        return null;
+    }
 
 
 

+ 1 - 1
nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/TOrderController.java

@@ -70,7 +70,7 @@ public class TOrderController {
     @RequestMapping(value = "wx/pay", method = RequestMethod.POST)
     public R pay(@RequestBody TOrder order) {
         try {
-            return R.ok(orderService.payOrder(order));
+            return orderService.payOrder(order);
         } catch (ServiceException s) {
             log.error(s.toString());
             return R.fail(s.getMessage());

+ 0 - 1
nightFragrance-admin/src/main/java/com/ylx/web/controller/massage/WxController.java

@@ -62,7 +62,6 @@ public class WxController extends BaseController {
     @Resource
     private TWxUserService wxUserService;
 
-
     @Resource
     private WxTokenService wxTokenService;
 

+ 3 - 1
nightFragrance-admin/src/main/resources/application-dev.yml

@@ -214,7 +214,9 @@ wx:
   # 商户秘钥
   mch-key: 39C9AIJ1RQKT3I8V16BYZ6LLBI0H30NB
   # 异步回调地址
-  notify-url: https://5c29a93.r7.cpolar.top/wx/pay/payNotify
+  notify-url: https://7a75cfa.r7.cpolar.top/wx/pay/payNotify
+  # 异步退款回调地址
+  refund-Notify: https://7a75cfa.r7.cpolar.top/wx/pay/refundNotify
   # 证书地址
   cert-path: D:/1675015090_20240424_cert/apiclient_cert.pem
   # 证书秘钥地址

+ 5 - 0
nightFragrance-common/src/main/java/com/ylx/common/config/WxPayConfig.java

@@ -39,6 +39,11 @@ public class WxPayConfig {
      */
     private String notifyUrl;
 
+    /**
+     * 退款异步回调地址
+     */
+    private String refundNotify;
+
     /**
      * 证书地址
      */

+ 1 - 1
nightFragrance-framework/src/main/java/com/ylx/framework/config/SecurityConfig.java

@@ -114,7 +114,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 .antMatchers("/login", "/register", "/captchaImage","/wx/login",
                         "/api/lbt/v1/getAll", "/api/js/v1/select", "/api/xiangmu/v1/wx/getAll", "/api/order/v1/getStatus",
                         "/api/xiangmu/v1/getByid", "/api/js/v1/wx/getByid","/api/js/v1/wx/select", "/api/recharge/v1/test",
-                        "/wx/pay/payNotify").permitAll()
+                        "/wx/pay/payNotify","/wx/pay/refundNotify").permitAll()
                 // 静态资源,可匿名访问
                 .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
                 .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()

+ 2 - 1
nightFragrance-massage/src/main/java/com/ylx/massage/enums/BillTypeEnum.java

@@ -19,7 +19,8 @@ public enum BillTypeEnum {
     RECHARGE(1, "充值"),
     BALANCE_PAYMENT(2, "余额支付"),
     INCOME(3, "技师收益"),
-    WITHDRAWAL(4, "技师提现");
+    WITHDRAWAL(4, "技师提现"),
+    WX_PAY(5, "微信支付");
 
 
 

+ 4 - 1
nightFragrance-massage/src/main/java/com/ylx/massage/service/TOrderService.java

@@ -2,6 +2,7 @@ package com.ylx.massage.service;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ylx.common.core.domain.R;
 import com.ylx.massage.domain.TOrder;
 
 
@@ -17,7 +18,7 @@ public interface TOrderService extends IService<TOrder> {
     /**
      * 支付订单
      */
-    public Boolean payOrder(TOrder order);
+    public R payOrder(TOrder order) throws Exception;
 
     /**
      * 拒绝订单
@@ -50,4 +51,6 @@ public interface TOrderService extends IService<TOrder> {
     public Page<TOrder> getAll(Page<TOrder>page, TOrder param);
 
     void takingOrders(TOrder order);
+
+    void payNotifyOrder(String outTradeNo);
 }

+ 4 - 0
nightFragrance-massage/src/main/java/com/ylx/massage/service/TRechargeService.java

@@ -5,6 +5,8 @@ import com.ylx.common.core.domain.R;
 import com.ylx.massage.domain.TRecharge;
 import com.ylx.massage.domain.TWxUser;
 
+import java.math.BigDecimal;
+
 /**
  * 充值记录表 服务类
  */
@@ -15,4 +17,6 @@ public interface TRechargeService extends IService<TRecharge> {
 
 
     TRecharge increaseAmount(String rechargeNo);
+
+    R getPay(String setOutTradeNo, BigDecimal amount, String openId,String description,String attach) throws Exception;
 }

+ 68 - 35
nightFragrance-massage/src/main/java/com/ylx/massage/service/impl/TOrderServiceImpl.java

@@ -10,6 +10,7 @@ import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ylx.common.constant.MassageConstants;
+import com.ylx.common.core.domain.R;
 import com.ylx.common.exception.ServiceException;
 import com.ylx.massage.domain.*;
 import com.ylx.massage.enums.BillTypeEnum;
@@ -45,6 +46,9 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
     @Resource
     private TWxUserService wxUserService;
 
+    @Resource
+    private TRechargeService rechargeService;
+
     @Resource
     private TXiangmuService xiangmuService;
 
@@ -136,6 +140,15 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
         return order;
     }
 
+
+    @Override
+    public void payNotifyOrder(String outTradeNo) {
+        TOrder orderNew = this.getByNo(outTradeNo);
+        TWxUser user = wxUserService.getByOpenId(orderNew.getcOpenId());
+        orderPayManage(user, orderNew);
+    }
+
+
     /**
      * 支付订单
      *
@@ -143,7 +156,7 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public Boolean payOrder(TOrder order) {
+    public R payOrder(TOrder order) throws Exception {
         // 根据orderid查询订单信息
         TOrder orderNew = getById(order.getcId());
         if (!orderNew.getnStatus().equals(OrderStatusEnum.WAIT_PAY.getCode())) {
@@ -156,6 +169,13 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
             }
         }
 
+        //判断支付方式
+        if (order.getPayType().equals(MassageConstants.INTEGER_ONE)) {
+            //微信支付
+            R resp = rechargeService.getPay(orderNew.getOrderNo(), orderNew.getTotalPrice(), orderNew.getcOpenId(), BillTypeEnum.WX_PAY.getInfo(),BillTypeEnum.WX_PAY.getCode().toString());
+            return resp;
+        }
+
         // 从对应账户扣款
         TWxUser user = wxUserService.getByOpenId(orderNew.getcOpenId());
         if (null == user) {
@@ -164,44 +184,57 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
         if (user.getdBalance().compareTo(orderNew.getTotalPrice()) < MassageConstants.INTEGER_ZERO) {
             throw new ServiceException("账户金额不够请充值");
         } else {
-            // 更新用户金额 及下单此时
-            TWxUser paramUser = new TWxUser();
-            paramUser.setcOpenid(user.getcOpenid());
+            orderPayManage(user, orderNew);
+            return R.ok();
+        }
+    }
+
+    private void orderPayManage(TWxUser user, TOrder orderNew) {
+        // 更新用户金额 及下单此时
+        TWxUser paramUser = new TWxUser();
+        paramUser.setcOpenid(user.getcOpenid());
+        if (!orderNew.getPayType().equals(MassageConstants.INTEGER_ONE)){
             paramUser.setdBalance(user.getdBalance().subtract(orderNew.getTotalPrice()));
-            paramUser.setdMoney(user.getdMoney().add(orderNew.getTotalPrice()));
-            paramUser.setnNum(user.getnNum() + MassageConstants.INTEGER_ZERO);
-            paramUser.setId(user.getId());
-            wxUserService.updateById(paramUser);
-            //增加消费记录
-            TConsumptionLog tConsumptionLog = new TConsumptionLog();
-            tConsumptionLog.setAmount(orderNew.getTotalPrice().negate());
-            tConsumptionLog.setBillNo(orderNew.getOrderNo());
-            tConsumptionLog.setOpenId(orderNew.getcOpenId());
+        }
+        paramUser.setdMoney(user.getdMoney().add(orderNew.getTotalPrice()));
+        paramUser.setnNum(user.getnNum() + MassageConstants.INTEGER_ZERO);
+        paramUser.setId(user.getId());
+        wxUserService.updateById(paramUser);
+        //增加消费记录
+        TConsumptionLog tConsumptionLog = new TConsumptionLog();
+        tConsumptionLog.setAmount(orderNew.getTotalPrice().negate());
+        tConsumptionLog.setBillNo(orderNew.getOrderNo());
+        tConsumptionLog.setOpenId(orderNew.getcOpenId());
+        if (!orderNew.getPayType().equals(MassageConstants.INTEGER_ONE)){
             tConsumptionLog.setBillType(BillTypeEnum.BALANCE_PAYMENT.getCode());
             tConsumptionLog.setNote("余额支付");
-            consumptionLogService.save(tConsumptionLog);
-            // 更新项目数据
-            JSONArray objects = orderNew.getcGoods();
-            objects.forEach(item -> {
-                UpdateWrapper<TXiangmu> wrapper = new UpdateWrapper<>();
-                // 获取参数
-                wrapper.lambda().eq(TXiangmu::getcId, ((JSONObject) item).getString("cId"));
-                // 设置数量
-                wrapper.setSql(" n_sale_number = n_sale_number + " + ((JSONObject) item).getInteger("number"));
-                xiangmuService.update(wrapper);
-            });
-            TOrder orderParam = new TOrder();
-            orderParam.setcId(orderNew.getcId());
-            orderParam.setnStatus(OrderStatusEnum.WAIT_JD.getCode());
-            //加钟的订单支付完直接服务中
-            if (StringUtils.isNotBlank(order.getParentNo())) {
-                orderParam.setnStatus(OrderStatusEnum.SERVICE.getCode());
-            }
-//            orderParam.setnStatus(OrderStatusEnum.SERVICE.getCode());
-            //更新及技师状态
-            updateJs(orderNew);
-            return updateById(orderParam);
+        }else{
+            tConsumptionLog.setBillType(BillTypeEnum.WX_PAY.getCode());
+            tConsumptionLog.setNote("微信支付");
         }
+
+        consumptionLogService.save(tConsumptionLog);
+        // 更新项目数据
+        JSONArray objects = orderNew.getcGoods();
+        objects.forEach(item -> {
+            UpdateWrapper<TXiangmu> wrapper = new UpdateWrapper<>();
+            // 获取参数
+            wrapper.lambda().eq(TXiangmu::getcId, ((JSONObject) item).getString("cId"));
+            // 设置数量
+            wrapper.setSql(" n_sale_number = n_sale_number + " + ((JSONObject) item).getInteger("number"));
+            xiangmuService.update(wrapper);
+        });
+        TOrder orderParam = new TOrder();
+        orderParam.setcId(orderNew.getcId());
+        orderParam.setnStatus(OrderStatusEnum.WAIT_JD.getCode());
+        //加钟的订单支付完直接服务中
+        if (StringUtils.isNotBlank(orderNew.getParentNo())) {
+            orderParam.setnStatus(OrderStatusEnum.SERVICE.getCode());
+        }
+//            orderParam.setnStatus(OrderStatusEnum.SERVICE.getCode());
+        //更新及技师状态
+        updateJs(orderNew);
+        updateById(orderParam);
     }
 
     /**

+ 101 - 1
nightFragrance-massage/src/main/java/com/ylx/massage/service/impl/TRechargeServiceImpl.java

@@ -1,9 +1,27 @@
 package com.ylx.massage.service.impl;
 
 
+import cn.hutool.core.date.DatePattern;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 
+import com.ijpay.core.IJPayHttpResponse;
+import com.ijpay.core.enums.RequestMethodEnum;
+import com.ijpay.core.kit.PayKit;
+import com.ijpay.core.kit.WxPayKit;
+import com.ijpay.core.utils.DateTimeZoneUtil;
+import com.ijpay.wxpay.WxPayApi;
+import com.ijpay.wxpay.enums.WxDomainEnum;
+import com.ijpay.wxpay.enums.v3.BasePayApiEnum;
+import com.ijpay.wxpay.model.v3.Amount;
+import com.ijpay.wxpay.model.v3.Payer;
+import com.ijpay.wxpay.model.v3.UnifiedOrderModel;
+import com.ylx.common.config.WxPayConfig;
+import com.ylx.common.core.domain.R;
 import com.ylx.common.exception.ServiceException;
 import com.ylx.common.utils.StringUtils;
 import com.ylx.massage.domain.TConsumptionLog;
@@ -16,14 +34,17 @@ import com.ylx.massage.service.TRechargeService;
 import com.ylx.massage.service.TWxUserService;
 import com.ylx.massage.utils.OrderNumberGenerator;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.security.cert.X509Certificate;
 import java.time.LocalDateTime;
+import java.util.Map;
 
-
+import static com.ylx.common.constant.HttpStatus.SUCCESS;
 
 
 /**
@@ -42,6 +63,11 @@ public class TRechargeServiceImpl extends ServiceImpl<TRechargeMapper, TRecharge
     @Resource
     private TConsumptionLogService consumptionLogService;
 
+    @Autowired
+    private WxPayConfig wxPayProperties;
+
+    String serialNo;
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public TRecharge recharge(TRecharge recharge) {
@@ -94,6 +120,80 @@ public class TRechargeServiceImpl extends ServiceImpl<TRechargeMapper, TRecharge
         return recharge;
     }
 
+    @Override
+    public R getPay(String setOutTradeNo, BigDecimal amount, String openId, String description, String attach) throws Exception {
+        String timeExpire = DateTimeZoneUtil.dateToTimeZone(System.currentTimeMillis() + 1000 * 60 * 3);
+        UnifiedOrderModel unifiedOrderModel = new UnifiedOrderModel()
+                .setAppid(wxPayProperties.getAppId())
+                .setMchid(wxPayProperties.getMchId())
+                //商品描述
+                .setDescription(description)
+                //订单号
+                .setOut_trade_no(setOutTradeNo)
+                //交易结束时间
+                .setTime_expire(timeExpire)
+                //附加数据
+                .setAttach(attach)
+                //通知地址异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。 公网域名必须为https,如果是走专线接入,使用专线NAT IP或者私有回调域名可使用http
+                //示例值:https://www.weixin.qq.com/wxpay/pay.php
+                .setNotify_url(wxPayProperties.getNotifyUrl())
+                //支付金额以分为单位
+                .setAmount(new Amount().setTotal(amount.multiply(new BigDecimal(100)).intValue()))
+                //交易人
+                .setPayer(new Payer().setOpenid(openId));
+
+        log.info("统一下单参数 {}", JSONUtil.toJsonStr(unifiedOrderModel));
+        IJPayHttpResponse response = WxPayApi.v3(
+                RequestMethodEnum.POST,
+                WxDomainEnum.CHINA.toString(),
+                BasePayApiEnum.JS_API_PAY.toString(),
+                wxPayProperties.getMchId(),
+                getSerialNumber(),
+                null,
+                wxPayProperties.getCertKeyPath(),
+                JSONUtil.toJsonStr(unifiedOrderModel)
+        );
+
+        log.info("统一下单响应 {}", response);
+        // 根据证书序列号查询对应的证书来验证签名结果
+        boolean verifySignature = WxPayKit.verifySignature(response, wxPayProperties.getPlatFormPath());
+        log.info("verifySignature: {}", verifySignature);
+        if (response.getStatus() == SUCCESS && verifySignature) {
+            String body = response.getBody();
+            JSONObject jsonObject = JSONUtil.parseObj(body);
+            String prepayId = jsonObject.getStr("prepay_id");
+            Map<String, String> map = WxPayKit.jsApiCreateSign(wxPayProperties.getAppId(), prepayId, wxPayProperties.getCertKeyPath());
+            log.info("唤起支付参数:{}", map);
+            return R.ok(JSONUtil.toJsonStr(map));
+        }
+        return R.ok(JSONUtil.toJsonStr(response));
+    }
+
+    private String getSerialNumber() {
+        if (StrUtil.isEmpty(serialNo)) {
+            // 获取证书序列号
+            X509Certificate certificate = PayKit.getCertificate(wxPayProperties.getCertPath());
+            if (null != certificate) {
+                serialNo = certificate.getSerialNumber().toString(16).toUpperCase();
+                // 提前两天检查证书是否有效
+                boolean isValid = PayKit.checkCertificateIsValid(certificate, wxPayProperties.getMchId(), -2);
+                log.info("证书是否可用 {} 证书有效期为 {}", isValid, DateUtil.format(certificate.getNotAfter(), DatePattern.NORM_DATETIME_PATTERN));
+            }
+//            System.out.println("输出证书信息:\n" + certificate.toString());
+//            // 输出关键信息,截取部分并进行标记
+//            System.out.println("证书序列号:" + certificate.getSerialNumber().toString(16));
+//            System.out.println("版本号:" + certificate.getVersion());
+//            System.out.println("签发者:" + certificate.getIssuerDN());
+//            System.out.println("有效起始日期:" + certificate.getNotBefore());
+//            System.out.println("有效终止日期:" + certificate.getNotAfter());
+//            System.out.println("主体名:" + certificate.getSubjectDN());
+//            System.out.println("签名算法:" + certificate.getSigAlgName());
+//            System.out.println("签名:" + certificate.getSignature().toString());
+        }
+        System.out.println("serialNo:" + serialNo);
+        return serialNo;
+    }
+
     private TRecharge getByRechargeNo(String rechargeNo) {
         return getOne(new LambdaQueryWrapper<TRecharge>().eq(TRecharge::getRechargeNo, rechargeNo).eq(TRecharge::getPayStatus, -1));
     }