diff --git a/daxpay-plugin/daxpay-plugin-risk/src/main/java/cn/daxpay/open/plugin/risk/strategy/DefaultPayRiskChecker.java b/daxpay-plugin/daxpay-plugin-risk/src/main/java/cn/daxpay/open/plugin/risk/strategy/DefaultPayRiskChecker.java index 13c1d8e06..f913710db 100644 --- a/daxpay-plugin/daxpay-plugin-risk/src/main/java/cn/daxpay/open/plugin/risk/strategy/DefaultPayRiskChecker.java +++ b/daxpay-plugin/daxpay-plugin-risk/src/main/java/cn/daxpay/open/plugin/risk/strategy/DefaultPayRiskChecker.java @@ -12,6 +12,7 @@ import cn.daxpay.open.plugin.risk.enums.PayBlacklistTypeEnum; import cn.daxpay.open.plugin.risk.enums.PayRiskHitPhaseEnum; import cn.daxpay.open.plugin.risk.service.PayBlacklistService; import cn.daxpay.open.plugin.risk.service.PayRiskHitService; +import cn.hutool.core.lang.Validator; import cn.hutool.core.net.NetUtil; import cn.hutool.core.util.StrUtil; import com.github.benmanes.caffeine.cache.Cache; @@ -150,6 +151,10 @@ public class DefaultPayRiskChecker implements PayRiskChecker { if (StrUtil.isBlank(ip)) { return; } + // IPv6 暂不参与网段判定, 直接放行(NetUtil.isInnerIP 仅支持 IPv4, 传入 IPv6 会抛异常) + if (Validator.isIpv6(ip)) { + return; + } // 内网/回环地址直通放行(网络层判定, 不查库) if (NetUtil.isInnerIP(ip)) { return; diff --git a/daxpay-plugin/daxpay-plugin-risk/src/test/java/cn/daxpay/open/plugin/risk/strategy/DefaultPayRiskCheckerTest.java b/daxpay-plugin/daxpay-plugin-risk/src/test/java/cn/daxpay/open/plugin/risk/strategy/DefaultPayRiskCheckerTest.java index 4d477bf83..7b137d65d 100644 --- a/daxpay-plugin/daxpay-plugin-risk/src/test/java/cn/daxpay/open/plugin/risk/strategy/DefaultPayRiskCheckerTest.java +++ b/daxpay-plugin/daxpay-plugin-risk/src/test/java/cn/daxpay/open/plugin/risk/strategy/DefaultPayRiskCheckerTest.java @@ -128,6 +128,24 @@ class DefaultPayRiskCheckerTest { verifyNoInteractions(payRiskHitService); } + @Test + @DisplayName("海外检查: IPv6 回环直通放行(NetUtil.isInnerIP 仅支持 IPv4, 传入 IPv6 会抛异常)") + void overseasIp_ipv6Loopback_shouldPassThroughWithoutLookup() { + assertDoesNotThrow(() -> checker.checkBeforePay(overseasCtx("::1"))); + + verify(ipToRegionService, never()).getRegionByIp(anyString()); + verifyNoInteractions(payRiskHitService); + } + + @Test + @DisplayName("海外检查: IPv6 公网地址直通放行") + void overseasIp_ipv6Public_shouldPassThroughWithoutLookup() { + assertDoesNotThrow(() -> checker.checkBeforePay(overseasCtx("2409:8a20:210:0:0:0:0:1"))); + + verify(ipToRegionService, never()).getRegionByIp(anyString()); + verifyNoInteractions(payRiskHitService); + } + @Test @DisplayName("海外检查: xdb 查询失败(region=null)放行不记录") void overseasIp_lookupReturnsNull_shouldPass() {