fix: 收款不再预查微信,恢复早期「有package就调起」逻辑
接入多俱乐部后每次收款先查微信,V3查单失败会永久返回code12。 改为仅读本地:有package直接确认,无package立刻作废重试;转账失败返回明确错误。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -105,7 +105,7 @@ RECONCILE_AUDIT_CLOSED = 'audit_closed'
|
||||
# 单笔实际到账上限(仅收款时校验)
|
||||
MAX_SINGLE_COLLECT_AMOUNT = decimal.Decimal('200')
|
||||
|
||||
# 查单失败且本地 zhuangtai=0 超过该秒数,才短暂提示「发起中」
|
||||
# tixianqr 查单时:无 package 且微信 404 超过该秒数才提示处理中
|
||||
PENDING_QUERY_GRACE_SECONDS = 20
|
||||
|
||||
|
||||
@@ -1292,8 +1292,10 @@ def _collapse_stale_pending_records(shenhe_danhao):
|
||||
|
||||
def reconcile_shenhe_wechat_bills(shenhe_danhao):
|
||||
"""
|
||||
收款前对账:防双笔,但不因查单失败无限「处理中」。
|
||||
原则:有 package 就调起微信确认;无 package 的旧单作废;仅极短窗口内提示发起中。
|
||||
收款前对账(仅读本地库,不阻塞查微信)。
|
||||
|
||||
早期可用版本也是:有 package 直接调起确认;没有 package 就重新发起转账。
|
||||
多俱乐部改造后「每次收款先查微信」在 V3 配置/查单异常时会永远返回处理中,已移除。
|
||||
"""
|
||||
records = list(
|
||||
TixianAutoRecord.query.filter(shenhe_danhao=shenhe_danhao).order_by('-CreateTime')
|
||||
@@ -1316,46 +1318,10 @@ def reconcile_shenhe_wechat_bills(shenhe_danhao):
|
||||
if local_wait:
|
||||
return local_wait
|
||||
|
||||
age = timezone.now() - pending.CreateTime
|
||||
if not _parse_package_info(pending.wechat_package):
|
||||
if age >= timedelta(seconds=PENDING_QUERY_GRACE_SECONDS):
|
||||
_mark_transfer_attempt_failed(
|
||||
pending, '上次发起未成功,请重新收款', close_audit=False,
|
||||
)
|
||||
return RECONCILE_ALLOW_NEW, {}
|
||||
return RECONCILE_PENDING, {
|
||||
'msg': '收款发起中,请稍后再试',
|
||||
'tixian_id': pending.tixian_id,
|
||||
}
|
||||
|
||||
wx_data = query_wechat_transfer_bill(
|
||||
pending.tixian_id, club_id_for_tixian_yonghuid(pending.yonghuid),
|
||||
# 进行中但无 package = 上次调微信没成功,立刻作废,允许本次重新发起
|
||||
_mark_transfer_attempt_failed(
|
||||
pending, '上次发起未成功,请重新收款', close_audit=False,
|
||||
)
|
||||
if wx_data is None:
|
||||
logger.warning(
|
||||
'查单不可用 bill=%s,使用本地 package 继续收款', pending.tixian_id,
|
||||
)
|
||||
return RECONCILE_WAIT_CONFIRM, _wait_confirm_payload(
|
||||
pending, _parse_package_info(pending.wechat_package),
|
||||
)
|
||||
|
||||
action, payload = _sync_record_from_wx_query(pending, wx_data)
|
||||
if action == RECONCILE_COMPLETED:
|
||||
return action, payload
|
||||
if action == RECONCILE_WAIT_CONFIRM:
|
||||
return action, payload
|
||||
if action == RECONCILE_ALLOW_NEW:
|
||||
return action, payload
|
||||
if action == RECONCILE_AUDIT_CLOSED:
|
||||
return action, payload
|
||||
if action == RECONCILE_PENDING:
|
||||
pkg = _parse_package_info(pending.wechat_package)
|
||||
if pkg:
|
||||
return RECONCILE_WAIT_CONFIRM, _wait_confirm_payload(pending, pkg)
|
||||
if age >= timedelta(seconds=PENDING_QUERY_GRACE_SECONDS):
|
||||
_mark_transfer_attempt_failed(pending, '收款超时,请重新发起', close_audit=False)
|
||||
return RECONCILE_ALLOW_NEW, {}
|
||||
return action, payload
|
||||
return RECONCILE_ALLOW_NEW, {}
|
||||
|
||||
|
||||
@@ -1429,30 +1395,20 @@ def resolve_collect_context(yonghuid, tixianjilu_id=None, shenhe_danhao='', shen
|
||||
|
||||
def handle_post_transfer_failure(tixian_id, shenhe_danhao, err_code='', err_msg=''):
|
||||
"""
|
||||
发起转账 HTTP 非成功时:先查微信再决定是否标失败(P0,禁止盲目标失败导致双笔)
|
||||
返回 (action, payload_or_user_msg)
|
||||
发起转账 HTTP 非成功:本地已有 package 则继续调起确认;否则标失败并返回可重试。
|
||||
"""
|
||||
try:
|
||||
ar = TixianAutoRecord.query.get(tixian_id=tixian_id)
|
||||
except TixianAutoRecord.DoesNotExist:
|
||||
return RECONCILE_PENDING, '收款处理中,请稍后再试'
|
||||
|
||||
wx_data = query_wechat_transfer_bill(tixian_id, club_id_for_tixian_yonghuid(ar.yonghuid))
|
||||
if wx_data is None:
|
||||
local = _maybe_wait_confirm_from_local(ar)
|
||||
if local:
|
||||
return local
|
||||
_mark_transfer_attempt_failed(ar, err_msg or '微信发起转账失败', close_audit=False)
|
||||
return RECONCILE_ALLOW_NEW, {'wx_err': err_msg or '微信发起转账失败'}
|
||||
|
||||
action, payload = _sync_record_from_wx_query(ar, wx_data)
|
||||
if action == RECONCILE_ALLOW_NEW:
|
||||
return RECONCILE_ALLOW_NEW, payload
|
||||
if action == RECONCILE_WAIT_CONFIRM:
|
||||
return RECONCILE_WAIT_CONFIRM, payload
|
||||
if action == RECONCILE_COMPLETED:
|
||||
return RECONCILE_COMPLETED, payload
|
||||
return RECONCILE_PENDING, payload.get('msg', '收款处理中,请稍后再试')
|
||||
local = _maybe_wait_confirm_from_local(ar)
|
||||
if local:
|
||||
return local
|
||||
|
||||
reason = (err_msg or err_code or '微信发起转账失败')[:500]
|
||||
_mark_transfer_attempt_failed(ar, reason, close_audit=False)
|
||||
return RECONCILE_ALLOW_NEW, {'wx_err': reason}
|
||||
|
||||
|
||||
def get_audit_for_collect(shenhe_danhao, yonghuid, shenhe_jilu_id=None):
|
||||
|
||||
@@ -272,11 +272,13 @@ def process_audit_collect(request):
|
||||
return quota_resp
|
||||
return _build_collect_success_response(payload)
|
||||
if action == RECONCILE_PENDING:
|
||||
msg = payload.get('msg') if isinstance(payload, dict) else payload
|
||||
return Response({'code': 12, 'msg': msg or '有收款处理中,请稍后再试'})
|
||||
logger.warning(
|
||||
'收款对账不应再返回 PENDING shenhe_danhao=%s payload=%s',
|
||||
shenhe_danhao, payload,
|
||||
)
|
||||
|
||||
if action != RECONCILE_ALLOW_NEW:
|
||||
return Response({'code': 12, 'msg': '收款处理中,请稍后再试'})
|
||||
return Response({'code': 99, 'msg': '收款状态异常,请再次点击收款'})
|
||||
|
||||
with transaction.atomic():
|
||||
audit, err = get_audit_for_collect(
|
||||
@@ -344,8 +346,9 @@ def process_audit_collect(request):
|
||||
err_code = wx_result.get('code', '')
|
||||
err_msg = wx_result.get('message', wx_result.get('detail', '微信接口调用失败'))
|
||||
logger.error(
|
||||
'微信发起转账未进入待确认: bill=%s code=%s msg=%s HTTP%s',
|
||||
tixian_id, err_code, err_msg, resp.status_code,
|
||||
'微信发起转账未进入待确认: bill=%s club=%s appid=%s mch=%s code=%s msg=%s HTTP%s body=%s',
|
||||
tixian_id, payout_club_id, wx_cfg.get('APPID'), wx_cfg.get('MCHID'),
|
||||
err_code, err_msg, resp.status_code, json.dumps(wx_result, ensure_ascii=False)[:500],
|
||||
)
|
||||
|
||||
is_balance_issue = _is_wx_balance_insufficient(err_code, err_msg)
|
||||
@@ -376,14 +379,11 @@ def process_audit_collect(request):
|
||||
'code': 400,
|
||||
'msg': post_payload.get('msg', '该笔提现已关闭,请重新申请'),
|
||||
})
|
||||
if post_action == RECONCILE_PENDING:
|
||||
pending_msg = (
|
||||
post_payload.get('msg', post_payload)
|
||||
if isinstance(post_payload, dict) else post_payload
|
||||
)
|
||||
return Response({'code': 12, 'msg': pending_msg or '有收款处理中,请稍后再试'})
|
||||
|
||||
user_msg = err_msg or '微信收款发起失败,请稍后重试'
|
||||
user_msg = (
|
||||
(post_payload.get('wx_err') if isinstance(post_payload, dict) else None)
|
||||
or err_msg
|
||||
or '微信收款发起失败,请稍后重试'
|
||||
)
|
||||
_mark_auto_record_failed(tixian_id, user_msg)
|
||||
if quota_reserved:
|
||||
release_collect_quota_for_record(
|
||||
|
||||
Reference in New Issue
Block a user