AIO Docs • Bilingual (English + 中文) • Full-width, white background

AIO Merchant Integration Manual (pay-in vs pay-out)

AIO 商户接入手册(入金与出金对比)

This doc focuses on what integrators need to ship fast: how to build the two pay-in flavors, how to build pay-outs, and how to read callbacks. Field names and statuses mirror the code.
本文只讲接入方最需要的内容,帮你快速上线:两种入金(pay-in)、出金(pay-out)的请求怎么做,回调怎么读。字段名和状态值与代码一致。


Quick map

快速导航


Pay-in types at a glance

入金类型一眼看懂

Flow Use when Fields that make it this type Address life Completion rule
One-time pay-in Single purchase/invoice vs_token + vs_amount (chain/token optional) ~1 day after an address is issued Tx completes when received >= expected amount; address expires at overdue_at
Long-time pay-in Reusable user deposit address vs_token + chain, without vs_amount (is_longtime_tx = true) Rolling 90 days since last deposit Stays Pending; extends to 90 days on each deposit; turns Overdue after 90 days idle

Chinese summary
中文总结:

Merchant pattern: request one long-time pay-in per user per chain, store your user id in bind_info, and reuse that address until it expires.
商户常用做法:每个用户、每条链各创建一个 long-time 入金,把 user id 写进 bind_info,一直复用该地址直到过期。


Build the requests

构建请求

One-time pay-in (invoice-style)

一次性入金(订单/账单)

POST /v2/tx/pay-in

Required: vs_token, vs_amount > 0 (min $0.5), chain.
Optional: token, bind_info.
必填:vs_tokenvs_amount > 0(最低约 0.5 美元)、chain
可选:tokenbind_info

Notes
注意点:

Example
示例:

{
    "vs_token": "USD",
    "vs_amount": "50",
    "chain": "Ethereum",
    "token": "USDT",
    "bind_info": "order=O123;user=U456"
  }
  

What you get back: txid, addr, pay_url, status (Pending once an address is issued), is_longtime_tx=false, overdue_at.
返回通常包含:txidaddrpay_urlstatus(地址分配后一般为 Pending)、is_longtime_tx=falseoverdue_at

Long-time pay-in (reusable address)

长期入金(可复用地址)

POST /v2/tx/pay-in-longtime

Required: chain (which defines the address), vs_token (defaults to USD).
Optional: bind_info.
必填:chain(决定地址所属链)、vs_token(默认 USD)。
可选:bind_info

Rules
规则:

Example
示例:

{
    "vs_token": "USD",
    "chain": "Ethereum",
    "bind_info": "user=U456"
  }
  

Pay-out (withdrawal)

出金(提现/付款)

POST /v2/tx/pay-out

Required: chain, payout_data (array length 1..30) with token, to_addr, amount > 0.
Optional: none—bind_info is not used for pay-outs.
必填:chainpayout_data(数组长度 1..30),每项包含 tokento_addramount > 0
可选:无(出金不使用 bind_info)。

Example
示例:

{
    "chain": "Ethereum",
    "payout_data": [
      { "token": "USDT", "to_addr": "0xRecipient1", "amount": "25" },
      { "token": "USDT", "to_addr": "0xRecipient2", "amount": "10" }
    ]
  }
  

Status on create: Pending Execution (auto-run) or Pending Approval (needs operator approval).
创建后的状态一般是:Pending Execution(自动执行)或 Pending Approval(需要人工审批)。

What the API returns
API 返回说明:


List transactions

列表查询交易

GET /v2/tx returns paged Tx summaries (pay-in and pay-out).
GET /v2/tx 返回分页的交易摘要(包含入金与出金)。

Query params (most used)
常用查询参数:

Response shape (fields you’ll see in data.txs[])
返回字段(常见于 data.txs[]):

Pay-in reading tips
入金阅读小技巧:

Pay-out reading tips
出金阅读小技巧:

Example (abbreviated)
示例(精简版):

