35pay Python SDK
单文件 pay35.py,drop-in 任何 Python 3.9+ 项目。
- 同步
Pay:零依赖(仅用 stdlib urllib + hmac),适合 Flask / Django sync / 脚本 - 异步
AsyncPay:基于 httpx,适合 FastAPI / Starlette / Litestar / aiohttp 等 async 框架
Install
# 方式 1:drop-in 单文件(同步用法)
curl -O https://pay.35team.com/sdk/python/pay35.py
# 方式 2:从 PyPI(同步用法)
pip install pay35
# 方式 3:async 用法(额外装 httpx)
pip install pay35[async]
Usage(同步)
import os
from pay35 import Pay
pay = Pay(api_key=os.environ["PAY_KEY"])
# 创建支付(dev: sk_test_xxx → 自动 mock;prod: sk_live_xxx → 真支付)
session = pay.create_checkout(
amount=9900, # 单位:分
currency="CNY",
description="追思视频套餐",
metadata={"order_id": str(order.id)},
success_url="https://yoursite.com/orders/123",
)
# 跳到 35pay 托管收银台
return redirect(session["url"])
Usage(异步,FastAPI / Starlette / Litestar / aiohttp)
import os
from contextlib import asynccontextmanager
from fastapi import FastAPI
from pay35 import AsyncPay
@asynccontextmanager
async def lifespan(app: FastAPI):
app.state.pay = AsyncPay(api_key=os.environ["PAY_KEY"])
try:
yield
finally:
await app.state.pay.aclose()
app = FastAPI(lifespan=lifespan)
@app.post("/checkout")
async def checkout():
session = await app.state.pay.create_checkout(
amount=9900, currency="CNY",
metadata={"order_id": "..."},
success_url="https://yoursite.com/done",
)
return {"url": session["url"]}
async 内部使用单例
httpx.AsyncClient,复用 TCP 连接池。建议进程级单例(如 FastAPI 的lifespan),不要每个请求new一次。
Webhook 验签
from pay35 import Pay
@app.route("/webhook", methods=["POST"])
def webhook():
sig = request.headers.get("X-35pay-Signature", "")
if not Pay.verify_webhook_signature(
request.data.decode(), sig, WEBHOOK_SECRET
):
return "invalid", 401
event = request.get_json()
if event["type"] == "payment.paid":
order_id = event["data"]["metadata"]["order_id"]
mark_order_paid(order_id)
return "ok"
API
同步 Pay 和异步 AsyncPay 方法签名一致,async 方法加 await。
| 方法 | 说明 |
|---|---|
Pay(api_key, base_url=..., timeout=15.0) |
同步客户端 |
AsyncPay(api_key, base_url=..., timeout=15.0) |
异步客户端,需 pip install pay35[async] |
(a)pay.create_checkout(amount, currency, ...) |
创建支付 session,返回 {"url": ..., "id": ...} |
(a)pay.get_session(session_id) |
查询状态 |
(a)pay.refund(record_id, amount=None, reason=None) |
退款 |
await async_pay.aclose() |
释放底层 httpx 连接池(推荐用 async with) |
Pay.verify_webhook_signature(payload, header, secret) |
static 方法,验签(同步/异步通用) |
兼容性
- Python 3.9+
- 默认零依赖(同步
Pay用urllib) - 异步可选:
pip install pay35[async]拉入httpx>=0.24 - 异常:HTTP 非 2xx 抛
PayError(status, body)
Metadata
Release files for 35m-sdk 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| 35m_sdk-0.2.0.tar.gz | 6.3 kB | Without provenance | Details for 35m_sdk-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| 35m_sdk-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for 35m_sdk-0.2.0-py3-none-any.whl |
Total release size: 13.6 kB
Release files / 35m_sdk-0.2.0.tar.gz
| Download URL | 35m_sdk-0.2.0.tar.gz |
|---|---|
| Size | 6.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cc174b3e0dfa2b3067c679acfc31ac3a7945f67448ddfb5d1a9750e4c7a5df4a
|
|
BLAKE2b-256 checksum How to use checksums |
91e05b0f1e884c5855c4b38512a7bc0fc4e4679e7ed443118339ec8a30619576
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / 35m_sdk-0.2.0-py3-none-any.whl
| Download URL | 35m_sdk-0.2.0-py3-none-any.whl |
|---|---|
| Size | 7.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
22169653363d5ac91801ff5bfda10d817ddeb768a8984189b7fbea8bb418f7e1
|
|
BLAKE2b-256 checksum How to use checksums |
5c1a21e99d53296bcecd5a587072d3a003b2f1e0909d91e7f311cb5287e6800d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Security for 35m-sdk 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.