统一支付基础设施 SDK,支持微信支付和支付宝
Project description
pay-kit
统一支付基础设施 SDK,支持微信支付和支付宝商户。一个 SDK 即可处理支付、转账、余额查询。
特性
- 双平台支持 — 微信支付 V3 + 支付宝 V3
- 多种支付方式 — 扫码、JSAPI、H5、App、电脑网站
- 统一接口 — PayProvider / WithdrawProvider / WalletProvider 三个 ABC
- 类型安全 — 全面类型注解,mypy strict 通过
- 纯异步 — 基于 httpx,async/await 原生支持
- 安全 — RSA-SHA256 签名/验签、AES-GCM 回调解密、SecretStr 敏感字段保护
安装
pip install pay-kit
快速开始
微信支付 — Native 扫码支付
from pay_kit.providers.wechat import WechatPay, WechatPayConfig
from pay_kit.models import PaymentRequest
from pay_kit.types import Fen
config = WechatPayConfig(
appid="wx_your_appid",
mch_id="your_mch_id",
private_key=open("apiclient_key.pem").read(), # 商户 API 私钥
cert_serial_no="YOUR_CERT_SERIAL_NO", # 商户证书序列号
wechat_public_key=open("wechat_public_key.pem").read(), # 微信支付公钥
wechat_public_key_id="YOUR_PUB_KEY_ID",
apiv3_key="your_apiv3_key",
notify_url="https://your-domain.com/callback/wechat",
)
async with WechatPay(config) as pay:
# 创建支付订单
result = await pay.create_payment(
PaymentRequest(out_trade_no="ORDER_001", total_amount=Fen(100), subject="商品名称")
)
print(result.credential["code_url"]) # 用此 URL 生成二维码
支付宝 — 当面付扫码支付
from pay_kit.providers.alipay import Alipay, AlipayConfig
from pay_kit.models import PaymentRequest
from pay_kit.types import Fen
config = AlipayConfig(
app_id="your_app_id",
private_key=open("app_private_key.pem").read(), # 应用私钥
alipay_public_key=open("alipay_public_key.pem").read(), # 支付宝公钥
notify_url="https://your-domain.com/callback/alipay",
)
async with Alipay(config) as pay:
result = await pay.create_payment(
PaymentRequest(out_trade_no="ORDER_001", total_amount=Fen(100), subject="商品名称")
)
print(result.credential["qr_code"]) # 二维码 URL
支付方式
微信支付
async with WechatPay(config) as pay:
# Native 扫码支付(通用接口)
result = await pay.create_payment(request)
# credential: {"code_url": "weixin://wxpay/..."}
# JSAPI 公众号/小程序支付
result = await pay.create_jsapi_payment(request, openid="user_openid")
# credential: {"appId", "timeStamp", "nonceStr", "package", "signType", "paySign"}
# H5 手机浏览器支付
result = await pay.create_h5_payment(request, payer_client_ip="1.2.3.4")
# credential: {"h5_url": "https://wx.tenpay.com/..."}
# App 支付
result = await pay.create_app_payment(request)
# credential: {"appId", "partnerId", "prepayId", "package", "nonceStr", "timeStamp", "sign"}
支付宝
async with Alipay(config) as pay:
# 当面付扫码支付(通用接口)
result = await pay.create_payment(request)
# credential: {"qr_code": "https://qr.alipay.com/..."}
# 电脑网站支付
result = await pay.create_page_payment(request, return_url="https://your-site.com/return")
# credential: {"pay_url": "https://openapi.alipay.com/..."}
# 手机网站支付
result = await pay.create_wap_payment(request, return_url="https://your-site.com/return")
# credential: {"pay_url": "https://openapi.alipay.com/..."}
# App 支付
result = await pay.create_app_payment(request)
# credential: {"order_str": "alipay_sdk=..."}
通用操作
查询、关单、退款等操作两个平台用法一致:
# 查询订单
result = await pay.query_payment("ORDER_001")
print(result.status) # PaymentStatus.PAID
# 关闭订单
await pay.close_payment("ORDER_001")
# 发起退款
from pay_kit.models import RefundRequest
refund = await pay.refund(
RefundRequest(
out_trade_no="ORDER_001",
out_refund_no="REFUND_001",
total_amount=Fen(100),
refund_amount=Fen(50),
)
)
# 查询退款
refund = await pay.query_refund("REFUND_001")
转账
from pay_kit.models import WithdrawRequest
async with WechatPay(config) as pay:
# 商家转账到零钱
result = await pay.create_withdrawal(
WithdrawRequest(
out_withdrawal_no="TRANSFER_001",
amount=Fen(1000),
recipient="user_openid", # 微信: openid / 支付宝: user_id
description="佣金提现",
)
)
print(result.status) # WithdrawStatus.PENDING
# 查询转账状态
result = await pay.query_withdrawal("TRANSFER_001")
余额查询
async with WechatPay(config) as pay:
balance = await pay.query_balance()
print(f"可用余额: {balance.available} 分")
print(f"待结算: {balance.pending} 分")
回调验签
# FastAPI 示例
from fastapi import Request
@app.post("/callback/wechat")
async def wechat_callback(request: Request):
headers = dict(request.headers)
body = await request.body()
async with WechatPay(config) as pay:
event = await pay.verify_callback(headers, body)
print(event.event_type) # "TRANSACTION.SUCCESS"
print(event.out_trade_no) # "ORDER_001"
print(event.trade_no) # 微信交易号
print(event.raw) # 完整回调数据
return {"code": "SUCCESS"}
异常处理
from pay_kit.exceptions import (
PayKitError, # 所有异常基类
ConfigError, # 配置错误
NetworkError, # 网络超时/连接失败
SignatureError, # 签名验证失败
PaymentError, # 支付业务错误
WithdrawError, # 转账业务错误
WalletError, # 余额查询错误
)
try:
result = await pay.create_payment(request)
except NetworkError:
# 网络问题,可重试
pass
except SignatureError:
# 签名验证失败,响应不可信
pass
except PaymentError as e:
# 业务错误
print(e.error_code) # 支付商错误码,如 "ORDER_CLOSED"
print(e.provider_name) # "wechat" 或 "alipay"
金额类型
pay-kit 使用 Fen(分)作为金额单位,避免浮点精度问题:
from pay_kit.types import Fen, Yuan, fen_to_yuan, yuan_to_fen
amount = Fen(100) # 100 分 = 1 元
yuan = fen_to_yuan(Fen(100)) # Yuan("1.00")
fen = yuan_to_fen(Yuan("1.00")) # Fen(100)
完整示例
examples/ 目录包含可运行的完整代码:
| 文件 | 场景 |
|---|---|
wechat_all_methods.py |
微信全场景(4 种支付 + 查询/关单/退款/转账/余额) |
alipay_all_methods.py |
支付宝全场景(4 种支付 + 查询/关单/退款/转账/余额) |
fastapi_server.py |
FastAPI 生产级集成(多 Provider + 回调 + 异常处理) |
multi_provider.py |
多支付商统一接口(PayProvider ABC 多态) |
uv sync --group examples
cp examples/.env.example examples/.env
# 编辑 .env 填入商户配置
uv run python examples/wechat_all_methods.py
开发
git clone https://github.com/Xinzz995/pay-kit.git
cd pay-kit
uv sync
uv run pytest # 运行测试
uv run pytest --cov=pay_kit # 覆盖率
uv run ruff check . # Lint
uv run mypy src/ # 类型检查
许可证
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
pay_py_kit-0.3.2.tar.gz
(98.2 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pay_py_kit-0.3.2.tar.gz.
File metadata
- Download URL: pay_py_kit-0.3.2.tar.gz
- Upload date:
- Size: 98.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1aa37bf70eff055b5fd2920c9fe3cca1abc28c7c072fe08ff4be66cac69eec3e
|
|
| MD5 |
80e3872d4c0d1dda615f6edf9c4d23a7
|
|
| BLAKE2b-256 |
79c13c77683bff3a3c214ce80f63bd17992f703b4ce537a60674280d58c7e077
|
File details
Details for the file pay_py_kit-0.3.2-py3-none-any.whl.
File metadata
- Download URL: pay_py_kit-0.3.2-py3-none-any.whl
- Upload date:
- Size: 23.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68d35fa3fb9aa608b297a50805a47242ed09eff17891d17d546dbb063d3a6c89
|
|
| MD5 |
4012a1f3087d031340330618a3dcc1cc
|
|
| BLAKE2b-256 |
c737128bd35c90a21c70f7f47762a8b11994feb1f5eca5b968d621b106cba415
|