{
    "success": true,
    "msg": "ok",
    "data": {
      "page": 1,
      "size": 10,
      "total": 1,
      "max_page": 1,
      "txs": [
        {
          "txid": "I...",
          "type": "Pay In",
          "status": "Pending",
          "vs_token": "USD",
          "vs_amount": "50",
          "usd": "50",
          "chain": "Ethereum",
          "token": "USDT",
          "amount": "50",
          "actual_amount": "0",
          "addr": "0x...",
          "gas": "0",
          "fee": "0",
          "created_at": "2019-08-24T14:15:22.123Z",
          "overdue_at": "2019-08-25T14:15:22.123Z",
          "is_longtime_tx": false,
          "total_fee": "0",
          "total_fee_usd": "0",
          "pay_url": "https://..."
        }
      ]
    }
  }
  

Use GET /v2/tx/info/{txid} when you need the SubTx list for a specific transaction.
当你需要某笔交易的 SubTx 明细时,用 GET /v2/tx/info/{txid}


Callbacks (AIO → Merchant)

回调(AIO 发给商户)

Every callback payload
每个回调的基础结构:

{ "type": "Transaction" | "Sub Transaction", "data": { ... } }
  

How to tell what you got
如何判断回调类型:

Pay-in flavor detection
区分入金类型:

Pay-out callbacks
出金回调:

Minimal shapes
最小示例:

// Transaction callback (example)
  {
    "type": "Transaction",
    "data": {
      "txid": "I...",
      "type": "Pay In",
      "status": "Pending",
      "vs_token": "USD",
      "vs_amount": "50",
      "chain": "Ethereum",
      "token": "USDT",
      "amount": "50",
      "bind_info": "order=O123;user=U456",
      "sub_txs": []
    }
  }

  // Sub Transaction callback (deposit or withdrawal record)
  {
    "type": "Sub Transaction",
    "data": {
      "txid": "I...",
      "type": "Pay In",
      "status": "Pending",
      "chain": "Ethereum",
      "token": "USDT",
      "sub_txs": [
        {
          "sub_txid": "7629621714635423",
          "status": "Completed",
          "amount": "50",
          "hash": "0x...",
          "from_addr": "0x...",
          "to_addr": "0x..."
        }
      ]
    }
  }

  // Pay-out Transaction callback (batch payout example)
  {
    "type": "Transaction",
    "data": {
      "uid": "U_xxx",
      "txid": "Oxxx",
      "status": "Completed",
      "type": "Pay Out",
      "vs_token": null,
      "vs_amount": null,
      "usd": "2.98",
      "chain": "Ethereum",
      "token": null,
      "amount": null,
      "bind_info": null,
      "sub_txs": [
        {
          "sub_txid": "subtx1",
          "status": "Completed",
          "token": "USDT",
          "amount": "1",
          "hash": "0xhash1",
          "from_addr": null,
          "to_addr": "0xRecipient1"
        },
        {
          "sub_txid": "subtx2",
          "status": "Completed",
          "token": "USDT",
          "amount": "2",
          "hash": "0xhash2",
          "from_addr": null,
          "to_addr": "0xRecipient1"
        }
      ]
    }
  }
  

Signature verification (must-do)
签名校验(必须做):

1) Check Body-MD5 == md5(raw_body_bytes).hexdigest().
校验 Body-MD5 是否等于 raw body 的 md5 hex
2) Build origin: {Algorithm} | {Date} | POST {callback_url} | {Body-MD5} using the exact configured callback URL.
用“配置在 AIO 的完整 callback_url”组装 origin
3) Validate Aio-Sign == base64(HMAC-SHA256(secret_key, origin)).
用回调密钥算 HMAC-SHA256,再 base64,对比 Aio-Sign

Delivery semantics: callbacks retry and can arrive out of order—handlers must be idempotent.
投递语义:回调会重试,且可能乱序到达,所以处理端必须幂等。


Status guide

状态指南


Auth headers (Merchant → AIO)

认证请求头(商户到 AIO)