API 概览
Uapi 为全球商户提供高性能、非托管的加密货币支付接入方案。我们的 API 旨在让复杂的区块链交互变得像传统支付一样简单。
Base URL
https://uapi.io/api/v1
1 鉴权认证
所有请求必须在 HTTP Header 中携带您的 API Key。密钥分为 Test Key (测试环境) 和 Live Key (生产环境)。
X-API-KEY: sk_live_xxxxxxxxxxxxxxxxxxxxxxxx
每次请求服务端会按顺序校验以下 6 项
| # | 检查 | 不通过时返回 | 如何排查 |
|---|---|---|---|
| 1 | X-API-KEY 头存在 | 401 Missing API Key | 在请求头加 X-API-KEY: sk_live_xxx |
| 2 | 调用者 IP 不在系统黑名单 | 403 IP Blocked | 多次失败尝试后会被自动屏蔽,联系支持解锁 |
| 3 | API Key 有效且账号 active | 403 Invalid API Key / Account suspended | 后台「API 设置」复制最新 Key;账号停用请联系支持 |
| 4 | Plan 未过期(适用于付费 Plan) | 403 Plan expired | 后台续费或降级到 Free Plan |
| 5 | 调用者 IP 在你的 API IP 白名单内(如已启用) | 403 IP not in whitelist | 后台 API 安全设置加入调用机器 IP;或关闭 IP 白名单功能 |
| 6 | 请求来源域名已绑定到该账户 | 403 Access Denied: ... | 两条路:浏览器场景请求需要带 Origin/Referer;服务端到服务端调用必须在 body 里传 domain,值是已绑定的网站域名 |
额外的"链"权限校验(仅 /order/create.php)
当你传入 chain 字段时,系统会额外检查该链是否在当前 Plan 开放。例如 Free Plan 默认只开 TRC20,升级到 Pro 才解锁多链。失败返回 403 Access Denied: Chain '…' is not enabled for your current plan。可在后台「订阅 / Plan」查看当前可用链列表。
网站绑定 (domain) 速查
前端场景:浏览器自动带 Origin 或 Referer,UAPI 据此识别绑定。
后端场景:服务端 curl / SDK 调用不带这些头,必须在 JSON body 里加 "domain": "yoursite.com"。
绑定操作在 商户后台 → API 设置 → 网站绑定。
对接流程
创建订单
商户调用接口,传入金额和网络,获取支付链接 (payment_url)。
用户支付
重定向用户至收银台,用户通过扫码或转账完成支付。
确认与回调
链上确认后,系统自动发送 Webhook 通知并更新订单状态。
免代码集成 (No-Code)
如果您不想编写代码,可以使用我们的“收款链接”功能:
- 在商户后台一键生成专属收款页面。
- 支持设置固定金额或允许用户自定义输入金额。
- 直接分享链接给客户,通过社交媒体、Telegram 或 WhatsApp 进行收款。
- 支付成功后,您依然可以在后台查看到账明细。
创建订单
POST创建一个全新的支付订单并获取收银台链接。
Endpoint
/order/create.php
| 参数名 | 类型 | 必填 | 描述 |
|---|---|---|---|
| amount | Float | YES | 订单金额 (USDT) |
| chain | String | YES | 网络: trc20, erc20, bsc, solana, polygon, etc. |
| merchant_order_id | String | YES | 您的系统订单号 (唯一) |
| notify_url | String | NO | 异步回调地址,支付成功后系统将向该地址发送 POST 请求 |
| domain | String | YES* | 服务端直连调用时必填(如 curl / 后端 SDK)。值为您已绑定的网站域名,例如 yoursite.com。若请求自带 Origin/Referer,则可不传。 |
| currency | String | NO | 结算币种:USDT(默认)或 USDC。注意:后端只接受 currency,不接受 token。 |
{
"status": "success",
"data": {
"order_no": "PAY2024...", // 系统生成的支付订单号(所有后续接口都用这个) "amount": 100.001234, // 回显订单金额 "currency": "USDT", // 回显结算币种 "chain": "trc20", // 回显支付链 "expire_in": 600, // 订单有效期 (秒),相对时间 "payment_url": "https://...", // 收银台链接,可重定向用户到此完成支付 "fast_sync_enabled": true // 是否启用了快速同步(影响链上确认速度) }
}
⚠️ 旧文档曾使用 order_id / token / payment_address / qr_code / expire_at(时间戳)等字段名,那些字段并不真实返回,请按以上字段对接。
查询订单状态
GETpay_access_token(已嵌入 payment_url)作鉴权——主要是给收银台轮询用的,第三方系统通常通过 Webhook 接收成功通知而不是直接轮询。 Endpoint
GET /api/v1/order/status.php?order_no=PAY...&token=ACCESS_TOKEN
查询参数
| 参数 | 必填 | 说明 |
|---|---|---|
| order_no | YES | UAPI 订单号(创建订单时返回) |
| token | YES | 订单访问令牌,从创建订单返回的 payment_url 里的 query 取出 |
响应(按状态分支)
// 支付成功{ "status": "paid", "tx_hash": "0x123abc..." }
// 等待支付{ "status": "pending" }
// 订单已超时{ "status": "expired" }
// 错误{ "status": "error", "error": "Invalid token" }
频率:同 IP 30 次/分钟;单订单跨所有 IP 40 次/10 秒。第三方系统强烈推荐用 Webhook 而非轮询。
提交订单争议
POST买家收到错款(少付 / 错币种)或对账有争议时,商户可把订单标记为 disputed,可选地把订单金额/币种调成实际收到的数值,以便后续核对。
Endpoint
POST /api/v1/order/dispute.php
请求头
X-API-KEY: sk_live_xxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
请求体
| 字段 | 必填 | 说明 |
|---|---|---|
| merchant_order_id | YES* | 你系统里的订单号。和 order_no 二选一。 |
| order_no | YES* | UAPI 订单号 |
| domain | YES* | 服务端调用必填,必须是已绑定域名(同 create.php) |
| mode | NO | original(默认,保持原金额)或 adjusted(按 new_amount / new_currency 改写) |
| new_amount | NO | mode=adjusted 时生效;必须 ≤ 原订单金额,否则会被截断 |
| new_currency | NO | mode=adjusted 时生效,USDT 或 USDC |
| note | NO | 备注,会追加到订单 notes 字段 |
成功响应
{
"status": "success",
"data": {
"order_id": 12345,
"order_no": "UAPI20260408001",
"merchant_order_id": "ORD-001",
"order_status": "disputed",
"amount": "100.000000",
"currency": "USDT",
"mode": "original"
}
}
频率:20 次/分钟/IP。提交后订单 status 即变为 disputed,不会再触发 Webhook。
回调通知 (Webhook)
当链上交易确认后,UAPI 会立即向你创建订单时传入的 notify_url 发送一个 POST 回调。
若创建订单时未传 notify_url,系统会自动使用商户后台「API 设置」中的默认 Webhook 地址。
请求头
| Header | 说明 |
|---|---|
| Content-Type | 固定 application/json |
| X-UAPI-Signature | HMAC-SHA256 签名(hex 字符串,不带 sha256= 前缀) |
| X-UAPI-Timestamp | 签名时的 Unix 秒级时间戳,参与签名输入 |
| X-UAPI-Event | 当前固定 order.paid |
| X-UAPI-Event-ID | 本次事件唯一 ID(16 hex 字符),用于幂等去重 |
请求体(扁平结构)
{
"status": "paid",
"order_no": "UAPI20260408001",
"merchant_order_id": "ORD-001",
"amount": "100.00",
"chain": "trc20",
"currency": "USDT",
"tx_hash": "0xabcdef1234567890...",
"paid_at": "2026-04-08T10:05:00+00:00"
}
⚠️ 注意字段名:order_no(不是 order_id)、currency(不是 token)、tx_hash(不是 txid)、没有嵌套的 event/data 包装层。
签名输入与验证
签名输入是 4 个字段的字符串拼接:order_no + amount + merchant_order_id + timestamp,密钥用 你账户的 API Key(没有独立的 webhook secret)。
<?php
$rawBody = file_get_contents('php://input');
$payload = json_decode($rawBody, true);
$signature = $_SERVER['HTTP_X_UAPI_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_UAPI_TIMESTAMP'] ?? '';
$apiKey = 'sk_live_your_api_key';
// reject signatures older than 5 minutes (anti-replay)
if (abs(time() - (int)$timestamp) > 300) {
http_response_code(401); exit('Stale timestamp');
}
$signInput = $payload['order_no']
. $payload['amount']
. $payload['merchant_order_id']
. $timestamp;
$expected = hash_hmac('sha256', $signInput, $apiKey);
if (!hash_equals($expected, $signature)) {
http_response_code(401); exit('Invalid signature');
}
// dedupe on X-UAPI-Event-ID, then process the order
// return HTTP 200 to acknowledge
http_response_code(200); echo 'success';
响应要求:接收端必须返回 HTTP 2xx(或返回包含字符串 success 的 body)。否则 UAPI 会重试最多 3 次,超时 10 秒。重试间签名头里的 X-UAPI-Event-ID 不变,建议据此做幂等。
订单状态机
| 状态 | 描述 |
|---|---|
| pending | 已创建,等待用户按指定金额转账。 |
| paid | 链上到账金额和地址匹配,已记录交易哈希并回调。 |
| expired | 超过有效期 (通常为 10-20 分钟) 未支付,系统自动标记过期。 |
限流、幂等与金额精度
四层限流(按代码实际生效顺序)
| 层级 | 范围 | 额度 | 触发后 |
|---|---|---|---|
| 1. Per-IP 黑名单 | 全站,按调用方 IP | 多次失败后自动入 | 403 IP Blocked: ... |
| 2. Per-endpoint burst | 每端点 × IP × 60 秒滑窗 | order/create.php: 30 / minorder/status.php: 30 / minorder/dispute.php: 20 / minstore/create_order.php: 20 / min | 429 Too Many Requests |
| 3. Per-order burst | 单订单跨所有 IP × 10 秒 | 40 / 10s | 429 Order polling too frequent |
| 4. Daily quota | 账户级,按 Plan | Free 100 / day Pro 20,000 / day Business 50,000 / day | 429 Daily quota exceeded |
幂等保证
- 创建订单: 用相同
merchant_order_id重复 POST,会返回已存在订单(同order_no/payment_url),不会重复创建。 - Webhook: 每次事件有唯一
X-UAPI-Event-ID。重试时同一 event_id 不变,请用它做去重。 - 并发: Webhook 处理建议加分布式锁(按 order_no),防多线程并发同一订单。
金额精度与防冲突随机数
请求的 amount 是普通 decimal,范围 (0, 1,000,000]。
响应里的 amount 与链上要求转账的金额可能比你传的多一个 6 位小数尾巴(如你传 100.00 → 客户实付 100.001234)。这是故意的:UAPI 用尾数小数区分同金额并发订单,链上 watcher 据此精确匹配付款。
客户必须按响应里的 amount 精确支付(少 1 个 micro 都不会被识别为该订单的付款)。
请勿对响应里的 amount 自行截断到 2 位小数;展示给客户的二维码 / 文案应使用 UAPI 返回的原值。
支持网络与精度
| 网络 (Slug) | 精度 | 代币 | 备注 |
|---|---|---|---|
| trc20 | 6 | USDT | Tron 网络,到账极速且费用极低。 |
| bsc | 18 | USDT/BNB | 币安智能链。 |
| erc20 | 18 | USDT/ETH | 以太坊主网 (Gas 较高)。 |
| polygon | 6/18 | USDT/MATIC | Layer 2 扩容网络。 |
| solana | 6/9 | USDT/USDC | 高性能非 EVM 链。 |
| arbitrum | 18 | USDT | 以太坊 L2 卷叠网络。 |
错误响应与错误码
当前外部 API(X-API-KEY 入口)以两种形式返回错误:单字段简略错误,或 status/error/code 三字段结构。两种都需兼容处理。
短格式(多见于鉴权/限流错误)
{ "error": "Invalid API Key" }
结构化格式(多见于业务错误)
{
"status": "error",
"error": "Plan expired. Please upgrade/renew.",
"code": "PLAN_EXPIRED"
}
HTTP 状态码
| 状态 | 含义 | 常见触发 |
|---|---|---|
| 200 | 成功 | 订单创建成功 / 查询正常返回 |
| 400 | 请求格式或参数错误 | 缺少必填字段 / 链不支持 / USDC 与 TRC20 组合 |
| 401 | 未鉴权 | 缺少 X-API-KEY 头 |
| 403 | 权限不足 | API Key 无效 / 账号停用 / Plan 过期 / IP 黑名单 / 不在 IP 白名单 / 链未在当前 Plan 开放 / Origin 与绑定域名不符 |
| 429 | 请求过于频繁 | 日额度耗尽 / 同 IP 短时间内突发过多请求 / 单订单查询频率超限 |
| 500 | 服务端错误 | 钱包未配置 / 链端 RPC 失败 / 数据库异常 |
常见 error 字符串与解决方法
| error | 如何修复 |
|---|---|
| Missing API Key | 在请求头加 X-API-KEY: sk_live_xxx |
| Invalid API Key | Key 错或已被重置。后台「API 设置」→ 复制最新 Key |
| IP not in whitelist | 后台 API 安全设置里把调用机器 IP 加进白名单 |
| Plan expired | 升级或续费当前 Plan |
| Access Denied: Chain '...' is not enabled for your current plan | 该链需要更高级 Plan,或换支持的链 |
| Access Denied: domain not bound | 在 API 设置「网站绑定」里加上 Origin/Referer 对应域名;服务端调用请在 body 里带 domain |
| Currency '...' is not supported on chain '...' | USDC 不支持 TRC20,其他链均可。换链或换币种 |
| Too many requests | 指数退避后重试;或升级 Plan 提高额度 |
工具与版本
TLS 要求
出于安全考虑,我们的 API 强制要求使用 TLS 1.2 或更高版本。旧版本的 SSL/TLS 将无法建立连接。
数据编码
所有请求和响应体必须使用 UTF-8 编码。请确保您的 Content-Type 设置为 application/json。
开发者 FAQ
订单有效期可以自定义吗?
默认有效期为 10-20 分钟。如果需要更长的有效期,请联系技术支持或在商户后台的 API 设置中进行配置。过长的有效期可能会增加订单金额冲突的概率。
为什么实际支付金额会有随机小数?
这是为了在非托管钱包中实现精确的订单匹配。由于区块链上可能存在多笔相同整数金额的转账,通过增加微小的随机数(例如 100.001234),我们可以确保每笔订单在您的钱包地址下是全网唯一的。
多语言接入示例
$apiKey = 'sk_live_xxx';
$data = [
'amount' => 100.0,
'chain' => 'trc20',
'merchant_order_id' => 'MY_ORDER_001',
'notify_url' => 'https://yoursite.com/callback',
'domain' => 'yoursite.com'
];
$ch = curl_init('https://uapi.io/api/v1/order/create.php');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-KEY: ' . $apiKey,
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$result = json_decode($response, true);
echo $result['data']['payment_url'] ?? 'Create order failed';
const axios = require('axios');
const createOrder = async () => {
const { data } = await axios.post('https://uapi.io/api/v1/order/create.php', {
amount: 100.0,
chain: 'trc20',
merchant_order_id: 'MY_ORDER_001',
notify_url: 'https://yoursite.com/callback',
domain: 'yoursite.com'
}, {
headers: {
'X-API-KEY': 'sk_live_xxx',
'Content-Type': 'application/json'
}
});
console.log(data.data.payment_url);
};