bepusdt 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bepusdt/__init__.py +8 -0
- bepusdt/client.py +278 -0
- bepusdt/exceptions.py +26 -0
- bepusdt/models.py +91 -0
- bepusdt/signature.py +53 -0
- bepusdt-0.2.0.dist-info/METADATA +179 -0
- bepusdt-0.2.0.dist-info/RECORD +10 -0
- bepusdt-0.2.0.dist-info/WHEEL +5 -0
- bepusdt-0.2.0.dist-info/licenses/LICENSE +21 -0
- bepusdt-0.2.0.dist-info/top_level.txt +1 -0
bepusdt/__init__.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""BEpusdt Python SDK - USDT/TRX/USDC 支付网关客户端"""
|
|
2
|
+
|
|
3
|
+
from .client import BEpusdtClient
|
|
4
|
+
from .exceptions import BEpusdtError, SignatureError, APIError
|
|
5
|
+
from .models import Order, OrderStatus, TradeType
|
|
6
|
+
|
|
7
|
+
__version__ = "0.2.0"
|
|
8
|
+
__all__ = ["BEpusdtClient", "BEpusdtError", "SignatureError", "APIError", "Order", "OrderStatus", "TradeType"]
|
bepusdt/client.py
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"""BEpusdt 客户端"""
|
|
2
|
+
|
|
3
|
+
import requests
|
|
4
|
+
from typing import Optional, Dict, Any, List
|
|
5
|
+
from .signature import generate_signature, verify_signature
|
|
6
|
+
from .models import Order, TradeType
|
|
7
|
+
from .exceptions import APIError
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class BEpusdtClient:
|
|
11
|
+
"""BEpusdt 支付网关客户端
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
api_url: BEpusdt API 地址
|
|
15
|
+
api_token: API Token
|
|
16
|
+
timeout: 请求超时时间(秒),默认 30
|
|
17
|
+
|
|
18
|
+
Example:
|
|
19
|
+
>>> client = BEpusdtClient(
|
|
20
|
+
... api_url="https://pay.kuaijieyi.com",
|
|
21
|
+
... api_token="your-api-token"
|
|
22
|
+
... )
|
|
23
|
+
>>> order = client.create_order(
|
|
24
|
+
... order_id="ORDER_001",
|
|
25
|
+
... amount=10.0,
|
|
26
|
+
... notify_url="https://your-domain.com/notify"
|
|
27
|
+
... )
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(self, api_url: str, api_token: str, timeout: int = 30):
|
|
31
|
+
self.api_url = api_url.rstrip("/")
|
|
32
|
+
self.api_token = api_token
|
|
33
|
+
self.timeout = timeout
|
|
34
|
+
self.session = requests.Session()
|
|
35
|
+
|
|
36
|
+
def create_order(
|
|
37
|
+
self,
|
|
38
|
+
order_id: str,
|
|
39
|
+
amount: float,
|
|
40
|
+
notify_url: str,
|
|
41
|
+
redirect_url: Optional[str] = None,
|
|
42
|
+
address: Optional[str] = None,
|
|
43
|
+
trade_type: str = TradeType.USDT_TRC20,
|
|
44
|
+
timeout: Optional[int] = None,
|
|
45
|
+
rate: Optional[float] = None
|
|
46
|
+
) -> Order:
|
|
47
|
+
"""创建支付订单
|
|
48
|
+
|
|
49
|
+
使用相同订单号创建订单时,不会产生两个交易;会根据实际参数重建订单。
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
order_id: 商户订单号,必须唯一
|
|
53
|
+
amount: 支付金额(CNY)
|
|
54
|
+
notify_url: 支付回调地址(必须 HTTPS)
|
|
55
|
+
redirect_url: 支付成功跳转地址(可选)
|
|
56
|
+
address: 指定收款地址(可选)
|
|
57
|
+
trade_type: 支付类型,默认 "usdt.trc20"
|
|
58
|
+
支持的类型:
|
|
59
|
+
- USDT: usdt.trc20, usdt.erc20, usdt.polygon, usdt.bep20,
|
|
60
|
+
usdt.aptos, usdt.solana, usdt.xlayer, usdt.arbitrum, usdt.plasma
|
|
61
|
+
- USDC: usdc.trc20, usdc.erc20, usdc.polygon, usdc.bep20,
|
|
62
|
+
usdc.aptos, usdc.solana, usdc.xlayer, usdc.arbitrum, usdc.base
|
|
63
|
+
- 其他: tron.trx
|
|
64
|
+
timeout: 订单超时时间(秒,最低60,可选)
|
|
65
|
+
rate: 自定义汇率(可选)
|
|
66
|
+
- 固定汇率:7.4 表示固定 7.4
|
|
67
|
+
- 浮动汇率:~1.02 表示最新汇率上浮 2%,~0.97 表示下浮 3%
|
|
68
|
+
- 增减汇率:+0.3 表示最新加 0.3,-0.2 表示最新减 0.2
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
Order: 订单对象
|
|
72
|
+
|
|
73
|
+
Raises:
|
|
74
|
+
APIError: API 请求失败
|
|
75
|
+
|
|
76
|
+
Example:
|
|
77
|
+
>>> # USDT TRC20 支付
|
|
78
|
+
>>> order = client.create_order(
|
|
79
|
+
... order_id="ORDER_001",
|
|
80
|
+
... amount=10.0,
|
|
81
|
+
... notify_url="https://your-domain.com/notify",
|
|
82
|
+
... trade_type=TradeType.USDT_TRC20
|
|
83
|
+
... )
|
|
84
|
+
|
|
85
|
+
>>> # TRX 支付
|
|
86
|
+
>>> order = client.create_order(
|
|
87
|
+
... order_id="ORDER_002",
|
|
88
|
+
... amount=1.0,
|
|
89
|
+
... notify_url="https://your-domain.com/notify",
|
|
90
|
+
... trade_type=TradeType.TRON_TRX
|
|
91
|
+
... )
|
|
92
|
+
|
|
93
|
+
>>> # 自定义汇率(上浮2%)
|
|
94
|
+
>>> order = client.create_order(
|
|
95
|
+
... order_id="ORDER_003",
|
|
96
|
+
... amount=10.0,
|
|
97
|
+
... notify_url="https://your-domain.com/notify",
|
|
98
|
+
... rate="~1.02"
|
|
99
|
+
... )
|
|
100
|
+
"""
|
|
101
|
+
params = {
|
|
102
|
+
"order_id": order_id,
|
|
103
|
+
"amount": int(amount) if amount == int(amount) else amount,
|
|
104
|
+
"notify_url": notify_url,
|
|
105
|
+
"trade_type": trade_type
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# redirect_url 是必需的,但不能为空字符串(BEpusdt会跳过空值导致签名不匹配)
|
|
109
|
+
if redirect_url:
|
|
110
|
+
params["redirect_url"] = redirect_url
|
|
111
|
+
else:
|
|
112
|
+
# 使用 notify_url 作为默认值
|
|
113
|
+
params["redirect_url"] = notify_url
|
|
114
|
+
if address:
|
|
115
|
+
params["address"] = address
|
|
116
|
+
if timeout:
|
|
117
|
+
params["timeout"] = timeout
|
|
118
|
+
if rate:
|
|
119
|
+
params["rate"] = rate
|
|
120
|
+
|
|
121
|
+
params["signature"] = generate_signature(params, self.api_token)
|
|
122
|
+
|
|
123
|
+
# 调试日志
|
|
124
|
+
import logging
|
|
125
|
+
logger = logging.getLogger(__name__)
|
|
126
|
+
logger.info(f"创建订单请求参数: {params}")
|
|
127
|
+
|
|
128
|
+
url = f"{self.api_url}/api/v1/order/create-transaction"
|
|
129
|
+
response = self._post(url, params)
|
|
130
|
+
|
|
131
|
+
if response["status_code"] != 200:
|
|
132
|
+
raise APIError(
|
|
133
|
+
response.get("message", "创建订单失败"),
|
|
134
|
+
status_code=response["status_code"],
|
|
135
|
+
response=response
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
return Order.from_dict(response["data"])
|
|
139
|
+
|
|
140
|
+
def cancel_order(self, trade_id: str) -> Dict[str, Any]:
|
|
141
|
+
"""取消订单
|
|
142
|
+
|
|
143
|
+
取消后,系统将不再监控此订单,同时释放对应金额占用。
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
trade_id: BEpusdt 交易ID
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
dict: 取消结果
|
|
150
|
+
|
|
151
|
+
Raises:
|
|
152
|
+
APIError: API 请求失败
|
|
153
|
+
|
|
154
|
+
Example:
|
|
155
|
+
>>> result = client.cancel_order(trade_id="xxx")
|
|
156
|
+
"""
|
|
157
|
+
params = {"trade_id": trade_id}
|
|
158
|
+
params["signature"] = generate_signature(params, self.api_token)
|
|
159
|
+
|
|
160
|
+
url = f"{self.api_url}/api/v1/order/cancel-transaction"
|
|
161
|
+
response = self._post(url, params)
|
|
162
|
+
|
|
163
|
+
if response["status_code"] != 200:
|
|
164
|
+
raise APIError(
|
|
165
|
+
response.get("message", "取消订单失败"),
|
|
166
|
+
status_code=response["status_code"],
|
|
167
|
+
response=response
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
return response["data"]
|
|
171
|
+
|
|
172
|
+
def query_order(self, trade_id: str) -> Order:
|
|
173
|
+
"""查询订单状态
|
|
174
|
+
|
|
175
|
+
查询指定订单的当前状态和详细信息。
|
|
176
|
+
注意:此接口不需要签名验证。
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
trade_id: BEpusdt 交易ID
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
Order: 订单对象,包含当前状态
|
|
183
|
+
|
|
184
|
+
Raises:
|
|
185
|
+
APIError: API 请求失败或订单不存在
|
|
186
|
+
|
|
187
|
+
Example:
|
|
188
|
+
>>> order = client.query_order(trade_id="xxx")
|
|
189
|
+
>>> if order.status == OrderStatus.SUCCESS:
|
|
190
|
+
... print("订单已支付")
|
|
191
|
+
"""
|
|
192
|
+
url = f"{self.api_url}/pay/check-status/{trade_id}"
|
|
193
|
+
response = self._get(url)
|
|
194
|
+
|
|
195
|
+
# check-status 接口返回格式不同,需要特殊处理
|
|
196
|
+
if "trade_id" not in response:
|
|
197
|
+
raise APIError("订单不存在或查询失败", response=response)
|
|
198
|
+
|
|
199
|
+
# 构造 Order 对象需要的数据
|
|
200
|
+
# 注意:查询接口返回的字段较少,某些字段会是默认值
|
|
201
|
+
order_data = {
|
|
202
|
+
"trade_id": response["trade_id"],
|
|
203
|
+
"order_id": "", # 查询接口不返回此字段
|
|
204
|
+
"amount": 0, # 查询接口不返回此字段
|
|
205
|
+
"actual_amount": 0, # 查询接口不返回此字段
|
|
206
|
+
"token": "", # 查询接口不返回此字段
|
|
207
|
+
"expiration_time": 0, # 查询接口不返回此字段
|
|
208
|
+
"payment_url": "", # 查询接口不返回此字段
|
|
209
|
+
"status": response["status"],
|
|
210
|
+
"block_transaction_id": response.get("trade_hash", "")
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return Order.from_dict(order_data)
|
|
214
|
+
|
|
215
|
+
def verify_callback(self, callback_data: Dict[str, Any]) -> bool:
|
|
216
|
+
"""验证支付回调签名
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
callback_data: 回调数据字典
|
|
220
|
+
|
|
221
|
+
Returns:
|
|
222
|
+
bool: 签名是否有效
|
|
223
|
+
|
|
224
|
+
Example:
|
|
225
|
+
>>> callback_data = request.get_json()
|
|
226
|
+
>>> if client.verify_callback(callback_data):
|
|
227
|
+
... # 处理支付成功
|
|
228
|
+
... pass
|
|
229
|
+
"""
|
|
230
|
+
received_signature = callback_data.get("signature")
|
|
231
|
+
if not received_signature:
|
|
232
|
+
return False
|
|
233
|
+
|
|
234
|
+
params = {k: v for k, v in callback_data.items() if k != "signature"}
|
|
235
|
+
return verify_signature(params, self.api_token, received_signature)
|
|
236
|
+
|
|
237
|
+
def _post(self, url: str, data: Dict[str, Any]) -> Dict[str, Any]:
|
|
238
|
+
"""发送 POST 请求
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
url: 请求 URL
|
|
242
|
+
data: 请求数据
|
|
243
|
+
|
|
244
|
+
Returns:
|
|
245
|
+
dict: 响应数据
|
|
246
|
+
|
|
247
|
+
Raises:
|
|
248
|
+
APIError: 请求失败或响应解析失败
|
|
249
|
+
"""
|
|
250
|
+
try:
|
|
251
|
+
resp = self.session.post(url, json=data, timeout=self.timeout)
|
|
252
|
+
resp.raise_for_status()
|
|
253
|
+
return resp.json()
|
|
254
|
+
except requests.exceptions.RequestException as e:
|
|
255
|
+
raise APIError(f"请求失败: {str(e)}")
|
|
256
|
+
except ValueError as e:
|
|
257
|
+
raise APIError(f"响应解析失败: {str(e)}")
|
|
258
|
+
|
|
259
|
+
def _get(self, url: str) -> Dict[str, Any]:
|
|
260
|
+
"""发送 GET 请求
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
url: 请求 URL
|
|
264
|
+
|
|
265
|
+
Returns:
|
|
266
|
+
dict: 响应数据
|
|
267
|
+
|
|
268
|
+
Raises:
|
|
269
|
+
APIError: 请求失败或响应解析失败
|
|
270
|
+
"""
|
|
271
|
+
try:
|
|
272
|
+
resp = self.session.get(url, timeout=self.timeout)
|
|
273
|
+
resp.raise_for_status()
|
|
274
|
+
return resp.json()
|
|
275
|
+
except requests.exceptions.RequestException as e:
|
|
276
|
+
raise APIError(f"请求失败: {str(e)}")
|
|
277
|
+
except ValueError as e:
|
|
278
|
+
raise APIError(f"响应解析失败: {str(e)}")
|
bepusdt/exceptions.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""异常定义"""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class BEpusdtError(Exception):
|
|
5
|
+
"""BEpusdt SDK 基础异常"""
|
|
6
|
+
pass
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SignatureError(BEpusdtError):
|
|
10
|
+
"""签名错误"""
|
|
11
|
+
pass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class APIError(BEpusdtError):
|
|
15
|
+
"""API 请求错误
|
|
16
|
+
|
|
17
|
+
Attributes:
|
|
18
|
+
message: 错误消息
|
|
19
|
+
status_code: HTTP 状态码(可选)
|
|
20
|
+
response: 完整响应数据(可选)
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, message: str, status_code: int = None, response: dict = None):
|
|
24
|
+
super().__init__(message)
|
|
25
|
+
self.status_code = status_code
|
|
26
|
+
self.response = response
|
bepusdt/models.py
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""数据模型"""
|
|
2
|
+
|
|
3
|
+
from enum import IntEnum
|
|
4
|
+
from typing import Optional
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class OrderStatus(IntEnum):
|
|
9
|
+
"""订单状态枚举"""
|
|
10
|
+
WAITING = 1 # 等待支付
|
|
11
|
+
SUCCESS = 2 # 支付成功
|
|
12
|
+
TIMEOUT = 3 # 支付超时
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TradeType:
|
|
16
|
+
"""支付类型常量
|
|
17
|
+
|
|
18
|
+
支持的区块链网络和代币类型
|
|
19
|
+
"""
|
|
20
|
+
# USDT
|
|
21
|
+
USDT_TRC20 = "usdt.trc20" # Tron 网络
|
|
22
|
+
USDT_ERC20 = "usdt.erc20" # Ethereum 网络
|
|
23
|
+
USDT_POLYGON = "usdt.polygon" # Polygon 网络
|
|
24
|
+
USDT_BEP20 = "usdt.bep20" # BSC 网络
|
|
25
|
+
USDT_APTOS = "usdt.aptos" # Aptos 网络
|
|
26
|
+
USDT_SOLANA = "usdt.solana" # Solana 网络
|
|
27
|
+
USDT_XLAYER = "usdt.xlayer" # X-Layer 网络
|
|
28
|
+
USDT_ARBITRUM = "usdt.arbitrum" # Arbitrum-One 网络
|
|
29
|
+
USDT_PLASMA = "usdt.plasma" # Plasma 网络
|
|
30
|
+
|
|
31
|
+
# USDC
|
|
32
|
+
USDC_TRC20 = "usdc.trc20" # Tron 网络
|
|
33
|
+
USDC_ERC20 = "usdc.erc20" # Ethereum 网络
|
|
34
|
+
USDC_POLYGON = "usdc.polygon" # Polygon 网络
|
|
35
|
+
USDC_BEP20 = "usdc.bep20" # BSC 网络
|
|
36
|
+
USDC_APTOS = "usdc.aptos" # Aptos 网络
|
|
37
|
+
USDC_SOLANA = "usdc.solana" # Solana 网络
|
|
38
|
+
USDC_XLAYER = "usdc.xlayer" # X-Layer 网络
|
|
39
|
+
USDC_ARBITRUM = "usdc.arbitrum" # Arbitrum-One 网络
|
|
40
|
+
USDC_BASE = "usdc.base" # Base 网络
|
|
41
|
+
|
|
42
|
+
# 其他
|
|
43
|
+
TRON_TRX = "tron.trx" # TRX
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class Order:
|
|
48
|
+
"""订单信息
|
|
49
|
+
|
|
50
|
+
Attributes:
|
|
51
|
+
trade_id: BEpusdt 交易ID
|
|
52
|
+
order_id: 商户订单号
|
|
53
|
+
amount: 请求金额(CNY)
|
|
54
|
+
actual_amount: 实际支付金额(USDT/TRX/USDC)
|
|
55
|
+
token: 收款地址
|
|
56
|
+
expiration_time: 过期时间(秒)
|
|
57
|
+
payment_url: 支付链接
|
|
58
|
+
status: 订单状态(可选)
|
|
59
|
+
block_transaction_id: 区块链交易ID(可选)
|
|
60
|
+
"""
|
|
61
|
+
trade_id: str
|
|
62
|
+
order_id: str
|
|
63
|
+
amount: float
|
|
64
|
+
actual_amount: float
|
|
65
|
+
token: str
|
|
66
|
+
expiration_time: int
|
|
67
|
+
payment_url: str
|
|
68
|
+
status: Optional[OrderStatus] = None
|
|
69
|
+
block_transaction_id: Optional[str] = None
|
|
70
|
+
|
|
71
|
+
@classmethod
|
|
72
|
+
def from_dict(cls, data: dict) -> "Order":
|
|
73
|
+
"""从字典创建订单对象
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
data: 订单数据字典
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
Order: 订单对象
|
|
80
|
+
"""
|
|
81
|
+
return cls(
|
|
82
|
+
trade_id=data["trade_id"],
|
|
83
|
+
order_id=data["order_id"],
|
|
84
|
+
amount=float(data["amount"]),
|
|
85
|
+
actual_amount=float(data["actual_amount"]),
|
|
86
|
+
token=data["token"],
|
|
87
|
+
expiration_time=int(data["expiration_time"]),
|
|
88
|
+
payment_url=data["payment_url"],
|
|
89
|
+
status=OrderStatus(data["status"]) if "status" in data else None,
|
|
90
|
+
block_transaction_id=data.get("block_transaction_id")
|
|
91
|
+
)
|
bepusdt/signature.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""签名算法"""
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
from typing import Dict, Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def generate_signature(params: Dict[str, Any], api_token: str) -> str:
|
|
8
|
+
"""生成签名
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
params: 参数字典
|
|
12
|
+
api_token: API Token
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
str: MD5 签名(小写)
|
|
16
|
+
|
|
17
|
+
Example:
|
|
18
|
+
>>> params = {"order_id": "001", "amount": 10}
|
|
19
|
+
>>> signature = generate_signature(params, "your-token")
|
|
20
|
+
"""
|
|
21
|
+
# 过滤空值
|
|
22
|
+
filtered = {k: v for k, v in params.items() if v not in (None, "", [])}
|
|
23
|
+
|
|
24
|
+
# 按键排序
|
|
25
|
+
sorted_params = sorted(filtered.items())
|
|
26
|
+
|
|
27
|
+
# 拼接参数
|
|
28
|
+
param_str = "&".join([f"{k}={v}" for k, v in sorted_params])
|
|
29
|
+
|
|
30
|
+
# 添加 token 并计算 MD5
|
|
31
|
+
sign_str = param_str + api_token
|
|
32
|
+
signature = hashlib.md5(sign_str.encode("utf-8")).hexdigest().lower()
|
|
33
|
+
|
|
34
|
+
return signature
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def verify_signature(params: Dict[str, Any], api_token: str, received_signature: str) -> bool:
|
|
38
|
+
"""验证签名
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
params: 参数字典(不包含 signature)
|
|
42
|
+
api_token: API Token
|
|
43
|
+
received_signature: 接收到的签名
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
bool: 签名是否有效
|
|
47
|
+
|
|
48
|
+
Example:
|
|
49
|
+
>>> params = {"order_id": "001", "amount": 10}
|
|
50
|
+
>>> is_valid = verify_signature(params, "your-token", "xxx")
|
|
51
|
+
"""
|
|
52
|
+
expected_signature = generate_signature(params, api_token)
|
|
53
|
+
return expected_signature == received_signature
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bepusdt
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: BEpusdt 支付网关 Python SDK - 支持 USDT/TRX/USDC 多链支付
|
|
5
|
+
Home-page: https://github.com/luoyanglang/bepusdt-python-sdk
|
|
6
|
+
Author: luoyanglang
|
|
7
|
+
Author-email: luoyanglang <luoyanglang@users.noreply.github.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
Project-URL: Homepage, https://github.com/luoyanglang/bepusdt-python-sdk
|
|
10
|
+
Project-URL: Documentation, https://github.com/luoyanglang/bepusdt-python-sdk#readme
|
|
11
|
+
Project-URL: Repository, https://github.com/luoyanglang/bepusdt-python-sdk
|
|
12
|
+
Project-URL: Issues, https://github.com/luoyanglang/bepusdt-python-sdk/issues
|
|
13
|
+
Keywords: bepusdt,payment,usdt,trx,cryptocurrency,blockchain
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
25
|
+
Requires-Python: >=3.7
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: requests>=2.25.0
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-cov>=3.0.0; extra == "dev"
|
|
32
|
+
Requires-Dist: black>=22.0.0; extra == "dev"
|
|
33
|
+
Requires-Dist: flake8>=4.0.0; extra == "dev"
|
|
34
|
+
Requires-Dist: mypy>=0.950; extra == "dev"
|
|
35
|
+
Dynamic: author
|
|
36
|
+
Dynamic: home-page
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
Dynamic: requires-python
|
|
39
|
+
|
|
40
|
+
**❗️声明:本 SDK 为 BEpusdt 支付网关的非官方 Python 客户端库,仅供学习研究使用。使用本项目请遵守当地法律法规,任何违法违规使用产生的后果由使用者自行承担。**
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
# BEpusdt Python SDK
|
|
45
|
+
|
|
46
|
+
<p align="center">
|
|
47
|
+
<a href="https://pypi.org/project/bepusdt/"><img src="https://badge.fury.io/py/bepusdt.svg" alt="PyPI version"></a>
|
|
48
|
+
<a href="https://pypi.org/project/bepusdt/"><img src="https://img.shields.io/pypi/pyversions/bepusdt.svg" alt="Python Support"></a>
|
|
49
|
+
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
|
|
50
|
+
<a href="https://github.com/v03413/bepusdt"><img src="https://img.shields.io/badge/BEpusdt-v1.22+-blue" alt="BEpusdt"></a>
|
|
51
|
+
</p>
|
|
52
|
+
|
|
53
|
+
## 🪧 介绍
|
|
54
|
+
|
|
55
|
+
BEpusdt 支付网关的 Python SDK,让 Python 开发者能够快速集成 USDT/TRX/USDC 加密货币支付功能。
|
|
56
|
+
|
|
57
|
+
## ✨ 特性
|
|
58
|
+
|
|
59
|
+
- 🎯 **简单易用** - 几行代码即可集成
|
|
60
|
+
- 🔐 **自动签名** - 内置签名生成和验证
|
|
61
|
+
- 🌐 **多链支持** - 支持 10+ 区块链网络
|
|
62
|
+
- 💰 **多币种** - USDT、USDC、TRX
|
|
63
|
+
- 📝 **类型提示** - 完整的 IDE 智能提示
|
|
64
|
+
- ✅ **生产就绪** - 经过真实环境测试
|
|
65
|
+
- 🔄 **完全兼容** - 完整支持 BEpusdt API
|
|
66
|
+
|
|
67
|
+
## 🌟 支持的网络
|
|
68
|
+
|
|
69
|
+
### USDT
|
|
70
|
+
🔥 主流网络:Tron (TRC20) · Ethereum (ERC20) · BSC (BEP20) · Polygon
|
|
71
|
+
⚡ 其他网络:Arbitrum · Solana · Aptos · X-Layer · Plasma
|
|
72
|
+
|
|
73
|
+
### USDC
|
|
74
|
+
🔥 主流网络:Tron (TRC20) · Ethereum (ERC20) · BSC (BEP20) · Polygon
|
|
75
|
+
⚡ 其他网络:Arbitrum · Solana · Aptos · X-Layer · Base
|
|
76
|
+
|
|
77
|
+
### 其他
|
|
78
|
+
💎 TRX (Tron)
|
|
79
|
+
|
|
80
|
+
## 📦 安装
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
pip install bepusdt
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 🚀 快速开始
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
from bepusdt import BEpusdtClient, TradeType
|
|
90
|
+
|
|
91
|
+
# 初始化客户端
|
|
92
|
+
client = BEpusdtClient(
|
|
93
|
+
api_url="https://your-bepusdt-server.com",
|
|
94
|
+
api_token="your-api-token"
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# 创建订单
|
|
98
|
+
order = client.create_order(
|
|
99
|
+
order_id="ORDER_001",
|
|
100
|
+
amount=10.0,
|
|
101
|
+
notify_url="https://your-domain.com/notify",
|
|
102
|
+
trade_type=TradeType.USDT_TRC20
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
print(f"💰 支付金额: {order.actual_amount} USDT")
|
|
106
|
+
print(f"📍 收款地址: {order.token}")
|
|
107
|
+
print(f"🔗 支付链接: {order.payment_url}")
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## 📖 文档
|
|
111
|
+
|
|
112
|
+
- 📚 [完整文档](./docs/README.md)
|
|
113
|
+
- 📖 [API 参考](./docs/api.md)
|
|
114
|
+
- 💡 [使用示例](./docs/examples.md)
|
|
115
|
+
- ❓ [常见问题](./docs/faq.md)
|
|
116
|
+
|
|
117
|
+
## 🔧 核心功能
|
|
118
|
+
|
|
119
|
+
### 创建订单
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
order = client.create_order(
|
|
123
|
+
order_id="ORDER_001",
|
|
124
|
+
amount=10.0,
|
|
125
|
+
notify_url="https://your-domain.com/notify",
|
|
126
|
+
redirect_url="https://your-domain.com/success",
|
|
127
|
+
trade_type=TradeType.USDT_TRC20
|
|
128
|
+
)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 查询订单
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
order = client.query_order(trade_id="xxx")
|
|
135
|
+
if order.status == OrderStatus.SUCCESS:
|
|
136
|
+
print("✅ 支付成功")
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 验证回调
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
@app.route('/notify', methods=['POST'])
|
|
143
|
+
def notify():
|
|
144
|
+
data = request.get_json()
|
|
145
|
+
if client.verify_callback(data):
|
|
146
|
+
# 处理支付成功
|
|
147
|
+
return "ok", 200
|
|
148
|
+
return "fail", 400
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## 🏝️ 交流反馈
|
|
152
|
+
|
|
153
|
+
- 💬 Telegram: [@luoyanglang](https://t.me/luoyanglang)
|
|
154
|
+
- 📝 [提交 Issue](https://github.com/luoyanglang/bepusdt-python-sdk/issues)
|
|
155
|
+
- 🔗 [BEpusdt 官方群组](https://t.me/BEpusdtChat)
|
|
156
|
+
|
|
157
|
+
## 🙏 感谢
|
|
158
|
+
|
|
159
|
+
- [BEpusdt](https://github.com/v03413/bepusdt) - 优秀的 USDT 支付网关
|
|
160
|
+
- [Epusdt](https://github.com/assimon/epusdt) - BEpusdt 的前身
|
|
161
|
+
|
|
162
|
+
## 🔗 相关链接
|
|
163
|
+
|
|
164
|
+
- 🏠 [BEpusdt 官方](https://github.com/v03413/bepusdt)
|
|
165
|
+
- 📦 [PyPI 页面](https://pypi.org/project/bepusdt/)
|
|
166
|
+
- 💻 [GitHub 仓库](https://github.com/luoyanglang/bepusdt-python-sdk)
|
|
167
|
+
- 📋 [更新日志](./CHANGELOG.md)
|
|
168
|
+
|
|
169
|
+
## 📄 许可证
|
|
170
|
+
|
|
171
|
+
[MIT License](LICENSE)
|
|
172
|
+
|
|
173
|
+
## 📢 声明
|
|
174
|
+
|
|
175
|
+
本项目仅供学习研究使用,使用过程中请遵守当地法律法规,任何违法违规使用产生的后果由使用者自行承担。
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
Made with ❤️ for BEpusdt community
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
bepusdt/__init__.py,sha256=vEN_e60bu9gLDYwkR-q1Q7sCIQ-OaWkJ-QM_I9mgffQ,353
|
|
2
|
+
bepusdt/client.py,sha256=1VrTCDO4NLtQkLP9iy0AADCTFqJKd5k-pDE0Qeo-RRE,9962
|
|
3
|
+
bepusdt/exceptions.py,sha256=j9kH893Jnkw7-Y9ioTmqmLtD0facS6-FikJYXTzIOZc,601
|
|
4
|
+
bepusdt/models.py,sha256=rykr736hTz64lb_3AyTu_MwvrLCbgaUjmbs25WMydaM,2874
|
|
5
|
+
bepusdt/signature.py,sha256=XvNNx4tdWfkmPq7Ld86K9ODsg2grvxf2dLWuccN4Xh0,1489
|
|
6
|
+
bepusdt-0.2.0.dist-info/licenses/LICENSE,sha256=WFdbxSMjGJcnWo7H69jxUhwXI_nYsGrOP0FH5LZKcb8,1109
|
|
7
|
+
bepusdt-0.2.0.dist-info/METADATA,sha256=syl-YK5yA14tpIGbvyTH1S2hDpUAkNTGQ9Qm-Q9i0PM,5780
|
|
8
|
+
bepusdt-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
9
|
+
bepusdt-0.2.0.dist-info/top_level.txt,sha256=ueck4MF4gGLNL7z02NMcFayIfaDNGFzCwg0HjBQOaso,8
|
|
10
|
+
bepusdt-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 BEpusdt Python SDK Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
bepusdt
|