Pārlūkot izejas kodu

feat(pay): 添加微信支付配置和相关功能

- 新增微信支付配置文件和证书
- 实现订单查询和退款相关功能- 添加支付回调处理和主动查询支付信息的方法
- 优化订单创建和处理逻辑
wzq 2 nedēļas atpakaļ
vecāks
revīzija
95011cf05a
12 mainītis faili ar 388 papildinājumiem un 35 dzēšanām
  1. 14 29
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/OrderServiceImpl.java
  2. 87 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/serverPay/TelAnonymousController.java
  3. 40 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/serverPay/WxPayConfiguration.java
  4. 55 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/serverPay/WxPayProperties.java
  5. 1 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/quartz/job/OrTeachingJobService.java
  6. 68 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/quartz/job/RefundJobService.java
  7. 46 0
      national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/quartz/job/SchoolOrderJobService.java
  8. BIN
      national-motion-module-system/national-motion-system-biz/src/main/resources/cert/apiclient_cert.p12
  9. 25 0
      national-motion-module-system/national-motion-system-biz/src/main/resources/cert/apiclient_cert.pem
  10. 28 0
      national-motion-module-system/national-motion-system-biz/src/main/resources/cert/apiclient_key.pem
  11. 9 0
      national-motion-module-system/national-motion-system-biz/src/main/resources/cert/pub_key.pem
  12. 15 6
      national-motion-module-system/national-motion-system-start/src/main/resources/application-dev.yml

+ 14 - 29
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/app/service/impl/OrderServiceImpl.java

@@ -38,8 +38,6 @@ import org.jeecg.modules.app.vo.PageOrdersVO;
 import org.jeecg.modules.app.vo.QueryOrderVerifyRecordsVO;
 import org.jeecg.modules.pay.config.WechatConstants;
 import org.jeecg.modules.pay.config.WechatUrlConstants;
-import org.jeecg.modules.pay.vo.NotifyRequest;
-import org.jeecg.modules.pay.vo.NotifyResponse;
 import org.jeecg.modules.redission.RedissonDelayQueue;
 import org.jeecg.modules.system.app.dto.receiptPaymentDetails.ReceiptPaymentDetailsInfoVo;
 import org.jeecg.modules.system.app.entity.*;
