mirror of
https://gitee.com/dromara/dax-pay
synced 2026-08-09 06:26:00 +08:00
fix(payment-auth): OAuth 回调 session.channelMchNo 反查装载商户上下文, 修复 mchContextMissing
OAuth 重定向回调 /auth 仅含 authToken, param 无 mchNo/appId 时原逻辑跳过商户上下文装载, 导致下游查询 MchBaseEntity 表(wx_channel_app_capability)时 MchNoTenantLineHandler 取不到租户号 fail-closed。 新增 session.channelMchNo 兜底分支: findByChannelMchNoNotTenant 反查 mchNo 后调 initMch 装载到 PaymentContext(含启用校验), 覆盖微信直连/服务商码牌等所有走 ChannelProductAuthService.auth 的通道策略。
This commit is contained in:
@@ -42,7 +42,7 @@ public class ChannelProductAuthService {
|
||||
/// 授权回调后凭此恢复上下文。同时生成 queryCode 供调试轮询(微信等 OAuth 重定向通道回调 URL
|
||||
/// 不含 queryCode, 需随会话保存)。
|
||||
public AuthUrlResult generateAuthUrl(GenerateAuthUrlParam param) {
|
||||
initMchContext(param.getAppId(), param.getMchNo());
|
||||
initMchContext(param.getAppId(), param.getMchNo(), null);
|
||||
// 支付产品: 显式传入优先, 否则从通道商户号反查(调试工具/直接指定通道商户场景)
|
||||
String product = resolveProduct(param);
|
||||
var strategy = PaymentStrategyFactory.createByProduct(product, AbsChannelAuthStrategy.class);
|
||||
@@ -70,7 +70,7 @@ public class ChannelProductAuthService {
|
||||
/// @param session 认证会话上下文(H5场景从 authToken 恢复; 小程序直连场景可为空, 此时从 param 取上下文)。
|
||||
/// 由认证分发层在调用前通过 [AuthSessionStore#loadSession] 加载后注入。
|
||||
public AuthResult auth(AuthCodeParam param, AuthSession session) {
|
||||
initMchContext(param.getAppId(), param.getMchNo());
|
||||
initMchContext(param.getAppId(), param.getMchNo(), session);
|
||||
// product 优先从会话恢复, 其次取参数(小程序直连场景)
|
||||
String product = (session != null && StrUtil.isNotBlank(session.getProduct()))
|
||||
? session.getProduct() : param.getProduct();
|
||||
@@ -87,12 +87,21 @@ public class ChannelProductAuthService {
|
||||
}
|
||||
|
||||
/// 商户上下文初始化: appId 优先(渠道配置/小程序直连), appId 为空则用 mchNo(调试/直接指定通道商户场景),
|
||||
/// 两者均空时跳过(微信 OAuth 重定向回调仅含 authToken, 商户上下文由 session.channelMchNo 维度定位, 无需线程级 mchNo)。
|
||||
private void initMchContext(String appId, String mchNo) {
|
||||
/// 两者均空时从 session.channelMchNo 反查(OAuth 重定向回调场景, param 仅含 authToken)。
|
||||
/// 反查后调 initMch 把 mchNo 装载到 PaymentContext: 下游对 MchBaseEntity 表(如 wx_channel_app_capability)
|
||||
/// 的查询依赖线程级 mchNo, 否则 MchNoTenantLineHandler fail-closed 抛 mchContextMissing。
|
||||
private void initMchContext(String appId, String mchNo, AuthSession session) {
|
||||
if (StrUtil.isNotBlank(appId)) {
|
||||
merchantContextLoader.initMchByApp(appId);
|
||||
} else if (StrUtil.isNotBlank(mchNo)) {
|
||||
merchantContextLoader.initMch(mchNo);
|
||||
} else if (session != null && StrUtil.isNotBlank(session.getChannelMchNo())) {
|
||||
String resolvedMchNo = channelMerchantManager
|
||||
.findByChannelMchNoNotTenant(session.getChannelMchNo())
|
||||
.map(ChannelMerchant::getMchNo)
|
||||
.orElseThrow(() -> new BizInfoException(CommonErrorCode.VALIDATE_PARAMETERS_ERROR,
|
||||
"pay.error.assist.channelMchNotFound", session.getChannelMchNo()));
|
||||
merchantContextLoader.initMch(resolvedMchNo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user