diff --git a/jsowell-admin/src/main/java/com/jsowell/api/uniapp/TempController.java b/jsowell-admin/src/main/java/com/jsowell/api/uniapp/TempController.java index 61941ea62..ff5a1be3d 100644 --- a/jsowell-admin/src/main/java/com/jsowell/api/uniapp/TempController.java +++ b/jsowell-admin/src/main/java/com/jsowell/api/uniapp/TempController.java @@ -367,4 +367,25 @@ public class TempController extends BaseController { logger.info("查询未分账订单result:{}", JSON.toJSONString(response)); return response; } + + /** + * 余额支付订单分账工具 + * 8月17号之后使用汇付余额支付的订单 + * 需要重新走一遍分账 + */ + @PostMapping("/splitTheBillForOrderTemp") + public RestApiResponse splitTheBillForOrderTemp(QueryOrderDTO dto) { + RestApiResponse response; + try { + orderBasicInfoService.splitTheBillForOrderTemp(dto.getMerchantId(), dto.getOrderCodeList()); + response = new RestApiResponse<>(); + } catch (BusinessException e) { + logger.error("余额支付订单分账工具 error,", e); + response = new RestApiResponse<>(e.getCode(), e.getMessage()); + } catch (Exception e) { + logger.error("余额支付订单分账工具 error,", e); + response = new RestApiResponse<>("00300003", "余额支付订单分账工具异常"); + } + return response; + } } diff --git a/jsowell-admin/src/test/java/SpringBootTestController.java b/jsowell-admin/src/test/java/SpringBootTestController.java index 9d5737460..93ebf8af9 100644 --- a/jsowell-admin/src/test/java/SpringBootTestController.java +++ b/jsowell-admin/src/test/java/SpringBootTestController.java @@ -46,7 +46,6 @@ import com.jsowell.pile.domain.ykcCommond.ProofreadTimeCommand; import com.jsowell.pile.dto.*; import com.jsowell.pile.dto.amap.GetStationInfoDTO; import com.jsowell.pile.dto.lutongyunting.BindCouponDTO; -import com.jsowell.pile.dto.lutongyunting.GetTokenDTO; import com.jsowell.pile.mapper.MemberBasicInfoMapper; import com.jsowell.pile.mapper.PileBillingTemplateMapper; import com.jsowell.pile.service.*; @@ -244,7 +243,7 @@ public class SpringBootTestController { public void queryPaymentConfirmListTest() { QueryPaymentConfirmDTO dto = new QueryPaymentConfirmDTO(); dto.setWechatAppId("wxbb3e0d474569481d"); - dto.setPaymentId("002212023080223561910532842298673803264"); + dto.setPaymentId("002212023081712452810538109291674042368"); QueryPaymentConfirmDetailResponse queryPaymentConfirmDetailResponse = adapayService.queryPaymentConfirmList(dto); System.out.println(queryPaymentConfirmDetailResponse); } diff --git a/jsowell-common/src/main/java/com/jsowell/common/enums/ykc/ReturnCodeEnum.java b/jsowell-common/src/main/java/com/jsowell/common/enums/ykc/ReturnCodeEnum.java index 1a7c7f040..cde118e50 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/enums/ykc/ReturnCodeEnum.java +++ b/jsowell-common/src/main/java/com/jsowell/common/enums/ykc/ReturnCodeEnum.java @@ -116,6 +116,8 @@ public enum ReturnCodeEnum { CODE_BALANCE_REFUNDS_ARE_IN_PROGRESS_ERROR("00100054", "会员余额退款正在进行中,请稍后再试"), + CODE_QUERY_WECHAT_APP_ID_IS_NULL("00100056", "未查询到商户的微信小程序id"), + /* 个人桩 start */ CODE_PILE_HAS_BEEN_BINDING_ERROR("00400001", "此桩已被绑定,请联系管理员!"), diff --git a/jsowell-pile/src/main/java/com/jsowell/adapay/service/AdapayService.java b/jsowell-pile/src/main/java/com/jsowell/adapay/service/AdapayService.java index 6ca54b822..41d09e573 100644 --- a/jsowell-pile/src/main/java/com/jsowell/adapay/service/AdapayService.java +++ b/jsowell-pile/src/main/java/com/jsowell/adapay/service/AdapayService.java @@ -33,7 +33,6 @@ import com.jsowell.pile.domain.ClearingWithdrawInfo; import com.jsowell.pile.domain.MemberBasicInfo; import com.jsowell.pile.dto.PayOrderDTO; import com.jsowell.pile.service.*; -import com.jsowell.wxpay.service.WxAppletRemoteService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -73,9 +72,6 @@ public class AdapayService { @Autowired private IPileMerchantInfoService pileMerchantInfoService; - @Autowired - private WxAppletRemoteService wxAppletRemoteService; - @Autowired private IMemberBasicInfoService memberBasicInfoService; diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/IOrderBasicInfoService.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/IOrderBasicInfoService.java index c0efb4b39..bf9ddac46 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/IOrderBasicInfoService.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/IOrderBasicInfoService.java @@ -5,7 +5,6 @@ import com.jsowell.adapay.response.PaymentReverseResponse; import com.jsowell.adapay.vo.OrderSettleResult; import com.jsowell.common.core.domain.ykc.RealTimeMonitorData; import com.jsowell.common.core.domain.ykc.TransactionRecordsData; -import com.jsowell.common.exception.BusinessException; import com.jsowell.pile.domain.AdapayMemberAccount; import com.jsowell.pile.domain.OrderBasicInfo; import com.jsowell.pile.domain.OrderDetail; @@ -347,4 +346,6 @@ public interface IOrderBasicInfoService { * @param orderCode 订单编号 */ void retryRefundOrder(String orderCode) throws BaseAdaPayException; + + void splitTheBillForOrderTemp(String merchantId, List orderCodeList); } diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java index f7ef53ad2..80784be72 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java @@ -8,8 +8,10 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.huifu.adapay.core.exception.BaseAdaPayException; +import com.jsowell.adapay.dto.QueryPaymentConfirmDTO; import com.jsowell.adapay.response.PaymentConfirmResponse; import com.jsowell.adapay.response.PaymentReverseResponse; +import com.jsowell.adapay.response.QueryPaymentConfirmDetailResponse; import com.jsowell.adapay.service.AdapayService; import com.jsowell.adapay.vo.OrderSettleResult; import com.jsowell.common.constant.CacheConstants; @@ -1173,20 +1175,20 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { BigDecimal deductionAmount = vo.getDeductionAmount(); // 调汇付的分账接口 确认交易 PaymentConfirmResponse paymentConfirmResponse = adapayService.createPaymentConfirmRequest(paymentId, adapayMemberAccount, deductionAmount, orderCode, wechatAppId); - if (paymentConfirmResponse != null) { + if (paymentConfirmResponse != null && paymentConfirmResponse.isNotFailed()) { confirmAmt = confirmAmt.add(new BigDecimal(paymentConfirmResponse.getConfirmed_amt())); feeAmt = feeAmt.add(new BigDecimal(paymentConfirmResponse.getFee_amt())); status = paymentConfirmResponse.getStatus(); description = paymentConfirmResponse.getDescription(); - } - // 更新这笔交易的剩余金额 - MemberAdapayRecord record = memberAdapayRecordService.selectByPaymentId(paymentId); - // 更新此笔交易单的消费金额 = 历史消费金额 + 本次消费金额 - record.setSpendAmt(record.getSpendAmt().add(deductionAmount)); - // 更新此笔交易单的剩余金额 = 支付金额 - 累计退款金额 - 累计消费金额 - record.setBalanceAmt(record.getPayAmt().subtract(record.getRefundAmt()).subtract(record.getSpendAmt())); - memberAdapayRecordService.updateByPrimaryKeySelective(record); + // 更新这笔交易的剩余金额 + MemberAdapayRecord record = memberAdapayRecordService.selectByPaymentId(paymentId); + // 更新此笔交易单的消费金额 = 历史消费金额 + 本次消费金额 + record.setSpendAmt(record.getSpendAmt().add(deductionAmount)); + // 更新此笔交易单的剩余金额 = 支付金额 - 累计退款金额 - 累计消费金额 + record.setBalanceAmt(record.getPayAmt().subtract(record.getRefundAmt()).subtract(record.getSpendAmt())); + memberAdapayRecordService.updateByPrimaryKeySelective(record); + } } // 分账接口返回的信息 @@ -2820,82 +2822,106 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { } } - /** - * 使用汇付支付 - * - * @param dto - * @return - */ - /*private Map adapayPayOrder(PayOrderDTO dto) { - logger.info("===============使用汇付支付"); - // 相同参数重复请求,返回同一个支付对象 - String redisKey = CacheConstants.ADAPAY_ORDER_PARAM + dto.getOrderCode(); - Map cacheObject = redisCache.getCacheObject(redisKey); - if (cacheObject != null) { - return cacheObject; + @Override + public void splitTheBillForOrderTemp(String merchantId, List orderCodeList) { + String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(merchantId); + if (StringUtils.isBlank(wechatAppId)) { + throw new BusinessException(ReturnCodeEnum.CODE_QUERY_WECHAT_APP_ID_IS_NULL); } - - // 获取支付配置 - AbstractAdapayConfig config = AdapayConfigFactory.getConfig(dto.getWechatAppId()); - if (config == null) { - throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR); + AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId); + if (adapayMemberAccount == null) { + throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_MEMBER_IS_NULL_ERROR); } - - // OrderBasicInfo orderInfo = dto.getOrderBasicInfo(); - // if (orderInfo == null) { - // // 订单为空重新查询 - // orderInfo = this.getOrderInfoByOrderCode(dto.getOrderCode()); - // } - - // 获取openId - String openId = wxAppletRemoteService.getOpenIdByCode(dto.getCode()); - if (StringUtils.isBlank(openId)) { - throw new BusinessException(ReturnCodeEnum.CODE_GET_OPEN_ID_BY_CODE_ERROR); - } - - // 封装对象 - String amount = AdapayUtil.formatAmount(dto.getPayAmount()); // 用户支付金额 - String payMode = Constants.ADAPAY_PAY_MODE_DELAY; // 汇付延时分账 - CreateAdaPaymentParam createAdaPaymentParam = new CreateAdaPaymentParam(); - createAdaPaymentParam.setOrder_no(dto.getOrderCode()); - createAdaPaymentParam.setPay_amt(amount); - createAdaPaymentParam.setApp_id(config.getAdapayAppId()); - createAdaPaymentParam.setPay_channel("wx_lite"); // todo 如果以后有支付宝等别的渠道,这里需要做修改,判断是什么渠道的请求 - createAdaPaymentParam.setGoods_title("充电费用"); - createAdaPaymentParam.setGoods_desc("充电桩预付款金额"); // 这个字段是微信支付凭证的商品名 - Map map = Maps.newHashMap(); - map.put("type", ScenarioEnum.ORDER.getValue()); - map.put("orderCode", dto.getOrderCode()); - map.put("payMode", payMode); - map.put("memberId", dto.getMemberId()); - createAdaPaymentParam.setDescription(JSON.toJSONString(map)); - // 异步通知地址,url为http/https路径,服务器POST回调,URL 上请勿附带参数 - createAdaPaymentParam.setNotify_url(ADAPAY_CALLBACK_URL); - createAdaPaymentParam.setExpend(JSONObject.toJSONString(ImmutableMap.of("open_id", openId))); - - // 延时分账 - createAdaPaymentParam.setPay_mode(payMode); - try { - logger.info("创建汇付支付参数:{}", JSONObject.toJSONString(createAdaPaymentParam)); - Map response = Payment.create(BeanMap.create(createAdaPaymentParam), config.getWechatAppId()); - if (response != null && !response.isEmpty()) { - JSONObject expend = JSONObject.parseObject(response.get("expend").toString()); - JSONObject pay_info = expend.getJSONObject("pay_info"); - Map resultMap = JSONObject.parseObject(pay_info.toJSONString(), new TypeReference>() { - }); - if (resultMap != null) { - // 表示已经获取到支付参数了,后续再有支付请求就拒绝 - redisCache.setCacheObject(redisKey, resultMap, 15, TimeUnit.MINUTES); - - // 设置订单号的 - } - return resultMap; + List orderBasicInfos = queryOrderList(orderCodeList); + for (OrderBasicInfo orderBasicInfo : orderBasicInfos) { + try { + splitTheBillForOrderTemp(adapayMemberAccount, orderBasicInfo, wechatAppId); + } catch (BaseAdaPayException e) { + logger.error("余额支付订单分账工具, 发生异常", e); + throw new RuntimeException(e); } - } catch (BaseAdaPayException e) { - logger.error("汇付-获取支付对象发生异常", e); } - return null; - }*/ + } + + /** + * 余额支付订单分账工具 + */ + public void splitTheBillForOrderTemp(AdapayMemberAccount adapayMemberAccount, OrderBasicInfo orderBasicInfo, String wechatAppId) throws BaseAdaPayException { + // 查询会员余额支付记录 + List recordList = memberAdapayRecordService.selectAdapayRecordList(orderBasicInfo.getMemberId(), ScenarioEnum.BALANCE.getValue()); + if (CollectionUtils.isEmpty(recordList)) { + logger.info("余额支付订单分账工具, memberId:{}, 未查询到余额充值记录", orderBasicInfo.getMemberId()); + return; + } + if (recordList.size() > 1) { + logger.info("余额支付订单分账工具, 会员充值记录存在多条,orderCode:{}由人工手动处理", orderBasicInfo.getOrderCode()); + return; + } + + // 订单分账金额 + BigDecimal amount = queryBalanceOrderSettleInfo(orderBasicInfo.getOrderCode(), orderBasicInfo.getMemberId(), wechatAppId); + + // 判断分账金额 和结算金额是否相等 + if (amount.compareTo(BigDecimal.ZERO) == 0) { + logger.info("余额支付订单分账工具, 已分账金额为0, 订单结算金额为:{}, 重试执行订单分账", orderBasicInfo.getSettleAmount()); + + // 修改会员的汇付支付记录 + for (MemberAdapayRecord memberAdapayRecord : recordList) { + BigDecimal spendAmt = memberAdapayRecord.getSpendAmt(); + spendAmt = spendAmt.subtract(orderBasicInfo.getOrderAmount()); + memberAdapayRecord.setSpendAmt(spendAmt); + + BigDecimal balanceAmt = memberAdapayRecord.getBalanceAmt(); + balanceAmt = balanceAmt.add(orderBasicInfo.getOrderAmount()); + memberAdapayRecord.setBalanceAmt(balanceAmt); + memberAdapayRecordService.updateByPrimaryKeySelective(memberAdapayRecord); + } + + // 分账金额为0,表示该订单没有执行过分账,再次执行分账 + if (OrderPayModeEnum.PAYMENT_OF_BALANCE.getValue().equals(orderBasicInfo.getPayMode())) { + // 余额支付的订单 + doBalancePayment(orderBasicInfo, adapayMemberAccount, wechatAppId); + } + + // 再次查询分账 + BigDecimal bigDecimal = queryBalanceOrderSettleInfo(orderBasicInfo.getOrderCode(), orderBasicInfo.getMemberId(), wechatAppId); + logger.info("余额支付订单分账工具, 重新分账完成, 分账金额:{}, 订单结算金额:{}", bigDecimal, orderBasicInfo.getSettleAmount()); + } else { + logger.info("余额支付订单分账工具, 已分账金额为:{}, 订单结算金额为:{}, 不再执行订单分账", amount, orderBasicInfo.getSettleAmount()); + } + } + + /** + * 查询余额订单分账信息 + * @param orderCode 订单编号 + * @param memberId 会员id + */ + private BigDecimal queryBalanceOrderSettleInfo(String orderCode, String memberId, String wechatAppId) { + BigDecimal resultAmt = BigDecimal.ZERO; + // 查询会员余额支付记录 + List recordList = memberAdapayRecordService.selectAdapayRecordList(memberId, ScenarioEnum.BALANCE.getValue()); + if (CollectionUtils.isEmpty(recordList)) { + return resultAmt; + } + + // 用汇付api查询分账信息 + for (MemberAdapayRecord record : recordList) { + QueryPaymentConfirmDTO dto = new QueryPaymentConfirmDTO(); + dto.setWechatAppId(wechatAppId); + dto.setPaymentId(record.getPaymentId()); + QueryPaymentConfirmDetailResponse response = adapayService.queryPaymentConfirmList(dto); + if (response != null && CollectionUtils.isNotEmpty(response.getPaymentConfirms()) ) { + for (QueryPaymentConfirmDetailResponse.PaymentConfirmInfo paymentConfirm : response.getPaymentConfirms()) { + JSONObject jsonObject = JSON.parseObject(paymentConfirm.getDescription()); + if (StringUtils.equals(jsonObject.getString("orderCode"), orderCode)) { + // 订单号对的上,累计分账金额 + resultAmt = resultAmt.add(new BigDecimal(paymentConfirm.getConfirmAmt())); + } + } + } + } + return resultAmt; + } /** * 余额支付订单逻辑