@@ -526,6 +524,7 @@ public class OrderServiceImpl implements IOrderService {
                     AppOrderProInfo proInfo = appOrderProInfoMapper.selectOne(Wrappers.<AppOrderProInfo>lambdaQuery()
                             .eq(AppOrderProInfo::getProductId, productId)
                             .in(AppOrderProInfo::getFamilyUserId, familyIds)
+                            .last("limit 1")
                     );
                     if (ObjectUtil.isNotEmpty(proInfo)) {
                         String userName = proInfo.getUserName();
@@ -537,6 +536,7 @@ public class OrderServiceImpl implements IOrderService {
 
                     // 查询库存
                     Integer stock = (Integer) redisTemplate.opsForValue().get(stockKey);
+                    log.info("学校场地预约商品库存数量:{}", stock);
                     // 缓存没有商品库存,查询数据库
                     if (stock == null) {
                         AppSitePriceRules product = appSitePriceRulesMapper.selectById(productId);
@@ -579,7 +579,6 @@ public class OrderServiceImpl implements IOrderService {
                             .setFamilyIds(createOrderForm.getFamilyIds())
                             .setOriginalPrice(priceRule.getSellingPrice())
                             .setAddressSiteId(appSite.getId())
-                            .setPrice(totalPrice)
                             .setCreateTime(new Date())
                             .setUpdateTime(new Date())
                             .setCreateBy(user.getId())
@@ -649,7 +648,7 @@ public class OrderServiceImpl implements IOrderService {
                         appOrderProInfo.setAddress(appSite.getName());
                         appOrderProInfo.setType(CommonConstant.ORDER_PRO_INFO_TYPE_1);
                         appOrderProInfo.setProductImage(appSite.getCover());
-                        appOrderProInfo.setOriginalPrice(priceRule.getOriginalPrice());
+                        appOrderProInfo.setOriginalPrice(priceRule.getSellingPrice());
                         appOrderProInfo.setPrice(priceRule.getSellingPrice());
                         appOrderProInfo.setOrderStatus(0);
                         appOrderProInfo.setQuantity(1);
@@ -889,11 +888,17 @@ public class OrderServiceImpl implements IOrderService {
                     //判断当前课程是否已下过单
                     List<AppOrderProInfo> infos = appOrderProInfoMapper.selectList(Wrappers.<AppOrderProInfo>lambdaQuery()
                             .eq(AppOrderProInfo::getProductId, appCourse.getId())
-                            .eq(AppOrderProInfo::getFamilyUserId, familyUserId)
-                            .eq(AppOrderProInfo::getOrFreePro, CommonConstant.STATUS_1_INT));
-                    if (ObjectUtil.isNotEmpty(infos)) {
+                            .eq(AppOrderProInfo::getFamilyUserId, familyUserId));
+                    List<AppOrderProInfo> infoList = infos.stream().filter(info -> Objects.equals(info.getOrFreePro(), CommonConstant.STATUS_0_INT)).collect(Collectors.toList());
+                    if (ObjectUtil.isNotEmpty(infoList)) {
                         throw new JeecgBootException("当前课程已下过单,请勿重复下单");
                     }
+                    if (Objects.equals(createOrderForm.getOrFreeOrder(), CommonConstant.STATUS_1_INT)){
+                        List<AppOrderProInfo> freeProList = infos.stream().filter(info -> Objects.equals(info.getOrFreePro(), CommonConstant.STATUS_0_INT)).collect(Collectors.toList());
+                        if (ObjectUtil.isNotEmpty(freeProList)) {
+                            throw new JeecgBootException("当前试听课课程已下过单,请勿重复下单");
+                        }
+                    }
                     AppOrderProInfo appOrderProInfo = new AppOrderProInfo();
                     appOrderProInfo.setProductId(createOrderForm.getProductIds());
                     appOrderProInfo.setProductName(appCourse.getName());
@@ -969,8 +974,6 @@ public class OrderServiceImpl implements IOrderService {
                     //团购优惠
                     appOrder.setTDiscounts(BigDecimal.ZERO);
                 }
-                //原订单总价
-                appOrder.setOriginalPrice(sumCoursePrice);
                 //使用人IDs
                 appOrder.setFamilyIds(createOrderForm.getFamilyIds());
 
@@ -1016,6 +1019,8 @@ public class OrderServiceImpl implements IOrderService {
             //计算总价 = 订单金额 + 保单金额
             totalPrice = totalPrice.add(sumPrice);
         }
+        //原订单总价
+        appOrder.setOriginalPrice(totalPrice);
         appOrder.setPrice(totalPrice);
         appOrderMapper.insert(appOrder);
         if (appOrder.getOrderType() == 5 && appOrder.getOrderOrFree() == 0) {
@@ -1598,26 +1603,6 @@ public class OrderServiceImpl implements IOrderService {
         return appOrder;
     }
 
-    @Override
-    public NotifyResponse orderNotify(NotifyRequest notifyRequestForm) {
-
-        //查询订单
-        AppOrder appOrder = appOrderMapper.selectOne(Wrappers.<AppOrder>lambdaQuery().eq(AppOrder::getOrderCode, notifyRequestForm.getOut_trade_no()).last("limit 1"));
-        if (ObjectUtil.isNotEmpty(appOrder)) {
-            appOrder
-                    .setPayId(notifyRequestForm.getAcc_trade_no())
-                    .setOrderStatus(2)
-                    .setPayStatus(2)
-                    .setPayTime(DateUtil.parse(notifyRequestForm.getTrade_time(), "yyyyMMddHHmmss"))
-                    .setCallbackStatus(1);
-        }
-
-        NotifyResponse notifyResponse = new NotifyResponse();
-        notifyResponse.setCode("SUCCESS").setMessage("执行成功");
-
-        return notifyResponse;
-    }
-
     @Override
     public String orderQuery(String orderCode) throws IOException {
 

+ 87 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/serverPay/TelAnonymousController.java

@@ -0,0 +1,87 @@
+package org.jeecg.modules.pay.serverPay;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/anonymous")
+@Slf4j
+public class TelAnonymousController
+{
+    
+//    @Autowired
+//    private WxPayService wxPayService;
+//
+//    //发起支付
+//    @PostMapping("/wx/order/create")
+//    public WxUnifiedOrderVo createOrder(){
+//        //发起V3 服务商发起支付
+//        EcommerceServiceImpl ecommerceService=new EcommerceServiceImpl(wxPayService);
+//     // 1. 创建请求对象
+//        PartnerTransactionsRequest orderRequest=new PartnerTransactionsRequest();
+//        // 2. 根据订单系统传过来的订单信息组装支付参数,创建支付订单
+//        //服务商应用ID
+//        orderRequest.setSpAppid(wxPayProperties.getAppId());
+//        //服务商户号
+//        orderRequest.setSpMchid(wxPayProperties.getMchId());
+//        //子商户号
+//        orderRequest.setSubMchid(dealerMerchant.getMchid());
+//        //子商户/二级商户应用ID
+//        orderRequest.setSubAppid(wxPayProperties.getSubAppId());
+//        //商品描述
+//        orderRequest.setDescription("商品描述");
+//        //商户订单号
+//        orderRequest.setOutTradeNo("订单id");
+//        //设置交易结束时间为24小时
+//        orderRequest.setTimeExpire(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").format(new Date()));
+//        //通知地址
+//        orderRequest.setNotifyUrl(wxPayProperties.getNotifyUrl());
+//        //订单金额
+//        PartnerTransactionsRequest.Amount amount = new PartnerTransactionsRequest.Amount();
+//        amount.setTotal(BaseWxPayRequest.yuanToFen("订单金额"));
+//        orderRequest.setAmount(amount);
+//        //支付者
+//        PartnerTransactionsRequest.Payer payer = new PartnerTransactionsRequest.Payer();
+//        payer.setSubOpenid("支付者的openid");
+//        orderRequest.setPayer(payer);
+//        //发起下单请求
+//        TransactionsResult partner = ecommerceService.partner(TradeTypeEnum.JSAPI, partnerTransactionsRequest);
+//        //生成签名
+//        WxUnifiedOrderVo tokenJSAPI = WechatSignUtil.getTokenJSAPI(wxPayProperties.getSubAppId(), partner.getPrepayId(), wxPayProperties.getPrivateKeyPath());
+//        tokenJSAPI.setOrderId(order.getId());
+//        return tokenJSAPI;
+//    }
+//
+//		//支付回调
+//	@ApiOperation(value = "支付回调通知处理")
+//    @PostMapping("/wx/notify/order")
+//    public void parseOrderNotifyResult(@RequestBody String resultData) throws WxPayException {
+//        log.info("回调:{}",resultData);
+//        EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
+//        PartnerTransactionsNotifyResult notifyResult = ecommerceService.parsePartnerNotifyResult(resultData, null);
+//        //此处解析到了回调信息
+//        log.info("回调:{}",notifyResult.getResult());
+//      //业务逻辑
+//    }
+//
+//    		//支付回调
+//	@ApiOperation(value = "主动查询支付信息")
+//    @PostMapping("/wx/order/select")
+//    public void wxSelectOrderStatus() throws WxPayException {
+//        //构建ecommerceService
+//        EcommerceServiceImpl ecommerceService = new EcommerceServiceImpl(wxPayService);
+//        //构建PartnerTransactionsQueryRequest对象
+//        PartnerTransactionsQueryRequest queryRequest = new PartnerTransactionsQueryRequest();
+//        queryRequest.setOutTradeNo("订单ID");
+//        queryRequest.setSpMchid("服务商ID");
+//        queryRequest.setSubMchid("特约商户ID");
+//        PartnerTransactionsResult partnerTransactionsResult=new PartnerTransactionsResult();
+//        try {
+//            //普通查询订单API
+//            partnerTransactionsResult = ecommerceService.queryPartnerTransactions(queryRequest);
+//        } catch (WxPayException e) {
+//            e.printStackTrace();
+//        }
+//    }
+}

+ 40 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/serverPay/WxPayConfiguration.java

@@ -0,0 +1,40 @@
+package org.jeecg.modules.pay.serverPay;
+//
+//
+//import lombok.AllArgsConstructor;
+//import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+//import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+//import org.springframework.boot.context.properties.EnableConfigurationProperties;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//
+///**
+// * @author Binary Wang
+// */
+//@Configuration
+//@ConditionalOnClass(WxPayService.class)
+//@EnableConfigurationProperties(WxPayProperties.class)
+//@AllArgsConstructor
+//public class WxPayConfiguration {
+//  private WxPayProperties properties;
+//
+//  @Bean("wxPayService")
+//  @ConditionalOnMissingBean
+//  public WxPayService wxService() {
+//    WxPayConfig payConfig = new WxPayConfig();
+//    payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId()));
+//    payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId()));
+//    payConfig.setApiV3Key(StringUtils.trimToNull(this.properties.getApiV3Key()));
+//    payConfig.setCertSerialNo(StringUtils.trimToNull(this.properties.getCertSerialNo()));
+//    payConfig.setPrivateKeyPath(StringUtils.trimToNull(this.properties.getPrivateKeyPath()));
+//    payConfig.setPrivateCertPath(StringUtils.trimToNull(this.properties.getPrivateCertPath()));
+//    payConfig.setNotifyUrl(StringUtils.trimToNull(this.properties.getNotifyUrl()));
+//    payConfig.setTradeType("JSAPI");
+//    payConfig.setSignType("MD5");
+//    WxPayService wxPayService = new WxPayServiceImpl();
+//    wxPayService.setConfig(payConfig);
+//    return wxPayService;
+//  }
+//
+//}
+

+ 55 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/pay/serverPay/WxPayProperties.java

@@ -0,0 +1,55 @@
+package org.jeecg.modules.pay.serverPay;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * wxpay pay properties.
+ *
+ * @author Binary Wang
+ */
+@Data
+@ConfigurationProperties(prefix = "wx.pay")
+public class WxPayProperties {
+  /**
+   * 设置微信公众号或者小程序等的appid
+   */
+  private String appId;
+
+  /**
+   * 设置微信公众号或者小程序等的appid
+   */
+  private String subAppId;
+
+  /**
+   * 微信支付商户号
+   */
+  private String mchId;
+
+  /**
+   * 微信支付商户V3密钥
+   */
+  private String apiV3Key;
+
+  /**
+   * 证书号
+   */
+  private String certSerialNo;
+
+  /**
+   * apiclient_key.pem证书文件的绝对路径或者以classpath:开头的类路径
+   */
+  private String privateKeyPath;
+
+  /**
+   * apiclient_cert.pem证书文件的绝对路径或者以classpath:开头的类路径
+   */
+  private String privateCertPath;
+
+  /**
+   * 回调地址
+   */
+  private String notifyUrl;
+
+}
+

+ 1 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/quartz/job/OrTeachingJobService.java

@@ -256,6 +256,7 @@ public class OrTeachingJobService {
                             .setCreateTime(new Date())
                             .setUpdateTime(new Date())
                             .setDeviceSerialNo(data.getDeviceSerial()));
+
                 }
             });
 

+ 68 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/quartz/job/RefundJobService.java

@@ -0,0 +1,68 @@
+package org.jeecg.modules.quartz.job;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.common.constant.CommonConstant;
+import org.jeecg.modules.system.app.entity.AppOrder;
+import org.jeecg.modules.system.app.entity.AppOrderProInfo;
+import org.jeecg.modules.system.app.service.IAppOrderProInfoService;
+import org.jeecg.modules.system.app.service.IAppOrderService;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalDate;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author wzq
+ * @date 2025/9/8 14:40
+ * @description
+ */
+@Slf4j
+@AllArgsConstructor
+@Component
+public class RefundJobService {
+
+    private final IAppOrderService appOrderService;
+
+    private final IAppOrderProInfoService appOrderProInfoService;
+
+    /**
+     *  @Description 检查已过期未使用的订单进行退款
+     */
+    @Scheduled(cron = "")
+    @Transactional(rollbackFor = Exception.class)
+    public void execute(){
+        log.info("开始执行检查已过期未使用的订单退款定时任务");
+        try {
+            List<AppOrder> refundOrderList = new ArrayList<>();
+            List<AppOrder> list = appOrderService.list(Wrappers.<AppOrder>lambdaQuery().eq(AppOrder::getPayStatus, 1).eq(AppOrder::getOrderStatus, CommonConstant.ORDER_STATUS_1));
+            for (AppOrder appOrder : list) {
+                List<AppOrderProInfo> orderProInfoList = appOrderProInfoService.list(Wrappers.lambdaQuery(AppOrderProInfo.class)
+                        .eq(AppOrderProInfo::getOrderId, appOrder.getId())
+                        .ne(AppOrderProInfo::getType, CommonConstant.ORDER_PRO_INFO_TYPE_6)
+                );
+                for (AppOrderProInfo appOrderProInfo : orderProInfoList) {
+                    if (appOrderProInfo.getOrderStatus() == 1) {
+                        // 订单未使用,判断是否已过期
+                        LocalDate expireTime = LocalDate.parse((appOrderProInfo.getExpireTime()));
+                        if (expireTime.isBefore(LocalDate.now())) {
+                            // 订单已过期
+                            refundOrderList.add(appOrder);
+                            continue;
+                        }
+                    }
+                }
+            }
+            //批量退款
+            for (AppOrder appOrder : refundOrderList) {
+                //todo 退款(分账回退)
+            }
+        }catch (Exception e){
+            log.error("检查已过期未使用的订单退款定时任务异常",e);
+        }
+    }
+}

+ 46 - 0
national-motion-module-system/national-motion-system-biz/src/main/java/org/jeecg/modules/quartz/job/SchoolOrderJobService.java

@@ -0,0 +1,46 @@
+package org.jeecg.modules.quartz.job;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.modules.system.app.entity.AppGmtInfo;
+import org.jeecg.modules.system.app.mapper.AppGmtInfoMapper;
+import org.jeecg.modules.system.app.service.IAppOrderProInfoService;
+import org.jeecg.modules.system.app.service.IAppOrderService;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+
+/**
+ * @author wzq
+ * @date 2025/9/8 15:18
+ * @description
+ */
+@Slf4j
+@AllArgsConstructor
+@Component
+public class SchoolOrderJobService {
+
+    private final IAppOrderService appOrderService;
+
+    private final IAppOrderProInfoService appOrderProInfoService;
+
+    @Resource
+    private AppGmtInfoMapper appGmtInfoMapper;
+
+    /**
+     *  @Description 查询学校开门记录表,匹配已开过门的订单,修改订单状态为已使用
+     */
+    @Scheduled(cron = "")
+    @Transactional(rollbackFor = Exception.class)
+    public void execute(){
+        log.info("开始执行检查学校开门记录定时任务");
+        try {
+
+        }catch (Exception e){
+            log.error("检查已过期未使用的订单退款定时任务异常",e);
+        }
+    }
+}

BIN
national-motion-module-system/national-motion-system-biz/src/main/resources/cert/apiclient_cert.p12


+ 25 - 0
national-motion-module-system/national-motion-system-biz/src/main/resources/cert/apiclient_cert.pem

@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEKzCCAxOgAwIBAgIUQ1h+Z6zzKt6Fsxj5PFb9wbI4jt4wDQYJKoZIhvcNAQEL
+BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
+FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
+Q0EwHhcNMjUwOTAzMDI1NDQ2WhcNMzAwOTAyMDI1NDQ2WjCBhDETMBEGA1UEAwwK
+MTcyNjM5NDQ4MTEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTAwLgYDVQQL
+DCfotLXpmLPop4LlsbHmuZbpkavpmLPkuqfkuJrmnInpmZDlhazlj7gxCzAJBgNV
+BAYTAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAOjNTpElk3jdTWYhhI2DbS6TDh0aGZmCzyrTzZUuXSljjchGWd1A
+wtzIOHtmwDAe3VHRhqoz1G9G4Ee1BzAoeDGI3NfEAPH9egYwBQnPxOIBy//FsYrw
+LvgKOrlhQkiUTR/ZQfa9Ay+KGLV8/BKzFckYuC7f9RqNd7/Nz5iuaFaekAdTjqZU
+n8EsTDMFWZ9yAZcA8n+yHnvNxKhrJYtguPudRnwojbYMRgcON5kPSLzBx8JWnB+y
+epI7dt3YeBdKsMDlSI5tc8/KkzflCSd/TqxcJhrQbZSLhiUawLYNMG7R3unxv+E5
+7u/JXNfDva4kNDgYZ3zAOJfGcaS+cQpORrcCAwEAAaOBuTCBtjAJBgNVHRMEAjAA
+MAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGEaHR0cDovL2V2
+Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIwRTUwREJD
+MDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFCNjU0MjJFMTJC
+MjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEBCwUAA4IBAQAj
+wIp02IkmFpfX1Icbwr9VE+eGKjwVNhp05BczqquZDWiVjmWytG1n1PjveueGd9zD
+Fa/VMhR+bqZdpzFcWsfkwYMm9hUX86cx/tHbgj+p2hYV+gWAdgkUg+6iW5LvNSBS
+u952qPud5Dmelx48sMWfgGEytGlDvAKnufvXWOSmk8pFCOXzpYuJPd5Z61pIQ0no
+esoVMnGSvUYCm8VPPjANXQfm4FPbmQS5iOyts8iP8eDuWIOOx0cBm71jFQm9gAvy
+1rFvjfqe/n0TAxXz7I4CIvTwUeduc65p+/p4me7jurtZPWJ2S5L8Pp+MAt7GE63e
+zl0Fzkd6MZUvH9zybyve
+-----END CERTIFICATE-----

+ 28 - 0
national-motion-module-system/national-motion-system-biz/src/main/resources/cert/apiclient_key.pem

@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDozU6RJZN43U1m
+IYSNg20ukw4dGhmZgs8q082VLl0pY43IRlndQMLcyDh7ZsAwHt1R0YaqM9RvRuBH
+tQcwKHgxiNzXxADx/XoGMAUJz8TiAcv/xbGK8C74Cjq5YUJIlE0f2UH2vQMvihi1
+fPwSsxXJGLgu3/UajXe/zc+YrmhWnpAHU46mVJ/BLEwzBVmfcgGXAPJ/sh57zcSo
+ayWLYLj7nUZ8KI22DEYHDjeZD0i8wcfCVpwfsnqSO3bd2HgXSrDA5UiObXPPypM3
+5Qknf06sXCYa0G2Ui4YlGsC2DTBu0d7p8b/hOe7vyVzXw72uJDQ4GGd8wDiXxnGk
+vnEKTka3AgMBAAECggEBAIeWm/3Znsy0R9IGD4fEViDcMUot218XWsWc2o3alRP4
+Eanln41HnLauPodQzvq33zs6B262BTJSW2ooO2mHCIoBJm7cj5hhg2J7MVQHmKnx
+VflAESnUveZlPtKdnNdc2JaGGO82ItbbXYzGoKHbgALBzPQwKDcw0d/6ZMCOQ+K+
+FrwLi+93HXlW6jGrPAgJ09kcim6efZOHvxFdZq8zMBFoZeiGnGj6G0peHI5PGb8V
+YKjBXiuxHs96w079R3eID1ViiNnGonm6M9AWT2mxMYMt/VPTr0TZUUet6DmKRs+0
+T3XuqoIunpju5RwWDN9CRdIysc5Ylo9U5rnLjBv6ygECgYEA+ipaz9mvqGo9+EQ2
+30VVGpY1W8r4oOZu8pSnmm9FXZFLVznnq0CB22F7fp1WLr3Yr0XoL2NOHZFVtzT8
+5ww9//o/OUgY3uVC9UoosUtSPowAZeldRc2JaFABusQw34/E96BVeuqTZgFxyvo2
+sAmtBfDXHCOjEmwZlaumKNxw3YECgYEA7jtIBTAE70nPTh7s3Kb81L2k0BT2JVki
+VZdBRPqj/mMxu6MEJ5UjzNhZEH3FXHxxC4Oe8v/r1opxs6ES5RnqQ+agtL5mUBn/
+B0327/96DKZWaKFCaoieCUamY/3jqguoIdK80kjGX6xuQISw5tCCJVrnEuxW+CmI
+XDrcOsTGsDcCgYBck+IJe1i7LZ4DS1M3KxREg4P5lVKPUNeMJCEmULlN2CAWhpJK
+WNP1mMy33YfwQkd3DZrQNqLI5GjhJNXWtzwWh8hv7VNu4U73MVt/yQ0Foo/fJw5i
+b57DIKCTOlmP0kelEAuyMi8cF7rBz/j/CoWiZi9k9Xc6sRCCyAP0qSeHgQKBgBpl
+2z8n6QQS67O+XYS9xDpWoVKlX/kXfWR6lDLuiwl/OF2QXL9+GS9zsbrQFPSAnY4n
+EY/fp+RoBt1etddJHdpUTe55QqERoF7Q1tIVPxLzw5NoexGO/eQNPhbKZVXMYN8O
+mPm8Mq8bTkQ779ZDuIgnIH/KTIDHKWL+6rRgZZvVAoGALZn4IpUhcRe7v/+pnYSQ
+6AhmUmTM3OdAA+XJDMuZzDM+5DNmuhZx4Y9sw/Xg1+kejR0W48aFNZ4xhSz89XC6
+rusYJfTda1iqqlaH453yJti98u2EkESJMdY2YlT7H75VjD/A1o1Fn3qnGStn9CKt
+DOukDtlOzybCJFsjG5uBwcg=
+-----END PRIVATE KEY-----

+ 9 - 0
national-motion-module-system/national-motion-system-biz/src/main/resources/cert/pub_key.pem

@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqSqeCl7ab3f/n44mdbuy
+pKwGXxrZM221aOed+5rjTUZzOaUqyKaLychg3u0vIOxQoghetQXnXmC+wApqgnx0
+odyXCoQk92a4zFO0NwYl3vJdVXTjVNDL23GQB9M6AKcSPpds2zMGonUuBWqFvg1O
+H1EQqrf1ak2GF8wewNwqO/bAL5yBOFHy7DWWCJqoThte+5leH6UGWLm/4fCZyjF6
+3umM5bNb4hSzZtq6M2Sy0VPVmZA76liDWcsk6gkVNqt7oXyHv8tD8+8t41tf6vxL
+oZaoNt4qxvXlkikVgOQ9Br87Gbe4r5hpuw+URjoXadGjYVWqJA0gCs6lcu3lRYU6
+6QIDAQAB
+-----END PUBLIC KEY-----

+ 15 - 6
national-motion-module-system/national-motion-system-start/src/main/resources/application-dev.yml

@@ -344,17 +344,26 @@ wx:
         msgDataFormat: JSON
 # 微信支付配置
   pay:
-    #服务商id
-    mchId: 12
+    #服务商微信支付商户号
+    mchId:
     #证书
     keyPath: apiclient_cert.p12
-    #服务商appid
-    appId: wxe12233
+    #服务商微信公众号或者小程序等的appid
+    appId:
     #支付回调通知地址
     notifyUrl:
     #服务商key的密钥
-    mchKey: 123444
-
+    mchKey:
+    #特约商户微信公众号或者小程序等的appid
+    subAppId:
+    #apiV3秘钥
+    apiV3Key:
+    #证书号
+    certSerialNo:
+    #apiclient_key.pem证书文件的绝对路径或者以classpath:开头的类路径
+    privateKeyPath: classpath:cert/apiclient_key.pem
+    #apiclient_cert.pem证书文件的绝对路径或者以classpath:开头的类路径
+    privateCertPath: classpath:cert/apiclient_cert.pem
 
 baidu:
   map: