From 9517fffcd80fbf10470434802d96a63bb1415153 Mon Sep 17 00:00:00 2001 From: 18650502300 <18650502300@163.com> Date: Fri, 13 Sep 2024 20:27:36 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E9=80=9A=E8=81=94=E6=94=AF=E4=BB=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/common/CallbackController.java | 73 +++++ .../system/EtChannelController.java | 6 + .../common/constant/ServiceConstants.java | 7 +- .../common/core/domain/entity/SysDept.java | 11 + .../com/ruoyi/common/enums/PayChannel.java | 26 ++ .../common/pay/syb/service/ApiTestV2.java | 2 +- .../common/pay/syb/service/SybPayClient.java | 3 +- .../common/pay/syb/service/SybPayService.java | 7 +- .../com/ruoyi/common/pay/wx/RefundAble.java | 33 +- .../java/com/ruoyi/system/domain/Channel.java | 36 ++- .../ruoyi/system/service/CallbackService.java | 12 +- .../ruoyi/system/service/IWxPayService.java | 2 +- .../service/impl/CallbackServiceImpl.java | 292 +++++++++--------- .../service/impl/EtOrderServiceImpl.java | 19 +- .../system/service/impl/WxPayService.java | 254 +++++++++++---- .../java/com/ruoyi/system/task/EtTask.java | 5 +- .../mapper/system/EtChannelMapper.xml | 18 +- .../resources/mapper/system/SysDeptMapper.xml | 12 +- 18 files changed, 548 insertions(+), 270 deletions(-) create mode 100644 electripper-common/src/main/java/com/ruoyi/common/enums/PayChannel.java diff --git a/electripper-admin/src/main/java/com/ruoyi/web/controller/common/CallbackController.java b/electripper-admin/src/main/java/com/ruoyi/web/controller/common/CallbackController.java index e2f4734..1f92247 100644 --- a/electripper-admin/src/main/java/com/ruoyi/web/controller/common/CallbackController.java +++ b/electripper-admin/src/main/java/com/ruoyi/web/controller/common/CallbackController.java @@ -1,5 +1,17 @@ package com.ruoyi.web.controller.common; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.common.constant.ServiceConstants; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.pay.syb.enums.SybTrxCode; +import com.ruoyi.common.pay.syb.enums.SybTrxStatus; +import com.ruoyi.common.pay.syb.service.SybPayService; +import com.ruoyi.common.pay.syb.util.SybUtil; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.system.domain.EtCallbackLog; +import com.ruoyi.system.domain.vo.AttachVo; +import com.ruoyi.system.mapper.EtCallbackLogMapper; import com.ruoyi.system.service.CallbackService; import com.wechat.pay.java.core.exception.ValidationException; import io.swagger.annotations.ApiOperation; @@ -11,7 +23,11 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; +import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; +import java.util.TreeMap; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; /** * 支付回调 @@ -24,6 +40,15 @@ public class CallbackController { @Autowired private CallbackService callbackService; + @Autowired + private SybPayService sybPayService; + + @Autowired + private ScheduledExecutorService scheduledExecutorService; + + @Resource + private EtCallbackLogMapper callbackLogMapper; + /** * 微信支付回调 */ @@ -57,4 +82,52 @@ public class CallbackController { } return ResponseEntity.status(HttpStatus.OK).body(null); } + + /** + * 通联微信支付回调 + */ + @ApiOperation(value = "通联微信支付回调") + @RequestMapping(value = "/tlwx", method = RequestMethod.POST) + public String tlwx(HttpServletRequest request) { + try { + request.setCharacterEncoding("UTF-8");//通知传输的编码为GBK + // 获取所有参数 + TreeMap params = SybUtil.getParams(request); + boolean sign = sybPayService.validSign(params); + + if (sign) { + EtCallbackLog etCallbackLog = new EtCallbackLog(); + etCallbackLog.setBody(JSON.toJSONString(params)); + etCallbackLog.setType("1"); + + String trxCode = params.get("trxcode"); // 交易类型 + String outTradeNo = params.get("cusorderid"); // 商户自定义订单号 + String trxStatus = params.get("trxstatus"); // 交易结果 + String remark = params.get("remark"); // 附加信息,用于判断业务类型 + AttachVo attachVo = JSONObject.parseObject(remark,AttachVo.class); + + if (SybTrxStatus.isSuccess(trxStatus) && SybTrxCode.WX_PAY.equalsCode(trxCode)) { + // 新版支付订单 + callbackService.businessHandle(outTradeNo,attachVo, ServiceConstants.PAY_TYPE_TLWX); + } + //异步保存回调日志 + asynchronousSaveCallbackLog(etCallbackLog); + } + return "error"; + } catch (Exception e) { + throw new ServiceException(e.getMessage()); + } + } + + private void asynchronousSaveCallbackLog(EtCallbackLog etCallbackLog) { + //开异步线程保存回调参数 + scheduledExecutorService.schedule(() -> { + log.info("【微信支付回调】异步保存回调参数"); + etCallbackLog.setCreateTime(DateUtils.getNowDate()); + int i = callbackLogMapper.insertEtCallbackLog(etCallbackLog); + if(i>0){ + log.info("【微信支付回调】异步保存回调参数成功"); + } + }, 0, TimeUnit.SECONDS); + } } diff --git a/electripper-admin/src/main/java/com/ruoyi/web/controller/system/EtChannelController.java b/electripper-admin/src/main/java/com/ruoyi/web/controller/system/EtChannelController.java index c49397c..0fad8b6 100644 --- a/electripper-admin/src/main/java/com/ruoyi/web/controller/system/EtChannelController.java +++ b/electripper-admin/src/main/java/com/ruoyi/web/controller/system/EtChannelController.java @@ -80,6 +80,12 @@ public class EtChannelController extends BaseController channel.setEnabled(form.getEnabled()); channel.setCostRate(form.getCostRate()); channel.setPicture(form.getPicture()); + channel.setMerchantId(form.getMerchantId()); + channel.setApiV3Key(form.getApiV3Key()); + channel.setNotifyUrl(form.getNotifyUrl()); + channel.setPrivateKeyPath(form.getPrivateKeyPath()); + channel.setMerchantSerialNumber(form.getMerchantSerialNumber()); + channel.setRefundNotifyUrl(form.getRefundNotifyUrl()); return toAjax(smEtChannelService.updateSmChannel(channel)); } diff --git a/electripper-common/src/main/java/com/ruoyi/common/constant/ServiceConstants.java b/electripper-common/src/main/java/com/ruoyi/common/constant/ServiceConstants.java index 168eff4..a7d7cd5 100644 --- a/electripper-common/src/main/java/com/ruoyi/common/constant/ServiceConstants.java +++ b/electripper-common/src/main/java/com/ruoyi/common/constant/ServiceConstants.java @@ -140,12 +140,17 @@ public class ServiceConstants { /**----------------------------支付状态end----------------------------*/ /**----------------------------类型start----------------------------*/ - /** 支付方式:wx-微信,alipay-支付宝 */ + /** 支付方式:wx-微信,alipay-支付宝,tlwx-通联微信*/ /** * 支付方式: wx-微信 */ public static final String PAY_TYPE_WX = "wx"; + /** + * 支付方式: tlwx-通联微信 + */ + public static final String PAY_TYPE_TLWX = "tlwx"; + /** * 支付方式: sys-系统 免费骑行时,订单金额为0 */ diff --git a/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java b/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java index 9a002d8..9566a10 100644 --- a/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java +++ b/electripper-common/src/main/java/com/ruoyi/common/core/domain/entity/SysDept.java @@ -130,6 +130,17 @@ public class SysDept extends BaseEntity /** 可提现金额 */ public BigDecimal withdrawableAmount; + /** 支付渠道 */ + public Long payChannel; + + public Long getPayChannel() { + return payChannel; + } + + public void setPayChannel(Long payChannel) { + this.payChannel = payChannel; + } + public void setPlatformServiceFee(String platformServiceFee) { this.platformServiceFee = platformServiceFee; } diff --git a/electripper-common/src/main/java/com/ruoyi/common/enums/PayChannel.java b/electripper-common/src/main/java/com/ruoyi/common/enums/PayChannel.java new file mode 100644 index 0000000..a6bdc28 --- /dev/null +++ b/electripper-common/src/main/java/com/ruoyi/common/enums/PayChannel.java @@ -0,0 +1,26 @@ +package com.ruoyi.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 支付渠道枚举 + * @author qzz + * 2024/9/13 + */ + +@Getter +@AllArgsConstructor +public enum PayChannel { + CT_WX("ctwx", "创特微信支付"), + TL_WX("tlwx", "通联微信支付"), + YS_WX("yswx", "嵛山岛微信支付"); + + private final String code; + + private final String msg; + + public boolean equalsCode(String code) { + return this.getCode().equals(code); + } +} diff --git a/electripper-common/src/main/java/com/ruoyi/common/pay/syb/service/ApiTestV2.java b/electripper-common/src/main/java/com/ruoyi/common/pay/syb/service/ApiTestV2.java index ef852e1..fb9e74b 100644 --- a/electripper-common/src/main/java/com/ruoyi/common/pay/syb/service/ApiTestV2.java +++ b/electripper-common/src/main/java/com/ruoyi/common/pay/syb/service/ApiTestV2.java @@ -32,7 +32,7 @@ public class ApiTestV2 extends BaseController { @PostMapping("/refund") public AjaxResult testRefund() throws Exception { String reqsn = String.valueOf(System.currentTimeMillis()); - Map map = service.refund(1, reqsn, "", "20160712167578.2547"); + Map map = service.refund(1, reqsn, "", "20160712167578.2547",""); return success(map); } diff --git a/electripper-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayClient.java b/electripper-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayClient.java index e41a355..2874904 100644 --- a/electripper-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayClient.java +++ b/electripper-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayClient.java @@ -149,7 +149,7 @@ public class SybPayClient { return map; } - public Map refund(long trxamt,String reqsn,String oldtrxid,String oldreqsn) throws Exception{ + public Map refund(long trxamt,String reqsn,String oldtrxid,String oldreqsn,String reason) throws Exception{ HttpConnectionUtil http = new HttpConnectionUtil(sybConfig.getApiUrl()+"/refund"); http.init(); TreeMap params = new TreeMap(); @@ -164,6 +164,7 @@ public class SybPayClient { params.put("oldtrxid", oldtrxid); params.put("randomstr", SybUtil.getValidatecode(8)); params.put("signtype", sybConfig.getSignType()); + params.put("remark", reason); String appkey = ""; if(sybConfig.getSignType().equals("RSA")) appkey = sybConfig.getRsaCusPriKey(); diff --git a/electripper-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayService.java b/electripper-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayService.java index 7275e93..684ed6f 100644 --- a/electripper-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayService.java +++ b/electripper-common/src/main/java/com/ruoyi/common/pay/syb/service/SybPayService.java @@ -102,10 +102,11 @@ public class SybPayService { public Map refundWx(RefundAble refundAble) { try { return sybPayClient.refund( - refundAble.refundAmount().getRefund().longValue(), - refundAble.refundOutRefundNo(), + refundAble.getAmount(), + refundAble.getOutRefundNo(), "", - refundAble.refundOutTradeNo() + refundAble.getOutTradeNo(), + refundAble.getReason() ); } catch (Exception e) { throw new ServiceException("发起退款异常:" + e.getMessage()); diff --git a/electripper-common/src/main/java/com/ruoyi/common/pay/wx/RefundAble.java b/electripper-common/src/main/java/com/ruoyi/common/pay/wx/RefundAble.java index 2a9a54c..af4a203 100644 --- a/electripper-common/src/main/java/com/ruoyi/common/pay/wx/RefundAble.java +++ b/electripper-common/src/main/java/com/ruoyi/common/pay/wx/RefundAble.java @@ -1,23 +1,34 @@ package com.ruoyi.common.pay.wx; -import com.wechat.pay.java.service.refund.model.AmountReq; +import lombok.Data; + +import java.math.BigDecimal; /** * @author wjh - * 2024/7/10 + * 2024/9/12 */ -public interface RefundAble { +@Data +public class RefundAble { - // 原商户订单号 - String refundOutTradeNo(); + /** + * 外部订单号 + */ + private String outTradeNo; - // 退款单号 - String refundOutRefundNo(); + /** + * 退款订单号 + */ + private String outRefundNo; - // 退款原因 - String refundReason(); + /** + * 退款原因 + */ + private String reason; - // 退款金额(分) - AmountReq refundAmount(); + /** + * 退款金额 + */ + private long amount; } diff --git a/electripper-system/src/main/java/com/ruoyi/system/domain/Channel.java b/electripper-system/src/main/java/com/ruoyi/system/domain/Channel.java index 3cdd8a1..21fe400 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/domain/Channel.java +++ b/electripper-system/src/main/java/com/ruoyi/system/domain/Channel.java @@ -1,9 +1,7 @@ package com.ruoyi.system.domain; -import com.fasterxml.jackson.annotation.JsonView; import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.core.domain.BaseEntity; -//import com.ruoyi.common.core.domain.JsonViewProfile; import com.ruoyi.common.core.domain.ValidGroup; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -23,34 +21,44 @@ public class Channel extends BaseEntity private static final long serialVersionUID = 1L; /** 主键 */ -// @JsonView(JsonViewProfile.App.class) private Long channelId; /** 渠道名称 */ @Excel(name = "渠道名称") -// @JsonView(JsonViewProfile.App.class) private String name; + /** 渠道代码 */ + @Excel(name = "渠道代码") + private String code; + /** 是否启用 */ @Excel(name = "是否启用") private Boolean enabled; -// /** 服务费费率% */ -// @Excel(name = "服务费费率%") -// @Min(value = 0, message = "服务费费率不允许低于0", groups = {ValidGroup.Update.class}) -// private BigDecimal serviceRate; - /** 成本率% */ @Excel(name = "成本率%") @Min(value = 0, message = "成本率不允许低于0", groups = {ValidGroup.Update.class}) private BigDecimal costRate; -// @Excel(name = "服务费类型") -// @ApiModelProperty("服务费类型") -// private String serviceType; - @ApiModelProperty("渠道图片") -// @JsonView(JsonViewProfile.App.class) private String picture; + /** merchantId */ + private String merchantId; + + /** apiV3Key */ + private String apiV3Key; + + /** 通知回调地址 */ + private String notifyUrl; + + /** 密钥所在位置 */ + private String privateKeyPath; + + /** 证书序列号 */ + private String merchantSerialNumber; + + /** 退款回调地址 */ + private String refundNotifyUrl; + } diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/CallbackService.java b/electripper-system/src/main/java/com/ruoyi/system/service/CallbackService.java index 2a34a99..ea8da35 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/CallbackService.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/CallbackService.java @@ -5,6 +5,7 @@ import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.system.domain.EtCapitalFlow; import com.ruoyi.system.domain.EtOperatingArea; import com.ruoyi.system.domain.EtOrder; +import com.ruoyi.system.domain.vo.AttachVo; import javax.servlet.http.HttpServletRequest; import java.math.BigDecimal; @@ -21,6 +22,13 @@ public interface CallbackService { */ void weChat(HttpServletRequest request); + /** + * 支付成功后的业务处理 + * @param outTradeNo + * @return String + */ + public void businessHandle(String outTradeNo,AttachVo attachVo,String payType); + /** * 微信退款回调 * @param request 微信回调json @@ -58,7 +66,7 @@ public interface CallbackService { * @param type 类型 * @param busType 业务类型 * @param ownerType 所属人类型 - * @param user 合伙人对象 + * @param sysDept 运营商对象 * @return void */ public int capitalFlowRecords2(EtOrder order, String type, String busType, String ownerType, SysDept sysDept); @@ -69,8 +77,6 @@ public interface CallbackService { * @param type 类型 * @param busType 业务类型 * @param ownerType 所属人类型 - * @param user 合伙人对象 - * @param payType 支付方式 * @return void */ public int capitalFlowRecordsByAppUser(EtOrder order, String type, String busType, String ownerType, SysDept sysDept); diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/IWxPayService.java b/electripper-system/src/main/java/com/ruoyi/system/service/IWxPayService.java index 04baafe..183368a 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/IWxPayService.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/IWxPayService.java @@ -78,7 +78,7 @@ public interface IWxPayService { * @param amount 退款金额 * @param outRefundNo 退款订单号 */ - Refund refund(EtOrder etOrder, String reason, BigDecimal amount, String outRefundNo); + void refund(EtOrder etOrder, String reason, BigDecimal amount, String outRefundNo); /** * 发起商家转账 diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java b/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java index 8dbf299..52cd500 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/impl/CallbackServiceImpl.java @@ -8,6 +8,7 @@ import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; import com.aliyuncs.exceptions.ClientException; import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.IotConstants; import com.ruoyi.common.constant.ServiceConstants; import com.ruoyi.common.core.domain.entity.AsUser; import com.ruoyi.common.core.domain.entity.SysDept; @@ -32,7 +33,6 @@ import com.wechat.pay.java.core.notification.NotificationParser; import com.wechat.pay.java.core.notification.RequestParam; import com.wechat.pay.java.service.payments.model.Transaction; import com.wechat.pay.java.service.profitsharing.model.CreateOrderReceiver; -import com.wechat.pay.java.service.profitsharing.model.OrdersEntity; import com.wechat.pay.java.service.profitsharing.model.ReceiverType; import com.wechat.pay.java.service.refund.model.Refund; import com.wechat.pay.java.service.refund.model.RefundNotification; @@ -43,11 +43,15 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.support.TransactionTemplate; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.math.BigDecimal; -import java.util.*; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Optional; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -81,9 +85,6 @@ public class CallbackServiceImpl implements CallbackService { @Autowired private IEtRefundService etRefundService; - @Autowired - private IEtFeeRuleService etFeeRuleService; - @Autowired private IWxPayService wxPayService; @@ -108,9 +109,6 @@ public class CallbackServiceImpl implements CallbackService { @Autowired private IEtDividendDetailService dividendDetailService; - @Resource - private EtAreaDeptMapper etAreaDeptMapper; - @Autowired private ISysDeptService deptService; @@ -126,6 +124,9 @@ public class CallbackServiceImpl implements CallbackService { @Resource private EtCouponClaimLogMapper etCouponClaimLogMapper; + @Autowired + private TransactionTemplate transactionTemplate; + @Value("${aliyun.accessKeyId}") private String accessKeyId; @@ -150,7 +151,6 @@ public class CallbackServiceImpl implements CallbackService { * 微信支付回调 */ @Override -// @SneakyThrows @Transactional public void weChat(HttpServletRequest request) { String body = HttpUtils.getBody(request); @@ -160,7 +160,6 @@ public class CallbackServiceImpl implements CallbackService { etCallbackLog.setType("1"); // 解析通知数据 Notification notification = JSON.parseObject(body, Notification.class); - String outTradeNo; //异步保存回调日志 asynchronousSaveCallbackLog(etCallbackLog); @@ -168,148 +167,143 @@ public class CallbackServiceImpl implements CallbackService { // 支付成功通知 if (NotifyEventType.TRANSACTION_SUCCESS.getValue().equals(notification.getEventType())) { // 验签、解密并转换成 Transaction - String wechatpaySerial = request.getHeader("Wechatpay-Serial"); - logger.info("证书序列号:" + wechatpaySerial); Transaction transaction = checkAndParse(request, body, Transaction.class); if (Transaction.TradeStateEnum.SUCCESS.equals(transaction.getTradeState())) { - // 充值成功后的业务处理 - logger.info("【微信支付回调】交易对象(验签后) : " + JSON.toJSONString(transaction)); etCallbackLog.setBody(JSON.toJSONString(transaction)); - String transactionId = transaction.getTransactionId(); AttachVo attachVo = JSONObject.parseObject(transaction.getAttach(),AttachVo.class); - logger.info("【微信支付回调】附加信息 : " + JSON.toJSONString(attachVo)); - outTradeNo = transaction.getOutTradeNo(); - EtOrder order = orderService.selectEtOrderByOutTradeNo(outTradeNo); - logger.info("【微信支付回调】订单信息 : " + JSON.toJSONString(order)); - - AsUser asUser = asUserMapper.selectUserById(order.getUserId()); - /** 支付回调逻辑 1. 处理预约还是开锁 电压 */ - AsDevice asDevice = null; - if(StrUtil.isNotBlank(order.getSn())){ - asDevice = asDeviceMapper.selectAsDeviceBySn(order.getSn()); - } - //先判断是骑行订单还是押金,如果是骑行订单 - // 还要区分是取消预约支付 - // 如果是,更新订单状态,pay_time、pay_type(默认是wx)、appointment_fee等于total_fee,状态改为4 订单结束 - // 如果是扫码骑行后还车支付 - // 更新订单状态,pay_time、pay_type(默认是wx)、total_fee等于预约费+骑行费+管理费+调度费,状态改为4 订单结束,保存微信内部订单号 callbackVo.getOutTradeNo() - order.setPaid("1"); - order.setPayTime(DateUtils.getNowDate()); - order.setPayType(ServiceConstants.PAY_TYPE_WX); - order.setLocking("0"); - // 如果使用了优惠券则扣除一次使用次数 - if(ObjectUtil.isNotNull(order.getLogId())){ - EtCouponUserLog couponUserLog = etCouponClaimLogMapper.selectEtCouponClaimLogByLogId(order.getLogId()); - EtCoupon etCoupon = etCouponMapper.selectEtCouponByCouponId(couponUserLog.getCouponId()); - logger.info("【微信支付回调】优惠券信息 : " + JSON.toJSONString(etCoupon)); - if(ObjectUtil.isNotNull(etCoupon) && (etCoupon.getType().equals(ServiceConstants.COUPON_TYPE_DISCOUNT_CARD) || etCoupon.getType().equals(ServiceConstants.COUPON_TYPE_VOUCHER)) && couponUserLog.getLimitNum() > 0){ - etCouponClaimLogMapper.deductLimitNum(couponUserLog.getLogId()); - logger.info("【微信支付回调】优惠券使用次数-1"); - } - } - if(attachVo.getType().equals(ServiceConstants.BUSINESS_TYPE_RIDING)){ - logger.info("【微信支付回调】骑行支付"); - // 1-骑行支付 关锁 - EtOperatingArea area = etOperatingAreaService.selectEtOperatingAreaByAreaId(order.getAreaId()); - order.setMark("骑行支付"); - logger.info("=================【微信支付回调】11111111=================="); - if(ServiceConstants.RETURN_VERIFY_YES.equals(area.getReturnVerify())){ - logger.info("【微信支付回调】还车-----需要-----拍照审核"); - order.setStatus(ServiceConstants.ORDER_STATUS_TO_BE_AUDIT);//如果还车需要拍照审核,状态为待审核 - BigDecimal amount = order.getPayFee(); - - // 异步处理短信 - if("1".equals(area.getMsgSwitch())){ - asynchronousMsg(order, amount); - } - }else{ - logger.info("【微信支付回调】还车-----不需要-----拍照审核"); - order.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END); - // 还车结算___小时后自动退押金---创建一个定时器TimerTask,计算出退还时间后,执行退款操作 - logger.info("=================【微信支付回调】22222222=================="); - // 退还押金处理 - refundDeposit(area.getDeposit(), order, asUser); - logger.info("=================【微信支付回调】33333333=================="); - // 用户付款通知 - if("1".equals(area.getMsgSwitch())){ - asynchronousMsg2(order); - } - } - asDevice.setStatus(ServiceConstants.VEHICLE_STATUS_NORMAL);//还车后车辆正常运营 - asDevice.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE); - // 新增资金流水记录 - EtCapitalFlow capitalFlow = capitalFlowRecords(order, ServiceConstants.FLOW_TYPE_INCOME, ServiceConstants.ORDER_TYPE_RIDING, ServiceConstants.OWNER_TYPE_OPERATOR, null, ServiceConstants.PAY_TYPE_WX); - logger.info("=================【骑行支付回调-新增资金流水记录后】=================={}",JSON.toJSON(capitalFlow)); - order.setHandlingCharge(capitalFlow.getHandlingCharge()); - order.setPlatformServiceFee(capitalFlow.getPlatformServiceFee()); - order.setOperatorDividend(capitalFlow.getOperatorDividend()); - order.setCost(getCost(order.getPayFee())); - // 发起分账 -// BigDecimal dividendAmount= order.getPayFee().subtract(capitalFlow.getHandlingCharge()).subtract(capitalFlow.getPlatformServiceFee());//分账金额(订单实际支付金额-平台服务费-支付手续费) -// logger.info("=================【微信支付回调】分账金额=================={}",dividendAmount); -// dividendHandle(transactionId, order, area,dividendAmount); - logger.info("=================【微信支付回调】4444444=================="); - }else if(attachVo.getType().equals(ServiceConstants.BUSINESS_TYPE_APPOINTMENT)){ - logger.info("【微信支付回调】取消预约支付"); - // 2-取消预约支付 - order.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END); - order.setMark("取消预约支付"); - asDevice.setStatus(ServiceConstants.VEHICLE_STATUS_NORMAL);//取消预约支付后车辆正常运营 - asDevice.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE); - }else if(attachVo.getType().equals(ServiceConstants.ORDER_TYPE_COUPON)){ - /** 优惠券订单 */ - logger.info("【微信支付回调】优惠券支付"); - // 3-优惠券支付 - order.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END); - order.setMark("优惠券支付"); - // 优惠券成功处理逻辑 - couponSuccessHandle(order); - }else if(attachVo.getType().equals(ServiceConstants.BUSINESS_TYPE_DEPOSIT)){ - logger.info("【微信支付回调】押金支付"); - // 4-押金支付 - order.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END); - asUser.setBalance(order.getTotalFee()); - order.setMark("押金支付"); - - // 新增资金流水记录 -// capitalFlowRecords(order,ServiceConstants.FLOW_TYPE_INCOME,ServiceConstants.ORDER_TYPE_DEPOSIT); - // 删除用户缓存 - String token = attachVo.getToken(); - logger.info("【微信支付回调】删除用户缓存:"+token); - if (StringUtils.isNotNull(token)) - { - redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + token); - } - }else{ - logger.error("【微信支付回调】 : 支付场景不存在"); - throw new ServiceException("【微信支付回调】支付场景不存在"); - } - if(ObjectUtil.isNotNull(asDevice)){ - int device = asDeviceService.updateAsDevice(asDevice); - if(device==0){ - logger.error("【微信支付回调】更新车辆状态失败"); - throw new ServiceException("【微信支付回调】更新车辆状态失败"); - } - } - logger.info("=================【微信支付回调】开始更新订单信息=================={}",JSON.toJSON(order)); - int updateEtOrder = orderService.updateEtOrder(order); - if(updateEtOrder==0){ - logger.error("【微信支付回调】更新订单信息失败"); - throw new ServiceException("【微信支付回调】更新订单信息失败"); - } - if(attachVo.getType().equals(ServiceConstants.BUSINESS_TYPE_DEPOSIT)){ - logger.info("=================【微信支付回调】开始更新用户信息=================="); - int updateUser = userService.updateUser(asUser); - if(updateUser==0){ - logger.error("【微信支付回调】更新用户押金失败"); - throw new ServiceException("【微信支付回调】更新用户押金失败"); - } - } - logger.info("=================【微信支付回调】全部结束!!!!!=================="); + businessHandle(transaction.getOutTradeNo(), attachVo, ServiceConstants.PAY_TYPE_WX);//业务处理 } } } + /** + * 支付成功后的业务处理 + */ + @Override + public void businessHandle(String outTradeNo,AttachVo attachVo,String payType) { + // 充值成功后的业务处理 + EtOrder order = orderService.selectEtOrderByOutTradeNo(outTradeNo); + logger.info("【微信支付回调】订单信息 : " + JSON.toJSONString(order)); + + AsUser asUser = asUserMapper.selectUserById(order.getUserId()); + /** 支付回调逻辑 1. 处理预约还是开锁 电压 */ + AsDevice asDevice = null; + if(StrUtil.isNotBlank(order.getSn())){ + asDevice = asDeviceMapper.selectAsDeviceBySn(order.getSn()); + } + if(attachVo.getType().equals(ServiceConstants.BUSINESS_TYPE_RIDING)){ + logger.info("【微信支付回调】骑行支付"); + // 1-骑行支付 关锁 + EtOperatingArea area = etOperatingAreaService.selectEtOperatingAreaByAreaId(order.getAreaId()); + order.setMark("骑行支付"); + logger.info("=================【微信支付回调】11111111=================="); + if(ServiceConstants.RETURN_VERIFY_YES.equals(area.getReturnVerify())){ + logger.info("【微信支付回调】还车-----需要-----拍照审核"); + order.setStatus(ServiceConstants.ORDER_STATUS_TO_BE_AUDIT);//如果还车需要拍照审核,状态为待审核 + BigDecimal amount = order.getPayFee(); + + // 异步处理短信 + if("1".equals(area.getMsgSwitch())){ + asynchronousMsg(order, amount); + } + }else{ + logger.info("【微信支付回调】还车-----不需要-----拍照审核"); + order.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END); + // 还车结算___小时后自动退押金---创建一个定时器TimerTask,计算出退还时间后,执行退款操作 + logger.info("=================【微信支付回调】22222222=================="); + // 退还押金处理 + refundDeposit(area.getDeposit(), order, asUser); + logger.info("=================【微信支付回调】33333333=================="); + // 用户付款通知 + if("1".equals(area.getMsgSwitch())){ + asynchronousMsg2(order); + } + } + asDevice.setStatus(ServiceConstants.VEHICLE_STATUS_NORMAL);//还车后车辆正常运营 + asDevice.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE); + // 新增资金流水记录 + EtCapitalFlow capitalFlow = capitalFlowRecords(order, ServiceConstants.FLOW_TYPE_INCOME, ServiceConstants.ORDER_TYPE_RIDING, ServiceConstants.OWNER_TYPE_OPERATOR, null, ServiceConstants.PAY_TYPE_WX); + logger.info("=================【骑行支付回调-新增资金流水记录后】=================={}",JSON.toJSON(capitalFlow)); + order.setHandlingCharge(capitalFlow.getHandlingCharge()); + order.setPlatformServiceFee(capitalFlow.getPlatformServiceFee()); + order.setOperatorDividend(capitalFlow.getOperatorDividend()); + order.setCost(getCost(order.getPayFee())); + logger.info("=================【微信支付回调】4444444=================="); + }else if(attachVo.getType().equals(ServiceConstants.BUSINESS_TYPE_APPOINTMENT)){ + logger.info("【微信支付回调】取消预约支付"); + // 2-取消预约支付 + order.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END); + order.setMark("取消预约支付"); + asDevice.setStatus(ServiceConstants.VEHICLE_STATUS_NORMAL);//取消预约支付后车辆正常运营 + asDevice.setLockStatus(ServiceConstants.LOCK_STATUS_CLOSE); + }else if(attachVo.getType().equals(ServiceConstants.ORDER_TYPE_COUPON)){ + /** 优惠券订单 */ + logger.info("【微信支付回调】优惠券支付"); + // 3-优惠券支付 + order.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END); + order.setMark("优惠券支付"); + // 优惠券成功处理逻辑 + couponSuccessHandle(order); + }else if(attachVo.getType().equals(ServiceConstants.BUSINESS_TYPE_DEPOSIT)){ + logger.info("【微信支付回调】押金支付"); + // 4-押金支付 + order.setStatus(ServiceConstants.ORDER_STATUS_ORDER_END); + asUser.setBalance(order.getTotalFee()); + order.setMark("押金支付"); + // 删除用户缓存 + String token = attachVo.getToken(); + logger.info("【微信支付回调】删除用户缓存:"+token); + if (StringUtils.isNotNull(token)) + { + redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + token); + } + }else{ + logger.error("【微信支付回调】 : 支付场景不存在"); + throw new ServiceException("【微信支付回调】支付场景不存在"); + } + if(ObjectUtil.isNotNull(asDevice)){ + int device = asDeviceService.updateAsDevice(asDevice); + if(device==0){ + logger.error("【微信支付回调】更新车辆状态失败"); + throw new ServiceException("【微信支付回调】更新车辆状态失败"); + } + } + + Boolean execute = transactionTemplate.execute(e -> { + order.setPaid("1"); + order.setPayTime(DateUtils.getNowDate()); + order.setPayType(payType); + order.setLocking("0"); + // 如果使用了优惠券则扣除一次使用次数 + if(ObjectUtil.isNotNull(order.getLogId())){ + EtCouponUserLog couponUserLog = etCouponClaimLogMapper.selectEtCouponClaimLogByLogId(order.getLogId()); + EtCoupon etCoupon = etCouponMapper.selectEtCouponByCouponId(couponUserLog.getCouponId()); + logger.info("【微信支付回调】优惠券信息 : " + JSON.toJSONString(etCoupon)); + if(ObjectUtil.isNotNull(etCoupon) && (etCoupon.getType().equals(ServiceConstants.COUPON_TYPE_DISCOUNT_CARD) || etCoupon.getType().equals(ServiceConstants.COUPON_TYPE_VOUCHER)) && couponUserLog.getLimitNum() > 0){ + etCouponClaimLogMapper.deductLimitNum(couponUserLog.getLogId()); + logger.info("【微信支付回调】优惠券使用次数-1"); + } + } + logger.info("=================【微信支付回调】开始更新订单信息=================={}",JSON.toJSON(order)); + int updateEtOrder = orderService.updateEtOrder(order); + if(updateEtOrder==0){ + logger.error("【微信支付回调】更新订单信息失败"); + throw new ServiceException("【微信支付回调】更新订单信息失败"); + } + if(attachVo.getType().equals(ServiceConstants.BUSINESS_TYPE_DEPOSIT)){ + logger.info("=================【微信支付回调】开始更新用户信息=================="); + int updateUser = userService.updateUser(asUser); + if(updateUser==0){ + logger.error("【微信支付回调】更新用户押金失败"); + throw new ServiceException("【微信支付回调】更新用户押金失败"); + } + } + logger.info("=================【微信支付回调】全部结束!!!!!=================="); + return Boolean.TRUE; + }); + if(!execute)throw new ServiceException("管理员开锁失败"); + } + private BigDecimal getCost(BigDecimal payFee) { // todo 获取到微信的成本 BigDecimal bigDecimal = new BigDecimal(0.54).divide(new BigDecimal(100), 6, BigDecimal.ROUND_HALF_UP); @@ -649,9 +643,9 @@ public class CallbackServiceImpl implements CallbackService { } String reason = autoRefundDeposit + "个小时后自动退押金"; String outRefundNo = IdUtils.getOrderNo("ref"); - Refund refund = wxPayService.refund(newestOrder,reason, newestOrder.getTotalFee(), outRefundNo); + wxPayService.refund(newestOrder,reason, newestOrder.getTotalFee(), outRefundNo); newestOrder.setReason(reason); - EtRefund refund1= orderService.createRefund(newestOrder, newestOrder.getTotalFee(), null, null, null, null, refund.getOutRefundNo(),ServiceConstants.REFUND_TYPE_DEPOSIT); + EtRefund refund1= orderService.createRefund(newestOrder, newestOrder.getTotalFee(), null, null, null, null, outRefundNo,ServiceConstants.REFUND_TYPE_DEPOSIT); int i = etRefundService.insertEtRefund(refund1); if(i>0){ logger.info("【自动退款】保存退款对象成功"); @@ -1163,12 +1157,6 @@ public class CallbackServiceImpl implements CallbackService { logger.error("【微信退款回调】更新退款单失败"); throw new ServiceException("【微信退款回调】更新退款单失败"); } - EtRefund refund = etRefundService.selectEtRefundByRefundNo(outRefundNo); - EtOrder order = orderService.selectEtOrderByOrderNo(refund.getOrderNo()); - // 新增资金流水记录 -// if(order.getOrderNo().contains("qx")){ -// capitalFlowRecords(order,ServiceConstants.FLOW_TYPE_DISBURSE,ServiceConstants.ORDER_TYPE_RIDING_REFUND); -// } logger.info("【微信退款回调】全部结束!!!!!"); } } diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtOrderServiceImpl.java b/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtOrderServiceImpl.java index 6748a78..1525b8f 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtOrderServiceImpl.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/impl/EtOrderServiceImpl.java @@ -580,11 +580,12 @@ public class EtOrderServiceImpl implements IEtOrderService throw new ServiceException("押金抵扣失败,更新押金订单失败"); } if(afterDeductionFee.compareTo(BigDecimal.ZERO) > 0){ + String refNo = IdUtils.getOrderNo("ref"); /** 退款剩余押金*/ - Refund refund = wxPayService.refund(depositOrder, "押金抵扣退款",afterDeductionFee,IdUtils.getOrderNo("ref")); + wxPayService.refund(depositOrder, "押金抵扣退款",afterDeductionFee,refNo); /** 2.记录退款表 创建退款对象*/ depositOrder.setReason("押金抵扣退款"); - EtRefund refund1= createRefund(depositOrder, afterDeductionFee, null, null, null, null, refund.getOutRefundNo(),ServiceConstants.REFUND_TYPE_DEPOSIT); + EtRefund refund1= createRefund(depositOrder, afterDeductionFee, null, null, null, null, refNo,ServiceConstants.REFUND_TYPE_DEPOSIT); int i = etRefundService.insertEtRefund(refund1); if(i == 0){ log.info("【押金抵扣】保存退款对象失败"); @@ -667,10 +668,11 @@ public class EtOrderServiceImpl implements IEtOrderService /** 2.退押金*/ EtOrder depositOrder = getDepositOrder(etOrder.getUserId()); BigDecimal deposit = depositOrder.getTotalFee(); - Refund refund = wxPayService.refund(depositOrder, "还车审核通过后退押金",deposit,IdUtils.getOrderNo("ref")); + String refNo = IdUtils.getOrderNo("ref"); + wxPayService.refund(depositOrder, "还车审核通过后退押金",deposit,refNo); /** 3.记录退款表 创建退款对象*/ depositOrder.setReason("还车审核通过后退押金"); - EtRefund refund1= createRefund(depositOrder, deposit, null, null, null, null, refund.getOutRefundNo(),ServiceConstants.REFUND_TYPE_DEPOSIT); + EtRefund refund1= createRefund(depositOrder, deposit, null, null, null, null, refNo,ServiceConstants.REFUND_TYPE_DEPOSIT); int i = etRefundService.insertEtRefund(refund1); if(i == 0){ log.info("【还车审核通过】保存退款对象失败"); @@ -749,11 +751,12 @@ public class EtOrderServiceImpl implements IEtOrderService EtOrder depositOrder = getDepositOrder(etOrder.getUserId()); BigDecimal deductionAmount = new BigDecimal(etOrder.getDeductionAmount()); BigDecimal residualDeposit = depositOrder.getTotalFee().subtract(deductionAmount);//抵扣后的金额 - Refund refund = wxPayService.refund(depositOrder, "还车审核通过后退押金",residualDeposit,IdUtils.getOrderNo("ref")); + String refNo = IdUtils.getOrderNo("ref"); + wxPayService.refund(depositOrder, "还车审核通过后退押金",residualDeposit,refNo); /** 3.记录退款表 创建退款对象*/ depositOrder.setReason("还车审核通过后退押金"); if(deductionAmount.compareTo(BigDecimal.ZERO) > 0){ - EtRefund refund1= createRefund(depositOrder, residualDeposit, null, null, null, null, refund.getOutRefundNo(),ServiceConstants.REFUND_TYPE_DEPOSIT); + EtRefund refund1= createRefund(depositOrder, residualDeposit, null, null, null, null, refNo,ServiceConstants.REFUND_TYPE_DEPOSIT); int i = etRefundService.insertEtRefund(refund1); if(i == 0){ log.info("【还车审核通过】保存退款对象失败"); @@ -1778,7 +1781,7 @@ public class EtOrderServiceImpl implements IEtOrderService log.info("保存退款对象成功"); } log.info("总金额:【{}】,退款金额:【{}】", etOrder1.getTotalFee(), refundAmount); - Refund refund = wxPayService.refund(etOrder1, etOrder.getReason(), refundAmount,outRefundNo); + wxPayService.refund(etOrder1, etOrder.getReason(), refundAmount,outRefundNo); return i; } @@ -1796,7 +1799,7 @@ public class EtOrderServiceImpl implements IEtOrderService if(i>0){ log.info("【提现金额】保存退款对象成功"); } - Refund refund = wxPayService.refund(etOrder1, "押金提现",deposit,outRefundNo); + wxPayService.refund(etOrder1, "押金提现",deposit,outRefundNo); return i; } diff --git a/electripper-system/src/main/java/com/ruoyi/system/service/impl/WxPayService.java b/electripper-system/src/main/java/com/ruoyi/system/service/impl/WxPayService.java index 15b94a7..b59d376 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/service/impl/WxPayService.java +++ b/electripper-system/src/main/java/com/ruoyi/system/service/impl/WxPayService.java @@ -4,23 +4,28 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.ServiceConstants; import com.ruoyi.common.core.domain.entity.AsUser; import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.core.redis.RedisLock; +import com.ruoyi.common.enums.PayChannel; import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.pay.syb.enums.SybTrxStatus; +import com.ruoyi.common.pay.syb.service.SybPayService; import com.ruoyi.common.pay.wx.Payable; +import com.ruoyi.common.pay.wx.RefundAble; import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.ServiceUtil; import com.ruoyi.common.utils.uuid.IdUtils; +import com.ruoyi.system.domain.ChannelVO; import com.ruoyi.system.domain.EtAreaDept; import com.ruoyi.system.domain.EtOrder; +import com.ruoyi.system.domain.EtRefund; import com.ruoyi.system.domain.vo.AttachVo; import com.ruoyi.system.mapper.AsUserMapper; import com.ruoyi.system.mapper.EtAreaDeptMapper; -import com.ruoyi.system.service.IAsUserService; -import com.ruoyi.system.service.IEtOrderService; -import com.ruoyi.system.service.ISysDeptService; -import com.ruoyi.system.service.IWxPayService; +import com.ruoyi.system.service.*; import com.wechat.pay.java.core.Config; import com.wechat.pay.java.core.RSAAutoCertificateConfig; import com.wechat.pay.java.service.payments.jsapi.JsapiService; @@ -45,6 +50,9 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.List; +import java.util.Map; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; /** * 微信支付服务 @@ -76,6 +84,18 @@ public class WxPayService implements IWxPayService { @Autowired private IEtOrderService orderService; + @Autowired + private SybPayService sybPayService; + + @Autowired + private EtChannelService etChannelService; + + @Autowired + private ScheduledExecutorService scheduledExecutorService; + + @Autowired + private IEtRefundService etRefundService; + private static final String CNY = "CNY"; private static final String PREPAY_LOCK = "prepay:"; @@ -94,37 +114,65 @@ public class WxPayService implements IWxPayService { if(ObjectUtil.isNull(sysDept)){ throw new ServiceException("没有运营商:【"+etAreaDept.getDeptId()+"】"); } + String type = order.getType(); + String description = type.equals(ServiceConstants.ORDER_TYPE_RIDING) ? "骑行订单-"+billNo : "押金充值-"+billNo; -// String isProfitSharing = sysDept.getIsProfitSharing(); - // 获取JSAPI所需参数 -// PrepayRequest request = new PrepayRequest(); - Payable payable = new Payable(); - payable.setAmount(order.getPayFee().longValue()); - if(StrUtil.isNotBlank(order.getOutTradeNo())){ - String tradeNo = order.getOutTradeNo(); - // 关闭订单 - CloseOrderRequest closeOrderRequest = new CloseOrderRequest(); - closeOrderRequest.setMchid(sysDept.getMerchantId()); - closeOrderRequest.setOutTradeNo(tradeNo); - jsapiServiceExtension.closeOrder(closeOrderRequest); - } String outTradeNo = IdUtils.getOrderNo("wx"); - order.setOutTradeNo(outTradeNo); - int updateEtOrder = etOrderService.updateEtOrder(order); + EtOrder order1 = new EtOrder(); + order1.setOutTradeNo(outTradeNo); + order1.setOrderId(order.getOrderId()); + int updateEtOrder = etOrderService.updateEtOrder(order1); if(updateEtOrder == 0){ throw new ServiceException("更新订单outTradeNo失败"); } - payable.setOutTradeNo(outTradeNo); -// request.setOutTradeNo(outTradeNo); -// request.setMchid(sysDept.getMerchantId()); - String type = order.getType(); - String description = type.equals(ServiceConstants.ORDER_TYPE_RIDING) ? "骑行订单-"+billNo : "押金充值-"+billNo; - request.setAttach(JSON.toJSONString(new AttachVo(payType,user.getUserId(), ""))); - request.setDescription(description); - request.setNotifyUrl(sysDept.getNotifyUrl()); - request.setPayer(getPayer(user.getWxopenid())); - PrepayWithRequestPaymentResponse res = jsapiServiceExtension.prepayWithRequestPayment(request); - return res; + + Long payChannel = sysDept.getPayChannel(); + if(ObjectUtil.isNull(payChannel)){ + throw new ServiceException("运营商【"+sysDept.getDeptName()+"】没有支付渠道"); + } + + ChannelVO channelVO = etChannelService.selectSmChannelByChannelId(payChannel); + if(PayChannel.CT_WX.equalsCode(channelVO.getCode()) || PayChannel.YS_WX.equalsCode(channelVO.getCode())){ + log.info("----------{}-------------","微信官方支付"); + PrepayRequest request = new PrepayRequest(); + request.setAmount(getAmount(order.getPayFee())); + request.setOutTradeNo(outTradeNo); + request.setAppid(sysDept.getAppid()); + request.setMchid(sysDept.getMerchantId()); + request.setAttach(JSON.toJSONString(new AttachVo(payType,user.getUserId(), ""))); + request.setDescription(description); + request.setNotifyUrl(sysDept.getNotifyUrl()); + request.setPayer(getPayer(user.getWxopenid())); + JsapiServiceExtension jsapiServiceExtension = getJsapiServiceExtension(sysDept); + PrepayWithRequestPaymentResponse res = jsapiServiceExtension.prepayWithRequestPayment(request); + + if(StrUtil.isNotBlank(order.getOutTradeNo())){ + String tradeNo = order.getOutTradeNo(); + // 关闭订单 + CloseOrderRequest closeOrderRequest = new CloseOrderRequest(); + closeOrderRequest.setMchid(sysDept.getMerchantId()); + closeOrderRequest.setOutTradeNo(tradeNo); + jsapiServiceExtension.closeOrder(closeOrderRequest); + } + return res; + }else if(PayChannel.TL_WX.equalsCode(channelVO.getCode())){ + log.info("----------{}-------------","通联微信支付"); + + if(StrUtil.isNotBlank(order.getOutTradeNo())){ + // 关闭订单 + sybPayService.closeOrderWx(order.getOutTradeNo()); + } + Payable payable = new Payable(); + payable.setAmount(order.getPayFee().longValue()); + payable.setOutTradeNo(outTradeNo); + payable.setAttach(JSON.toJSONString(new AttachVo(payType,user.getUserId(), ""))); + payable.setDescription(description); + payable.setOpenid(user.getWxopenid()); + PrepayWithRequestPaymentResponse res = sybPayService.prepayWxApp(payable); + return res; + }else{ + throw new ServiceException("支付渠道【"+channelVO.getCode()+"】暂不支持"); + } }else{ log.info("区域:【{}】没有绑定运营商",order.getAreaId()); throw new ServiceException("区域:【"+order.getAreaId()+"】没有绑定运营商"); @@ -148,34 +196,68 @@ public class WxPayService implements IWxPayService { if(ObjectUtil.isNull(sysDept)){ throw new ServiceException("没有运营商:【"+etAreaDept.getDeptId()+"】"); } - // 获取JSAPI所需参数 - PrepayRequest request = new PrepayRequest(); - request.setAmount(getAmount(order.getPayFee())); - JsapiServiceExtension jsapiServiceExtension = getJsapiServiceExtension(sysDept); - if(StrUtil.isNotBlank(order.getOutTradeNo())){ - String tradeNo = order.getOutTradeNo(); - // 关闭订单 - CloseOrderRequest closeOrderRequest = new CloseOrderRequest(); - closeOrderRequest.setMchid(sysDept.getMerchantId()); - closeOrderRequest.setOutTradeNo(tradeNo); - jsapiServiceExtension.closeOrder(closeOrderRequest); - } + + String description = "优惠券订单-"+billNo; + String outTradeNo = IdUtils.getOrderNo("wx"); - order.setOutTradeNo(outTradeNo); - int updateEtOrder = etOrderService.updateEtOrder(order); + EtOrder order1 = new EtOrder(); + order1.setOutTradeNo(outTradeNo); + order1.setOrderId(order.getOrderId()); + int updateEtOrder = etOrderService.updateEtOrder(order1); if(updateEtOrder == 0){ throw new ServiceException("更新订单outTradeNo失败"); } - request.setOutTradeNo(outTradeNo); - request.setAppid(sysDept.getAppid()); - request.setMchid(sysDept.getMerchantId()); - String description = "优惠券订单-"+billNo; - request.setAttach(JSON.toJSONString(new AttachVo(order.getType(),user.getUserId(), ""))); - request.setDescription(description); - request.setNotifyUrl(sysDept.getNotifyUrl()); - request.setPayer(getPayer(user.getWxopenid())); - PrepayWithRequestPaymentResponse res = jsapiServiceExtension.prepayWithRequestPayment(request); - return res; + + Long payChannel = sysDept.getPayChannel(); + if(ObjectUtil.isNull(payChannel)){ + throw new ServiceException("运营商【"+sysDept.getDeptName()+"】没有支付渠道"); + } + + ChannelVO channelVO = etChannelService.selectSmChannelByChannelId(payChannel); + if(PayChannel.CT_WX.equalsCode(channelVO.getCode()) || PayChannel.YS_WX.equalsCode(channelVO.getCode())){ + log.info("----------{}-------------","微信官方支付"); + PrepayRequest request = new PrepayRequest(); + request.setAmount(getAmount(order.getPayFee())); + request.setOutTradeNo(outTradeNo); + request.setAppid(sysDept.getAppid()); + request.setMchid(sysDept.getMerchantId()); + request.setAttach(JSON.toJSONString(new AttachVo(order.getType(),user.getUserId(), ""))); + request.setDescription(description); + request.setNotifyUrl(sysDept.getNotifyUrl()); + request.setPayer(getPayer(user.getWxopenid())); + JsapiServiceExtension jsapiServiceExtension = getJsapiServiceExtension(sysDept); + PrepayWithRequestPaymentResponse res = jsapiServiceExtension.prepayWithRequestPayment(request); + + if(StrUtil.isNotBlank(order.getOutTradeNo())){ + String tradeNo = order.getOutTradeNo(); + // 关闭订单 + CloseOrderRequest closeOrderRequest = new CloseOrderRequest(); + closeOrderRequest.setMchid(sysDept.getMerchantId()); + closeOrderRequest.setOutTradeNo(tradeNo); + jsapiServiceExtension.closeOrder(closeOrderRequest); + } + + return res; + }else if(PayChannel.TL_WX.equalsCode(channelVO.getCode())){ + log.info("----优惠券------{}-------------","通联微信支付"); + + // 获取JSAPI所需参数 + if(StrUtil.isNotBlank(order.getOutTradeNo())){ + // 关闭订单 + sybPayService.closeOrderWx(order.getOutTradeNo()); + } + + Payable payable = new Payable(); + payable.setAmount(order.getPayFee().longValue()); + payable.setOutTradeNo(outTradeNo); + payable.setAttach(JSON.toJSONString(new AttachVo(order.getType(),user.getUserId(), ""))); + payable.setDescription(description); + payable.setOpenid(user.getWxopenid()); + PrepayWithRequestPaymentResponse res = sybPayService.prepayWxApp(payable); + return res; + }else{ + throw new ServiceException("支付渠道【"+channelVO.getCode()+"】暂不支持"); + } }else{ log.info("区域:【{}】没有绑定运营商",order.getAreaId()); throw new ServiceException("区域:【"+order.getAreaId()+"】没有绑定运营商"); @@ -314,19 +396,59 @@ public class WxPayService implements IWxPayService { * @param outRefundNo 退款订单号 */ @Override - public Refund refund(EtOrder etOrder,String reason,BigDecimal amount,String outRefundNo) { + public void refund(EtOrder etOrder,String reason,BigDecimal amount,String outRefundNo) { SysDept sysDept = getDeptObjByAreaId(etOrder.getAreaId()); - CreateRequest request = new CreateRequest(); - request.setOutTradeNo(etOrder.getOutTradeNo()); - request.setOutRefundNo(outRefundNo); - request.setReason(reason); - request.setAmount(getAmountReq(etOrder.getTotalFee(),amount)); - request.setNotifyUrl(sysDept.getRefundNotifyUrl()); - log.info("【退款】请求微信参数:【{}】",JSON.toJSONString(request)); - RefundService refundService = getRefundService(sysDept); - Refund refund = refundService.create(request); - log.info("【退款】微信返回结果:【{}】",JSON.toJSONString(refund)); - return refund; + + if(ObjectUtil.isNull(sysDept.getPayChannel())) throw new ServiceException("运营商【"+sysDept.getDeptName()+"】没有支付渠道"); + ChannelVO channelVO = etChannelService.selectSmChannelByChannelId(sysDept.getPayChannel()); + + if(PayChannel.CT_WX.equalsCode(channelVO.getCode()) || PayChannel.YS_WX.equalsCode(channelVO.getCode())){ + log.info("----------{}-------------","微信官方退款"); + CreateRequest request = new CreateRequest(); + request.setOutTradeNo(etOrder.getOutTradeNo()); + request.setOutRefundNo(outRefundNo); + request.setReason(reason); + request.setAmount(getAmountReq(etOrder.getTotalFee(),amount)); + request.setNotifyUrl(sysDept.getRefundNotifyUrl()); + log.info("【退款】请求微信参数:【{}】",JSON.toJSONString(request)); + RefundService refundService = getRefundService(sysDept); + Refund refund = refundService.create(request); + log.info("【退款】微信返回结果:【{}】",JSON.toJSONString(refund)); + }else if(PayChannel.TL_WX.equalsCode(channelVO.getCode())){ + log.info("----------{}-------------","通联微信退款"); + RefundAble refundAble = new RefundAble(); + refundAble.setOutTradeNo(etOrder.getOutTradeNo()); + refundAble.setOutRefundNo(outRefundNo); + refundAble.setReason(reason); + refundAble.setAmount(amount.multiply(new BigDecimal(100)).longValue()); + Map refundResult = sybPayService.refundWx(refundAble); + String trxStatus = refundResult.get("trxstatus"); + // 当状态不为空,则判断是否处理退款成功 + if (trxStatus != null) { + ServiceUtil.assertion(!SybTrxStatus.isSuccess(trxStatus), "发起退款失败:" + refundResult.get("errmsg")); + // 通联退款是同步通知,直接处理退款成功 + scheduledExecutorService.schedule(() -> { + handleRefundSuccess(outRefundNo); + }, 0, TimeUnit.SECONDS); + } + }else{ + throw new ServiceException("支付渠道【"+channelVO.getCode()+"】暂不支持"); + } + } + + /** + * 退款成功后的处理 + * @param refundNo 退款订单号 + */ + private void handleRefundSuccess(String refundNo) { + EtRefund etRefund = new EtRefund(); + etRefund.setRefundNo(refundNo); + etRefund.setRefundResult(Constants.SUCCESS2); + int i = etRefundService.updateEtRefundByRefundNo(etRefund); + if(i==0){ + log.error("【通联退款】更新退款单失败"); + throw new ServiceException("【通联退款】更新退款单失败"); + } } private RefundService getRefundService(SysDept sysDept){ diff --git a/electripper-system/src/main/java/com/ruoyi/system/task/EtTask.java b/electripper-system/src/main/java/com/ruoyi/system/task/EtTask.java index 99218c8..f4758ae 100644 --- a/electripper-system/src/main/java/com/ruoyi/system/task/EtTask.java +++ b/electripper-system/src/main/java/com/ruoyi/system/task/EtTask.java @@ -72,9 +72,6 @@ public class EtTask { @Autowired private IWxPayService wxPayService; - @Autowired - private IEtFeeRuleService etFeeRuleService; - @Autowired private IEtRefundService etRefundService; @@ -246,7 +243,7 @@ public class EtTask { // redisCache.deleteObject(keys); log.info("【系统启动】退还押金,更新用户余额成功!"); } - Refund refund = wxPayService.refund(lastOrder, reason, lastOrder.getTotalFee(),outRefundNo); + wxPayService.refund(lastOrder, reason, lastOrder.getTotalFee(),outRefundNo); log.info("=================【系统启动】退还押金定时任务结束!!!=================="); }else{ throw new ServiceException("【系统启动】保存退款对象失败"); diff --git a/electripper-system/src/main/resources/mapper/system/EtChannelMapper.xml b/electripper-system/src/main/resources/mapper/system/EtChannelMapper.xml index 41d1272..8fc42ef 100644 --- a/electripper-system/src/main/resources/mapper/system/EtChannelMapper.xml +++ b/electripper-system/src/main/resources/mapper/system/EtChannelMapper.xml @@ -12,9 +12,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select sc.channel_id, sc.name, + sc.code, sc.enabled, sc.cost_rate, - sc.picture + sc.picture, + sc.merchant_id, + sc.api_v3_key, + sc.notify_url, + sc.private_key_path, + sc.merchant_serial_number, + sc.refund_notify_url from et_channel sc @@ -46,6 +53,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" channel_id, `name`, + `code`, enabled, cost_rate, picture, @@ -53,6 +61,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{channelId}, #{name}, + #{code}, #{enabled}, #{costRate}, #{picture}, @@ -63,9 +72,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" update et_channel name = #{data.name}, + code = #{data.code}, enabled = #{data.enabled}, cost_rate = #{data.costRate}, picture = #{data.picture}, + merchant_id = #{data.merchantId}, + api_v3_key = #{data.apiV3Key}, + notify_url = #{data.notifyUrl}, + private_key_path = #{data.privateKeyPath}, + merchant_serial_number = #{data.merchantSerialNumber}, + refund_notify_url = #{data.refundNotifyUrl}, where channel_id = #{data.channelId} diff --git a/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml b/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml index 414b13e..d1c04dd 100644 --- a/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml +++ b/electripper-system/src/main/resources/mapper/system/SysDeptMapper.xml @@ -40,6 +40,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + @@ -47,7 +48,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" d.order_num, d.leader, d.phone, d.email, d.status, d.del_flag,d.platform_service_fee, d.handling_charge, d.is_profit_sharing, d.separate_account, d.domain, d.is_use_platform_app, d.appid, d.app_name, d.balance, d.app_secret, d.merchant_id, d.api_v3_key, d.notify_url, d.private_key_path,d.merchant_serial_number,d.refund_notify_url, d.app_user_id, d.handling_charge_type,withdraw_handling_charge, - d.create_by, d.create_time,d.collection_code + d.create_by, d.create_time,d.collection_code, d.pay_channel from sys_dept d @@ -58,7 +59,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" d.merchant_id, d.api_v3_key, d.notify_url, d.private_key_path, d.merchant_serial_number, d.refund_notify_url, d.app_user_id,d.handling_charge_type,withdraw_handling_charge, u.user_name AS userName, GROUP_CONCAT(oa.area_name SEPARATOR ' | ') AS areaName, - d.create_by, d.create_time,d.collection_code + d.create_by, d.create_time,d.collection_code, d.pay_channel FROM sys_dept d LEFT JOIN et_user u ON d.app_user_id = u.user_id LEFT JOIN et_area_dept ad ON ad.dept_id = d.dept_id @@ -102,7 +103,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" select d.dept_id, d.parent_id, d.app_user_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.phone, d.email, d.status,d.platform_service_fee, d.handling_charge, d.is_profit_sharing,d.domain,d.is_use_platform_app, d.appid, d.app_name, d.balance, d.app_secret,d.balance,d.separate_account, - d.merchant_id, d.api_v3_key, d.notify_url, d.private_key_path,d.merchant_serial_number,d.refund_notify_url,d.app_user_id,d.handling_charge_type,withdraw_handling_charge,d.collection_code, + d.merchant_id, d.api_v3_key, d.notify_url, d.private_key_path,d.merchant_serial_number,d.refund_notify_url,d.app_user_id,d.handling_charge_type,withdraw_handling_charge,d.collection_code,,d.pay_channel, (select dept_name from sys_dept where dept_id = d.parent_id) parent_name from sys_dept d where d.app_user_id = #{appUserId} @@ -186,6 +187,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" handling_charge_type, withdraw_handling_charge, collection_code, + pay_channel, create_time )values( #{deptId}, @@ -217,6 +219,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" #{handlingChargeType}, #{withdrawHandlingCharge}, #{collectionCode}, + #{payChannel}, sysdate() ) @@ -252,6 +255,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" handling_charge_type = #{handlingChargeType}, withdraw_handling_charge = #{withdrawHandlingCharge}, collection_code = #{collectionCode}, + pay_channel = #{payChannel}, update_time = sysdate() where dept_id = #{deptId}