package com.ruoyi.web.controller.api; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.fasterxml.jackson.core.type.TypeReference; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.utils.CodeGenerateUtils; import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.system.model.TSysAppUser; import com.ruoyi.system.model.TSysInspection; import com.ruoyi.system.model.TSysOtherConfig; import com.ruoyi.system.model.TSysPayRecord; import com.ruoyi.system.service.TSysAppUserService; import com.ruoyi.system.service.TSysInspectionService; import com.ruoyi.system.service.TSysOtherConfigService; import com.ruoyi.system.service.TSysPayRecordService; import com.ruoyi.system.wxPay.enums.RefundEnum; import com.ruoyi.system.wxPay.enums.TradeStateEnum; import com.ruoyi.system.wxPay.model.WeixinPayProperties; import com.ruoyi.system.wxPay.model.WxPaymentRefundModel; import com.ruoyi.system.wxPay.utils.WxTimeUtils; import com.ruoyi.system.wxPay.utils.WxV3Pay; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.math.BigDecimal; import java.util.Map; import java.util.Objects; /** * 微信相关接口 */ @Slf4j @RestController @CrossOrigin @RequestMapping("/wx/") @Api(tags = {"微信支付相关接口"}) public class WxPayController { @Autowired private WxV3Pay wxV3Pay; @Autowired private TokenService tokenService; @Autowired private TSysAppUserService sysAppUserService; @Autowired private TSysOtherConfigService sysOtherConfigService; @Autowired private TSysPayRecordService sysPayRecordService; @Autowired private WeixinPayProperties weixinPayProperties; @Autowired private TSysInspectionService sysInspectionService; /** * 按实际修改 */ @ApiOperation("订单支付") @PostMapping("orderPay") public R> orderPay(@RequestParam(value = "inspectionId") String inspectionId) { TSysOtherConfig sysOtherConfig = sysOtherConfigService.getById(1); if (Objects.isNull(sysOtherConfig.getAiPrice())) { return R.fail("系统未配置AI支付价格"); } String userId = tokenService.getLoginUserApplet().getUserId(); TSysAppUser sysAppUser = sysAppUserService.getById(userId); // 价格 Integer totalPrice = sysOtherConfig.getAiPrice().multiply(new BigDecimal(100)).intValue(); // 生成订单号 String orderNo = CodeGenerateUtils.generateOrderSn(); // 查询用户信息 用户openid String openId = sysAppUser.getOpenId(); // 存储支付记录 sysPayRecordService.saveData(orderNo, userId, sysOtherConfig.getAiPrice(), 1); // 调用支付方法 Map result = wxV3Pay.jsApi(orderNo, totalPrice, openId,"AI检测报告支付"); log.info("支付参数:{}", result); return R.ok(result); } /** * 微信v3支付-订单退款 * * @return */ @ApiOperation("订单退款") @PostMapping(value = "refund-order") public AjaxResult refundOrder() { Map result = wxV3Pay.refund(new WxPaymentRefundModel()); log.info("退款结果:{}", result); // 微信支付退款单号 String refund_id = result.get("refund_id").toString(); // 商户退款单号 String out_refund_no = result.get("out_refund_no").toString(); // 微信支付订单号 String transaction_id = result.get("transaction_id").toString(); // 商户订单号 tradeNo String out_trade_no = result.get("out_trade_no").toString(); // 退款成功时间 String success_time = Objects.nonNull(result.get("success_time")) ? result.get("success_time").toString() : null; // 退款状态 RefundEnum String status = result.get("status").toString(); // TODO 退款业务处理 return AjaxResult.success(); } /** * 支付回调 */ @PostMapping("pay/notify") @ApiOperation("订单回调") public void payNotify(HttpServletRequest request) throws Exception { try { Map params = wxV3Pay.verifyNotify(request, new TypeReference>() {}); log.info("支付回调:{}", params); // 商户订单号 String tradeNo = params.get("out_trade_no").toString(); // 交易状态 String trade_state = params.get("trade_state").toString(); // 交易状态描述 String trade_state_desc = params.get("trade_state_desc").toString(); // 微信支付订单号 String transaction_id = params.get("transaction_id").toString(); // 支付完成时间 // 时间不对的话,可以调用 WxTimeUtils.toRfc3339Date(success_time)转换一下 String success_time = params.get("success_time").toString(); // 附加数据 Integer attach = Integer.parseInt(params.get("attach").toString()); // 查询订单 TSysPayRecord sysPayRecord = sysPayRecordService.getOne(Wrappers.lambdaQuery(TSysPayRecord.class) .eq(TSysPayRecord::getOrderNo, tradeNo).last("LIMIT 1")); // 处理订单 if (trade_state.equals(TradeStateEnum.SUCCESS.name())) { log.info("回调成功"); // 订单号查询订单 sysPayRecord.setPayState(2); sysPayRecord.setPayTime(WxTimeUtils.dateToLocalDateTime(WxTimeUtils.toRfc3339Date(success_time))); sysPayRecord.setTransactionId(transaction_id); sysPayRecordService.updateById(sysPayRecord); // 处理检测报告为可见 TSysInspection sysInspection = sysInspectionService.getById(sysPayRecord.getInspectionId()); sysInspection.setIsPay(1); sysInspectionService.updateById(sysInspection); wxV3Pay.ack(); } wxV3Pay.ack(); } catch (Exception e) { log.error("支付回调异常:{}", e, e); wxV3Pay.ack(false, e.getMessage()); } } /** * 支付回调成功后 */ @PostMapping("pay/ack") public void ack(){ try { wxV3Pay.ack(); } catch (IOException e) { throw new RuntimeException(e); } } /** * 退款回调 */ @PostMapping("refund/notify") public void refundNotify(HttpServletRequest request) throws IOException { try { Map params = wxV3Pay.verifyNotify(request, new TypeReference>() { }); // 商户订单号 String out_trade_no = params.get("out_trade_no").toString(); // 商户退款单号 String out_refund_no = params.get("out_refund_no").toString(); // 微信支付订单号 String transaction_id = params.get("transaction_id").toString(); // 微信支付退款单号 String refund_id = params.get("refund_id").toString(); // 退款状态 String tradeState = params.get("refund_status").toString(); // 退款成功时间 // 时间不对的话,可以调用 WxTimeUtils.toRfc3339Date(success_time)转换一下 String success_time = params.get("success_time").toString(); if (tradeState.equals(RefundEnum.SUCCESS.name())) { wxV3Pay.ack(); } else { wxV3Pay.ack(false, "不是成功的退款状态"); } } catch (Exception e) { e.printStackTrace(); wxV3Pay.ack(false, e.getMessage()); } } }