概览
开放 API 让代理商通过程序完成查询余额、开卡、查询卡片、创建充值单等操作。所有接口使用同一个入口,通过 r 参数区分:
https://你的域名/api/open/v1.php?r=接口名
请求体与返回均为 JSON(UTF-8)。返回统一结构:
{ "code": 0, "msg": "ok", "data": { ... } }
code = 0 表示成功,其他值见 错误码。
申请与密钥
- 登录后进入 用户中心 → 开发者 API,点击“申请开通”。
- 审核通过后点击“生成密钥”,得到
API Key和API Secret。Secret 只显示一次,请立即保存。 - 建议同时填写服务器 IP 白名单;不填则不限制 IP。
签名规则
每个请求都要带上 3 个请求头:
| 请求头 | 说明 |
|---|---|
X-Api-Key | 你的 API Key |
X-Timestamp | 当前 Unix 时间戳(秒),与服务器误差不能超过 5 分钟 |
X-Sign | 签名,见下方 |
签名原文由三部分用换行符 \n 连接:
签名原文 = 时间戳 + "\n" + 接口名 + "\n" + 请求体原文
X-Sign = HMAC-SHA256(签名原文, API Secret) 的小写十六进制
- GET 请求的请求体原文为空字符串,参数放在 URL 上。
- POST 请求的请求体原文必须与实际发送的 JSON 字符串完全一致(包括空格)。
代码示例
PHP
<?php
$apiKey = 'ak_xxxxxxxx';
$apiSecret = 'sk_xxxxxxxx';
$base = 'https://你的域名/api/open/v1.php';
function call($route, $body = null) {
global $apiKey, $apiSecret, $base;
$ts = (string)time();
$raw = $body === null ? '' : json_encode($body, JSON_UNESCAPED_UNICODE);
$sign = hash_hmac('sha256', $ts . "\n" . $route . "\n" . $raw, $apiSecret);
$ch = curl_init($base . '?r=' . $route);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["X-Api-Key: $apiKey", "X-Timestamp: $ts", "X-Sign: $sign", 'Content-Type: application/json'],
]);
if ($body !== null) { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $raw); }
$res = json_decode(curl_exec($ch), true);
curl_close($ch);
return $res;
}
print_r(call('account.balance'));
print_r(call('card.create', ['card_type' => 'virtual_std', 'out_order_no' => 'A10001']));
Python
import time, hmac, hashlib, json, requests
API_KEY, API_SECRET = "ak_xxxxxxxx", "sk_xxxxxxxx"
BASE = "https://你的域名/api/open/v1.php"
def call(route, body=None):
ts = str(int(time.time()))
raw = "" if body is None else json.dumps(body, ensure_ascii=False, separators=(",", ":"))
sign = hmac.new(API_SECRET.encode(), f"{ts}\n{route}\n{raw}".encode(), hashlib.sha256).hexdigest()
headers = {"X-Api-Key": API_KEY, "X-Timestamp": ts, "X-Sign": sign, "Content-Type": "application/json"}
url = f"{BASE}?r={route}"
r = requests.post(url, data=raw.encode(), headers=headers) if body is not None else requests.get(url, headers=headers)
return r.json()
print(call("account.balance"))
print(call("recharge.create", {"amount": 100, "out_order_no": "R20001"}))
Node.js
const crypto = require('crypto');
const API_KEY = 'ak_xxxxxxxx', API_SECRET = 'sk_xxxxxxxx';
const BASE = 'https://你的域名/api/open/v1.php';
async function call(route, body) {
const ts = String(Math.floor(Date.now() / 1000));
const raw = body === undefined ? '' : JSON.stringify(body);
const sign = crypto.createHmac('sha256', API_SECRET).update(`${ts}\n${route}\n${raw}`).digest('hex');
const res = await fetch(`${BASE}?r=${route}`, {
method: body === undefined ? 'GET' : 'POST',
headers: { 'X-Api-Key': API_KEY, 'X-Timestamp': ts, 'X-Sign': sign, 'Content-Type': 'application/json' },
body: body === undefined ? undefined : raw,
});
return res.json();
}
call('card.list').then(console.log);
查询余额
GET?r=account.balance
{ "code": 0, "msg": "ok", "data": { "balance": 156.5, "currency": "USDT", "email": "[email protected]" } }
卡种列表
GET?r=card.types
返回可开的卡种及当前开卡费。
{ "code": 0, "data": [ { "card_type": "virtual_ai", "name": "AI 订阅卡", "fee": 2 }, ... ] }
开卡
POST?r=card.create
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| card_type | string | 是 | 卡种:virtual_ai / virtual_ad / virtual_std |
| out_order_no | string | 建议 | 你系统里的订单号(≤64 位)。同一单号重复请求只会开一张卡、扣一次费 |
开卡费从余额中扣除。成功返回完整卡片信息:
{ "code": 0, "msg": "开卡成功", "data": { "id": 12, "out_order_no": "A10001", "card_type": "virtual_std",
"card_number": "4111xxxxxxxx1234", "cvv": "123", "expiry": "12/29", "last4": "1234", "status": "active" } }
卡片列表
GET?r=card.list&page=1&size=20
返回卡片列表(不含完整卡号和 CVV),size 最大 100。
卡片详情
GET?r=card.detail&id=12
传 id 或 out_order_no 其中之一,返回完整卡号与 CVV。
创建充值单
POST?r=recharge.create
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| amount | number | 是 | 充值金额(USDT),不低于站点最低充值金额 |
| out_order_no | string | 建议 | 你系统里的单号,幂等 |
{ "code": 0, "msg": "请按 amount 精确转账到 address",
"data": { "id": 88, "amount": 100.37, "address": "TXXXXXXXX...", "network": "TRC20", "status": "pending" } }
固定地址模式下,返回的 amount 带有小数尾数,必须按该金额精确转账;专属地址模式下金额不变。
查询充值单
GET?r=recharge.query&out_order_no=R20001
传 id 或 out_order_no,status 为 pending / success / failed。
资金流水
GET?r=ledger.list&page=1
返回余额变动记录:amount 正数为入账,负数为扣款;type 取值 recharge / open_card / commission / refund / admin_add / admin_sub。
到账回调
在开发者页面填写回调地址后,充值到账时平台会向该地址发送 POST 请求:
{ "event": "recharge.success", "timestamp": 1791700000,
"data": { "recharge_id": 88, "out_order_no": "R20001", "amount": 100.37, "txid": "..." } }
请求头带 X-Timestamp 和 X-Sign,签名为 HMAC-SHA256(时间戳 + "\n" + 请求体, API Secret)。请先验签再处理,处理完成返回 ok。
<?php
// 你的回调接收地址示例
$secret = 'sk_xxxxxxxx';
$raw = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_TIMESTAMP'] ?? '';
$sign = $_SERVER['HTTP_X_SIGN'] ?? '';
if (!hash_equals(hash_hmac('sha256', $ts . "\n" . $raw, $secret), $sign)) { http_response_code(401); exit; }
$msg = json_decode($raw, true);
if ($msg['event'] === 'recharge.success') {
// $msg['data']['out_order_no'] / amount / txid
}
echo 'ok';
错误码
| code | 说明 |
|---|---|
| 0 | 成功 |
| 1001 | 开放 API 未启用 |
| 1002 | 缺少鉴权请求头 |
| 1003 | 时间戳无效或已过期 |
| 1004 | API Key 不存在 |
| 1005 | API 权限未开通或已停用 |
| 1006 | 签名错误 |
| 1007 | IP 不在白名单 |
| 1008 | 请求过于频繁 |
| 1009 | 请求方法不正确 |
| 1010 | 接口不存在 |
| 1011 | 缺少 id 或 out_order_no |
| 1012 | 记录不存在 |
| 2001 | 开卡失败(余额不足、卡种不支持、上游失败等,见 msg) |
| 3001 | 创建充值单失败(见 msg) |
调用限制
每个 API Key 默认每分钟最多 60 次请求,超出返回 1008。每次调用都会记录在开发者页面的调用日志中。