fix(withdraw): 免确认授权已开启判定加 authorization_id 非空,与打款一致
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -192,7 +192,7 @@ def withdraw_info(
|
||||
wechat_bound=bool(u and u.wechat_openid),
|
||||
wechat_nickname=u.wechat_nickname if u else None,
|
||||
wechat_avatar_url=u.wechat_avatar_url if u else None,
|
||||
transfer_auth_enabled=bool(auth and auth.state == "active"),
|
||||
transfer_auth_enabled=bool(auth and auth.state == "active" and auth.authorization_id),
|
||||
tiers=[WithdrawTierOut(**t) for t in crud_wallet.withdraw_tier_states(db, user.id, source)],
|
||||
)
|
||||
|
||||
@@ -335,7 +335,8 @@ def open_transfer_auth(user: CurrentUser, db: DbSession) -> TransferAuthResultOu
|
||||
def transfer_auth_status(user: CurrentUser, db: DbSession) -> TransferAuthStatusOut:
|
||||
auth = crud_wallet.sync_transfer_auth(db, user.id)
|
||||
state = auth.state if auth else "none"
|
||||
return TransferAuthStatusOut(state=state, enabled=(state == "active"))
|
||||
enabled = bool(auth and auth.state == "active" and auth.authorization_id)
|
||||
return TransferAuthStatusOut(state=state, enabled=enabled)
|
||||
|
||||
|
||||
@router.post(
|
||||
|
||||
+58
-1
@@ -9,7 +9,7 @@ from sqlalchemy import select
|
||||
|
||||
from app.db.session import SessionLocal
|
||||
from app.models.user import User
|
||||
from app.models.wallet import CoinAccount, WithdrawOrder
|
||||
from app.models.wallet import CoinAccount, WithdrawOrder, WechatTransferAuthorization
|
||||
from app.repositories import wallet as crud_wallet
|
||||
|
||||
|
||||
@@ -426,3 +426,60 @@ def test_withdraw_reject_refunds(client, monkeypatch) -> None:
|
||||
r = client.get("/api/v1/wallet/withdraw/status", params={"out_bill_no": bill}, headers=_auth(token))
|
||||
assert r.json()["status"] == "rejected"
|
||||
assert r.json()["fail_reason"] == "测试拒绝"
|
||||
|
||||
|
||||
# ===== §fix 免确认授权 enabled 判定收严:active+authorization_id 非空才算已授权 =====
|
||||
|
||||
def _seed_transfer_auth(phone: str, state: str, authorization_id: str | None) -> None:
|
||||
"""直接在库里写/改该用户的免确认授权记录(绕过微信,用于判定测试)。"""
|
||||
db = SessionLocal()
|
||||
try:
|
||||
user = db.execute(select(User).where(User.phone == phone)).scalar_one()
|
||||
auth = db.get(WechatTransferAuthorization, user.id)
|
||||
if auth is None:
|
||||
auth = WechatTransferAuthorization(
|
||||
user_id=user.id, openid="openid_test_abc",
|
||||
out_authorization_no=f"oan_{user.id}",
|
||||
)
|
||||
db.add(auth)
|
||||
auth.state = state
|
||||
auth.authorization_id = authorization_id
|
||||
db.commit()
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def test_withdraw_info_auth_enabled_requires_authorization_id(client, monkeypatch) -> None:
|
||||
_patch_userinfo(monkeypatch)
|
||||
token = _login(client, "13800002051")
|
||||
# 触发建号 + 绑定微信(withdraw-info 读 openid)
|
||||
client.get("/api/v1/wallet/withdraw-info", headers=_auth(token))
|
||||
client.post("/api/v1/wallet/bind-wechat", json={"code": "c1"}, headers=_auth(token))
|
||||
|
||||
# active 但无 authorization_id → 视为未授权
|
||||
_seed_transfer_auth("13800002051", "active", None)
|
||||
r = client.get("/api/v1/wallet/withdraw-info", headers=_auth(token))
|
||||
assert r.status_code == 200, r.text
|
||||
assert r.json()["transfer_auth_enabled"] is False
|
||||
|
||||
# active 且有 authorization_id → 已授权
|
||||
_seed_transfer_auth("13800002051", "active", "wx_auth_123")
|
||||
r = client.get("/api/v1/wallet/withdraw-info", headers=_auth(token))
|
||||
assert r.json()["transfer_auth_enabled"] is True
|
||||
|
||||
|
||||
def test_transfer_auth_status_requires_authorization_id(client, monkeypatch) -> None:
|
||||
_patch_userinfo(monkeypatch)
|
||||
token = _login(client, "13800002052")
|
||||
client.get("/api/v1/wallet/withdraw-info", headers=_auth(token))
|
||||
client.post("/api/v1/wallet/bind-wechat", json={"code": "c2"}, headers=_auth(token))
|
||||
|
||||
_seed_transfer_auth("13800002052", "active", None)
|
||||
r = client.get("/api/v1/wallet/transfer-auth/status", headers=_auth(token))
|
||||
assert r.status_code == 200, r.text
|
||||
assert r.json()["state"] == "active"
|
||||
assert r.json()["enabled"] is False
|
||||
|
||||
_seed_transfer_auth("13800002052", "active", "wx_auth_456")
|
||||
r = client.get("/api/v1/wallet/transfer-auth/status", headers=_auth(token))
|
||||
assert r.json()["enabled"] is True
|
||||
|
||||
Reference in New Issue
Block a user