feat: add avatar payments and finance management

This commit is contained in:
stefanfeng
2026-09-08 18:44:21 +08:00
parent 1bcdcead8d
commit 7e7aa06903
36 changed files with 10228 additions and 43 deletions
@@ -1,6 +1,7 @@
"""Signed client for Huihui's production payment-v3 service."""
import hashlib
import os
import random
import string
from datetime import datetime, timedelta, timezone
@@ -122,3 +123,59 @@ class HuihuiPaymentClient:
if not isinstance(data, dict):
raise HuihuiPaymentError("会会支付未返回订单信息")
return data
def request_refund(
self,
*,
huihui_token: str,
huihui_user_id: str,
order_no: str,
refund_no: str,
amount: str,
reason: str,
) -> dict[str, Any]:
"""Submit a full refund to payment-v3.
The refund path remains configurable because private Huihui deployments
may expose the same contract below a different gateway route.
"""
if not self.configured:
raise HuihuiPaymentError("会会支付服务未配置")
if not huihui_token or not huihui_user_id:
raise HuihuiPaymentError("当前会会登录凭证无法发起退款")
path = os.getenv("HUIHUI_PAYMENT_REFUND_PATH", "/payment/refund").strip()
if not path.startswith("/"):
path = f"/{path}"
if ".." in path:
raise HuihuiPaymentError("会会退款接口路径配置不正确")
body = {
"appId": self.app_id,
"masterOrderNo": order_no,
"refundOrderNo": refund_no,
"refundAmt": float(amount),
"refundReason": reason or "后台退款",
}
headers = {
"Authorization": f"Bearer {huihui_token}",
"appId": self.app_id,
"windowAppId": self.app_id,
}
try:
response = httpx.post(
f"{self.base_url}{path}",
headers=headers,
params=self._signed_params(huihui_user_id),
json=body,
timeout=self.timeout,
follow_redirects=True,
)
except httpx.HTTPError as exc:
raise HuihuiPaymentError("会会退款连接失败,请稍后重试") from exc
payload = self._json(response)
code = payload.get("code")
if response.status_code >= 400 or code not in (0, 200, "0", "200"):
raise HuihuiPaymentError(payload.get("message") or "会会退款申请失败")
data = payload.get("data") or {}
return data if isinstance(data, dict) else {"result": data}