From d6237ccc7b88b2529ecc1ee278cc68a5c7a6973d Mon Sep 17 00:00:00 2001 From: XingQue Date: Fri, 10 Jul 2026 22:07:09 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=94=B6=E6=AC=BE=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E9=A2=84=E6=9F=A5=E5=BE=AE=E4=BF=A1=EF=BC=8C=E6=81=A2=E5=A4=8D?= =?UTF-8?q?=E6=97=A9=E6=9C=9F=E3=80=8C=E6=9C=89package=E5=B0=B1=E8=B0=83?= =?UTF-8?q?=E8=B5=B7=E3=80=8D=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 接入多俱乐部后每次收款先查微信,V3查单失败会永久返回code12。 改为仅读本地:有package直接确认,无package立刻作废重试;转账失败返回明确错误。 Co-authored-by: Cursor --- users/tixian_shenhe_services.py | 76 +++++++-------------------------- users/tixian_shenhe_views.py | 26 +++++------ 2 files changed, 29 insertions(+), 73 deletions(-) diff --git a/users/tixian_shenhe_services.py b/users/tixian_shenhe_services.py index 91a0f99..7aff445 100644 --- a/users/tixian_shenhe_services.py +++ b/users/tixian_shenhe_services.py @@ -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): diff --git a/users/tixian_shenhe_views.py b/users/tixian_shenhe_views.py index aa900c9..5661431 100644 --- a/users/tixian_shenhe_views.py +++ b/users/tixian_shenhe_views.py @@ -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(