diff --git a/src/main/java/com/gxwebsoft/common/core/security/SecurityConfig.java b/src/main/java/com/gxwebsoft/common/core/security/SecurityConfig.java index 9864eaa..8cd95a0 100644 --- a/src/main/java/com/gxwebsoft/common/core/security/SecurityConfig.java +++ b/src/main/java/com/gxwebsoft/common/core/security/SecurityConfig.java @@ -67,6 +67,7 @@ public class SecurityConfig { "/api/shop/wx-login/**", "/api/shop/wx-native-pay/**", "/api/shop/wx-pay/**", + "/api/system/wx-pay/**", "/api/bszx/bszx-pay/notify/**", "/api/wxWorkQrConnect", "/WW_verify_QMv7HoblYU6z63bb.txt", diff --git a/src/main/java/com/gxwebsoft/credit/mapper/xml/CreditRiskRelationMapper.xml b/src/main/java/com/gxwebsoft/credit/mapper/xml/CreditRiskRelationMapper.xml index 9683d91..b425443 100644 --- a/src/main/java/com/gxwebsoft/credit/mapper/xml/CreditRiskRelationMapper.xml +++ b/src/main/java/com/gxwebsoft/credit/mapper/xml/CreditRiskRelationMapper.xml @@ -12,9 +12,9 @@ AND a.id = #{param.id} - - AND a.company_id = #{param.companyId} - + + AND a.company_id = #{param.companyId} + AND a.main_body_name LIKE CONCAT('%', #{param.mainBodyName}, '%') @@ -63,7 +63,7 @@ AND (a.comments LIKE CONCAT('%', #{param.keywords}, '%') OR b.name = #{param.keywords} - OR b.main_body_name LIKE CONCAT('%', #{param.keywords}, '%') + OR b.match_name LIKE CONCAT('%', #{param.keywords}, '%') ) diff --git a/src/main/java/com/gxwebsoft/shop/controller/WxPayNotifyAliasController.java b/src/main/java/com/gxwebsoft/shop/controller/WxPayNotifyAliasController.java new file mode 100644 index 0000000..6a27350 --- /dev/null +++ b/src/main/java/com/gxwebsoft/shop/controller/WxPayNotifyAliasController.java @@ -0,0 +1,47 @@ +package com.gxwebsoft.shop.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +/** + * 微信支付回调别名入口(兼容历史 notify_url) + * + * 说明: + * - 旧代码曾使用 /api/system/wx-pay/notify/{tenantId} 或 /api/shop/wx-pay/notify/{tenantId} + * - 微信支付“请求重入”要求 notify_url 等参数与首次一致,因此需要保留旧回调地址可用 + */ +@Tag(name = "微信支付回调(别名)") +@RestController +public class WxPayNotifyAliasController { + + @Resource + private ShopOrderController shopOrderController; + + @Operation(summary = "微信支付回调别名(兼容旧回调地址)") + @PostMapping({"/api/system/wx-pay/notify/{tenantId}", "/api/shop/wx-pay/notify/{tenantId}"}) + public String wxNotifyAlias(@RequestHeader Map header, + @RequestBody String body, + @PathVariable("tenantId") Integer tenantId) { + // ShopOrderController.wxNotify 读取的是小写 header key,这里做一次兼容转换 + Map lower = new HashMap<>(); + if (header != null) { + header.forEach((k, v) -> { + if (k != null) { + lower.put(k.toLowerCase(Locale.ROOT), v); + } + }); + } + return shopOrderController.wxNotify(lower, body, tenantId); + } +} + diff --git a/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java b/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java index 3c0e4d4..24322b7 100644 --- a/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java +++ b/src/main/java/com/gxwebsoft/shop/service/impl/ShopOrderServiceImpl.java @@ -30,12 +30,14 @@ import com.wechat.pay.java.service.payments.jsapi.model.*; import com.wechat.pay.java.service.payments.nativepay.NativePayService; // Native支付的类将使用完全限定名避免冲突 import com.wechat.pay.java.service.payments.model.Transaction; +import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import javax.annotation.Resource; import java.math.BigDecimal; +import java.math.RoundingMode; import java.time.LocalDateTime; import java.util.*; import java.util.concurrent.TimeUnit; @@ -86,6 +88,165 @@ public class ShopOrderServiceImpl extends ServiceImpl buildNotifyUrlCandidates(ShopOrder order, Payment payment, WechatPrepaySnapshot snapshot) { + LinkedHashSet urls = new LinkedHashSet<>(); + if (snapshot != null && StrUtil.isNotBlank(snapshot.getNotifyUrl())) { + urls.add(trimTrailingSlashes(snapshot.getNotifyUrl())); + } + if (payment != null && StrUtil.isNotBlank(payment.getNotifyUrl())) { + urls.add(ensureTenantSuffix(payment.getNotifyUrl(), order.getTenantId())); + } + + // 新默认回调(本项目已实现) + String shopOrderNotify = defaultShopOrderNotifyUrl(order.getTenantId()); + if (StrUtil.isNotBlank(shopOrderNotify)) { + urls.add(shopOrderNotify); + } + + // 兼容历史回调地址(用于已创建订单的“重新支付”重入校验) + String legacySystem = legacySystemWxPayNotifyUrl(order.getTenantId()); + if (StrUtil.isNotBlank(legacySystem)) { + urls.add(legacySystem); + } + + if ("dev".equals(active)) { + String devNotify = devShopOrderNotifyUrl(order.getTenantId()); + if (StrUtil.isNotBlank(devNotify)) { + urls.add(devNotify); + } + String devLegacy = legacyShopWxPayNotifyUrl(order.getTenantId()); + if (StrUtil.isNotBlank(devLegacy)) { + urls.add(devLegacy); + } + } + + return new ArrayList<>(urls); + } @Override @@ -321,13 +482,15 @@ public class ShopOrderServiceImpl extends ServiceImpl orderInfo = new HashMap<>(); - orderInfo.put("provider", "wxpay"); - orderInfo.put("codeUrl", response.getCodeUrl()); // Native支付返回二维码URL - orderInfo.put("orderNo", order.getOrderNo()); - orderInfo.put("payType", WechatPayType.NATIVE); - orderInfo.put("wechatPayType", WechatPayType.NATIVE); + snapshot.setNotifyUrl(notifyUrlUsed); + snapshot.setTotal(amount.getTotal()); + snapshot.setDescription(request.getDescription()); + savePrepaySnapshot(payment, snapshot); - return orderInfo; + final HashMap orderInfo = new HashMap<>(); + orderInfo.put("provider", "wxpay"); + orderInfo.put("codeUrl", response.getCodeUrl()); // Native支付返回二维码URL + orderInfo.put("orderNo", order.getOrderNo()); + orderInfo.put("payType", WechatPayType.NATIVE); + orderInfo.put("wechatPayType", WechatPayType.NATIVE); + + return orderInfo; + } catch (Exception e) { + last = e; + if (!isIdempotencyParamMismatch(e)) { + throw e; + } + log.warn("Native预下单重入参数不一致,尝试切换notifyUrl重试 - outTradeNo={}, notifyUrl={}", outTradeNo, notifyUrl, e); + } + } + if (last != null) { + throw last; + } + throw new RuntimeException("创建Native支付订单失败:notifyUrl为空"); } /** @@ -399,10 +615,12 @@ public class ShopOrderServiceImpl extends ServiceImpl orderInfo = new HashMap<>(); + orderInfo.put("provider", "wxpay"); + orderInfo.put("timeStamp", response.getTimeStamp()); + orderInfo.put("nonceStr", response.getNonceStr()); + orderInfo.put("package", response.getPackageVal()); + orderInfo.put("signType", "RSA"); + orderInfo.put("paySign", response.getPaySign()); + orderInfo.put("orderNo", order.getOrderNo()); + orderInfo.put("payType", WechatPayType.JSAPI); + orderInfo.put("wechatPayType", WechatPayType.JSAPI); + return orderInfo; + } catch (Exception e) { + last = e; + if (!isIdempotencyParamMismatch(e)) { + throw e; + } + log.warn("JSAPI预下单重入参数不一致,尝试切换notifyUrl重试 - outTradeNo={}, notifyUrl={}", outTradeNo, notifyUrl, e); + } } - System.out.println("=== 发起微信支付请求 ==="); - System.out.println("请求参数: " + request); - - PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request); - - System.out.println("=== 微信支付响应成功 ==="); - System.out.println("预支付ID: " + response.getPackageVal()); - - final HashMap orderInfo = new HashMap<>(); - orderInfo.put("provider", "wxpay"); - orderInfo.put("timeStamp", response.getTimeStamp()); - orderInfo.put("nonceStr", response.getNonceStr()); - orderInfo.put("package", response.getPackageVal()); - orderInfo.put("signType", "RSA"); - orderInfo.put("paySign", response.getPaySign()); - orderInfo.put("orderNo", order.getOrderNo()); - orderInfo.put("payType", WechatPayType.JSAPI); - orderInfo.put("wechatPayType", WechatPayType.JSAPI); - return orderInfo; + if (last != null) { + throw last; + } + throw new RuntimeException("创建JSAPI支付订单失败:notifyUrl为空"); } @Override