diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/admin/init/CityController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/admin/init/CityController.java index f55b9c8f..4f3508fa 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/admin/init/CityController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/cai/admin/init/CityController.java @@ -30,8 +30,8 @@ public class CityController { } @GetMapping("/resetOrder") - public R resetOrder(String orderNo,String payType){ - JSONObject jsonObject = payTrdConfigService.resetOrder(orderNo,payType); + public R resetOrder(String orderNo,String payType,boolean updateData){ + JSONObject jsonObject = payTrdConfigService.resetOrder(orderNo,payType,updateData); return R.ok(jsonObject); } 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 0047edc1..833f2b04 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 @@ -24,6 +24,8 @@ import com.ruoyi.cai.service.OrderLogsService; import com.ruoyi.cai.service.PayTrdConfigService; import com.ruoyi.cai.trdpay.TrdPayManager; import com.ruoyi.cai.trdpay.TrdPayProperties; +import com.ruoyi.cai.trdpay.TrdPayTypeEnum; +import com.ruoyi.cai.trdpay.dto.NotifyResp; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.enums.BusinessType; @@ -310,13 +312,11 @@ public class PayController { try { Map params = AliPayApi.toMap(request); log.info("第三方支付回调V1:{}",JSON.toJSONString(params)); - String mchOrderNo = params.get("mchOrderNo"); - String payOrderId = params.get("payOrderId"); - String productId = params.get("productId"); - payManager.callBack(mchOrderNo,payOrderId,params,"V1", PayTypeEnum.TRD); + NotifyResp notifyResp = trdPayManager.getNotifyResp(params, TrdPayTypeEnum.V1); + payManager.callBack(notifyResp.getOrderNo(),notifyResp.getTrdOrderNo(),params,notifyResp.getPayTypeEnum().name(), PayTypeEnum.TRD); return "success"; } catch (Exception e) { - log.error("第三方支付回调失败!",e); + log.error("第三方支付回调失败V1!",e); return "failure"; } } @@ -330,13 +330,11 @@ public class PayController { try { Map params = AliPayApi.toMap(request); log.info("第三方支付回调V2:{}",JSON.toJSONString(params)); - String mchOrderNo = params.get("mchOrderNo"); - String payOrderId = params.get("payOrderId"); - String productId = params.get("productId"); - payManager.callBack(mchOrderNo,payOrderId,params,"V2", PayTypeEnum.TRD); + NotifyResp notifyResp = trdPayManager.getNotifyResp(params, TrdPayTypeEnum.V2); + payManager.callBack(notifyResp.getOrderNo(),notifyResp.getTrdOrderNo(),params,notifyResp.getPayTypeEnum().name(), PayTypeEnum.TRD); return "success"; } catch (Exception e) { - log.error("第三方支付回调失败!",e); + log.error("第三方支付回调失败V2!",e); return "failure"; } } @@ -350,13 +348,11 @@ public class PayController { try { Map params = AliPayApi.toMap(request); log.info("第三方支付回调V3:{}",JSON.toJSONString(params)); - String mchOrderNo = params.get("mchOrderNo"); - String payOrderId = params.get("payOrderId"); - String productId = params.get("productId"); - payManager.callBack(mchOrderNo,payOrderId,params,"V3", PayTypeEnum.TRD); + NotifyResp notifyResp = trdPayManager.getNotifyResp(params, TrdPayTypeEnum.V3); + payManager.callBack(notifyResp.getOrderNo(),notifyResp.getTrdOrderNo(),params,notifyResp.getPayTypeEnum().name(), PayTypeEnum.TRD); return "success"; } catch (Exception e) { - log.error("第三方支付回调失败!",e); + log.error("第三方支付回调失败V3!",e); return "failure"; } } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/filter/EncryptionFilter.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/filter/EncryptionFilter.java index 93e46ba9..fd6ae681 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/filter/EncryptionFilter.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/filter/EncryptionFilter.java @@ -1,6 +1,7 @@ package com.ruoyi.cai.filter; import com.ruoyi.cai.config.CaiProperties; +import com.ruoyi.cai.trdpay.TrdPayTypeEnum; import com.ruoyi.cai.util.AES; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -23,9 +24,10 @@ public class EncryptionFilter implements Filter { IGNORE_URL.add("/api/pay/wx/notify"); IGNORE_URL.add("/api/yx/im/notify"); IGNORE_URL.add("/api/yx/im/check"); - IGNORE_URL.add("/api/pay/trd/notify/v1"); - IGNORE_URL.add("/api/pay/trd/notify/v2"); - IGNORE_URL.add("/api/pay/trd/notify/v3"); + TrdPayTypeEnum[] values = TrdPayTypeEnum.values(); + for (TrdPayTypeEnum value : values) { + IGNORE_URL.add(value.getNotifyPath()); + } } private static final AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher(); diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/PayTrdConfigService.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/PayTrdConfigService.java index b653d699..146b211d 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/PayTrdConfigService.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/PayTrdConfigService.java @@ -17,7 +17,7 @@ public interface PayTrdConfigService extends IService { JSONObject queryOrder(String orderNo, String trdPayType); - JSONObject resetOrder(String orderNo, String trdPayType); + JSONObject resetOrder(String orderNo, String trdPayType,boolean updateData); void enableStatus(Long id, Integer enableStatus); } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/PayTrdConfigServiceImpl.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/PayTrdConfigServiceImpl.java index fa2d40b9..414e5680 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/PayTrdConfigServiceImpl.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/service/impl/PayTrdConfigServiceImpl.java @@ -1,6 +1,5 @@ package com.ruoyi.cai.service.impl; -import com.alibaba.fastjson.JSON; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; @@ -9,21 +8,16 @@ import com.ruoyi.cai.mapper.PayTrdConfigMapper; import com.ruoyi.cai.pay.PayManager; import com.ruoyi.cai.pay.PayOrderInfoDTO; import com.ruoyi.cai.pay.PayReturnResp; -import com.ruoyi.cai.pay.PayTypeEnum; import com.ruoyi.cai.service.OrderLogsService; import com.ruoyi.cai.service.PayTrdConfigService; import com.ruoyi.cai.trdpay.TrdPayManager; import com.ruoyi.cai.trdpay.TrdPayTypeEnum; import com.ruoyi.common.exception.ServiceException; -import com.tencentcloudapi.gme.v20180711.models.AppStatisticsItem; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.HashMap; -import java.util.Map; - /** * 四方支付配置Service业务层处理 * @@ -51,6 +45,9 @@ public class PayTrdConfigServiceImpl extends ServiceImpl params, String key) { + 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=" + key; + String sign = DigestUtil.md5Hex(stringSignTemp).toUpperCase(); + url.add("sign=" + sign); + return StringUtils.join(url, "&"); + } +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/PayTrdService.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/PayTrdService.java new file mode 100644 index 00000000..3ee3ff69 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/PayTrdService.java @@ -0,0 +1,22 @@ +package com.ruoyi.cai.trdpay; + +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.cai.domain.PayTrdConfig; +import com.ruoyi.cai.pay.PayOrderInfoDTO; +import com.ruoyi.cai.pay.PayReturnResp; +import com.ruoyi.cai.trdpay.dto.NotifyResp; + +import java.util.Map; + +public interface PayTrdService { + TrdPayTypeEnum getType(); + + PayReturnResp createOrderAli(PayOrderInfoDTO payOrderInfoDTO, PayTrdConfig payTrdConfig); + + NotifyResp getNotifyResp(Map sourceData); + + JSONObject queryOrder(String orderNo, PayTrdConfig payTrdConfig); + + JSONObject resetOrder(String orderNo, PayTrdConfig payTrdConfig,boolean updateData); + +} 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 index e7d8f3e5..1359bef2 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayManager.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayManager.java @@ -1,22 +1,16 @@ 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.domain.Account; -import com.ruoyi.cai.domain.OrderLogs; import com.ruoyi.cai.domain.PayTrdConfig; import com.ruoyi.cai.enums.SystemConfigEnum; import com.ruoyi.cai.manager.SystemConfigManager; import com.ruoyi.cai.pay.PayOrderInfoDTO; +import com.ruoyi.cai.pay.PayReturnResp; import com.ruoyi.cai.service.AccountService; -import com.ruoyi.cai.service.OrderLogsService; -import com.ruoyi.common.exception.ServiceException; -import com.ruoyi.common.utils.ServletUtils; -import lombok.Data; +import com.ruoyi.cai.trdpay.dto.NotifyResp; 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; @@ -25,15 +19,12 @@ import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; +import javax.annotation.PostConstruct; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; @Component @Slf4j @@ -56,6 +47,47 @@ public class TrdPayManager { } } + @Autowired + private List payTrdServiceList; + private final Map payTrdServiceMap = new HashMap<>(); + + @PostConstruct + public void init(){ + for (PayTrdService payTrdService : payTrdServiceList) { + payTrdServiceMap.put(payTrdService.getType().name(),payTrdService); + } + } + + public PayTrdService getPayTrdService(String key){ + return payTrdServiceMap.get(key); + } + + @Autowired + private AccountService accountService; + @Autowired + private SystemConfigManager systemConfigManager; + + public PayReturnResp createOrderAliMerge(PayOrderInfoDTO payOrderInfoDTO, PayTrdConfig payTrdConfig,TrdPayTypeEnum typeEnum){ + PayTrdService payTrdService = getPayTrdService(typeEnum.name()); + return payTrdService.createOrderAli(payOrderInfoDTO,payTrdConfig); + } + + public NotifyResp getNotifyResp(Map sourceData,TrdPayTypeEnum typeEnum){ + PayTrdService payTrdService = getPayTrdService(typeEnum.name()); + return payTrdService.getNotifyResp(sourceData); + } + + public JSONObject queryOrder(String orderNo, PayTrdConfig payTrdConfig,TrdPayTypeEnum typeEnum){ + PayTrdService payTrdService = getPayTrdService(typeEnum.name()); + return payTrdService.queryOrder(orderNo, payTrdConfig); + } + + public JSONObject resetQuery(String orderNo, PayTrdConfig payTrdConfig,TrdPayTypeEnum typeEnum,boolean updateData){ + PayTrdService payTrdService = getPayTrdService(typeEnum.name()); + return payTrdService.resetOrder(orderNo, payTrdConfig,updateData); + } + + /*@Deprecated public JSONObject createOrderAli(PayOrderInfoDTO payOrderInfoDTO, PayTrdConfig payTrdConfig,TrdPayTypeEnum typeEnum){ Map params = new HashMap<>(); params.put("mchId", payTrdConfig.getMchId()); @@ -84,15 +116,9 @@ public class TrdPayManager { log.info("第三方支付成功 URL={}, body={}",url, body); orderLogsService.createAliPayLogs(payOrderInfoDTO.getOrderNo(),url,jsonObject,typeEnum); return jsonObject; - } + }*/ - @Autowired - private OrderLogsService orderLogsService; - @Autowired - private AccountService accountService; - @Autowired - private SystemConfigManager systemConfigManager; public boolean useTrdPay(Long userId){ Account account = accountService.getByUserId(userId); @@ -109,6 +135,7 @@ public class TrdPayManager { return true; } + /* @Deprecated public JSONObject queryOrder(String orderNo, PayTrdConfig payTrdConfig,TrdPayTypeEnum typeEnum){ Map params = new HashMap<>(); params.put("mchId", payTrdConfig.getMchId()); @@ -128,10 +155,10 @@ public class TrdPayManager { } log.info("第三方支付成功 URL={}, body={}",url, body); return jsonObject; - } + }*/ - private String createParams(Map params,String key){ + /*private String createParams(Map params,String key){ List url = new ArrayList<>(); for (Map.Entry entry : params.entrySet()) { url.add(entry.getKey()+"="+entry.getValue()); @@ -141,11 +168,7 @@ public class TrdPayManager { String sign = DigestUtil.md5Hex(stringSignTemp).toUpperCase(); url.add("sign="+sign); return StringUtils.join(url, "&"); - } + }*/ - public static void main(String[] args) { - - } - } diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayTypeEnum.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayTypeEnum.java index ec47c596..b927702b 100644 --- a/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayTypeEnum.java +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/TrdPayTypeEnum.java @@ -8,6 +8,7 @@ public enum TrdPayTypeEnum { V1("http://pay.jpay.one/api","/pay/create_order","/pay/query_order","/api/pay/trd/notify/v1"), V2("http://121.40.24.67:56700/api","/pay/create_order","/pay/query_order","/api/pay/trd/notify/v2"), V3("http://pay.linken.click/api","/pay/create_order","/pay/query_order","/api/pay/trd/notify/v3"), + V4("http://47.243.172.120:8089","/channel/apiPay","/channel/order/query","/api/pay/trd/notify/v4"), ; private final String gatewayUrl; private final String createOrderUrl; diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/dto/NotifyResp.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/dto/NotifyResp.java new file mode 100644 index 00000000..28e5409d --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/dto/NotifyResp.java @@ -0,0 +1,14 @@ +package com.ruoyi.cai.trdpay.dto; + +import com.ruoyi.cai.trdpay.TrdPayTypeEnum; +import lombok.Data; + +import java.util.Map; + +@Data +public class NotifyResp { + private String orderNo; + private String trdOrderNo; + private TrdPayTypeEnum payTypeEnum; + private Map sourceData; +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/handle/PayTrdV1Service.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/handle/PayTrdV1Service.java new file mode 100644 index 00000000..97f6c099 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/handle/PayTrdV1Service.java @@ -0,0 +1,132 @@ +package com.ruoyi.cai.trdpay.handle; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ijpay.alipay.AliPayApi; +import com.ruoyi.cai.domain.PayTrdConfig; +import com.ruoyi.cai.pay.PayManager; +import com.ruoyi.cai.pay.PayOrderInfoDTO; +import com.ruoyi.cai.pay.PayReturnResp; +import com.ruoyi.cai.pay.PayTypeEnum; +import com.ruoyi.cai.service.OrderLogsService; +import com.ruoyi.cai.trdpay.PayMd5Util; +import com.ruoyi.cai.trdpay.PayTrdService; +import com.ruoyi.cai.trdpay.TrdPayTypeEnum; +import com.ruoyi.cai.trdpay.dto.NotifyResp; +import com.ruoyi.cai.util.RestTemplateUtil; +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.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.Map; + +@Service +@Slf4j +public class PayTrdV1Service implements PayTrdService { + + @Autowired + private OrderLogsService orderLogsService; + @Autowired + private PayManager payManager; + + @Override + public TrdPayTypeEnum getType() { + return TrdPayTypeEnum.V1; + } + + @Override + public PayReturnResp createOrderAli(PayOrderInfoDTO payOrderInfoDTO, PayTrdConfig payTrdConfig) { + TrdPayTypeEnum type = getType(); + RestTemplate rest = RestTemplateUtil.getRest(); + Map params = new HashMap<>(); + params.put("mchId", payTrdConfig.getMchId()); + params.put("productId", payTrdConfig.getAliProductId()); + params.put("mchOrderNo", payOrderInfoDTO.getOrderNo()); + params.put("amount", payOrderInfoDTO.getPriceFenStr()); + String notifyUrl = payTrdConfig.getNotifyUrl() + type.getNotifyPath(); + params.put("notifyUrl", notifyUrl); + String para = PayMd5Util.createParams(params, payTrdConfig.getSign()); + String gatewayUrl = type.getGatewayUrl(); + if (StringUtils.isNotBlank(payTrdConfig.getGatewayUrl())) { + gatewayUrl = payTrdConfig.getGatewayUrl(); + } + String createOrderUrl = gatewayUrl + type.getCreateOrderUrl(); + String url = createOrderUrl + "?" + para; + String body = rest.getForEntity(url, String.class).getBody(); + JSONObject jsonObject = JSON.parseObject(body); + orderLogsService.createAliPayLogs(payOrderInfoDTO.getOrderNo(), url, jsonObject, type); + if(jsonObject == null){ + log.error("第三方支付失败 V1返回数据为空 url={}",url); + throw new ServiceException("调用支付失败"); + } + if(!"SUCCESS".equals(jsonObject.getString("retCode"))){ + log.info("第三方支付失败 V1统一支付失败失败 dto={}, payTrdConfig={}, typeEnum={}", body, JSON.toJSONString(payTrdConfig), JSON.toJSONString(jsonObject)); + throw new ServiceException("调用支付失败"); + } + String payUrl = jsonObject.getJSONObject("payParams").getString("payUrl"); + return PayReturnResp.createH5(payUrl); + } + + @Override + public NotifyResp getNotifyResp(Map sourceData) { + String mchOrderNo = sourceData.get("mchOrderNo"); + String payOrderId = sourceData.get("payOrderId"); + NotifyResp resp = new NotifyResp(); + resp.setOrderNo(mchOrderNo); + resp.setTrdOrderNo(payOrderId); + resp.setPayTypeEnum(getType()); + resp.setSourceData(sourceData); + return resp; + } + + @Override + public JSONObject queryOrder(String orderNo, PayTrdConfig payTrdConfig) { + TrdPayTypeEnum type = getType(); + Map params = new HashMap<>(); + params.put("mchId", payTrdConfig.getMchId()); + params.put("mchOrderNo", orderNo); + String para = PayMd5Util.createParams(params,payTrdConfig.getSign()); + String gatewayUrl = type.getGatewayUrl(); + if(StringUtils.isNotBlank(payTrdConfig.getGatewayUrl())){ + gatewayUrl = payTrdConfig.getGatewayUrl(); + } + String queryOrderUrl = gatewayUrl + type.getQueryOrderUrl(); + String url = queryOrderUrl + "?" + para; + String body = RestTemplateUtil.getRest().getForEntity(url, String.class).getBody(); + JSONObject jsonObject = JSON.parseObject(body); + if(jsonObject == null){ + log.error("第三方支付查询失败 返回数据为空 URL={}",url); + throw new ServiceException("调用支付失败"); + } + log.info("第三方支付查询成功 V1 URL={}, body={}",url, body); + return jsonObject; + } + + @Override + public JSONObject resetOrder(String orderNo, PayTrdConfig payTrdConfig,boolean updateData) { + JSONObject jsonObject = this.queryOrder(orderNo,payTrdConfig); + if(!"SUCCESS".equals(jsonObject.getString("retCode"))){ + log.info("第三方支付失败 V1统一支付失败失败 orderNo={}, payTrdConfig={}", orderNo, JSON.toJSONString(payTrdConfig)); + throw new ServiceException("调用支付失败"); + } + Integer status = jsonObject.getInteger("status"); + if(status != null && status.equals(2)){ + String mchOrderNo = jsonObject.getString("mchOrderNo"); + String payOrderId = jsonObject.getString("payOrderId"); + String productId = jsonObject.getString("productId"); + Map objectJson = new HashMap<>(); + for (String key : jsonObject.keySet()) { + objectJson.put(key, jsonObject.getString(key)); + } + if(updateData){ + payManager.callBack(mchOrderNo,payOrderId,objectJson,"V1", PayTypeEnum.TRD); + } + } + return jsonObject; + } + +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/handle/PayTrdV2Service.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/handle/PayTrdV2Service.java new file mode 100644 index 00000000..033b57ce --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/handle/PayTrdV2Service.java @@ -0,0 +1,146 @@ +package com.ruoyi.cai.trdpay.handle; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.cai.domain.PayTrdConfig; +import com.ruoyi.cai.pay.PayManager; +import com.ruoyi.cai.pay.PayOrderInfoDTO; +import com.ruoyi.cai.pay.PayReturnResp; +import com.ruoyi.cai.pay.PayTypeEnum; +import com.ruoyi.cai.service.OrderLogsService; +import com.ruoyi.cai.trdpay.PayMd5Util; +import com.ruoyi.cai.trdpay.PayTrdService; +import com.ruoyi.cai.trdpay.TrdPayTypeEnum; +import com.ruoyi.cai.trdpay.dto.NotifyResp; +import com.ruoyi.cai.util.RestTemplateUtil; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.ServletUtils; +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.Map; + +@Service +@Slf4j +@Deprecated +public class PayTrdV2Service implements PayTrdService { + + @Autowired + private OrderLogsService orderLogsService; + @Autowired + private PayManager payManager; + + @Override + public TrdPayTypeEnum getType() { + return TrdPayTypeEnum.V2; + } + + @Override + public PayReturnResp createOrderAli(PayOrderInfoDTO payOrderInfoDTO, PayTrdConfig payTrdConfig) { + TrdPayTypeEnum type = getType(); + RestTemplate rest = RestTemplateUtil.getRest(); + Map params = new HashMap<>(); + params.put("mchId", payTrdConfig.getMchId()); + params.put("productId", payTrdConfig.getAliProductId()); + params.put("mchOrderNo", payOrderInfoDTO.getOrderNo()); + params.put("amount", payOrderInfoDTO.getPriceFenStr()); + params.put("reqTime", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); + params.put("version","1.0"); + params.put("clientIp", ServletUtils.getClientIP()); + params.put("subject",payOrderInfoDTO.getSubject()); + params.put("body",payOrderInfoDTO.getBody()); + params.put("currency","cny"); + String notifyUrl = payTrdConfig.getNotifyUrl() + type.getNotifyPath(); + params.put("notifyUrl", notifyUrl); + String para = PayMd5Util.createParams(params, payTrdConfig.getSign()); + String gatewayUrl = type.getGatewayUrl(); + if (StringUtils.isNotBlank(payTrdConfig.getGatewayUrl())) { + gatewayUrl = payTrdConfig.getGatewayUrl(); + } + String createOrderUrl = gatewayUrl + type.getCreateOrderUrl(); + String url = createOrderUrl + "?" + para; + String body = rest.getForEntity(url, String.class).getBody(); + JSONObject jsonObject = JSON.parseObject(body); + orderLogsService.createAliPayLogs(payOrderInfoDTO.getOrderNo(), url, jsonObject, type); + if(jsonObject == null){ + log.error("第三方支付失败 V2返回数据为空 url={}",url); + throw new ServiceException("调用支付失败"); + } + if(!"0".equals(jsonObject.getString("retCode"))){ + log.info("第三方支付失败 V2统一支付失败失败 dto={}, payTrdConfig={}, typeEnum={}", body, JSON.toJSONString(payTrdConfig), JSON.toJSONString(jsonObject)); + throw new ServiceException("调用支付失败"); + } + String payMethod = jsonObject.getString("payMethod"); + if("alipayApp".equals(payMethod)){ + String appStr = jsonObject.getJSONObject("payParams").getString("appStr"); + return PayReturnResp.createApp(appStr); + } + return PayReturnResp.createH5(JSON.toJSONString(jsonObject)); + } + + @Override + public NotifyResp getNotifyResp(Map sourceData) { + String mchOrderNo = sourceData.get("mchOrderNo"); + String payOrderId = sourceData.get("payOrderId"); + NotifyResp resp = new NotifyResp(); + resp.setOrderNo(mchOrderNo); + resp.setTrdOrderNo(payOrderId); + resp.setPayTypeEnum(TrdPayTypeEnum.V1); + resp.setSourceData(sourceData); + return resp; + } + + @Override + public JSONObject queryOrder(String orderNo, PayTrdConfig payTrdConfig) { + TrdPayTypeEnum type = getType(); + Map params = new HashMap<>(); + params.put("mchId", payTrdConfig.getMchId()); + params.put("mchOrderNo", orderNo); + String para = PayMd5Util.createParams(params,payTrdConfig.getSign()); + String gatewayUrl = type.getGatewayUrl(); + if(StringUtils.isNotBlank(payTrdConfig.getGatewayUrl())){ + gatewayUrl = payTrdConfig.getGatewayUrl(); + } + String queryOrderUrl = gatewayUrl + type.getQueryOrderUrl(); + String url = queryOrderUrl + "?" + para; + String body = RestTemplateUtil.getRest().getForEntity(url, String.class).getBody(); + JSONObject jsonObject = JSON.parseObject(body); + if(jsonObject == null){ + log.error("第三方支付查询失败 返回数据为空 URL={}",url); + throw new ServiceException("调用支付失败"); + } + log.info("第三方支付查询成功 V2 URL={}, body={}",url, body); + return jsonObject; + } + + @Override + public JSONObject resetOrder(String orderNo, PayTrdConfig payTrdConfig, boolean updateData) { + JSONObject jsonObject = this.queryOrder(orderNo,payTrdConfig); + if(!"0".equals(jsonObject.getString("retCode"))){ + log.info("第三方支付失败 V2统一支付失败失败 orderNo={}, payTrdConfig={}", orderNo, JSON.toJSONString(payTrdConfig)); + throw new ServiceException("调用支付失败"); + } + Integer status = jsonObject.getInteger("status"); + if(status != null && (status.equals(2) || status.equals(3))){ + String mchOrderNo = jsonObject.getString("mchOrderNo"); + String payOrderId = jsonObject.getString("payOrderId"); + String productId = jsonObject.getString("productId"); + Map objectJson = new HashMap<>(); + for (String key : jsonObject.keySet()) { + objectJson.put(key, jsonObject.getString(key)); + } + if(updateData){ + payManager.callBack(mchOrderNo,payOrderId,objectJson,"V2", PayTypeEnum.TRD); + } + } + return jsonObject; + } + +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/handle/PayTrdV3Service.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/handle/PayTrdV3Service.java new file mode 100644 index 00000000..391d9eb7 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/handle/PayTrdV3Service.java @@ -0,0 +1,131 @@ +package com.ruoyi.cai.trdpay.handle; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.cai.domain.PayTrdConfig; +import com.ruoyi.cai.pay.PayManager; +import com.ruoyi.cai.pay.PayOrderInfoDTO; +import com.ruoyi.cai.pay.PayReturnResp; +import com.ruoyi.cai.pay.PayTypeEnum; +import com.ruoyi.cai.service.OrderLogsService; +import com.ruoyi.cai.trdpay.PayMd5Util; +import com.ruoyi.cai.trdpay.PayTrdService; +import com.ruoyi.cai.trdpay.TrdPayTypeEnum; +import com.ruoyi.cai.trdpay.dto.NotifyResp; +import com.ruoyi.cai.util.RestTemplateUtil; +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.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.Map; + +@Service +@Slf4j +public class PayTrdV3Service implements PayTrdService { + + @Autowired + private OrderLogsService orderLogsService; + @Autowired + private PayManager payManager; + + @Override + public TrdPayTypeEnum getType() { + return TrdPayTypeEnum.V3; + } + + @Override + public PayReturnResp createOrderAli(PayOrderInfoDTO payOrderInfoDTO, PayTrdConfig payTrdConfig) { + TrdPayTypeEnum type = getType(); + RestTemplate rest = RestTemplateUtil.getRest(); + Map params = new HashMap<>(); + params.put("mchId", payTrdConfig.getMchId()); + params.put("productId", payTrdConfig.getAliProductId()); + params.put("mchOrderNo", payOrderInfoDTO.getOrderNo()); + params.put("amount", payOrderInfoDTO.getPriceFenStr()); + String notifyUrl = payTrdConfig.getNotifyUrl() + type.getNotifyPath(); + params.put("notifyUrl", notifyUrl); + String para = PayMd5Util.createParams(params, payTrdConfig.getSign()); + String gatewayUrl = type.getGatewayUrl(); + if (StringUtils.isNotBlank(payTrdConfig.getGatewayUrl())) { + gatewayUrl = payTrdConfig.getGatewayUrl(); + } + String createOrderUrl = gatewayUrl + type.getCreateOrderUrl(); + String url = createOrderUrl + "?" + para; + String body = rest.getForEntity(url, String.class).getBody(); + JSONObject jsonObject = JSON.parseObject(body); + orderLogsService.createAliPayLogs(payOrderInfoDTO.getOrderNo(), url, jsonObject, type); + if(jsonObject == null){ + log.error("第三方支付失败 V3 返回数据为空 url={}",url); + throw new ServiceException("调用支付失败"); + } + if(!"SUCCESS".equals(jsonObject.getString("retCode"))){ + log.info("第三方支付失败 V3 统一支付失败失败 dto={}, payTrdConfig={}, typeEnum={}", body, JSON.toJSONString(payTrdConfig), JSON.toJSONString(jsonObject)); + throw new ServiceException("调用支付失败"); + } + String payUrl = jsonObject.getJSONObject("payParams").getString("payUrl"); + return PayReturnResp.createH5(payUrl); + } + + @Override + public NotifyResp getNotifyResp(Map sourceData) { + String mchOrderNo = sourceData.get("mchOrderNo"); + String payOrderId = sourceData.get("payOrderId"); + NotifyResp resp = new NotifyResp(); + resp.setOrderNo(mchOrderNo); + resp.setTrdOrderNo(payOrderId); + resp.setPayTypeEnum(getType()); + resp.setSourceData(sourceData); + return resp; + } + + @Override + public JSONObject queryOrder(String orderNo, PayTrdConfig payTrdConfig) { + TrdPayTypeEnum type = getType(); + Map params = new HashMap<>(); + params.put("mchId", payTrdConfig.getMchId()); + params.put("mchOrderNo", orderNo); + String para = PayMd5Util.createParams(params,payTrdConfig.getSign()); + String gatewayUrl = type.getGatewayUrl(); + if(StringUtils.isNotBlank(payTrdConfig.getGatewayUrl())){ + gatewayUrl = payTrdConfig.getGatewayUrl(); + } + String queryOrderUrl = gatewayUrl + type.getQueryOrderUrl(); + String url = queryOrderUrl + "?" + para; + String body = RestTemplateUtil.getRest().getForEntity(url, String.class).getBody(); + JSONObject jsonObject = JSON.parseObject(body); + if(jsonObject == null){ + log.error("第三方支付查询失败 返回数据为空 URL={}",url); + throw new ServiceException("调用支付失败"); + } + log.info("第三方支付查询成功 V3 URL={}, body={}",url, body); + return jsonObject; + } + + @Override + public JSONObject resetOrder(String orderNo, PayTrdConfig payTrdConfig, boolean updateData) { + JSONObject jsonObject = this.queryOrder(orderNo,payTrdConfig); + if(!"SUCCESS".equals(jsonObject.getString("retCode"))){ + log.info("第三方支付失败 V3统一支付失败失败 orderNo={}, payTrdConfig={}", orderNo, JSON.toJSONString(payTrdConfig)); + throw new ServiceException("调用支付失败"); + } + Integer status = jsonObject.getInteger("status"); + if(status != null && status.equals(2)){ + String mchOrderNo = jsonObject.getString("mchOrderNo"); + String payOrderId = jsonObject.getString("payOrderId"); + String productId = jsonObject.getString("productId"); + Map objectJson = new HashMap<>(); + for (String key : jsonObject.keySet()) { + objectJson.put(key, jsonObject.getString(key)); + } + if(updateData){ + payManager.callBack(mchOrderNo,payOrderId,objectJson,"V3", PayTypeEnum.TRD); + } + } + return jsonObject; + } + +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/handle/PayTrdV4Service.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/handle/PayTrdV4Service.java new file mode 100644 index 00000000..46761ff1 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/trdpay/handle/PayTrdV4Service.java @@ -0,0 +1,132 @@ +package com.ruoyi.cai.trdpay.handle; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import com.ruoyi.cai.domain.PayTrdConfig; +import com.ruoyi.cai.pay.PayManager; +import com.ruoyi.cai.pay.PayOrderInfoDTO; +import com.ruoyi.cai.pay.PayReturnResp; +import com.ruoyi.cai.service.OrderLogsService; +import com.ruoyi.cai.trdpay.PayMd5Util; +import com.ruoyi.cai.trdpay.PayTrdService; +import com.ruoyi.cai.trdpay.TrdPayTypeEnum; +import com.ruoyi.cai.trdpay.dto.NotifyResp; +import com.ruoyi.cai.util.RestTemplateUtil; +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.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.util.HashMap; +import java.util.Map; + +@Service +@Slf4j +public class PayTrdV4Service implements PayTrdService { + + @Autowired + private OrderLogsService orderLogsService; + @Autowired + private PayManager payManager; + + @Override + public TrdPayTypeEnum getType() { + return TrdPayTypeEnum.V4; + } + + @Override + public PayReturnResp createOrderAli(PayOrderInfoDTO payOrderInfoDTO, PayTrdConfig payTrdConfig) { + TrdPayTypeEnum type = getType(); + RestTemplate rest = RestTemplateUtil.getRest(); + Map params = new HashMap<>(); + params.put("merchantId", payTrdConfig.getMchId()); + params.put("tradeType", payTrdConfig.getAliProductId()); + params.put("merchantPayNo", payOrderInfoDTO.getOrderNo()); + params.put("amt", payOrderInfoDTO.getPrice().toString()); + String notifyUrl = payTrdConfig.getNotifyUrl() + type.getNotifyPath(); + params.put("notifyUrl", notifyUrl); + params.put("goodsName",payOrderInfoDTO.getBody()); + String para = PayMd5Util.createParams(params, payTrdConfig.getSign()); + String gatewayUrl = type.getGatewayUrl(); + if (StringUtils.isNotBlank(payTrdConfig.getGatewayUrl())) { + gatewayUrl = payTrdConfig.getGatewayUrl(); + } + String createOrderUrl = gatewayUrl + type.getCreateOrderUrl(); + String url = createOrderUrl + "?" + para; + String body = rest.postForObject(url, null, String.class); + JSONObject jsonObject = JSON.parseObject(body); + orderLogsService.createAliPayLogs(payOrderInfoDTO.getOrderNo(), url, jsonObject, type); + if(jsonObject == null){ + log.error("第三方支付失败 V4 返回数据为空 url={}",url); + throw new ServiceException("调用支付失败"); + } + if(!"0000".equals(jsonObject.getString("code"))){ + log.info("第三方支付失败 V4 统一支付失败失败 dto={}, payTrdConfig={}, typeEnum={}", body, JSON.toJSONString(payTrdConfig), JSON.toJSONString(jsonObject)); + throw new ServiceException("调用支付失败"); + } + String payUrl = jsonObject.getJSONObject("data").getString("url"); + return PayReturnResp.createH5(payUrl); + } + + @Override + public NotifyResp getNotifyResp(Map sourceData) { + String mchOrderNo = sourceData.get("merchantPayNo"); + String payOrderId = sourceData.get("payNo"); + NotifyResp resp = new NotifyResp(); + resp.setOrderNo(mchOrderNo); + resp.setTrdOrderNo(payOrderId); + resp.setPayTypeEnum(getType()); + resp.setSourceData(sourceData); + return resp; + } + + @Override + public JSONObject queryOrder(String orderNo, PayTrdConfig payTrdConfig) { + TrdPayTypeEnum type = getType(); + Map params = new HashMap<>(); + params.put("merchantId", payTrdConfig.getMchId()); + params.put("merchantPayNo", orderNo); + String para = PayMd5Util.createParams(params,payTrdConfig.getSign()); + String gatewayUrl = type.getGatewayUrl(); + if(StringUtils.isNotBlank(payTrdConfig.getGatewayUrl())){ + gatewayUrl = payTrdConfig.getGatewayUrl(); + } + String queryOrderUrl = gatewayUrl + type.getQueryOrderUrl(); + String url = queryOrderUrl + "?" + para; + String body = RestTemplateUtil.getRest().getForEntity(url, String.class).getBody(); + JSONObject jsonObject = JSON.parseObject(body); + if(jsonObject == null){ + log.error("第三方支付查询失败 返回数据为空 URL={}",url); + throw new ServiceException("调用支付失败"); + } + log.info("第三方支付查询成功 V4 URL={}, body={}",url, body); + return jsonObject; + } + + @Override + public JSONObject resetOrder(String orderNo, PayTrdConfig payTrdConfig, boolean updateData) { + throw new ServiceException("V4不支持订单查询"); + /*JSONObject jsonObject = this.queryOrder(orderNo,payTrdConfig); + if(!"SUCCESS".equals(jsonObject.getString("retCode"))){ + log.info("第三方支付失败 V4统一支付失败失败 orderNo={}, payTrdConfig={}", orderNo, JSON.toJSONString(payTrdConfig)); + throw new ServiceException("调用支付失败"); + } + Integer status = jsonObject.getInteger("status"); + if(status != null && status.equals(1)){ + String mchOrderNo = jsonObject.getString("mchOrderNo"); + String payOrderId = jsonObject.getString("payOrderId"); + String productId = jsonObject.getString("productId"); + Map objectJson = new HashMap<>(); + for (String key : jsonObject.keySet()) { + objectJson.put(key, jsonObject.getString(key)); + } + if(updateData){ + payManager.callBack(mchOrderNo,payOrderId,objectJson,"V4", PayTypeEnum.TRD); + } + } + return jsonObject;*/ + } + +} diff --git a/ruoyi-cai/src/main/java/com/ruoyi/cai/util/RestTemplateUtil.java b/ruoyi-cai/src/main/java/com/ruoyi/cai/util/RestTemplateUtil.java new file mode 100644 index 00000000..f9c39a97 --- /dev/null +++ b/ruoyi-cai/src/main/java/com/ruoyi/cai/util/RestTemplateUtil.java @@ -0,0 +1,35 @@ +package com.ruoyi.cai.util; + +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.web.client.RestTemplate; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +public class RestTemplateUtil { + + 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 static RestTemplate getRest(){ + return restTemplate; + } +}