diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/controller/TransEasypayController.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/controller/TransEasypayController.java index cfbaa08b8..9c65830ec 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/controller/TransEasypayController.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/controller/TransEasypayController.java @@ -3,16 +3,22 @@ package com.wzj.soopin.transaction.controller; import cn.dev33.satoken.annotation.SaIgnore; import com.wzj.soopin.transaction.domain.bo.PaymentBO; import com.wzj.soopin.transaction.domain.bo.easypay.EasyPayRequest; +import com.wzj.soopin.transaction.domain.entity.WxAuthResponse; import com.wzj.soopin.transaction.domain.vo.EasypayPaymentResultVO; import com.wzj.soopin.transaction.domain.vo.EasypayPrePayVO; import com.wzj.soopin.transaction.service.IEasypayService; +import com.wzj.soopin.transaction.service.impl.WxAuthService; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.domain.R; import org.dromara.common.log.annotation.Log; import org.dromara.common.log.enums.BusinessType; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.rmi.ServerException; @@ -37,7 +43,7 @@ public class TransEasypayController { * @return */ @SaIgnore - @Log(title = "易生支付结果通知回调", businessType = BusinessType.UPDATE) + @Log(title = "易生支付-支付结果通知回调", businessType = BusinessType.UPDATE) @PostMapping("/trade/callback") public Map tradeCallback(@RequestBody EasyPayRequest easyPayRequest) { easypayService.handleTradeCallback(easyPayRequest); @@ -53,7 +59,7 @@ public class TransEasypayController { * @param paymentBO * @return */ - @Log(title = "发起支付", businessType = BusinessType.OTHER) + @Log(title = "易生支付-发起支付", businessType = BusinessType.OTHER) @PostMapping("/trade") public R trade(@RequestBody PaymentBO paymentBO) throws ServerException { EasypayPrePayVO easypayPrePayVO = easypayService.payment(paymentBO); @@ -67,8 +73,21 @@ public class TransEasypayController { * @return */ @GetMapping("/paymentQuery/{orderId}") - public R paymentQuery(@PathVariable("orderId") String orderId) throws ServerException { + public R paymentQuery(@PathVariable("orderId") Long orderId) throws ServerException { EasypayPaymentResultVO easypayPaymentResultVO = easypayService.paymentQuery(orderId); return R.ok(easypayPaymentResultVO); } + + /** + * 实时退款 + * + * @param orderId 订单id + * @return + */ + @Log(title = "易生支付-实时退款", businessType = BusinessType.OTHER) + @PostMapping("/refund/{orderId}") + public R refund(@PathVariable("orderId") Long orderId) throws ServerException { + easypayService.refund(orderId); + return R.ok(); + } } diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/controller/WxPayController.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/controller/WxPayController.java index d831a14f1..1b82041bf 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/controller/WxPayController.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/controller/WxPayController.java @@ -179,21 +179,7 @@ public class WxPayController { } } - /** - * 通过小程序的授权码获取用户的openid - * - * @param code 授权码 - * @return 包含openid的响应对象 - */ - @Tag(name = "获取用户openid") - @GetMapping("/openid2") - @Parameters({ - @Parameter(name = "code", description = "授权码", required = true, in = ParameterIn.QUERY) - }) - public R getOpenIdByMiniProgramCode(@RequestParam String code) { - WxAuthResponse response = wxAuthService.getOpenIdByMiniProgramCode(code); - return R.ok(response); - } + diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/PaymentBO.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/PaymentBO.java index d2e9cdd65..cab5ef156 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/PaymentBO.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/domain/bo/PaymentBO.java @@ -23,17 +23,6 @@ public class PaymentBO { @NotNull(message = "订单Id不能为空") private Long orderId; - /** - * 订单标题,对应支付宝订单里的 “商品说明”,微信订单里的“商品” - */ - @NotBlank(message = "订单标题不能为空") - private String orderSub; - /** - * 订单描述 - */ - @NotBlank(message = "订单描述不能为空") - private String orderDes; - /** * 支付方式 */ @@ -46,9 +35,9 @@ public class PaymentBO { private String buyerId; /** - * 微信业务参数:微信用户子标识 + * 微信登录授权码 */ - private String subOpenId; + private String wxLoginCode; // ============银联业务参数 start ============== /** diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/IEasypayService.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/IEasypayService.java index 9b07e7c71..00b8cbd9f 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/IEasypayService.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/IEasypayService.java @@ -24,7 +24,7 @@ public interface IEasypayService { * @param orderId * @return */ - EasypayPaymentResultVO paymentQuery(String orderId) throws ServerException; + EasypayPaymentResultVO paymentQuery(Long orderId) throws ServerException; /** * 处理易生支付结果通知回调 @@ -32,6 +32,12 @@ public interface IEasypayService { */ void handleTradeCallback(EasyPayRequest easyPayRequest); + /** + * 易生退款 + * @param orderId + */ + void refund(Long orderId); + /** * 获取易生账户 * @param memberId diff --git a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/EasypayServiceImpl.java b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/EasypayServiceImpl.java index 559732117..137f4194a 100644 --- a/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/EasypayServiceImpl.java +++ b/ruoyi-modules/ruoyi-transaction/src/main/java/com/wzj/soopin/transaction/service/impl/EasypayServiceImpl.java @@ -26,6 +26,9 @@ import com.wzj.soopin.transaction.config.EasypayConfig; import com.wzj.soopin.transaction.config.WechatMiniProgramConfig; import com.wzj.soopin.transaction.domain.bo.PaymentBO; import com.wzj.soopin.transaction.domain.bo.easypay.*; +import com.wzj.soopin.transaction.domain.bo.easypay.refund.apply.req.RefundApplyReqBody; +import com.wzj.soopin.transaction.domain.bo.easypay.refund.apply.req.RefundReqOrderInfo; +import com.wzj.soopin.transaction.domain.bo.easypay.refund.apply.resp.RefundApplyRespBody; import com.wzj.soopin.transaction.domain.bo.easypay.trade.jsapi.req.*; import com.wzj.soopin.transaction.domain.bo.easypay.trade.jsapi.resp.JsApiRespBody; import com.wzj.soopin.transaction.domain.bo.easypay.trade.jsapi.resp.JsapiRespOrderInfo; @@ -33,6 +36,7 @@ import com.wzj.soopin.transaction.domain.bo.easypay.trade.jsapi.resp.WxJsApiResp import com.wzj.soopin.transaction.domain.bo.easypay.trade.query.req.TradeQueryReqBody; import com.wzj.soopin.transaction.domain.bo.easypay.trade.query.resp.TradeQueryRespBody; import com.wzj.soopin.transaction.domain.bo.easypay.trade.query.resp.TradeQueryRespOrderInfo; +import com.wzj.soopin.transaction.domain.entity.WxAuthResponse; import com.wzj.soopin.transaction.domain.po.PayOrder; import com.wzj.soopin.transaction.domain.vo.EasypayAccountVO; import com.wzj.soopin.transaction.domain.vo.EasypayPaymentResultVO; @@ -76,12 +80,12 @@ import static com.wzj.soopin.transaction.constans.EasypayConstants.*; @Slf4j public class EasypayServiceImpl implements IEasypayService { - @Autowired private EasypayConfig easypayConfig; - @Autowired private WechatMiniProgramConfig wechatMiniProgramConfig; + private WxAuthService wxAuthService; + private final OrderMapper orderMapper; private final DivideMapper divideMapper; @@ -252,7 +256,7 @@ public class EasypayServiceImpl implements IEasypayService { private void checkPaymentParamByPayType(PaymentBO paymentBO) throws ServerException { switch (paymentBO.getPayType()) { case ALI_PAY_JSAPI, ALI_PAY_MINI_APP -> Assert.notBlank(paymentBO.getBuyerId(), () -> new ServiceException("支付宝支付缺少必要参数:buyerId")); - case WE_CHAT_JSAPI, WE_CHAT_MINI_APP -> Assert.notBlank(paymentBO.getSubOpenId(), () -> new ServiceException("微信支付缺少必要参数:subOpenId")); + case WE_CHAT_JSAPI, WE_CHAT_MINI_APP -> Assert.notBlank(paymentBO.getWxLoginCode(), () -> new ServiceException("微信支付缺少必要参数:微信登录授权code")); case UNION_PAY_JSAPI, UNION_PAY_Js_MINI -> Assert.isTrue(StrUtil.isAllNotBlank(paymentBO.getTransType(), paymentBO.getUserAuthCode(), paymentBO.getUserId(), paymentBO.getAreaInfo(), paymentBO.getPaymentValidTime(), paymentBO.getQrCode(), paymentBO.getQrCodeType()), () -> new ServiceException("银联支付缺少必要参数")); @@ -267,29 +271,21 @@ public class EasypayServiceImpl implements IEasypayService { * @param paymentBO */ private void setPayInfo(JsApiReqBody apiReqBody, PaymentBO paymentBO) throws ServerException { + switch (paymentBO.getPayType()) { + case ALI_PAY_JSAPI, ALI_PAY_MINI_APP -> apiReqBody.setAliBizParam(AliBizParam.builder().buyerId(paymentBO.getBuyerId()).build()); + case WE_CHAT_JSAPI, WE_CHAT_MINI_APP -> { + WxAuthResponse wxAuthResponse = wxAuthService.getOpenIdByMiniProgramCode(paymentBO.getWxLoginCode()); + Assert.isTrue(StrUtil.equals(wxAuthResponse.getErrcode(), "0"), () -> new ServiceException("微信小程序登录异常")); + apiReqBody.setWxBizParam(WxBizParam.builder().subAppid(wechatMiniProgramConfig.getAppId()).subOpenId(wxAuthResponse.getOpenid()).build()); + } + case UNION_PAY_JSAPI, UNION_PAY_Js_MINI -> apiReqBody.setQrBizParam(BeanUtil.copyProperties(paymentBO, QrBizParam.class)); + default -> throw new ServerException("不支持的支付方式"); + } PayInfo payInfo = PayInfo.builder() .payType(paymentBO.getPayType().getValue()) .transDate(DateUtils.parseDateToStr(FormatsType.YYYYMMDD, new Date())) .build(); apiReqBody.setPayInfo(payInfo); - switch (paymentBO.getPayType()) { - case ALI_PAY_JSAPI, ALI_PAY_MINI_APP -> { - Assert.isTrue(StrUtil.isNotBlank(paymentBO.getBuyerId()), () -> new ServiceException("支付宝支付需传入买家ID")); - apiReqBody.setAliBizParam(AliBizParam.builder().buyerId(paymentBO.getBuyerId()).build()); - } - case WE_CHAT_JSAPI, WE_CHAT_MINI_APP -> { - Assert.isTrue(StrUtil.isAllNotBlank(paymentBO.getSubOpenId()), () -> new ServiceException("微信支付需传入appId和openId")); - apiReqBody.setWxBizParam(WxBizParam.builder().subAppid(wechatMiniProgramConfig.getAppId()).subOpenId(paymentBO.getSubOpenId()).build()); - } - case UNION_PAY_JSAPI, UNION_PAY_Js_MINI -> { - Assert.isTrue(StrUtil.isAllNotBlank(paymentBO.getTransType(), paymentBO.getUserAuthCode(), - paymentBO.getUserId(), paymentBO.getAreaInfo(), paymentBO.getPaymentValidTime(), - paymentBO.getQrCode(), paymentBO.getQrCodeType()), () -> new ServiceException("银联支付传入参数不完整")); - QrBizParam qrBizParam = BeanUtil.copyProperties(paymentBO, QrBizParam.class); - apiReqBody.setQrBizParam(qrBizParam); - } - default -> throw new ServerException("不支持的支付方式"); - } } /** @@ -323,8 +319,8 @@ public class EasypayServiceImpl implements IEasypayService { .transAmount(transAmount) .backUrl(easypayConfig.getBackUrl()) .timeout(String.valueOf(TRACE_TIMEOUT)) - .orderSub(paymentBO.getOrderSub()) - .orderDes(paymentBO.getOrderDes()) + .orderSub("无终街支付订单") + .orderDes("无终街支付订单:" + order.getMerchantNote()) .build(); apiReqBody.setReqOrderInfo(jsapiReqOrderInfo); return payOrder; @@ -366,7 +362,7 @@ public class EasypayServiceImpl implements IEasypayService { * @throws ServerException */ @Override - public EasypayPaymentResultVO paymentQuery(String orderId) throws ServerException { + public EasypayPaymentResultVO paymentQuery(Long orderId) throws ServerException { Order order = orderMapper.selectById(orderId); Assert.notNull(order, () -> new ServiceException("订单不存在")); PayOrder payOrder = payOrderMapper.selectOne(Wrappers.lambdaQuery(PayOrder.class) @@ -477,6 +473,39 @@ public class EasypayServiceImpl implements IEasypayService { } } + @Override + public void refund(Long orderId) { + Order order = orderMapper.selectById(orderId); + Assert.notNull(order, () -> new ServiceException("订单不存在")); + PayOrder payOrder = payOrderMapper.selectOne(Wrappers.lambdaQuery(PayOrder.class).eq(PayOrder::getOrderId, orderId).last("limit 1")); + Assert.notNull(payOrder, () -> new ServiceException("订单不存在")); + EasyPayRequestHeader reqHeader = generateEasyPayRequestHeader(); + RefundApplyReqBody refundApplyReqBody = RefundApplyReqBody.builder() + .reqInfo(ReqInfo.builder().mchtCode(easypayConfig.getMchtCode()).build()) + .payInfo(PayInfo.builder().transDate(DateUtils.parseDateToStr(FormatsType.YYYYMMDD, new Date())).build()) + .reqOrderInfo(RefundReqOrderInfo.builder() + .orgTrace(StrBuilder.create(TRACE_PREFIX).append(System.currentTimeMillis()).append(RandomUtil.randomString(4)).toString()) + .oriOrgTrace(String.valueOf(order.getPayId())) + .oriTransDate(DateUtils.parseDateToStr(FormatsType.YYYYMMDD,payOrder.getStartTransDate())) + .refundAmount(payOrder.getTransAmount()) + .build()) + .build(); + String reqSign = getSignStr(reqHeader, refundApplyReqBody); + EasyPayRequest easyRequest = EasyPayRequest.builder() + .reqHeader(reqHeader) + .reqBody(refundApplyReqBody) + .reqSign(reqSign) + .build(); + log.debug("调用易生实时退款接口请求:{}",JSONObject.toJSONString(easyRequest)); + String url = StrBuilder.create(easypayConfig.getApiPathPrefix()).append("/trade/refund/apply").toString(); + String body = HttpRequest.post(url) + .timeout(3000) + .body(JSON.toJSONString(easyRequest)) + .execute() + .body(); + log.debug("调用易实时退款接口响应:{}",body); + RefundApplyRespBody refundApplyRespBody = JSONObject.parseObject(body, RefundApplyRespBody.class); + } @Override