修复IP白名单失败不换商户:跳过查单并放行卡住的旧单。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1394,6 +1394,18 @@ def reconcile_shenhe_wechat_bills(shenhe_danhao):
|
||||
|
||||
wx_data = query_wechat_transfer_bill(rec.tixian_id)
|
||||
if wx_data is None:
|
||||
# IP 未放行时创建/查单都会失败。若从未拿到 package,说明没进待确认,
|
||||
# 标失败放行换商户;否则会永远卡在「处理中」并反复打第一个商户。
|
||||
has_pkg = bool(_parse_package_info(rec.wechat_package))
|
||||
if rec.zhuangtai == 0 and not has_pkg:
|
||||
rec.zhuangtai = 2
|
||||
rec.fail_reason = '查单不可用且未待确认(常见于IP白名单),已换其他商户重试'
|
||||
rec.save(update_fields=['zhuangtai', 'fail_reason', 'update_time'])
|
||||
logger.warning(
|
||||
'对账查单不可用已放行换号 shenhe=%s bill=%s mch=%s',
|
||||
shenhe_danhao, rec.tixian_id, rec.mch_id,
|
||||
)
|
||||
continue
|
||||
logger.error(
|
||||
'对账查单不可用 shenhe_danhao=%s bill=%s',
|
||||
shenhe_danhao, rec.tixian_id,
|
||||
|
||||
@@ -90,11 +90,25 @@ def _is_wx_unsafe_to_switch(err_code='', err_msg='', status_code=None):
|
||||
return any(k in blob for k in keys)
|
||||
|
||||
|
||||
def _is_wx_ip_denied(err_code='', err_msg=''):
|
||||
"""商户未配置服务器出口 IP 白名单(创建/查单都会拦)。"""
|
||||
blob = f'{err_code} {err_msg}'.upper().replace('\t', '')
|
||||
if '268491067' in blob:
|
||||
return True
|
||||
if 'IP' in blob and '不允许' in blob:
|
||||
return True
|
||||
return any(k in blob for k in (
|
||||
'IP地址不允许', 'IP 地址不允许', '不允许调用该接口', '不允许调用接口',
|
||||
'NOT_ALLOW_IP', 'IP_DENIED',
|
||||
))
|
||||
|
||||
|
||||
def _is_wx_clear_switchable_fail(err_code='', err_msg='', status_code=None):
|
||||
"""
|
||||
明确未建单的业务失败:可静默换下一商户(日额度/余额不足/无权限等)。
|
||||
查单失败(None)时也允许换——避免首户卡死后永不试下一户。
|
||||
明确未建单的业务失败:可静默换下一商户(日额度/余额不足/IP白名单/无权限等)。
|
||||
"""
|
||||
if _is_wx_ip_denied(err_code, err_msg):
|
||||
return True
|
||||
if _is_wx_unsafe_to_switch(err_code, err_msg, status_code):
|
||||
return False
|
||||
if status_code in (400, 401, 403):
|
||||
@@ -267,6 +281,12 @@ def process_audit_collect(request):
|
||||
if not mch_cfgs or not wx_cfg_is_complete(mch_cfgs[0]):
|
||||
logger.error('微信打款配置不完整 enabled_count=%s', len(mch_cfgs))
|
||||
return Response({'code': 11, 'msg': '系统配置异常,请联系客服'})
|
||||
if len(mch_cfgs) < 2:
|
||||
logger.warning(
|
||||
'启用且配置完整的转账商户仅 %s 个,无法轮换 mch_ids=%s '
|
||||
'(后台多个启用但私钥路径无效会被跳过)',
|
||||
len(mch_cfgs), [c.get('MCHID') for c in mch_cfgs],
|
||||
)
|
||||
|
||||
ctx, err = resolve_collect_context(
|
||||
yonghuid,
|
||||
@@ -479,13 +499,47 @@ def process_audit_collect(request):
|
||||
if resp.status_code == 200 and (not err_code or err_msg == '微信接口调用失败'):
|
||||
err_msg = f'微信状态:{state200 or "未知"}'
|
||||
logger.error(
|
||||
'微信发起转账未进入待确认: bill=%s mch=%s code=%s msg=%s HTTP%s state=%s',
|
||||
'微信发起转账未进入待确认: bill=%s mch=%s code=%s msg=%s HTTP%s state=%s body=%s',
|
||||
tixian_id, mch_id, err_code, err_msg, resp.status_code, state200,
|
||||
json.dumps(wx_result, ensure_ascii=False)[:500],
|
||||
)
|
||||
|
||||
has_next = mch_idx < len(mch_cfgs) - 1
|
||||
unsafe = _is_wx_unsafe_to_switch(err_code, err_msg, resp.status_code)
|
||||
clear_fail = _is_wx_clear_switchable_fail(err_code, err_msg, resp.status_code)
|
||||
ip_denied = _is_wx_ip_denied(err_code, err_msg)
|
||||
|
||||
# IP 白名单/明确 4xx:创建失败时查单也会被同一 IP 拦住,查了只会误卡「处理中」
|
||||
# 直接标失败并静默换下一户,绝不回前端中间错误
|
||||
if ip_denied or (clear_fail and resp.status_code in (400, 401, 403)):
|
||||
user_msg = err_msg or '微信收款发起失败,请稍后重试'
|
||||
last_user_msg = user_msg
|
||||
last_was_balance = _is_wx_balance_insufficient(err_code, err_msg)
|
||||
_mark_auto_record_failed(tixian_id, f'[{mch_id}] {user_msg}')
|
||||
if has_next:
|
||||
logger.warning(
|
||||
'商户明确失败(含IP白名单),跳过查单静默换下一户 shenhe=%s '
|
||||
'from=%s code=%s msg=%s http=%s idx=%s/%s',
|
||||
shenhe_danhao, mch_id, err_code, err_msg, resp.status_code,
|
||||
mch_idx + 1, len(mch_cfgs),
|
||||
)
|
||||
continue
|
||||
if quota_reserved:
|
||||
release_collect_quota_for_record(
|
||||
TixianAutoRecord.objects.get(tixian_id=tixian_id),
|
||||
)
|
||||
quota_reserved = False
|
||||
if ip_denied:
|
||||
return Response({
|
||||
'code': 99,
|
||||
'msg': '微信商户未配置服务器IP白名单或配置未生效,请联系管理员检查各商户号',
|
||||
})
|
||||
if last_was_balance:
|
||||
return Response({
|
||||
'code': 99,
|
||||
'msg': '运营账户资金不足,需等管理员充值后才能提现',
|
||||
})
|
||||
return Response({'code': 99, 'msg': user_msg})
|
||||
|
||||
wx_q = query_wechat_transfer_bill(tixian_id, wx_cfg=wx_cfg)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user