's'
This commit is contained in:
82
app/payment/xorpay.py
Normal file
82
app/payment/xorpay.py
Normal file
@@ -0,0 +1,82 @@
|
||||
"""
|
||||
XorPay 支付渠道实现
|
||||
文档: https://xorpay.com
|
||||
"""
|
||||
import hashlib
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from .base import PaymentProvider
|
||||
|
||||
|
||||
class XorPayProvider(PaymentProvider):
|
||||
"""XorPay 支付"""
|
||||
|
||||
def __init__(self, aid: str, secret: str, cashier_url: str = "https://xorpay.com/api/cashier"):
|
||||
self.aid = aid
|
||||
self.secret = secret
|
||||
self.cashier_url = cashier_url.rstrip("/")
|
||||
|
||||
@property
|
||||
def name(self) -> str:
|
||||
return "xorpay"
|
||||
|
||||
def _sign(self, name: str, pay_type: str, price: str, order_id: str, notify_url: str) -> str:
|
||||
raw = name + pay_type + price + order_id + notify_url + self.secret
|
||||
return hashlib.md5(raw.encode("utf-8")).hexdigest().lower()
|
||||
|
||||
def create_order(
|
||||
self,
|
||||
*,
|
||||
order_id: str,
|
||||
name: str,
|
||||
total_fee_yuan: str,
|
||||
pay_type: str,
|
||||
notify_url: str,
|
||||
return_url: Optional[str] = None,
|
||||
client_ip: Optional[str] = None,
|
||||
extra: Optional[Dict[str, Any]] = None,
|
||||
) -> Dict[str, Any]:
|
||||
# XorPay 使用 jsapi 表示 H5/JSAPI 支付
|
||||
channel_pay_type = "jsapi"
|
||||
params = {
|
||||
"name": name,
|
||||
"pay_type": channel_pay_type,
|
||||
"price": total_fee_yuan,
|
||||
"order_id": order_id,
|
||||
"notify_url": notify_url,
|
||||
}
|
||||
params["sign"] = self._sign(
|
||||
params["name"],
|
||||
params["pay_type"],
|
||||
params["price"],
|
||||
params["order_id"],
|
||||
params["notify_url"],
|
||||
)
|
||||
return {
|
||||
"status": "ok",
|
||||
"provider": self.name,
|
||||
"params": params,
|
||||
"pay_url": f"{self.cashier_url}/{self.aid}",
|
||||
}
|
||||
|
||||
def verify_notify(self, data: Dict[str, Any]) -> bool:
|
||||
received_sign = data.get("sign", "")
|
||||
aoid = data.get("aoid", "")
|
||||
order_id = data.get("order_id", "")
|
||||
pay_price = data.get("pay_price", "")
|
||||
pay_time = data.get("pay_time", "")
|
||||
raw = aoid + order_id + pay_price + pay_time + self.secret
|
||||
calculated = hashlib.md5(raw.encode("utf-8")).hexdigest().lower()
|
||||
return calculated == received_sign
|
||||
|
||||
def parse_notify(self, data: Dict[str, Any]) -> Dict[str, Any]:
|
||||
return {
|
||||
"order_id": data.get("order_id", ""),
|
||||
"trade_no": data.get("aoid", ""),
|
||||
"pay_price": data.get("pay_price", ""),
|
||||
"pay_time": data.get("pay_time", ""),
|
||||
"trade_status": "success", # XorPay 验签通过即视为成功
|
||||
}
|
||||
|
||||
def success_response(self) -> str:
|
||||
return "ok"
|
||||
Reference in New Issue
Block a user