diff --git a/njzscloud-svr/pom.xml b/njzscloud-svr/pom.xml
index 2ed0d55..f7afa26 100644
--- a/njzscloud-svr/pom.xml
+++ b/njzscloud-svr/pom.xml
@@ -105,7 +105,7 @@
com.github.binarywang
weixin-java-pay
- 4.7.0
+ 4.8.0
diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/order/service/OrderInfoService.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/order/service/OrderInfoService.java
index 2ec7e3a..cabeac3 100644
--- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/order/service/OrderInfoService.java
+++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/order/service/OrderInfoService.java
@@ -881,13 +881,14 @@ public class OrderInfoService extends ServiceImpl openId = new HashSet<>();
UserEntity orderUserEntity = userService.getById(orderInfo.getUserId());
param.setCfCompanyName(orderUserEntity.getNickname());
+ OrderGoodsEntity entity = orderGoodsService.getById(orderInfo.getGoodsId());
+ param.setGoodsName(entity.getGoodsName());
+ BizCompanyEntity companyEntity = bizCompanyService.getById(orderInfo.getTransCompanyId());
+ param.setCompanyName(companyEntity.getCompanyName());
+ param.setCreateTime(orderInfo.getCreateTime());
+ Set openId = new HashSet<>();
for (SysUserRoleEntity userRoleEntity : userIds) {
UserEntity userEntity = userService.getById(userRoleEntity.getUserId());
if (null != userEntity && !Strings.isNullOrEmpty(userEntity.getOpenid())) {
@@ -2203,6 +2204,45 @@ public class OrderInfoService extends ServiceImpl userIds = userRoleService.list(Wrappers.lambdaQuery(SysUserRoleEntity.class)
+ .eq(SysUserRoleEntity::getRoleId, roleEntity.getId()));
+ TemplateMessageParam param = new TemplateMessageParam();
+ param.setTempType(TempType.AUDIT_PENDING.getVal());
+ param.setSn(order.getSn());
+ UserEntity orderUserEntity = userService.getById(order.getUserId());
+ param.setCfCompanyName(orderUserEntity.getNickname());
+ OrderGoodsEntity entity = orderGoodsService.getById(order.getGoodsId());
+ param.setGoodsName(entity.getGoodsName());
+ BizCompanyEntity companyEntity = bizCompanyService.getById(order.getTransCompanyId());
+ param.setCompanyName(companyEntity.getCompanyName());
+ param.setCreateTime(order.getCreateTime());
+ Set openId = new HashSet<>();
+ for (SysUserRoleEntity userRoleEntity : userIds) {
+ UserEntity userEntity = userService.getById(userRoleEntity.getUserId());
+ if (null != userEntity && !Strings.isNullOrEmpty(userEntity.getOpenid())) {
+ if (openId.add(userEntity.getOpenid())) {
+ param.setUserId(userRoleEntity.getUserId());
+ log.info("转办发送审核通知模板消息,参数:{}", param);
+ wechatTemplateMessageService.sendTemplateMessage(param);
+ }
+ } else {
+ log.info("转办未查到用户信息:{}", userRoleEntity.getUserId());
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.error("通知失败", e);
+ }
} else {
throw Exceptions.clierr("未查询到装货地址");
}
diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/config/WxPayConfiguration.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/config/WxPayConfiguration.java
index b8f0648..c0eb1aa 100644
--- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/config/WxPayConfiguration.java
+++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/config/WxPayConfiguration.java
@@ -1,6 +1,7 @@
package com.njzscloud.supervisory.wxPay.config;
import com.github.binarywang.wxpay.config.WxPayConfig;
+import com.github.binarywang.wxpay.service.ProfitSharingService;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import lombok.AllArgsConstructor;
@@ -13,6 +14,9 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StreamUtils;
+/**
+ * @author ljw
+ */
@Configuration
@ConditionalOnClass(WxPayService.class)
@EnableConfigurationProperties(WxPayProperties.class)
@@ -50,4 +54,10 @@ public class WxPayConfiguration {
wxPayService.setConfig(config);
return wxPayService;
}
+
+ @Bean
+ @ConditionalOnMissingBean
+ public ProfitSharingService profitSharingService(WxPayService wxPayService) {
+ return wxPayService.getProfitSharingService();
+ }
}
diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/config/WxPayProperties.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/config/WxPayProperties.java
index bfc1c78..ce65225 100644
--- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/config/WxPayProperties.java
+++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/config/WxPayProperties.java
@@ -5,36 +5,47 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* 微信支付配置
+ * @author ljw
*/
@Data
@ConfigurationProperties(prefix = "wechat.pay")
public class WxPayProperties {
-
+
/**
- * 商户APPID
+ * 服务商商户APPID
*/
private String appId;
-
+
/**
- * 商户号
+ * 服务商商户号
*/
private String mchId;
-
+
/**
- * API密钥
+ * 收款方商户号
+ */
+ private String subMchId;
+
+ /**
+ * 分账方商户号
+ */
+ private String receiverMchId;
+
+ /**
+ * 服务商API密钥
*/
private String apiKey;
-
+
/**
- * 证书序列号
+ * 服务商证书序列号
*/
private String certSerialNo;
-
+
/**
- * 私钥文件路径
+ * 服务商私钥文件路径
*/
private String privateKeyPath;
-
+
/**
* 支付回调地址
*/
@@ -44,5 +55,5 @@ public class WxPayProperties {
* 退款回调地址
*/
private String refundNotifyUrl;
-
+
}
diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/contant/TemplateID.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/contant/TemplateID.java
index 514be0b..2c3e5ec 100644
--- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/contant/TemplateID.java
+++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/contant/TemplateID.java
@@ -6,7 +6,9 @@ public class TemplateID {
public static final String DRIVER_TEMP_ID = "IwHV1nWwu8pO8Ppntyd7KzzV5S00dOEjbsgAFhz9tJM";
- public static final String AUDIT_PENDING = "0SzJv9l51KTvgXvKhQOwifR5pegR3gC1o3IAY8NpEcE";
+ // public static final String AUDIT_PENDING = "0SzJv9l51KTvgXvKhQOwifR5pegR3gC1o3IAY8NpEcE";
+
+ public static final String AUDIT_PENDING = "KYt9UYPf104Xw_wIh6RwKCsK3x3Q6XO1yu9h-q2b3bI";
public static final String AUDIT_OK = "3peGD6joWVyZ7B29lfJH_gK0oRqharynt0sXlIHE4cg";
diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/controller/PaymentController.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/controller/PaymentController.java
index e2056a3..22085e4 100644
--- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/controller/PaymentController.java
+++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/controller/PaymentController.java
@@ -1,5 +1,6 @@
package com.njzscloud.supervisory.wxPay.controller;
+import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
@@ -8,6 +9,7 @@ import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
+import com.google.common.base.Strings;
import com.njzscloud.common.core.ex.ExceptionMsg;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.core.utils.R;
@@ -17,7 +19,11 @@ import com.njzscloud.common.wechat.WechatUtil;
import com.njzscloud.common.wechat.param.Code2SessionParam;
import com.njzscloud.common.wechat.result.Code2SessionResult;
import com.njzscloud.supervisory.device.service.DeviceInfoService;
+import com.njzscloud.supervisory.money.contant.MoneyChangeCategory;
+import com.njzscloud.supervisory.money.contant.MoneyDetailType;
import com.njzscloud.supervisory.money.contant.PayStatus;
+import com.njzscloud.supervisory.money.pojo.entity.MoneyChangeDetailEntity;
+import com.njzscloud.supervisory.money.service.MoneyChangeDetailService;
import com.njzscloud.supervisory.order.contant.MoneyWay;
import com.njzscloud.supervisory.order.contant.OrderStatus;
import com.njzscloud.supervisory.order.contant.PaymentStatus;
@@ -30,15 +36,10 @@ import com.njzscloud.supervisory.order.pojo.result.PaymentContextResult;
import com.njzscloud.supervisory.order.service.OrderExpenseItemsService;
import com.njzscloud.supervisory.order.service.OrderGoodsService;
import com.njzscloud.supervisory.order.service.OrderInfoService;
-import com.njzscloud.supervisory.money.service.MoneyChangeDetailService;
-import com.njzscloud.supervisory.money.contant.MoneyChangeCategory;
-import com.njzscloud.supervisory.money.contant.MoneyDetailType;
-import com.njzscloud.supervisory.money.pojo.entity.MoneyChangeDetailEntity;
import com.njzscloud.supervisory.wxPay.config.WxPayProperties;
import com.njzscloud.supervisory.wxPay.dto.RefundRequestDto;
import com.njzscloud.supervisory.wxPay.param.PaymentParam;
import com.njzscloud.supervisory.wxPay.service.PaymentService;
-import com.njzscloud.supervisory.wxPay.service.WeChatPayService;
import com.njzscloud.supervisory.wxPay.utils.RequestHolder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -54,6 +55,7 @@ import java.time.LocalDateTime;
/**
* 支付相关接口
* 使用微信支付官方SDK的生产级实现
+ *
* @author ljw
*/
@Slf4j
@@ -64,7 +66,6 @@ public class PaymentController {
private final OrderExpenseItemsService orderExpenseItemsService;
private final OrderInfoService orderInfoService;
- private final WeChatPayService wechatPayService;
private final WxPayService wxPayService;
private final WxPayProperties properties;
private final OrderGoodsService orderGoodsService;
@@ -88,10 +89,8 @@ public class PaymentController {
// 校验支付清单:id、名称、金额
boolean invalidItem = paymentParam.getItems().stream().anyMatch(it ->
- it == null
- || it.getId() == null
- || it.getExpenseItemName() == null || it.getExpenseItemName().length() == 0
- || it.getSettleMoney() == null || it.getSettleMoney().signum() < 0
+ it == null || it.getId() == null || Strings.isNullOrEmpty(it.getExpenseItemName()) || it.getSettleMoney() == null
+ || it.getSettleMoney().signum() < 0
);
if (invalidItem) {
throw Exceptions.clierr("支付清单项不合法(id/名称/金额)");
@@ -134,18 +133,25 @@ public class PaymentController {
String outTradeNo = generateOutTradeNo(ctx.getSn());
WxPayUnifiedOrderRequest wxRequest = new WxPayUnifiedOrderRequest();
wxRequest.setOutTradeNo(outTradeNo);
- wxRequest.setBody("订单支付-" + ctx.getSn());
+ wxRequest.setBody("订单支付-108-" + ctx.getSn());
// 转换为分
wxRequest.setTotalFee(ctx.getSettleMoney().multiply(new BigDecimal("100")).intValue());
- wxRequest.setOpenid(getCurrentUserOpenid(paymentParam.getWxCode()));
wxRequest.setTradeType("JSAPI");
wxRequest.setSpbillCreateIp(RequestHolder.getClientIP());
// 需要配置实际的回调地址
wxRequest.setNotifyUrl(properties.getNotifyUrl());
+ // 设置分账标识为Y,开启分账功能
+ wxRequest.setProfitSharing("Y");
+ // 在服务商模式下,设置收款方子商户号
+ wxRequest.setSubMchId(properties.getSubMchId());
+ wxRequest.setSubOpenid(getCurrentUserOpenid(paymentParam.getWxCode()));
- // 调用微信支付服务
- WxPayMpOrderResult result = (WxPayMpOrderResult) wechatPayService.createJsapiOrder(wxRequest);
-
+ // 调用微信支付服务(使用服务商WxPayService,因为需要分账权限验证)
+ log.info("开始创建微信支付JSAPI订单,使用服务商WxPayService,商户号:{},收款方商户号:{},分账商户号:{}",
+ properties.getMchId(), properties.getSubMchId(), properties.getReceiverMchId());
+ log.info("开始创建微信支付JSAPI订单,入参为:{}", JSON.toJSONString(wxRequest));
+ WxPayMpOrderResult result = wxPayService.createOrder(wxRequest);
+ log.info("创建微信支付JSAPI订单,返回结果为:{}", JSON.toJSONString(result));
// 更新订单状态为待支付
orderInfoService.lambdaUpdate()
.eq(OrderInfoEntity::getId, paymentParam.getOrderId())
@@ -188,17 +194,23 @@ public class PaymentController {
}
/**
- * 获取当前用户openid
+ * 获取当前用户openid(使用小程序APPID)
*/
public String getCurrentUserOpenid(String wxCode) {
- // 调用微信API获取openId和unionId
- Code2SessionResult sessionResult = WechatUtil.code2Session(new Code2SessionParam().setJs_code(wxCode));
+ // 使用小程序APPID(子商户)来获取openid,因为前端wx.login()使用的是子商户APPID
+ Code2SessionParam param = new Code2SessionParam()
+ .setJs_code(wxCode);
+
+ log.info("获取openid,使用小程序APPID,code:{}", wxCode);
+
+ Code2SessionResult sessionResult = WechatUtil.code2Session(param);
Integer errcode = sessionResult.getErrcode();
if (errcode != null && errcode != 0) {
log.error("微信登录失败, errcode: {}, errmsg: {}", errcode, sessionResult.getErrmsg());
throw new UserLoginException(ExceptionMsg.CLI_ERR_MSG, "微信登录失败");
}
+ log.info("获取openid成功:{}", sessionResult.getOpenid());
return sessionResult.getOpenid();
}
@@ -234,6 +246,55 @@ public class PaymentController {
return null;
}
+ /**
+ * 根据订单ID获取微信交易ID
+ */
+ private String getTransactionIdByOrderId(Long orderId) {
+ log.debug("开始获取交易ID,订单ID:{}", orderId);
+
+ // 从资金明细的扩展信息中获取交易ID
+ MoneyChangeDetailEntity detail = moneyChangeDetailService.getByOrderIdAndType(orderId, MoneyDetailType.WX);
+
+ if (detail == null) {
+ log.warn("未找到订单的资金明细记录,订单ID:{}", orderId);
+ return null;
+ }
+
+ log.debug("找到资金明细记录,ID:{},扩展信息:{}", detail.getId(), detail.getExtendInfo());
+
+ if (detail.getExtendInfo() == null) {
+ log.warn("资金明细扩展信息为空,订单ID:{}", orderId);
+ return null;
+ }
+
+ // 解析JSON格式的扩展信息获取transactionId
+ try {
+ // 使用简单的字符串解析,实际项目中建议使用JSON库
+ String extendInfo = detail.getExtendInfo();
+ log.debug("解析扩展信息:{}", extendInfo);
+
+ if (extendInfo.contains("transactionId")) {
+ int startIndex = extendInfo.indexOf("\"transactionId\":\"") + 16;
+ int endIndex = extendInfo.indexOf("\"", startIndex);
+ if (startIndex > 15 && endIndex > startIndex) {
+ String transactionId = extendInfo.substring(startIndex, endIndex);
+ log.info("成功获取交易ID:{},订单ID:{}", transactionId, orderId);
+ return transactionId;
+ } else {
+ log.warn("交易ID格式不正确,startIndex:{},endIndex:{},订单ID:{}", startIndex, endIndex, orderId);
+ }
+ } else {
+ log.warn("扩展信息中不包含transactionId,订单ID:{}", orderId);
+ }
+ } catch (Exception e) {
+ log.error("解析交易ID异常,订单ID:{},扩展信息:{},错误:{}", orderId, detail.getExtendInfo(), e.getMessage(), e);
+ }
+
+ log.warn("获取交易ID失败,订单ID:{}", orderId);
+ return null;
+ }
+
+
/**
* 微信支付回调接口
*/
@@ -268,6 +329,26 @@ public class PaymentController {
log.info("支付回调:资金明细状态更新为已支付,订单ID:{}", entity.getId());
}
+ // 执行分账
+ log.info("支付回调:开始执行分账,订单ID:{},支付金额:{}元,交易ID:{}",
+ entity.getId(), entity.getSettleMoney(), notifyResult.getTransactionId());
+ try {
+ paymentService.profitSharingAsync(entity.getId(), notifyResult.getTransactionId(), entity.getSettleMoney());
+ log.info("支付回调:分账成功,订单ID:{}", entity.getId());
+ } catch (Exception e) {
+ log.error("支付回调:分账失败,订单ID:{},支付金额:{}元,交易ID:{},错误:{}",
+ entity.getId(), entity.getSettleMoney(), notifyResult.getTransactionId(), e.getMessage(), e);
+ // 分账失败不影响支付成功,但需要记录
+ }
+
+ // 保存交易ID到资金明细的扩展信息中
+ if (payDetail != null) {
+ // 将交易ID保存到扩展信息中,格式:{"transactionId":"xxx"}
+ String extendInfo = String.format("{\"transactionId\":\"%s\"}", notifyResult.getTransactionId());
+ payDetail.setExtendInfo(extendInfo);
+ moneyChangeDetailService.updateById(payDetail);
+ }
+
if (out) {
DeviceInfoService.open(orderSn);
}
@@ -321,9 +402,64 @@ public class PaymentController {
throw Exceptions.clierr("退款金额总和不能超过订单已结算金额");
}
refundRequest.setOutTradeNo(orderInfo.getOutTradeNo());
+
+ // 如果是微信支付,需要先执行分账回退
+ if (SettlementWay.CASH.getVal().equals(ctx.getOiPayWay())) {
+ log.info("退款处理:开始分账回退,订单ID:{},退款金额:{}元,支付方式:{}",
+ orderInfo.getId(), refundRequest.getRefundAmount(), ctx.getOiPayWay());
+ try {
+ paymentService.profitSharingReturn(orderInfo.getId(), refundRequest.getRefundAmount());
+ log.info("退款前分账回退成功,订单ID:{},退款金额:{}", orderInfo.getId(), refundRequest.getRefundAmount());
+ } catch (Exception e) {
+ log.error("退款前分账回退失败,订单ID:{},退款金额:{}元,错误:{}",
+ orderInfo.getId(), refundRequest.getRefundAmount(), e.getMessage(), e);
+ throw Exceptions.clierr("分账回退失败,无法退款");
+ }
+ }
+
paymentService.refund(refundRequest, ctx, Boolean.FALSE);
- if (SettlementWay.MONTH.getVal().equals(ctx.getOiPayWay()) || SettlementWay.BALANCE.getVal().equals(ctx.getOiPayWay())) {
+
+ // 微信支付的退款处理
+ if (SettlementWay.CASH.getVal().equals(ctx.getOiPayWay())) {
+ // 计算剩余金额 = 原结算金额 - 已退款金额 - 本次退款金额
+ BigDecimal remainingAmount = ctx.getSettleMoney()
+ .subtract(ctx.getRefundMoney() == null ? BigDecimal.ZERO : ctx.getRefundMoney())
+ .subtract(refundRequest.getRefundAmount());
+
+ // 如果剩余金额大于0,说明是部分退款,需要重新分账
+ if (remainingAmount.compareTo(BigDecimal.ZERO) > 0) {
+ log.info("部分退款:检测到剩余金额{}元,开始重新分账,订单ID:{}", remainingAmount, orderInfo.getId());
+ try {
+ // 查询原始交易ID
+ String transactionId = getTransactionIdByOrderId(orderInfo.getId());
+ if (transactionId != null) {
+ log.info("部分退款:获取到交易ID:{},开始重新分账", transactionId);
+ paymentService.reProfitSharing(orderInfo.getId(), transactionId, remainingAmount);
+ log.info("部分退款后重新分账成功,订单ID:{},剩余金额:{}元,交易ID:{}",
+ orderInfo.getId(), remainingAmount, transactionId);
+ } else {
+ log.warn("部分退款后无法获取交易ID,跳过重新分账,订单ID:{}", orderInfo.getId());
+ log.warn("请检查资金明细表中是否正确存储了交易ID信息");
+ }
+ } catch (Exception e) {
+ log.error("部分退款后重新分账失败,订单ID:{},剩余金额:{}元,错误:{}",
+ orderInfo.getId(), remainingAmount, e.getMessage(), e);
+ // 重新分账失败不影响退款成功,但需要记录
+ }
+ } else {
+ log.info("部分退款:剩余金额为0,无需重新分账,订单ID:{}", orderInfo.getId());
+ }
+
// 更新订单状态为已退款
+ orderInfoService.lambdaUpdate()
+ .eq(OrderInfoEntity::getId, refundRequest.getOrderId())
+ .set(OrderInfoEntity::getPaymentStatus, PaymentStatus.YiTuiKuan)
+ .set(OrderInfoEntity::getRefundMoney,
+ (ctx.getRefundMoney() == null ? BigDecimal.ZERO : ctx.getRefundMoney()).add(refundRequest.getRefundAmount()))
+ .set(OrderInfoEntity::getRefundTime, LocalDateTime.now())
+ .update();
+ } else if (SettlementWay.MONTH.getVal().equals(ctx.getOiPayWay()) || SettlementWay.BALANCE.getVal().equals(ctx.getOiPayWay())) {
+ // 月结和余额支付的退款处理
orderInfoService.lambdaUpdate()
.eq(OrderInfoEntity::getId, refundRequest.getOrderId())
.set(OrderInfoEntity::getPaymentStatus, PaymentStatus.YiTuiKuan)
@@ -380,4 +516,54 @@ public class PaymentController {
return WxPayNotifyResponse.fail(e.getMessage());
}
}
+
+ /**
+ * 发起支付(使用生产级微信支付SDK)
+ */
+ @PostMapping("/payTest")
+ @Transactional(rollbackFor = Exception.class)
+ public void payTest() {
+ // 构建微信支付请求
+ WxPayUnifiedOrderRequest wxRequest = new WxPayUnifiedOrderRequest();
+ wxRequest.setOutTradeNo("53456346xdfgsdfg");
+ wxRequest.setBody("订单支付-108-");
+ // 转换为分
+ BigDecimal settleMoney = new BigDecimal("0.01");
+ wxRequest.setTotalFee(settleMoney.multiply(new BigDecimal("100")).intValue());
+ // wxRequest.setOpenid("oaepd1zd7umBcg0v-dnVAN4urVc0");
+ wxRequest.setSubOpenid("oaepd1zd7umBcg0v-dnVAN4urVc0");
+ wxRequest.setTradeType("JSAPI");
+ wxRequest.setSpbillCreateIp(RequestHolder.getClientIP());
+ // 需要配置实际的回调地址
+ wxRequest.setNotifyUrl(properties.getNotifyUrl());
+ // 设置分账标识为Y,开启分账功能
+ wxRequest.setProfitSharing("Y");
+ // 在服务商模式下,设置子商户号
+ wxRequest.setSubMchId(properties.getSubMchId());
+
+ // 调用微信支付服务(使用服务商WxPayService,因为需要分账权限验证)
+ try {
+ log.info("测试方法:开始创建微信支付JSAPI订单,使用服务商WxPayService,商户号:{},收款方商户号:{},分账商户号:{}",
+ properties.getMchId(), properties.getSubMchId(), properties.getReceiverMchId());
+ log.info("测试方法:开始创建微信支付JSAPI订单,入参为:{}", JSON.toJSONString(wxRequest));
+ WxPayMpOrderResult result = wxPayService.createOrder(wxRequest);
+ log.info("测试方法:创建微信支付JSAPI订单,返回结果为:{}", JSON.toJSONString(result));
+ } catch (WxPayException e) {
+ log.error("测试方法:创建订单失败", e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 退款测试
+ */
+ @PostMapping("/refundTest")
+ @Transactional(rollbackFor = Exception.class)
+ public void refundTest(@RequestBody RefundRequestDto refundRequest) {
+ log.info("测试方法:开始微信退款,使用服务商WxPayService,商户号:{},收款方商户号:{},分账商户号:{}",
+ properties.getMchId(), properties.getSubMchId(), properties.getReceiverMchId());
+ PaymentContextResult ctx = orderInfoService.paymentContext(refundRequest.getOrderId());
+ paymentService.refund(refundRequest, ctx, Boolean.FALSE);
+ }
+
}
diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/param/TemplateMessageParam.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/param/TemplateMessageParam.java
index 99be810..7672fe4 100644
--- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/param/TemplateMessageParam.java
+++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/param/TemplateMessageParam.java
@@ -5,6 +5,8 @@ import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
+import java.time.LocalDateTime;
+
/**
* @author ljw
*/
@@ -59,4 +61,14 @@ public class TemplateMessageParam {
*/
private String licensePlate;
+ /**
+ * 清运公司
+ */
+ private String companyName;
+
+ /**
+ * 时间
+ */
+ private LocalDateTime createTime;
+
}
diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/PaymentService.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/PaymentService.java
index 8a5a19f..99af2b7 100644
--- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/PaymentService.java
+++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/PaymentService.java
@@ -1,8 +1,11 @@
package com.njzscloud.supervisory.wxPay.service;
+import com.github.binarywang.wxpay.exception.WxPayException;
import com.njzscloud.supervisory.order.pojo.result.PaymentContextResult;
import com.njzscloud.supervisory.wxPay.dto.RefundRequestDto;
+import java.math.BigDecimal;
+
/**
* 退款服务接口
* @author ljw
@@ -14,4 +17,23 @@ public interface PaymentService {
*/
void refund(RefundRequestDto refundRequest, PaymentContextResult ctx, Boolean isChange);
+ /**
+ * 执行分账(支付成功后)
+ */
+ void profitSharing(Long orderId, String transactionId, BigDecimal totalAmount) throws WxPayException;
+
+ /**
+ * 分账回退
+ */
+ void profitSharingReturn(Long orderId, BigDecimal refundAmount) throws WxPayException;
+
+ /**
+ * 重新分账剩余金额(用于部分退款后)
+ */
+ void reProfitSharing(Long orderId, String transactionId, BigDecimal remainingAmount) throws WxPayException;
+
+ /**
+ * 执行分账(支付成功后)
+ */
+ void profitSharingAsync(Long orderId, String transactionId, BigDecimal totalAmount) throws WxPayException;
}
diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/PaymentServiceImpl.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/PaymentServiceImpl.java
index 56f1c0b..a43bc63 100644
--- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/PaymentServiceImpl.java
+++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/PaymentServiceImpl.java
@@ -1,6 +1,14 @@
package com.njzscloud.supervisory.wxPay.service.impl;
import cn.hutool.core.util.IdUtil;
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONObject;
+import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingRequest;
+import com.github.binarywang.wxpay.bean.profitsharing.request.ProfitSharingReturnRequest;
+import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingResult;
+import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingReturnResult;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.ProfitSharingService;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.supervisory.money.contant.MoneyChangeCategory;
import com.njzscloud.supervisory.money.contant.MoneyDetailType;
@@ -17,12 +25,15 @@ import com.njzscloud.supervisory.wxPay.service.PaymentService;
import com.njzscloud.supervisory.wxPay.service.WeChatPayService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
+import java.math.RoundingMode;
/**
* 退款服务实现类
+ *
* @author ljw
*/
@Slf4j
@@ -30,11 +41,100 @@ import java.math.BigDecimal;
@RequiredArgsConstructor
public class PaymentServiceImpl implements PaymentService {
+ // 分账比例:千分之一
+ private static final int PROFIT_SHARING_RATIO = 1;
+ private static final int PROFIT_SHARING_BASE = 1000;
+
private final WxPayProperties properties;
private final WeChatPayService wechatPayService;
+ private final ProfitSharingService profitSharingService;
private final MoneyAccountService moneyAccountService;
private final MoneyChangeDetailService moneyChangeDetailService;
+ /**
+ * 执行分账(千分之一给特约商户)
+ */
+ @Override
+ public void profitSharing(Long orderId, String transactionId, BigDecimal totalAmount) throws WxPayException {
+ log.info("========== 开始执行分账 ==========");
+ log.info("分账参数 - 订单ID:{},交易ID:{},总金额:{}元", orderId, transactionId, totalAmount);
+
+ // 计算分账金额:总金额 * (1/1000)
+ BigDecimal sharingAmount = totalAmount.multiply(BigDecimal.valueOf(PROFIT_SHARING_RATIO))
+ .divide(BigDecimal.valueOf(PROFIT_SHARING_BASE), 2, RoundingMode.DOWN);
+
+ log.info("分账金额计算 - 总金额:{}元,分账比例:{}/{},分账金额:{}元",
+ totalAmount, PROFIT_SHARING_RATIO, PROFIT_SHARING_BASE, sharingAmount);
+
+ if (sharingAmount.compareTo(BigDecimal.ZERO) <= 0) {
+ log.info("分账金额为0,跳过分账,订单ID:{}", orderId);
+ log.info("========== 分账跳过结束 ==========");
+ return;
+ }
+
+ log.info("分账商户信息 - 特约商户:{},收款商户:{},分账商户:{}", properties.getMchId(), properties.getSubMchId(),
+ properties.getReceiverMchId());
+
+ // 构建分账请求
+ ProfitSharingRequest request = new ProfitSharingRequest();
+ request.setTransactionId(transactionId);
+ String outOrderNo = "PS_" + orderId + "_" + System.currentTimeMillis();
+ request.setOutOrderNo(outOrderNo);
+
+ log.info("分账请求构建 - 分账单号:{},交易ID:{}", outOrderNo, transactionId);
+
+ // 创建分账接收方JSON字符串
+ // 仅分账给 receiver-mch-id(1649452354),比例为千分之一;收款方为 subMchId(不作为接收方再次出现)
+ StringBuilder receiversJson = new StringBuilder("[");
+ int receiverMoney = sharingAmount.multiply(BigDecimal.valueOf(100)).intValue();
+ receiversJson.append("{\"type\":\"MERCHANT_ID\",\"account\":\"").append(properties.getReceiverMchId()).append("\",")
+ .append("\"amount\":").append(receiverMoney)
+ .append(",\"description\":\"分账商户108\"}");
+ receiversJson.append("]");
+ request.setReceivers(receiversJson.toString());
+ // 指定分账发生在收款子商户下
+ request.setSubMchId(properties.getSubMchId());
+
+ // 计算子商户留存金额(用于日志)
+ BigDecimal subMerchantAmount = totalAmount.subtract(sharingAmount);
+
+ log.info("分账接收方配置 - 特约商户分账:{}元({}分),子商户(留存):{}元",
+ sharingAmount, receiverMoney,
+ subMerchantAmount);
+ log.info("分账接收方JSON:{}", receiversJson);
+
+ try {
+ // 调用分账接口
+ log.info("调用微信分账接口...");
+ ProfitSharingResult result = profitSharingService.profitSharing(request);
+
+ log.info("分账成功!订单ID:{},总金额:{}元", orderId, totalAmount);
+ log.info("分账详情 - 特约商户分账:{}元,子商户分账:{}元", sharingAmount, subMerchantAmount);
+ log.info("分账结果 - 分账单号:{},微信返回状态:{}", result.getOutOrderNo(), result);
+
+ // 将分账单号保存到资金明细的扩展信息中
+ try {
+ MoneyChangeDetailEntity payDetail = moneyChangeDetailService.getByOrderIdAndType(orderId, MoneyDetailType.WX);
+ if (payDetail != null && payDetail.getExtendInfo() != null) {
+ // 解析现有的extendInfo,添加分账单号
+ JSONObject extendJson = JSON.parseObject(payDetail.getExtendInfo());
+ extendJson.put("profitSharingOrderNo", outOrderNo);
+ payDetail.setExtendInfo(extendJson.toJSONString());
+ moneyChangeDetailService.updateById(payDetail);
+ log.info("分账单号已保存到资金明细,订单ID:{},分账单号:{}", orderId, outOrderNo);
+ }
+ } catch (Exception e) {
+ log.warn("保存分账单号到资金明细失败,订单ID:{},分账单号:{},错误:{}", orderId, outOrderNo, e.getMessage());
+ }
+
+ log.info("========== 分账执行成功 ==========");
+ } catch (WxPayException e) {
+ log.error("分账执行失败!订单ID:{},错误信息:{}", orderId, e.getMessage(), e);
+ log.error("失败详情 - 交易ID:{},分账单号:{},金额:{}元", transactionId, outOrderNo, totalAmount);
+ throw e;
+ }
+ }
+
/**
* 申请退款
*/
@@ -46,7 +146,7 @@ public class PaymentServiceImpl implements PaymentService {
// 根据支付方式处理退款
if (SettlementWay.CASH.getVal().equals(ctx.getOiPayWay())) {
- //微信退款 生成退款单号
+ // 微信退款 生成退款单号
String orderSn = IdUtil.getSnowflake(0, 0).nextIdStr();
// 微信退全款
int money = ctx.getSettleMoney().multiply(new BigDecimal("100")).intValue();
@@ -124,5 +224,174 @@ public class PaymentServiceImpl implements PaymentService {
log.info("公司账户余额恢复成功,账户ID:{},恢复金额:{}", ctx.getCompanyAccountId(), refundAmount);
}
+ /**
+ * 分账回退
+ */
+ @Override
+ public void profitSharingReturn(Long orderId, BigDecimal refundAmount) throws WxPayException {
+ log.info("========== 开始执行分账回退 ==========");
+ log.info("分账回退参数 - 订单ID:{},退款金额:{}元", orderId, refundAmount);
+
+ // 计算需要回退的分账金额:退款金额 * (1/1000)
+ BigDecimal returnAmount = refundAmount.multiply(BigDecimal.valueOf(PROFIT_SHARING_RATIO))
+ .divide(BigDecimal.valueOf(PROFIT_SHARING_BASE), 2, RoundingMode.DOWN);
+
+ log.info("分账回退金额计算 - 退款金额:{}元,回退比例:{}/{},回退金额:{}元",
+ refundAmount, PROFIT_SHARING_RATIO, PROFIT_SHARING_BASE, returnAmount);
+
+ if (returnAmount.compareTo(BigDecimal.ZERO) <= 0) {
+ log.info("分账回退金额为0,跳过分账回退,订单ID:{}", orderId);
+ log.info("========== 分账回退跳过结束 ==========");
+ return;
+ }
+
+ log.info("分账回退商户信息 - 回退商户:{},回退类型:MERCHANT_ID", properties.getReceiverMchId());
+
+ // 构建分账回退请求
+ ProfitSharingReturnRequest request = new ProfitSharingReturnRequest();
+ String outReturnNo = "PSR_" + orderId + "_" + System.currentTimeMillis();
+ request.setOutReturnNo(outReturnNo);
+ request.setReturnAccountType("MERCHANT_ID");
+ // 从分账商户回退
+ request.setReturnAccount(properties.getReceiverMchId());
+ request.setDescription("订单退款分账回退108");
+ // 设置回退金额(分)
+ int returnMoney = returnAmount.multiply(BigDecimal.valueOf(100)).intValue();
+ request.setReturnAmount(returnMoney);
+ // 指定回退操作针对的子商户(收款方)
+ request.setSubMchId(properties.getSubMchId());
+
+ // 从资金明细中获取原始分账单号
+ String outOrderNo = null;
+ try {
+ MoneyChangeDetailEntity payDetail = moneyChangeDetailService.getByOrderIdAndType(orderId, MoneyDetailType.WX);
+ if (payDetail != null && payDetail.getExtendInfo() != null) {
+ JSONObject extendJson = JSON.parseObject(payDetail.getExtendInfo());
+ outOrderNo = extendJson.getString("profitSharingOrderNo");
+ log.info("从资金明细中获取到分账单号:{},订单ID:{}", outOrderNo, orderId);
+ }
+ } catch (Exception e) {
+ log.warn("从资金明细中获取分账单号失败,订单ID:{},错误:{}", orderId, e.getMessage());
+ }
+
+ // 如果没有找到分账单号,使用模糊匹配(不推荐,可能会导致回退失败)
+ if (outOrderNo == null) {
+ outOrderNo = "PS_" + orderId + "_*";
+ log.warn("未找到分账单号,使用模糊匹配:{},订单ID:{}", outOrderNo, orderId);
+ }
+
+ request.setOutOrderNo(outOrderNo);
+
+ log.info("分账回退请求构建 - 回退单号:{},原始分账单号:{},回退金额:{}元({}分)",
+ outReturnNo, outOrderNo, returnAmount, returnMoney);
+
+ try {
+ // 调用分账回退接口
+ log.info("调用微信分账回退接口...");
+ ProfitSharingReturnResult result = profitSharingService.profitSharingReturn(request);
+
+ log.info("分账回退成功!订单ID:{},退款金额:{}元", orderId, refundAmount);
+ log.info("分账回退详情 - 回退金额:{}元,从商户:{}回退", returnAmount, properties.getMchId());
+ log.info("分账回退结果 - 回退单号:{},微信返回状态:{}", result.getOutReturnNo(), result);
+ log.info("========== 分账回退执行成功 ==========");
+ } catch (WxPayException e) {
+ log.error("分账回退执行失败!订单ID:{},错误信息:{}", orderId, e.getMessage(), e);
+ log.error("失败详情 - 退款金额:{}元,回退金额:{}元,回退单号:{}", refundAmount, returnAmount, outReturnNo);
+ throw e;
+ }
+ }
+
+ /**
+ * 重新分账剩余金额(用于部分退款后)
+ */
+ @Override
+ public void reProfitSharing(Long orderId, String transactionId, BigDecimal remainingAmount) throws WxPayException {
+ log.info("========== 开始执行重新分账 ==========");
+ log.info("重新分账参数 - 订单ID:{},交易ID:{},剩余金额:{}元", orderId, transactionId, remainingAmount);
+
+ // 计算新的分账金额:剩余金额 * (1/1000)
+ BigDecimal sharingAmount = remainingAmount.multiply(BigDecimal.valueOf(PROFIT_SHARING_RATIO))
+ .divide(BigDecimal.valueOf(PROFIT_SHARING_BASE), 2, RoundingMode.DOWN);
+
+ log.info("重新分账金额计算 - 剩余金额:{}元,分账比例:{}/{},分账金额:{}元",
+ remainingAmount, PROFIT_SHARING_RATIO, PROFIT_SHARING_BASE, sharingAmount);
+
+ if (sharingAmount.compareTo(BigDecimal.ZERO) <= 0) {
+ log.info("重新分账金额为0,跳过重新分账,订单ID:{}", orderId);
+ log.info("========== 重新分账跳过结束 ==========");
+ return;
+ }
+
+ log.info("重新分账商户信息 - 分账商户:{},收款商户:{}", properties.getReceiverMchId(), properties.getSubMchId());
+
+ // 构建重新分账请求
+ ProfitSharingRequest request = new ProfitSharingRequest();
+ request.setTransactionId(transactionId);
+ String outOrderNo = "RE_PS_" + orderId + "_" + System.currentTimeMillis();
+ request.setOutOrderNo(outOrderNo);
+
+ log.info("重新分账请求构建 - 分账单号:{},交易ID:{}", outOrderNo, transactionId);
+
+ // 创建分账接收方JSON字符串(仅给分账接收方分一部分,收款子商户保持留存)
+ StringBuilder receiversJson = new StringBuilder("[");
+ int receiverMoney = sharingAmount.multiply(BigDecimal.valueOf(100)).intValue();
+ receiversJson.append("{\"type\":\"MERCHANT_ID\",\"account\":\"").append(properties.getReceiverMchId()).append("\",")
+ .append("\"amount\":").append(receiverMoney)
+ .append(",\"description\":\"部分退款后重新分账-分账商户\"}");
+ receiversJson.append("]");
+ request.setReceivers(receiversJson.toString());
+ // 指定分账发生在收款子商户下
+ request.setSubMchId(properties.getSubMchId());
+
+ BigDecimal subMerchantAmount = remainingAmount.subtract(sharingAmount);
+ log.info("重新分账接收方配置 - 特约商户分账:{}元({}分),子商户(留存):{}元",
+ sharingAmount, receiverMoney,
+ subMerchantAmount);
+ log.info("重新分账接收方JSON:{}", receiversJson);
+
+ try {
+ // 调用分账接口
+ log.info("调用微信重新分账接口...");
+ ProfitSharingResult result = profitSharingService.profitSharing(request);
+
+ log.info("重新分账成功!订单ID:{},剩余金额:{}元", orderId, remainingAmount);
+ log.info("重新分账详情 - 特约商户分账:{}元,子商户分账:{}元", sharingAmount, subMerchantAmount);
+ log.info("重新分账结果 - 分账单号:{},微信返回状态:{}", result.getOutOrderNo(), result);
+ log.info("========== 重新分账执行成功 ==========");
+ } catch (WxPayException e) {
+ log.error("重新分账执行失败!订单ID:{},错误信息:{}", orderId, e.getMessage(), e);
+ log.error("失败详情 - 交易ID:{},分账单号:{},剩余金额:{}元", transactionId, outOrderNo, remainingAmount);
+ throw e;
+ }
+ }
+
+ /**
+ * 异步执行分账(支付成功后,支持重试)
+ * 延迟10秒执行,避免订单处理中导致的分账失败
+ */
+ @Override
+ @Async
+ public void profitSharingAsync(Long orderId, String transactionId, BigDecimal totalAmount) {
+ log.info("异步分账任务启动,订单ID:{},交易ID:{},总金额:{}元", orderId, transactionId, totalAmount);
+
+ try {
+ // 延迟10秒执行分账,避免 ORDER_NOT_READY 错误
+ Thread.sleep(10000);
+ log.info("延迟10秒后开始执行分账,订单ID:{}", orderId);
+
+ // 调用同步分账方法
+ profitSharing(orderId, transactionId, totalAmount);
+ log.info("异步分账执行成功,订单ID:{}", orderId);
+
+ } catch (InterruptedException e) {
+ log.error("异步分账延迟被中断,订单ID:{},错误:{}", orderId, e.getMessage());
+ Thread.currentThread().interrupt(); // 恢复中断状态
+ } catch (Exception e) {
+ log.error("异步分账执行失败,订单ID:{},交易ID:{},总金额:{}元,错误:{}",
+ orderId, transactionId, totalAmount, e.getMessage(), e);
+ // 异步执行失败不抛出异常,避免影响主流程
+ }
+ }
+
}
diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/WeChatPayServiceImpl.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/WeChatPayServiceImpl.java
index c615b2e..dd2b399 100644
--- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/WeChatPayServiceImpl.java
+++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/WeChatPayServiceImpl.java
@@ -5,6 +5,7 @@ import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
+import com.njzscloud.supervisory.wxPay.config.WxPayProperties;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.njzscloud.supervisory.wxPay.service.WeChatPayService;
@@ -21,6 +22,7 @@ import org.springframework.stereotype.Service;
public class WeChatPayServiceImpl implements WeChatPayService {
private final WxPayService wxPayService;
+ private final WxPayProperties wxPayProperties;
@Override
public Object createJsapiOrder(WxPayUnifiedOrderRequest request) throws WxPayException {
@@ -96,6 +98,7 @@ public class WeChatPayServiceImpl implements WeChatPayService {
.notifyUrl(notifyUrl)
.build();
+ refundRequest.setSubMchId(wxPayProperties.getSubMchId());
WxPayRefundResult refundResult = wxPayService.refund(refundRequest);
return refundResult.getRefundId();
} catch (WxPayException e) {
diff --git a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/WechatTemplateMessageServiceImpl.java b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/WechatTemplateMessageServiceImpl.java
index 5ab3212..1470ab3 100644
--- a/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/WechatTemplateMessageServiceImpl.java
+++ b/njzscloud-svr/src/main/java/com/njzscloud/supervisory/wxPay/service/impl/WechatTemplateMessageServiceImpl.java
@@ -21,6 +21,7 @@ import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -122,8 +123,8 @@ public class WechatTemplateMessageServiceImpl implements WechatTemplateMessageSe
@Override
public void sendTemplateMessage(TemplateMessageParam param) {
UserEntity userEntity = userService.getById(param.getUserId());
-// UserEntity userEntity = new UserEntity();
-// userEntity.setOpenid("owC-r2Bf1axK1C2MQ6nOaCDbKuHw");
+ // UserEntity userEntity = new UserEntity();
+ // userEntity.setOpenid("owC-r2Bf1axK1C2MQ6nOaCDbKuHw");
if (!Strings.isNullOrEmpty(userEntity.getOpenid())) {
Map data;
if (TempType.TRANS_COMPANY.getVal().equals(param.getTempType())) {
@@ -147,10 +148,13 @@ public class WechatTemplateMessageServiceImpl implements WechatTemplateMessageSe
// 待审核
// 构建模板数据
data = new HashMap<>();
- data.put("character_string5", new TemplateData(param.getSn()));
- data.put("thing11", new TemplateData(param.getGoodsName()));
- data.put("thing9", new TemplateData(param.getCfCompanyName()));
- data.put("car_number13", new TemplateData(param.getLicensePlate()));
+ data.put("character_string2", new TemplateData(param.getSn()));
+ data.put("thing3", new TemplateData(truncateForThingField(param.getCfCompanyName())));
+ data.put("thing5", new TemplateData(param.getGoodsName()));
+ data.put("thing6", new TemplateData(truncateForThingField(param.getCompanyName())));
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm");
+ String formattedTime = param.getCreateTime().format(formatter);
+ data.put("time1", new TemplateData(formattedTime));
sendMessage(userEntity.getOpenid(), TemplateID.AUDIT_PENDING, data, null, "pages/adminPage/jianGuan");
} else if (TempType.AUDIT_OK.getVal().equals(param.getTempType())) {
// 审核通过
diff --git a/njzscloud-svr/src/main/resources/application-dev.yml b/njzscloud-svr/src/main/resources/application-dev.yml
index 5517cc0..bb5c3bb 100644
--- a/njzscloud-svr/src/main/resources/application-dev.yml
+++ b/njzscloud-svr/src/main/resources/application-dev.yml
@@ -68,13 +68,21 @@ wechat:
app-secret: 66c98dc487a372acb4f1931b38fee8ff
base-url: https://api.weixin.qq.com
pay:
- app-id: wx989ea47a5ddf9bfb
- mch-id: 1729703110
- # API密钥(32位字符串)
- api-key: KXM36nZCXji1sQt75tGk77k7b2K5RBpf
- # 证书序列号
- cert-serial-no: 1BCB1533688F349541C7B636EF67C666828BADBA
- # 文件路径
+ # 服务商 app-id
+ app-id: wxc09dc9d9bcc94edc
+ # 服务商 mch-id
+ mch-id: 1659535913
+ # 收款方 sub-mch-id
+ sub-mch-id: 1729703110
+ # 分账方 sub-mch-id
+ receiver-mch-id: 1649452354
+ # 服务商API密钥(32位字符串)
+ api-key: 00ba7ceab606427071d5d755ea99e976
+# api-key: KXM36nZCXji1sQt75tGk77k7b2K5RBpf
+ # 服务商证书序列号
+ cert-serial-no: 615FBF704AB2838EE8B387F633B340640E078F4B
+# cert-serial-no: 1BCB1533688F349541C7B636EF67C666828BADBA
+ # 服务商文件路径
private-key-path: classpath:cert/apiclient_cert.p12
# private-key-path: D:/project/再昇云/代码/njzscloud/njzscloud-svr/src/main/resources/cert/apiclient_cert.p12
# 支付回调地址
diff --git a/njzscloud-svr/src/main/resources/application-prod.yml b/njzscloud-svr/src/main/resources/application-prod.yml
index 0037142..ae83832 100644
--- a/njzscloud-svr/src/main/resources/application-prod.yml
+++ b/njzscloud-svr/src/main/resources/application-prod.yml
@@ -58,13 +58,21 @@ wechat:
app-secret: 66c98dc487a372acb4f1931b38fee8ff
base-url: https://api.weixin.qq.com
pay:
- app-id: wx989ea47a5ddf9bfb
- mch-id: 1729703110
- # API密钥(32位字符串)
- api-key: KXM36nZCXji1sQt75tGk77k7b2K5RBpf
- # 证书序列号
- cert-serial-no: 1BCB1533688F349541C7B636EF67C666828BADBA
- # 文件路径
+ # 服务商 app-id
+ app-id: wxc09dc9d9bcc94edc
+ # 服务商 mch-id
+ mch-id: 1659535913
+ # 收款方 sub-mch-id
+ sub-mch-id: 1729703110
+ # 分账方 sub-mch-id
+ receiver-mch-id: 1649452354
+ # 服务商API密钥(32位字符串)
+ api-key: 00ba7ceab606427071d5d755ea99e976
+ # api-key: KXM36nZCXji1sQt75tGk77k7b2K5RBpf
+ # 服务商证书序列号
+ cert-serial-no: 615FBF704AB2838EE8B387F633B340640E078F4B
+ # cert-serial-no: 1BCB1533688F349541C7B636EF67C666828BADBA
+ # 服务商文件路径
private-key-path: classpath:cert/apiclient_cert.p12
# private-key-path: D:/project/再昇云/代码/njzscloud/njzscloud-svr/src/main/resources/cert/apiclient_cert.p12
# 支付回调地址
diff --git a/njzscloud-svr/src/main/resources/cert/apiclient_cert.p12 b/njzscloud-svr/src/main/resources/cert/apiclient_cert.p12
index aa26919..6c9f077 100644
Binary files a/njzscloud-svr/src/main/resources/cert/apiclient_cert.p12 and b/njzscloud-svr/src/main/resources/cert/apiclient_cert.p12 differ
diff --git a/njzscloud-svr/src/main/resources/cert/cz_apiclient_cert.p12 b/njzscloud-svr/src/main/resources/cert/cz_apiclient_cert.p12
new file mode 100644
index 0000000..aa26919
Binary files /dev/null and b/njzscloud-svr/src/main/resources/cert/cz_apiclient_cert.p12 differ