feat(avatar): route token recharge through Huihui org orders

This commit is contained in:
stefanfeng
2026-10-16 14:56:00 +08:00
parent 9566eb8925
commit b1bf203018
9 changed files with 171 additions and 67 deletions
@@ -25,6 +25,7 @@ from models import (
)
from responses import fail, ok
from services.huihui_payment import HuihuiPaymentClient, HuihuiPaymentError
from services.huihui_org_payment import HuihuiOrgPaymentClient
from services.token_billing import get_or_create_account
from services.wechat_virtual_payment import (
PAYMENT_EVENTS as WECHAT_PAYMENT_EVENTS,
@@ -270,6 +271,7 @@ def _callback_amount_cents(payload) -> int | None:
"orderAmt",
"amount",
"totalAmount",
"chargeAmount",
)
if value in (None, ""):
return None
@@ -405,6 +407,47 @@ def charge(payload: dict = Body(...), authorization: str = Header(None), db: Ses
return ok(_payment_payload(order, get_or_create_account(db, user.id)))
@router.post("/token/charge/org")
def charge_via_huihui_org(payload: dict = Body(...), authorization: str = Header(None), db: Session = Depends(get_db)):
user = _require_user(authorization, db)
plan = db.query(TokenPlan).filter(TokenPlan.id == payload.get("planId")).first()
if not plan:
return fail("套餐不存在", 404)
method = str(payload.get("paymentMethod") or "").lower()
if method not in PAYMENT_METHODS:
return fail("支付方式不正确", 400)
scene = str(payload.get("payScene") or "APP").upper()
if scene not in PAYMENT_SCENES:
return fail("支付场景不正确", 400)
pay_type = 6 if scene == "LITE" else (1 if method == "wechat" else 2)
if scene == "LITE" and method != "wechat":
return fail("微信小程序仅支持微信支付", 400)
cents = _price_cents(plan.price)
try:
result = HuihuiOrgPaymentClient().create_order(
token=user.huihui_token, user_id=user.huihui_user_id,
name=user.nickname, phone=user.phone, avatar=user.avatar_url,
amount=f"{cents / 100:.2f}", pay_type=pay_type,
)
except HuihuiPaymentError as exc:
return fail(str(exc), 502)
provider_no = str(result.get("orderNo") or "")
if not provider_no.isdigit() or int(result.get("payStatus") or 0) != 1 or int(result.get("chargeType") or 0) != 9:
return fail("会会返回的充值订单不正确", 502)
if _callback_amount_cents({"chargeAmount": result.get("chargeAmount")}) != cents:
return fail("会会返回的充值金额不匹配", 502)
order = TokenPaymentOrder(
order_no=f"AV{datetime.utcnow().strftime('%Y%m%d%H%M%S')}{uuid.uuid4().hex[:12].upper()}",
user_id=user.id, plan_id=plan.id, payment_method=method,
pay_type=PAYMENT_METHODS[method], pay_way=scene, points_amount=plan.amount,
price_cents=cents, status="pending", provider="huihui_org",
provider_order_no=provider_no, provider_status="1",
)
db.add(order)
db.commit()
return ok(_payment_payload(order, get_or_create_account(db, user.id)))
@router.get("/token/payment/{order_id}")
def payment_status(order_id: str, authorization: str = Header(None), db: Session = Depends(get_db)):
user = _require_user(authorization, db)
@@ -414,6 +457,27 @@ def payment_status(order_id: str, authorization: str = Header(None), db: Session
).first()
if not order:
return fail("支付订单不存在", 404)
if order.provider == "huihui_org" and order.status == "pending":
try:
details = HuihuiOrgPaymentClient().get_order(
token=user.huihui_token, user_id=user.huihui_user_id,
order_no=order.provider_order_no,
)
status = int(details.get("payStatus") or 0)
if (str(details.get("orderNo") or "") == order.provider_order_no
and str(details.get("userId") or "") == user.huihui_user_id
and int(details.get("chargeType") or 0) == 9
and _callback_amount_cents({"chargeAmount": details.get("chargeAmount")}) == order.price_cents):
order.provider_status = str(status)
if status in (2, 3, 4):
_settle_paid_order(db, order, provider_status=f"ORG_{status}",
transaction_no=order.provider_order_no)
elif status == 5:
order.status = "closed"
db.commit()
db.refresh(order)
except (HuihuiPaymentError, TypeError, ValueError):
pass # 查询失败时保持待支付,不将未经核对的结果入账。
if order.provider == "wechat_virtual" and order.status == "pending" and user.wechat_mp_openid:
try:
provider_data = query_wechat_virtual_order(
@@ -560,6 +624,8 @@ def admin_request_refund(
return fail("订单不存在", 404)
if order.status != "paid" or order.refund_status not in {"", "none", "failed"}:
return fail("该订单当前不可退款", 409)
if order.provider == "huihui_org":
return fail("会会组织订单的原路退款接口尚未接入,请先在会会后台处理", 409)
account = get_or_create_account(db, order.user_id)
if int(account.balance or 0) < int(order.points_amount or 0):
return fail("该订单发放的积分已使用,不能执行全额退款", 409)