Python 示例
完整的 Python 集成示例,使用 requests + flask。
安装
pip install requests flask
配置
# .env
API_BASE=https://api.168tonpay.xyz/api/v1/compat/godapay
APPLY_BASE=https://apply.168tonpay.xyz/api/v1/compat/godapay
MERCHANT_ID=aef6025b-f435-443c-bb18-f10e65d9314c
API_SECRET=...
签名工具
# gateway/auth.py
import hashlib
def sign(params: dict, api_secret: str) -> str:
"""GodaPay 兼容 MD5 排序签名:排除 signature 与 None,按 key 升序拼接,
追加 &key=SECRET,MD5 小写十六进制。"""
items = sorted(
(k, v) for k, v in params.items()
if k != 'signature' and v is not None
)
def fmt(v):
return 'true' if v is True else 'false' if v is False else v
sign_str = '&'.join(f'{k}={fmt(v)}' for k, v in items) + f'&key={api_secret}'
return hashlib.md5(sign_str.encode()).hexdigest().lower()
API 客户端
# gateway/client.py
import os
import requests
from .auth import sign
class GatewayError(Exception):
def __init__(self, code, message):
super().__init__(message)
self.code = code
def post(base: str, path: str, params: dict):
body = dict(params)
body['signature'] = sign(body, os.environ['API_SECRET'])
response = requests.post(f"{base}{path}", json=body, timeout=30)
payload = response.json()
if payload.get('code') != 0:
raise GatewayError(payload.get('code'), payload.get('message', 'unknown'))
return payload['data']
API = os.environ['API_BASE']
APPLY = os.environ['APPLY_BASE']
def create_collect_order(data): return post(API, '/pay/order/create', data)
def query_order(data): return post(API, '/pay/order/query', data)
def get_balance(): return post(API, '/pay/balance', {'merchantId': os.environ['MERCHANT_ID']})
def create_payout_order(data): return post(APPLY, '/apply/create', data)
创建收款订单
from gateway.client import create_collect_order
def start_deposit(player, order_no):
order = create_collect_order({
'merchantId': os.environ['MERCHANT_ID'],
'orderNo': order_no,
'returnUrl': 'https://yourgame.com/api/webhooks/payment',
'playerPhone': player['phone'], # 玩家已登记号码,风控关键字段
'playerRef': player['id'],
})
return {'pay_url': order['payUrl'], 'platform_order_no': order['platformOrderNo']}
创建付款订单
def start_withdrawal(player, out_order_no, amount):
return create_payout_order({
'merchantId': os.environ['MERCHANT_ID'],
'outOrderNo': out_order_no,
'amount': f'{amount:.2f}',
'bankType': 'BKASH',
'userName': player['name'],
'account': player['phone'],
'returnUrl': 'https://yourgame.com/api/webhooks/payout',
})
Webhook 处理(Flask)
import os
from flask import Flask, request
from gateway.auth import sign
app = Flask(__name__)
@app.route('/api/webhooks/payment', methods=['POST'])
def payment_webhook():
# webhook 是 form-urlencoded
fields = request.form.to_dict()
signature = fields.pop('signature', '')
if sign(fields, os.environ['API_SECRET']) != signature:
return 'invalid signature', 401
if request.form.get('status') == '1':
# 幂等:用 platformOrderNo 去重;用 amount 上分
credit_player(request.form['orderNo'], request.form['amount'])
return 'SUCCESS', 200 # 必须应答字面量 SUCCESS
错误处理
from gateway.client import GatewayError, create_collect_order
try:
order = create_collect_order(data)
except GatewayError as e:
# code 非 0 即业务错误
raise Exception(f"[{e.code}] {e}")
测试
请平台把你的商户标记为 demo 商户,创建订单时带 isTest: true,平台会注入合成 SMS 并触发真实格式的 webhook。详见 测试凭证。