|
|
@@ -12,6 +12,7 @@ import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.RandomStringUtils;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.jeecg.common.constant.CommonConstant;
|
|
|
+import org.jeecg.common.exception.JeecgBootException;
|
|
|
import org.jeecg.modules.pay.config.*;
|
|
|
import org.jeecg.modules.pay.serverPay.WXPayUtility;
|
|
|
import org.jeecg.modules.system.app.dto.receiptPaymentDetails.ReceiptPaymentDetailsInfoVo;
|
|
|
@@ -211,6 +212,12 @@ public class WeChatPayService {
|
|
|
String orderCode = res.getString("out_trade_no");
|
|
|
//查询订单,判断是否已修改为已支付状态
|
|
|
AppOrder appOrder = appOrderMapper.selectOne(Wrappers.<AppOrder>lambdaQuery().eq(AppOrder::getOrderCode, orderCode).last("limit 1"));
|
|
|
+ if (ObjectUtil.isNotEmpty(appOrder) && appOrder.getCallbackStatus() == 1) {
|
|
|
+ result.put("code", "SUCCESS");
|
|
|
+ result.put("message", "OK");
|
|
|
+ result.put("orderCode", orderCode);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
if (ObjectUtil.isNotEmpty(appOrder)) {
|
|
|
if (Objects.equals(appOrder.getOrderStatus(), CommonConstant.ORDER_STATUS_0)) {
|
|
|
appOrder.setOrderStatus(CommonConstant.ORDER_STATUS_1);
|
|
|
@@ -227,25 +234,54 @@ public class WeChatPayService {
|
|
|
appOrderProInfoMapper.updateById(appOrderProInfo);
|
|
|
}
|
|
|
}
|
|
|
+ appOrder.setCallbackStatus(CommonConstant.STATUS_1_INT);
|
|
|
+ appOrderMapper.updateById(appOrder);
|
|
|
+ //创建预分账详情
|
|
|
+ if (appOrder.getOrProfitSharing() == 1) {
|
|
|
+ addProfitSharingInfos(appOrder);
|
|
|
+ }
|
|
|
}
|
|
|
- appOrder.setCallbackStatus(CommonConstant.STATUS_1_INT);
|
|
|
- appOrderMapper.updateById(appOrder);
|
|
|
- //创建预分账详情
|
|
|
- if (appOrder.getOrProfitSharing() == 1) {
|
|
|
- addProfitSharingInfos(appOrder);
|
|
|
- }
|
|
|
+
|
|
|
}
|
|
|
result.put("code", "SUCCESS");
|
|
|
result.put("message", "OK");
|
|
|
result.put("orderCode", orderCode);
|
|
|
return result;
|
|
|
} catch (Exception e) {
|
|
|
+ log.error("微信支付回调异常:" + e.getMessage());
|
|
|
result.put("code", "FAIL");
|
|
|
result.put("message", "失败");
|
|
|
return result;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private static final BigDecimal MIN_THRESHOLD = new BigDecimal("0.01"); // 最小阈值
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算千分之6并处理临界值
|
|
|
+ *
|
|
|
+ * @param input 输入金额(单位:元)
|
|
|
+ * @return 计算结果(保留两位小数,不足0.01按0.01计算)
|
|
|
+ * @throws IllegalArgumentException 输入为null或负数时抛出
|
|
|
+ */
|
|
|
+ public static BigDecimal calculate(BigDecimal input, BigDecimal multiplier) {
|
|
|
+ if (input == null) {
|
|
|
+ throw new IllegalArgumentException("输入金额不能为null");
|
|
|
+ }
|
|
|
+ if (input.compareTo(BigDecimal.ZERO) < 0) {
|
|
|
+ throw new IllegalArgumentException("输入金额不能为负数");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 精确乘法运算(保留4位中间精度)
|
|
|
+ BigDecimal product = input.multiply(multiplier)
|
|
|
+ .setScale(4, RoundingMode.HALF_UP);
|
|
|
+
|
|
|
+ // 临界值判断与补偿
|
|
|
+ return product.compareTo(MIN_THRESHOLD) < 0
|
|
|
+ ? MIN_THRESHOLD
|
|
|
+ : product.setScale(2, RoundingMode.DOWN);
|
|
|
+ }
|
|
|
+
|
|
|
public void addProfitSharingInfos(AppOrder appOrder) {
|
|
|
List<AppOrderProInfo> orderProInfoList = appOrderProInfoMapper.selectList(Wrappers.lambdaQuery(AppOrderProInfo.class).eq(AppOrderProInfo::getOrderId, appOrder.getId()).eq(AppOrderProInfo::getType, CommonConstant.ORDER_PRO_INFO_TYPE_6));
|
|
|
BigDecimal insurePrice = BigDecimal.ZERO;
|
|
|
@@ -264,10 +300,13 @@ public class WeChatPayService {
|
|
|
BigDecimal PT = separateAccounts.getPtSeparateAccounts();
|
|
|
BigDecimal SH = separateAccounts.getShSeparateAccounts();
|
|
|
BigDecimal MD = separateAccounts.getMdSeparateAccounts();
|
|
|
- //分账金额
|
|
|
+ //分账金额(支付金额-保险金额)
|
|
|
BigDecimal price = appOrder.getPrice().subtract(insurePrice);
|
|
|
- //微信手续费,不足1分按1分算
|
|
|
- Integer FEE = RatiosUtil.amount_fee(price.multiply(new BigDecimal("0.06")).setScale(0, RoundingMode.UP));
|
|
|
+ //微信手续费,不足1分按1分算(当计算值小于0.01时强制提升至0.01)
|
|
|
+ BigDecimal FEE = calculate(price, new BigDecimal("0.006"));
|
|
|
+
|
|
|
+ price = price.subtract(FEE);
|
|
|
+
|
|
|
//商户(分账给平台)
|
|
|
if (depart.getSystemType() == 1) {
|
|
|
BigDecimal[] allocate = RatiosUtil.allocate(price, new BigDecimal[]{SH, PT});
|
|
|
@@ -281,11 +320,15 @@ public class WeChatPayService {
|
|
|
SHAppProfitSharingInfo.setRatio(SH);
|
|
|
SHAppProfitSharingInfo.setPreAmount(RatiosUtil.amount_fee(allocate[0]));
|
|
|
appProfitSharingInfoMapper.insert(SHAppProfitSharingInfo);
|
|
|
- //平台所得金额(金额*比例-微信手续费,)
|
|
|
- Integer procedureFee = RatiosUtil.amount_fee(allocate[1]) - FEE;
|
|
|
- AppProfitSharingInfo PTAppProfitSharingInfo = getPtAppProfitSharingInfo(appOrder, PT, procedureFee);
|
|
|
- appProfitSharingInfoMapper.insert(PTAppProfitSharingInfo);
|
|
|
|
|
|
+ //平台所得金额(金额*比例-微信手续费)
|
|
|
+ Integer procedureFee = RatiosUtil.amount_fee(allocate[2].add(insurePrice));
|
|
|
+ AppProfitSharingInfo PTAppProfitSharingInfo = getPtAppProfitSharingInfo(appOrder, PT, procedureFee, insurePrice);
|
|
|
+ if (allocate[2] != null && ((allocate[2].add(insurePrice)).compareTo(BigDecimal.ZERO) == 0)) {
|
|
|
+ PTAppProfitSharingInfo.setAmount(RatiosUtil.amount_fee(BigDecimal.ZERO));
|
|
|
+ PTAppProfitSharingInfo.setDescription("分账金额为0,请自行处理");
|
|
|
+ }
|
|
|
+ appProfitSharingInfoMapper.insert(PTAppProfitSharingInfo);
|
|
|
}
|
|
|
//门店(分账给平台及商户)
|
|
|
if (depart.getSystemType() == 2) {
|
|
|
@@ -301,6 +344,7 @@ public class WeChatPayService {
|
|
|
MDAppProfitSharingInfo.setPreAmount(RatiosUtil.amount_fee(allocate[0]));
|
|
|
appProfitSharingInfoMapper.insert(MDAppProfitSharingInfo);
|
|
|
//商户所得金额
|
|
|
+
|
|
|
AppProfitSharingInfo SHAppProfitSharingInfo = new AppProfitSharingInfo();
|
|
|
SHAppProfitSharingInfo.setOrderId(appOrder.getId());
|
|
|
SHAppProfitSharingInfo.setOrgCode(orgCode);
|
|
|
@@ -308,18 +352,27 @@ public class WeChatPayService {
|
|
|
SHAppProfitSharingInfo.setMchName(depart.getMchName());
|
|
|
SHAppProfitSharingInfo.setType(2);
|
|
|
SHAppProfitSharingInfo.setRatio(SH);
|
|
|
- SHAppProfitSharingInfo.setPreAmount(RatiosUtil.amount_fee(allocate[0]));
|
|
|
+ SHAppProfitSharingInfo.setPreAmount(RatiosUtil.amount_fee(allocate[1]));
|
|
|
+ if (allocate[1] != null && allocate[1].compareTo(BigDecimal.ZERO) == 0) {
|
|
|
+ SHAppProfitSharingInfo.setAmount(RatiosUtil.amount_fee(BigDecimal.ZERO));
|
|
|
+ SHAppProfitSharingInfo.setDescription("分账金额为0,请自行处理");
|
|
|
+ }
|
|
|
appProfitSharingInfoMapper.insert(SHAppProfitSharingInfo);
|
|
|
+
|
|
|
//平台所得金额(金额*比例-微信手续费)
|
|
|
- Integer procedureFee = RatiosUtil.amount_fee(allocate[1]) - FEE;
|
|
|
- AppProfitSharingInfo PTAppProfitSharingInfo = getPtAppProfitSharingInfo(appOrder, PT, procedureFee);
|
|
|
+ Integer procedureFee = RatiosUtil.amount_fee(allocate[2].add(insurePrice));
|
|
|
+ AppProfitSharingInfo PTAppProfitSharingInfo = getPtAppProfitSharingInfo(appOrder, PT, procedureFee, insurePrice);
|
|
|
+ if (allocate[2] != null && ((allocate[2].add(insurePrice)).compareTo(BigDecimal.ZERO) == 0)) {
|
|
|
+ PTAppProfitSharingInfo.setAmount(RatiosUtil.amount_fee(BigDecimal.ZERO));
|
|
|
+ PTAppProfitSharingInfo.setDescription("分账金额为0,请自行处理");
|
|
|
+ }
|
|
|
appProfitSharingInfoMapper.insert(PTAppProfitSharingInfo);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@NotNull
|
|
|
- private static AppProfitSharingInfo getPtAppProfitSharingInfo(AppOrder appOrder, BigDecimal PT, Integer procedureFee) {
|
|
|
+ private static AppProfitSharingInfo getPtAppProfitSharingInfo(AppOrder appOrder, BigDecimal PT, Integer procedureFee, BigDecimal insurePrice) {
|
|
|
AppProfitSharingInfo PTAppProfitSharingInfo = new AppProfitSharingInfo();
|
|
|
PTAppProfitSharingInfo.setOrderId(appOrder.getId());
|
|
|
PTAppProfitSharingInfo.setOrgCode(WechatConstants.SUB_ORG_CODE);
|
|
|
@@ -327,6 +380,7 @@ public class WeChatPayService {
|
|
|
PTAppProfitSharingInfo.setMchName(WechatConstants.WECHAT_SUB_MCH_NAME);
|
|
|
PTAppProfitSharingInfo.setType(2);
|
|
|
PTAppProfitSharingInfo.setRatio(PT);
|
|
|
+ PTAppProfitSharingInfo.setInsureAmount(RatiosUtil.amount_fee(insurePrice));
|
|
|
PTAppProfitSharingInfo.setPreAmount(procedureFee);
|
|
|
return PTAppProfitSharingInfo;
|
|
|
}
|
|
|
@@ -337,7 +391,7 @@ public class WeChatPayService {
|
|
|
* @param out_trade_no 发起支付时创建的商户订单号
|
|
|
* @return null代表查询失败 SUCCESS-成功 USERPAYING和ACCEPT为中间态 其他为支付失败
|
|
|
*/
|
|
|
- public JSONObject orderQueryByOutTradeNo(String out_trade_no,String subMchId) {
|
|
|
+ public JSONObject orderQueryByOutTradeNo(String out_trade_no, String subMchId) {
|
|
|
String url = WechatUrlConstants.PAY_V3_QUERY_OUT;
|
|
|
url = url.replace("{out_trade_no}", WXPayUtility.urlEncode(out_trade_no));
|
|
|
Map<String, Object> args = new HashMap<>();
|
|
|
@@ -377,7 +431,7 @@ public class WeChatPayService {
|
|
|
appOrderRefundsInfo.setCreateTime(new Date());
|
|
|
|
|
|
JSONObject params = new JSONObject();
|
|
|
- params.put("sub_mchid",depart.getMchId());
|
|
|
+ params.put("sub_mchid", depart.getMchId());
|
|
|
params.put("out_trade_no", appOrder.getOrderCode());//商户订单号
|
|
|
params.put("out_refund_no", out_refund_no);//商户退款单号
|
|
|
params.put("reason", reason);//退款原因
|
|
|
@@ -484,6 +538,8 @@ public class WeChatPayService {
|
|
|
Map<String, Object> parm = new HashMap<>();
|
|
|
if (!StringUtils.isEmpty(refund_status) && "SUCCESS".equals(refund_status)) {
|
|
|
|
|
|
+ List<AppOrderProInfo> appOrderProInfoList = new ArrayList<>();
|
|
|
+
|
|
|
//查询订单
|
|
|
AppOrder order = appOrderMapper.selectOne(Wrappers.<AppOrder>lambdaQuery().eq(AppOrder::getOrderCode, out_trade_no).last("limit 1"));
|
|
|
if (ObjectUtil.isNotEmpty(order)) {
|
|
|
@@ -497,53 +553,32 @@ public class WeChatPayService {
|
|
|
List<AppOrderProInfo> proInfoList = appOrderProInfoMapper.selectList(Wrappers.<AppOrderProInfo>lambdaQuery().eq(AppOrderProInfo::getOrderId, order.getId()));
|
|
|
if (ObjectUtil.isNotEmpty(proInfoList)) {
|
|
|
for (AppOrderProInfo appOrderProInfo : proInfoList) {
|
|
|
- appOrderProInfo.setOrderStatus(CommonConstant.ORDER_STATUS_1);
|
|
|
- appOrderProInfoMapper.updateById(appOrderProInfo);
|
|
|
+ if (appOrderProInfo.getOrderStatus() == 5) {
|
|
|
+ appOrderProInfo.setOrderStatus(CommonConstant.ORDER_STATUS_6);
|
|
|
+ appOrderProInfoMapper.updateById(appOrderProInfo);
|
|
|
+ appOrderProInfoList.add(appOrderProInfo);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 创建退款订单
|
|
|
- AppOrderRefundsInfo appOrderRefundsInfo = appOrderRefundsInfoMapper.selectOne(Wrappers.lambdaQuery(AppOrderRefundsInfo.class).eq(AppOrderRefundsInfo::getOrderId, order.getId()));
|
|
|
+ for (AppOrderProInfo appOrderProInfo : appOrderProInfoList) {
|
|
|
+ // 创建退款订单
|
|
|
+ AppOrderRefundsInfo appOrderRefundsInfo = appOrderRefundsInfoMapper.selectOne(Wrappers.lambdaQuery(AppOrderRefundsInfo.class)
|
|
|
+ .eq(AppOrderRefundsInfo::getOrderId, order.getId())
|
|
|
+ .eq(AppOrderRefundsInfo::getOrderProInfoId, appOrderProInfo.getId())
|
|
|
+ );
|
|
|
|
|
|
- if (ObjectUtil.isNotEmpty(appOrderRefundsInfo)) {
|
|
|
- // appOrderRefundsInfo.setRefundId();
|
|
|
- appOrderRefundsInfo.setSuccessTime(new Date());
|
|
|
+ if (ObjectUtil.isNotEmpty(appOrderRefundsInfo)) {
|
|
|
+ // appOrderRefundsInfo.setRefundId();
|
|
|
+ appOrderRefundsInfo.setSuccessTime(new Date());
|
|
|
// appOrderRefundsInfo.setNotifyRequest();
|
|
|
- appOrderRefundsInfoMapper.updateById(appOrderRefundsInfo);
|
|
|
+ appOrderRefundsInfoMapper.updateById(appOrderRefundsInfo);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
parm.put("code", "SUCCESS");
|
|
|
parm.put("message", "成功");
|
|
|
- SysDepart sysDepart = sysDepartMapper.findByOrgCodeAndParentId(order.getOrgCode());
|
|
|
- SeparateAccounts separateAccounts = separateAccountsMapper.findByDeptIdAndStatus(sysDepart.getId());
|
|
|
- BigDecimal shBigDecimal = BigDecimal.ZERO;
|
|
|
- try {
|
|
|
- shBigDecimal = getBigDecimal(order.getPrice(), separateAccounts.getShSeparateAccounts());
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("百分比计算错误", e);
|
|
|
- }
|
|
|
- BigDecimal ptBigDecimal = BigDecimal.ZERO;
|
|
|
- try {
|
|
|
- ptBigDecimal = getBigDecimal(order.getPrice(), separateAccounts.getPtSeparateAccounts());
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("百分比计算错误", e);
|
|
|
- }
|
|
|
- SysDepart byOrgCode = sysDepartMapper.findByOrgCode("A01");
|
|
|
- BigDecimal mdBigDecimal = order.getPrice().subtract(shBigDecimal).subtract(ptBigDecimal).setScale(2, RoundingMode.HALF_UP);
|
|
|
- log.info("退款成功消息通知,金额:" + mdBigDecimal + ";" + shBigDecimal + ";" + ptBigDecimal);
|
|
|
- ReceiptPaymentDetailsInfoVo receiptPaymentDetailsInfoVo = new ReceiptPaymentDetailsInfoVo();
|
|
|
- receiptPaymentDetailsInfoVo.setMoney(order.getPrice());
|
|
|
- receiptPaymentDetailsInfoVo.setChangeMoney(appOrderRefundsInfo.getAmount());
|
|
|
- receiptPaymentDetailsInfoVo.setPayType(1);
|
|
|
- receiptPaymentDetailsInfoVo.setPurseChangeReason(1);
|
|
|
- receiptPaymentDetailsInfoVo.setCreateTime(new Date());
|
|
|
- receiptPaymentDetailsInfoVo.setUpdateTime(new Date());
|
|
|
- receiptPaymentDetailsInfoVo.setOrderId(appOrderRefundsInfo.getOrderId());
|
|
|
- ReceiptPaymentDetailsInfoVo receiptPaymentDetailsInfoVoMd = getChangeMoney(receiptPaymentDetailsInfoVo, order.getOrgCode(), order.getTenantId(), 2, mdBigDecimal);
|
|
|
- ReceiptPaymentDetailsInfoVo receiptPaymentDetailsInfoVoSh = getChangeMoney(receiptPaymentDetailsInfoVo, order.getOrgCode(), sysDepart.getId(), 1, shBigDecimal);
|
|
|
- ReceiptPaymentDetailsInfoVo receiptPaymentDetailsInfoVoPt = getChangeMoney(receiptPaymentDetailsInfoVo, order.getOrgCode(), byOrgCode.getId(), 0, ptBigDecimal);
|
|
|
} else {
|
|
|
parm.put("code", "FAIL");
|
|
|
parm.put("message", "失败");
|