40 lines
1.8 KiB
Python

# unipay/providers/stripe.py
import aiohttp, json
from ..core import Gateway, GatewayError
class StripeGateway(Gateway):
def __init__(self, api_key: str):
self.api_key = api_key
self.base = "https://api.stripe.com/v1"
async def create_payment(self, payload):
# 使用 PaymentIntent -> 前端使用 stripe.js 完成卡片采集
url = self.base + "/payment_intents"
body = {
"amount": str(payload["amount_total"]), # in cents
"currency": payload.get("currency","usd"),
"payment_method_types[]": "card",
"description": payload.get("description",""),
"metadata[out_trade_no]": payload.get("out_trade_no","")
}
async with aiohttp.ClientSession() as s:
async with s.post(url, data=body, auth=aiohttp.BasicAuth(self.api_key, "")) as r:
return {"provider":"stripe","data": await r.json()}
async def refund(self, payload):
url = self.base + "/refunds"
body = {"charge": payload["charge_id"], "amount": str(payload.get("refund_amount"))}
async with aiohttp.ClientSession() as s:
async with s.post(url, data=body, auth=aiohttp.BasicAuth(self.api_key, "")) as r:
return {"provider":"stripe","data": await r.json()}
async def query(self, payload):
# query payment intent or charge
pid = payload.get("payment_intent_id") or payload.get("charge_id")
if not pid:
raise GatewayError("need payment_intent_id or charge_id")
async with aiohttp.ClientSession() as s:
async with s.get(self.base + f"/payment_intents/{pid}", auth=aiohttp.BasicAuth(self.api_key, "")) as r:
return {"provider":"stripe","data": await r.json()}
async def handle_notify(self, headers, body):
# stripe webhook: verify signature header (Stripe-Signature) — production use official lib or implement verification
return {"provider":"stripe","data": json.loads(body)}