This commit is contained in:
eric
2026-03-12 19:50:50 -05:00
parent ae575f1828
commit 90378502cf
18 changed files with 438 additions and 22 deletions

View File

@@ -1,11 +1,15 @@
"""支付成功后的统一业务处理(基于 SDK"""
import logging
import requests
from ..config import PB_URL, PB_ADMIN_EMAIL, PB_ADMIN_PASSWORD
from .pb import get_pb_client
from .memos import create_memos_user
# 已处理订单(防重复)
processed_orders: set[str] = set()
DEFAULT_PASSWORD = "12345678"
def parse_order_id(order_id: str) -> tuple[str, str]:
@@ -19,6 +23,77 @@ def parse_order_id(order_id: str) -> tuple[str, str]:
return prefix, "unknown"
def _decode_pending_email(user_id: str) -> str | None:
"""从 pending_hex 格式解析邮箱"""
if not user_id.startswith("pending_"):
return None
hex_part = user_id[8:] # 去掉 "pending_"
try:
return bytes.fromhex(hex_part).decode("utf-8")
except Exception:
return None
def _create_user_by_email(email: str) -> str | None:
"""用管理员创建用户,返回 user_id。若已存在则返回已有用户 id"""
token, _ = _get_admin_token()
if not token:
return None
base = (PB_URL or "").rstrip("/")
r = requests.post(
f"{base}/api/collections/users/records",
json={
"email": email,
"password": DEFAULT_PASSWORD,
"passwordConfirm": DEFAULT_PASSWORD,
},
headers={"Content-Type": "application/json", "Authorization": f"Bearer {token}"},
timeout=10,
)
if r.status_code == 200:
return r.json().get("id")
if r.status_code == 400:
try:
err = r.json()
if "already" in str(err.get("data", {}).get("email", {}).get("message", "")).lower():
# 用户已存在,查询获取 id
get_r = requests.get(
f"{base}/api/collections/users/records",
params={"filter": f'email="{email}"', "perPage": 1},
headers={"Authorization": f"Bearer {token}"},
timeout=10,
)
if get_r.status_code == 200:
items = get_r.json().get("items", [])
if items:
return items[0].get("id")
except Exception:
pass
logging.warning(f"create user failed: {r.status_code} {r.text[:200]}")
return None
def _get_admin_token() -> tuple[str | None, str | None]:
"""获取 PocketBase 管理员 token"""
if not PB_ADMIN_EMAIL or not PB_ADMIN_PASSWORD:
return None, "未配置"
base = (PB_URL or "").rstrip("/")
for path in ["/api/collections/_superusers/auth-with-password", "/api/admins/auth-with-password"]:
try:
r = requests.post(
f"{base}{path}",
json={"identity": PB_ADMIN_EMAIL, "password": PB_ADMIN_PASSWORD},
timeout=10,
)
if r.status_code == 200:
return r.json().get("token"), None
if r.status_code == 404:
continue
except Exception:
pass
return None, "认证失败"
def handle_payment_success(
order_id: str,
pay_price: str,
@@ -36,10 +111,22 @@ def handle_payment_success(
if not user_id:
return
# meetup 新用户:支付成功后才创建用户
if pay_type == "meetup" and user_id.startswith("pending_"):
email = _decode_pending_email(user_id)
if email:
real_id = _create_user_by_email(email)
if real_id:
user_id = real_id
logging.info(f"meetup 支付成功,已创建用户: {email}")
else:
logging.error(f"meetup 支付成功但创建用户失败: {email}")
return
print(f"支付成功 [{provider_name}] 用户ID: {user_id},类型: {pay_type},站点: {site_id},订单: {order_id}")
if pay_type == "vip" and use_memos:
create_memos_user(user_id)
create_memos_user(user_id, password="12345678")
if pay_type == "meetup":
logging.info(f"meetup 类型支付成功,不创建 memos 用户 - user_id: {user_id}")