From f57a8d41f6a7d79496d1e6441e4fec15b842bd74 Mon Sep 17 00:00:00 2001 From: 77 <77@77.com> Date: Tue, 12 Nov 2024 18:56:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/v4.sql | 2 + .../web/controller/cai/app/PayController.java | 69 +++++++++++ .../src/main/resources/application-prod.yml | 6 + .../src/main/resources/application.yml | 6 + .../ruoyi/cai/manager/ConsumerManager.java | 2 +- .../com/ruoyi/cai/mapper/AccountMapper.java | 2 + .../com/ruoyi/cai/pay/PayTrdReturnResp.java | 8 ++ .../java/com/ruoyi/cai/pay/PayTypeEnum.java | 1 + .../com/ruoyi/cai/trdpay/TrdPayManager.java | 116 ++++++++++++++++++ .../ruoyi/cai/trdpay/TrdPayProperties.java | 16 +++ 10 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 doc/v4.sql create mode 100644 ruoyi-cai/src/main/java/com/ruoyi/cai/pay/PayTrdReturnResp.java create mode 100644 ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayManager.java create mode 100644 ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayProperties.java diff --git a/doc/v4.sql b/doc/v4.sql new file mode 100644 index 00000000..a832a8d3 --- /dev/null +++ b/doc/v4.sql @@ -0,0 +1,2 @@ +ALTER TABLE `cai_account` +ADD COLUMN `total_trd_money` decimal(20, 2) NOT NULL DEFAULT 0 COMMENT '三方充值总额' AFTER `total_buy_coin`; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/PayController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/PayController.java index 1f185c51..7f7f7721 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/PayController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/app/PayController.java @@ -2,6 +2,7 @@ package com.ruoyi.web.controller.cai.app; import cn.dev33.satoken.annotation.SaIgnore; import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; import com.alipay.api.AlipayApiException; import com.alipay.api.domain.AlipayTradeAppPayModel; import com.alipay.api.internal.util.AlipaySignature; @@ -14,10 +15,15 @@ import com.ijpay.core.kit.WxPayKit; import com.ijpay.wxpay.WxPayApi; import com.ijpay.wxpay.model.UnifiedOrderModel; import com.ruoyi.cai.domain.PayConfig; +import com.ruoyi.cai.enums.SystemConfigEnum; +import com.ruoyi.cai.manager.SystemConfigManager; import com.ruoyi.cai.pay.*; +import com.ruoyi.cai.trdpay.TrdPayManager; +import com.ruoyi.cai.trdpay.TrdPayProperties; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.helper.LoginHelper; import com.ruoyi.common.utils.ServletUtils; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -44,10 +50,53 @@ public class PayController { private PayConfigManager payConfigManager; @Autowired private PayManager payManager; + @Autowired + private TrdPayProperties trdPayProperties; + @Autowired + private TrdPayManager trdPayManager; + @Autowired + private SystemConfigManager systemConfigManager; private static final String NOTIFY_WX_URL = "/api/pay/wx/notify"; private static final String NOTIFY_ALI_URL = "/api/pay/ali/notify"; + + @PostMapping(value = "/trdAli") + @Operation(summary = "第三方支付宝支付") + @Log(title = "第三方支付宝支付", businessType = BusinessType.OTHER, isSaveDb = true) + public R> checkPayType(){ + Integer payInit = systemConfigManager.getSystemConfigOfInt(SystemConfigEnum.COS_DOMAIN); + Long userId = LoginHelper.getUserId(); + + + } + + + @PostMapping(value = "/trdAli") + @Operation(summary = "第三方支付宝支付") + @Log(title = "第三方支付宝支付", businessType = BusinessType.OTHER, isSaveDb = true) + public R trdWxPay(@RequestBody PayControllerDTO dto){ + PayOrderInfoDTO payOrderInfo = payManager.getOrderInfo(dto.getOrderNo()); + if(payOrderInfo == null){ + return R.fail(600,"支付失败,未找到订单"); + } + try { + JSONObject wx = trdPayManager.createOrderWx(payOrderInfo); + String code = wx.getString("retCode"); + if(!"SUCCESS".equals(code)){ + return R.fail(600,"支付失败!微信支付通道失败!"); + } + String payUrl = wx.getJSONObject("payParams").getString("payUrl"); + PayReturnResp payTrdReturnResp = new PayReturnResp(); + payTrdReturnResp.setData(payUrl); + return R.ok(payTrdReturnResp); + }catch (Exception e){ + log.error("第三方微信支付失败!",e); + return R.fail(600,"支付失败!微信支付通道失败!"); + } + } + + @PostMapping(value = "/wx") @Operation(summary = "微信支付") @Log(title = "微信支付", businessType = BusinessType.OTHER, isSaveDb = true) @@ -196,4 +245,24 @@ public class PayController { } } + + @PostMapping(value = "/trd/notify") + @Operation(hidden = true) + @Log(title = "第三方支付回调", businessType = BusinessType.OTHER, isSaveDb = false) + @SaIgnore + public String trdNotifyUrl(HttpServletRequest request) { + try { + Map params = AliPayApi.toMap(request); + log.info("第三方支付回调:{}",JSON.toJSONString(params)); + String mchOrderNo = params.get("mchOrderNo"); + String payOrderId = params.get("payOrderId"); + String productId = params.get("productId"); + payManager.callBack(mchOrderNo,payOrderId,params,productId, PayTypeEnum.TRD); + return "success"; + } catch (Exception e) { + log.error("第三方支付回调失败!",e); + return "failure"; + } + } + } diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml index b441f0fe..89d3c8f8 100644 --- a/ruoyi-admin/src/main/resources/application-prod.yml +++ b/ruoyi-admin/src/main/resources/application-prod.yml @@ -109,3 +109,9 @@ springdoc: enabled: false knife4j: enable: false +trd: + pay: + mch-id: 10418 + wx-product-id: 8000 + ali-product-id: 8000 + notify-url-domain: "http://1.12.220.225:9889" diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index 29a57790..f7345635 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -245,6 +245,12 @@ cai: websocket: false coin-name: 花钻 home-name: 花语 +trd: + pay: + mch-id: 10418 + wx-product-id: 8000 + ali-product-id: 8000 + notify-url-domain: "http://1.12.220.225:9889" --- # Actuator 监控端点的配置项 management: endpoints: diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/manager/ConsumerManager.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/manager/ConsumerManager.java index 9d3db815..bb1d1a6d 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/manager/ConsumerManager.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/manager/ConsumerManager.java @@ -177,7 +177,7 @@ public class ConsumerManager { log.error("RabbitMq 发送失败, 充值分销流程流转失败!",e); } try { - // 记录主播的消费记录 + // 记录用户的消费统计 accountTotalManager.incsPayIncomeCoin(resp.getUserId(), resp.getRechargeCoin(),resp.getPrice(), resp.getConsumeLogId()); }catch (Exception e){ log.error("主播消费记录失败-充值",e); diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/mapper/AccountMapper.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/mapper/AccountMapper.java index a95b8f17..8f4b9615 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/mapper/AccountMapper.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/mapper/AccountMapper.java @@ -36,4 +36,6 @@ public interface AccountMapper extends BaseMapper { void incsVideoIncomeIcon(@Param("userId") Long userId, @Param("amount") Long amount); void incsPayTotal(@Param("userId") Long userId, @Param("rechargeCoin") Long rechargeCoin, @Param("price") BigDecimal price); + + void incsTrdPayTotal(@Param("userId") Long userId, @Param("rechargeCoin") Long rechargeCoin, @Param("price") BigDecimal price); } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/pay/PayTrdReturnResp.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/pay/PayTrdReturnResp.java new file mode 100644 index 00000000..d686048e --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/pay/PayTrdReturnResp.java @@ -0,0 +1,8 @@ +package com.ruoyi.cai.pay; + +import lombok.Data; + +@Data +public class PayTrdReturnResp { + private String payUrl; +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/pay/PayTypeEnum.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/pay/PayTypeEnum.java index 4f4e5c32..495615a4 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/pay/PayTypeEnum.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/pay/PayTypeEnum.java @@ -3,6 +3,7 @@ package com.ruoyi.cai.pay; public enum PayTypeEnum { ALI(1), WX(2), + TRD(3), ; private final Integer code; diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayManager.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayManager.java new file mode 100644 index 00000000..9b8216cd --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayManager.java @@ -0,0 +1,116 @@ +package com.ruoyi.cai.trdpay; + + +import cn.hutool.crypto.digest.DigestUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.cai.pay.PayOrderInfoDTO; +import com.ruoyi.common.exception.ServiceException; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.client.BufferingClientHttpRequestFactory; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import java.math.BigDecimal; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Component +@Slf4j +public class TrdPayManager { + + private final String CREATE_ORDER_URL = "http://pay.jpay.one/api/pay/create_order"; + + private static final String NOTIFY_ALI_URL = "/api/pay/trd/notify"; + + @Autowired + private TrdPayProperties trdPayProperties; + + public static RestTemplate restTemplate; + + static { + SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); + requestFactory.setConnectTimeout(3000); + requestFactory.setReadTimeout(3000); + restTemplate = new RestTemplate(new BufferingClientHttpRequestFactory(requestFactory)); + List> messageConverters = restTemplate.getMessageConverters(); + //添加转换器 + for (HttpMessageConverter messageConverter : messageConverters) { + if (messageConverter instanceof StringHttpMessageConverter) { + StringHttpMessageConverter converter = (StringHttpMessageConverter) messageConverter; + converter.setDefaultCharset(StandardCharsets.UTF_8); + } + } + } + + public JSONObject createOrderWx(PayOrderInfoDTO payOrderInfoDTO){ + return createOrder(payOrderInfoDTO,trdPayProperties.getWxProductId()); + } + + public JSONObject createOrderAli(PayOrderInfoDTO payOrderInfoDTO){ + return createOrder(payOrderInfoDTO,trdPayProperties.getAliProductId()); + } + + + + public JSONObject createOrder(PayOrderInfoDTO payOrderInfoDTO,String productId){ + Map params = new HashMap<>(); + params.put("mchId", trdPayProperties.getMchId()); + params.put("productId", productId); + params.put("mchOrderNo", payOrderInfoDTO.getOrderNo()); + params.put("amount", payOrderInfoDTO.getPriceFenStr()); + String notifyUrl = trdPayProperties.getNotifyUrlDomain() + NOTIFY_ALI_URL; + params.put("notifyUrl", notifyUrl); + String para = createParams(params); + String url = CREATE_ORDER_URL + "?" + para; + String body = restTemplate.getForEntity(url, String.class).getBody(); + JSONObject jsonObject = JSON.parseObject(body); + if(jsonObject == null){ + log.error("第三方支付失败 返回数据为空"); + throw new ServiceException("调用支付失败"); + } + if(!"SUCCESS".equals(jsonObject.getString("retCode"))){ + log.info("第三方支付失败 统一支付失败失败 url={}, body={}",url, body); + throw new ServiceException("调用支付失败"); + } + log.info("第三方支付成功 URL={}, body={}",url, body); + return jsonObject; + } + + private String createParams(Map params){ + List url = new ArrayList<>(); + for (Map.Entry entry : params.entrySet()) { + url.add(entry.getKey()+"="+entry.getValue()); + } + url = url.stream().sorted().collect(Collectors.toList()); + String stringSignTemp = StringUtils.join(url, "&") + "&key=" + trdPayProperties.getSignKey(); + String sign = DigestUtil.md5Hex(stringSignTemp).toUpperCase(); + url.add("sign="+sign); + return StringUtils.join(url, "&"); + } + + + public static void main(String[] args) { + TrdPayProperties payProperties = new TrdPayProperties(); + payProperties.setMchId("10418"); + payProperties.setNotifyUrlDomain("https://api.ssss.com"); + PayOrderInfoDTO payOrderInfo = new PayOrderInfoDTO(); + payOrderInfo.setPrice(new BigDecimal("10")); + payOrderInfo.setOrderNo("DSKsdasklddshjkasdka"); + TrdPayManager trdPayManager = new TrdPayManager(); +// trdPayManager.(payProperties); + trdPayManager.createOrder(payOrderInfo,"8000"); + + + } + +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayProperties.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayProperties.java new file mode 100644 index 00000000..bdc5b6c7 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayProperties.java @@ -0,0 +1,16 @@ +package com.ruoyi.cai.trdpay; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Data +@Component +@ConfigurationProperties(prefix = "trd.pay") +public class TrdPayProperties { + private String mchId; + private String wxProductId; + private String aliProductId; + private String notifyUrlDomain; + private String signKey = "IQJWYHUKWOWWLJHTY8K9SVGLD8OCRNOT4817D383FIYZI53YPEKTIXOUKDHTY4TEXGKK45YY2YJJDHS5YHMKOWO6HASDQ4KX10R23BOQ8JNQUICSKW2OWQRBDMLRKL2J"; +}