API 概览

Uapi 为全球商户提供高性能、非托管的加密货币支付接入方案。我们的 API 旨在让复杂的区块链交互变得像传统支付一样简单。

Base URL

https://uapi.io/api/v1

1 鉴权认证

所有请求必须在 HTTP Header 中携带您的 API Key。密钥分为 Test Key (测试环境) 和 Live Key (生产环境)。

HTTP Header
X-API-KEY: sk_live_xxxxxxxxxxxxxxxxxxxxxxxx

每次请求服务端会按顺序校验以下 6 项

# 检查 不通过时返回 如何排查
1X-API-KEY 头存在401 Missing API Key在请求头加 X-API-KEY: sk_live_xxx
2调用者 IP 不在系统黑名单403 IP Blocked多次失败尝试后会被自动屏蔽,联系支持解锁
3API Key 有效且账号 active403 Invalid API Key / Account suspended后台「API 设置」复制最新 Key;账号停用请联系支持
4Plan 未过期(适用于付费 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 设置 → 网站绑定。

对接流程

1

创建订单

商户调用接口,传入金额和网络,获取支付链接 (payment_url)。

2

用户支付

重定向用户至收银台,用户通过扫码或转账完成支付。

3

确认与回调

链上确认后,系统自动发送 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(时间戳)等字段名,那些字段并不真实返回,请按以上字段对接。

查询订单状态

GET
此端点 不使用 X-API-KEY。它用订单创建时返回的 pay_access_token(已嵌入 payment_url)作鉴权——主要是给收银台轮询用的,第三方系统通常通过 Webhook 接收成功通知而不是直接轮询。

Endpoint

GET /api/v1/order/status.php?order_no=PAY...&token=ACCESS_TOKEN

查询参数

参数 必填 说明
order_noYESUAPI 订单号(创建订单时返回)
tokenYES订单访问令牌,从创建订单返回的 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_idYES*你系统里的订单号。和 order_no 二选一。
order_noYES*UAPI 订单号
domainYES*服务端调用必填,必须是已绑定域名(同 create.php)
modeNOoriginal(默认,保持原金额)或 adjusted(按 new_amount / new_currency 改写)
new_amountNOmode=adjusted 时生效;必须 ≤ 原订单金额,否则会被截断
new_currencyNOmode=adjusted 时生效,USDT 或 USDC
noteNO备注,会追加到订单 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-SignatureHMAC-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 / min
order/status.php: 30 / min
order/dispute.php: 20 / min
store/create_order.php: 20 / min
429 Too Many Requests
3. Per-order burst单订单跨所有 IP × 10 秒40 / 10s429 Order polling too frequent
4. Daily quota账户级,按 PlanFree 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 KeyKey 错或已被重置。后台「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),我们可以确保每笔订单在您的钱包地址下是全网唯一的。

多语言接入示例

PHP
$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';
Node.js (Axios)
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);
};