s''
This commit is contained in:
@@ -34,6 +34,17 @@ def get_payment_provider() -> PaymentProvider:
|
|||||||
return _provider_instance
|
return _provider_instance
|
||||||
|
|
||||||
|
|
||||||
|
def get_payment_provider_by_name(name: str) -> PaymentProvider:
|
||||||
|
"""按名称获取 Provider(用于 per-request 覆盖)"""
|
||||||
|
if name == "xorpay":
|
||||||
|
return XorPayProvider(
|
||||||
|
aid=XORPAY_AID,
|
||||||
|
secret=XORPAY_SECRET,
|
||||||
|
cashier_url=XORPAY_CASHIER_URL,
|
||||||
|
)
|
||||||
|
return ZPayProvider(pid=ZPAY_PID, key=ZPAY_KEY)
|
||||||
|
|
||||||
|
|
||||||
def reset_provider():
|
def reset_provider():
|
||||||
"""重置 Provider(用于测试或切换渠道)"""
|
"""重置 Provider(用于测试或切换渠道)"""
|
||||||
global _provider_instance
|
global _provider_instance
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ from fastapi import APIRouter, Request, HTTPException
|
|||||||
from fastapi.responses import RedirectResponse, JSONResponse
|
from fastapi.responses import RedirectResponse, JSONResponse
|
||||||
|
|
||||||
from ..config import BASE_URL
|
from ..config import BASE_URL
|
||||||
from ..payment import get_payment_provider
|
from ..payment import get_payment_provider, get_payment_provider_by_name
|
||||||
from ..payment.zpay import ZPayProvider
|
from ..payment.zpay import ZPayProvider
|
||||||
from ..services import handle_payment_success, processed_orders
|
from ..services import handle_payment_success, processed_orders
|
||||||
|
|
||||||
@@ -21,10 +21,11 @@ def _get_notify_path(provider_name: str) -> str:
|
|||||||
|
|
||||||
@router.post("/payh5")
|
@router.post("/payh5")
|
||||||
async def nomadvip_payh5(item: dict):
|
async def nomadvip_payh5(item: dict):
|
||||||
"""nomadvip 专用:创建支付订单,xorpay 直接返回收银台参数,zpay 返回表单参数"""
|
"""nomadvip 专用:创建支付订单,支持 per-request provider 覆盖(微信用 xorpay,PC/H5 用 zpay)"""
|
||||||
print("nomadvip/payh5 item:", item)
|
print("nomadvip/payh5 item:", item)
|
||||||
provider = get_payment_provider()
|
req_provider = (item.get("provider") or "").strip().lower()
|
||||||
total_fee = int(item.get("total_fee", 8800))
|
provider = get_payment_provider_by_name(req_provider) if req_provider in ("xorpay", "zpay") else get_payment_provider()
|
||||||
|
total_fee = int(item.get("total_fee", 880))
|
||||||
total_fee_yuan = f"{total_fee / 100:.2f}"
|
total_fee_yuan = f"{total_fee / 100:.2f}"
|
||||||
user_id = item.get("user_id", "unknown")
|
user_id = item.get("user_id", "unknown")
|
||||||
pay_type = (item.get("type") or "vip").lower()
|
pay_type = (item.get("type") or "vip").lower()
|
||||||
@@ -70,15 +71,16 @@ async def nomadvip_payh5(item: dict):
|
|||||||
@router.post("/payh5/redirect")
|
@router.post("/payh5/redirect")
|
||||||
async def nomadvip_payh5_redirect(item: dict, request: Request):
|
async def nomadvip_payh5_redirect(item: dict, request: Request):
|
||||||
"""nomadvip 专用:ZPAY mapi 接口(xorpay 无需 redirect,直接 payh5 即可)"""
|
"""nomadvip 专用:ZPAY mapi 接口(xorpay 无需 redirect,直接 payh5 即可)"""
|
||||||
provider = get_payment_provider()
|
req_provider = (item.get("provider") or "").strip().lower()
|
||||||
if provider.name != "zpay":
|
provider = get_payment_provider_by_name("zpay") if req_provider == "zpay" else get_payment_provider()
|
||||||
|
if not isinstance(provider, ZPayProvider):
|
||||||
raise HTTPException(status_code=400, detail="payh5/redirect 仅支持 zpay,xorpay 请直接使用 payh5")
|
raise HTTPException(status_code=400, detail="payh5/redirect 仅支持 zpay,xorpay 请直接使用 payh5")
|
||||||
logging.info(f"nomadvip payh5/redirect 请求: item={item}")
|
logging.info(f"nomadvip payh5/redirect 请求: item={item}")
|
||||||
try:
|
try:
|
||||||
total_fee = float(item.get("total_fee", 8800))
|
total_fee = float(item.get("total_fee", 880))
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
logging.warning(f"nomadvip payh5/redirect 无效 total_fee: {item.get('total_fee')}")
|
logging.warning(f"nomadvip payh5/redirect 无效 total_fee: {item.get('total_fee')}")
|
||||||
total_fee = 8800.0
|
total_fee = 880.0
|
||||||
total_fee_yuan = f"{total_fee / 100:.2f}"
|
total_fee_yuan = f"{total_fee / 100:.2f}"
|
||||||
user_id = item.get("user_id", "unknown")
|
user_id = item.get("user_id", "unknown")
|
||||||
pay_type = (item.get("type") or "vip").lower()
|
pay_type = (item.get("type") or "vip").lower()
|
||||||
@@ -144,14 +146,13 @@ async def nomadvip_zpay_order_status(out_trade_no: str):
|
|||||||
|
|
||||||
@router.get("/order_status")
|
@router.get("/order_status")
|
||||||
async def nomadvip_order_status(order_id: str):
|
async def nomadvip_order_status(order_id: str):
|
||||||
"""nomadvip 通用:查询订单支付状态(xorpay 查 PocketBase,zpay 查 ZPAY)"""
|
"""nomadvip 通用:查询订单支付状态。zpay 先查 ZPAY 实时,xorpay 或失败时查 PocketBase"""
|
||||||
provider = get_payment_provider()
|
zpay = get_payment_provider_by_name("zpay")
|
||||||
if isinstance(provider, ZPayProvider):
|
if isinstance(zpay, ZPayProvider):
|
||||||
result = provider.query_order_status(order_id, timeout=15)
|
result = zpay.query_order_status(order_id, timeout=15)
|
||||||
if result.get("error"):
|
if not result.get("error") and result.get("paid"):
|
||||||
logging.warning(f"nomadvip ZPAY 订单查询失败: {result.get('error')}")
|
return result
|
||||||
return result
|
# zpay 查不到或 xorpay:查 PocketBase(notify 后写入)
|
||||||
# xorpay:查 PocketBase
|
|
||||||
try:
|
try:
|
||||||
from ..services.pb import get_pb_client
|
from ..services.pb import get_pb_client
|
||||||
|
|
||||||
@@ -165,7 +166,7 @@ async def nomadvip_order_status(order_id: str):
|
|||||||
|
|
||||||
@router.post("/xorpay_notify")
|
@router.post("/xorpay_notify")
|
||||||
async def nomadvip_xorpay_notify(request: Request):
|
async def nomadvip_xorpay_notify(request: Request):
|
||||||
"""nomadvip 专用:XorPay 异步通知"""
|
"""nomadvip 专用:XorPay 异步通知(路径即渠道,不依赖全局 PAYMENT_PROVIDER)"""
|
||||||
form_data = await request.form()
|
form_data = await request.form()
|
||||||
data = {k: v for k, v in form_data.items()}
|
data = {k: v for k, v in form_data.items()}
|
||||||
logging.info(f"nomadvip XorPay 异步通知: {data}")
|
logging.info(f"nomadvip XorPay 异步通知: {data}")
|
||||||
@@ -173,9 +174,7 @@ async def nomadvip_xorpay_notify(request: Request):
|
|||||||
if order_id in processed_orders:
|
if order_id in processed_orders:
|
||||||
logging.info(f"nomadvip 订单已处理,跳过: {order_id}")
|
logging.info(f"nomadvip 订单已处理,跳过: {order_id}")
|
||||||
return "ok"
|
return "ok"
|
||||||
provider = get_payment_provider()
|
provider = get_payment_provider_by_name("xorpay")
|
||||||
if provider.name != "xorpay":
|
|
||||||
raise HTTPException(status_code=400, detail="xorpay_notify only for xorpay")
|
|
||||||
if not provider.verify_notify(data):
|
if not provider.verify_notify(data):
|
||||||
logging.error(f"nomadvip XorPay 验签失败: {data}")
|
logging.error(f"nomadvip XorPay 验签失败: {data}")
|
||||||
raise HTTPException(status_code=400, detail="sign error")
|
raise HTTPException(status_code=400, detail="sign error")
|
||||||
@@ -195,10 +194,8 @@ async def nomadvip_xorpay_notify(request: Request):
|
|||||||
@router.get("/zpay_notify")
|
@router.get("/zpay_notify")
|
||||||
@router.post("/zpay_notify")
|
@router.post("/zpay_notify")
|
||||||
async def nomadvip_zpay_notify(request: Request):
|
async def nomadvip_zpay_notify(request: Request):
|
||||||
"""nomadvip 专用:ZPAY 异步通知"""
|
"""nomadvip 专用:ZPAY 异步通知(路径即渠道,不依赖全局 PAYMENT_PROVIDER)"""
|
||||||
provider = get_payment_provider()
|
provider = get_payment_provider_by_name("zpay")
|
||||||
if provider.name != "zpay":
|
|
||||||
raise HTTPException(status_code=400, detail="zpay_notify only for zpay")
|
|
||||||
if request.method == "GET":
|
if request.method == "GET":
|
||||||
data = dict(request.query_params)
|
data = dict(request.query_params)
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user