""" 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"