Skip to content

Epusdt API 文档 ​

开发者可通过 Epusdt 提供的 HTTP API 将收款能力整合到业务系统。本文件以当前程序码路由为准。

旧版 POST /api/v1/order/create-transaction 已不再注册;建立订单请使用 POST /payments/gmpay/v1/order/create-transaction。

接口总览 ​

场景方法路径是否需要签名
建立 GMPay 交易POST/payments/gmpay/v1/order/create-transaction是
获取公开支付配置GET/payments/gmpay/v1/config否
收银台页面GET/pay/checkout-counter/{trade_id}否
收银台初始化数据GET/pay/checkout-counter-resp/{trade_id}否
查询支付状态GET/pay/check-status/{trade_id}否
切换支付网络/通道POST/pay/switch-network否
EPay 兼容建立交易GET/POST/payments/epay/v1/order/create-transaction/submit.php是
OkPay 平台回调POST/payments/okpay/v1/notifyOkPay 签名

统一响应格式 ​

除重定向和纯文本回调接口外,接口返回 JSON:

json
{
  "status_code": 200,
  "message": "success",
  "data": {},
  "request_id": "b1344d70-ff19-4543-b601-37abfb3b3686"
}

说明:

字段型别说明
status_codeinteger业务状态码。成功为 200,错误码见文末。
messagestring返回消息。
dataobject/null接口数据。
request_idstring请求 ID,服务端自动生成。

签名错误会返回 HTTP 401;业务错误通常返回 HTTP 400,并在 status_code 中给出具体业务码。

签名规则 ​

当前版本使用统一商户凭证。请求必须携带 pid,服务端用 pid 查询对应的 secret_key 作为签名密钥。默认安装会建立一个 PID 为 1000 的默认密钥。

GMPay 签名 ​

自 v2.0.0 起,GMPay 改用 HMAC-SHA256,这是相对 v2 之前 MD5 规则的破坏性变更。部署 v2.0.0 或更新版本前,既有 GMPay 客户端必须先升级请求与回调签名;EPay 兼容接口仍使用 MD5,不受影响。

  1. 将所有非空引数按引数名 ASCII 字典序升序排序。
  2. 使用 key=value 形式以 & 拼接。
  3. 不参与签名的字段:signature。
  4. 使用商户 secret_key 作为 HMAC key,以上述拼接字串作为 message,计算 HMAC-SHA256。
  5. 将结果编码为 64 位小写十六进位字串,作为 signature。

注意:

  • pid 必须参与签名。
  • GMPay 的 payment_type 不是必填;如果请求里传了非空 payment_type,它和其他非空引数一样必须参与签名。
  • 空字串和 null 不参与签名。
  • 引数名区分大小写。
  • JSON 数字会按服务端数字格式参与签名,例如 100.00 会被解析为 100;如果需要保留字串格式,可使用 application/x-www-form-urlencoded。

示例引数:

text
pid=1000
order_id=ORD202605230001
currency=cny
token=usdt
network=tron
amount=100
notify_url=https://merchant.example/notify
redirect_url=https://merchant.example/return
name=VIP

以下示例假设 secret_key 为 epusdt_secret_key,仅用于演示签名计算。

规范化引数字串:

text
amount=100&currency=cny&name=VIP&network=tron&notify_url=https://merchant.example/notify&order_id=ORD202605230001&pid=1000&redirect_url=https://merchant.example/return&token=usdt

得到:

text
signature=6f874b1919d95081835e2809b620e354a5866f5a6dbb2e432d1627f1eb10059d

PHP 签名示例 ​

GMPay 使用 signature 字段,签名时只排除 signature:

php
function gmpaySign(array $params, string $secretKey): string
{
    unset($params['signature']);
    ksort($params, SORT_STRING);

    $pairs = [];
    foreach ($params as $key => $value) {
        if ($value === '' || $value === null) {
            continue;
        }
        $pairs[] = $key . '=' . $value;
    }

    return hash_hmac('sha256', implode('&', $pairs), $secretKey);
}

EPay 兼容接口使用 sign 字段,签名时排除 sign 和 sign_type:

php
function epaySign(array $params, string $secretKey): string
{
    unset($params['sign'], $params['sign_type']);
    ksort($params, SORT_STRING);

    $pairs = [];
    foreach ($params as $key => $value) {
        if ($value === '' || $value === null) {
            continue;
        }
        $pairs[] = $key . '=' . $value;
    }

    return strtolower(md5(implode('&', $pairs) . $secretKey));
}

建立 GMPay 交易 ​

POST /payments/gmpay/v1/order/create-transaction

支持:

  • Content-Type: application/json
  • Content-Type: application/x-www-form-urlencoded

GMPay 请求示例 ​

json
{
  "pid": "1000",
  "order_id": "ORD202605230001",
  "currency": "cny",
  "token": "usdt",
  "network": "tron",
  "amount": 100,
  "notify_url": "https://merchant.example/notify",
  "redirect_url": "https://merchant.example/return",
  "name": "VIP",
  "signature": "6f874b1919d95081835e2809b620e354a5866f5a6dbb2e432d1627f1eb10059d"
}

GMPay 请求引数 ​

字段型别必填说明
pidstring是商户 PID,用于查询 API Key,并参与签名。
order_idstring是商户订单号,最长 32 字元,不能重复。
currencystring是法币币种,如 cny、usd。
tokenstring条件必填收款币种,如 usdt、trx、usdc、sol。GMPay 可与 network 同时省略以建立状态 4 占位订单。
networkstring条件必填收款网络,如 tron、solana、ethereum、bsc、polygon、plasma。GMPay 可与 token 同时省略以建立状态 4 占位订单。
amountnumber是法币金额,必须大于 0.01。
notify_urlstring是支付成功异步回调地址。
redirect_urlstring否支付完成后的同步跳转地址。
namestring否商品/订单名称。
payment_typestring否GMPay 兼容字段,不要求必须传;如果传了非空值,必须参与 GMPay signature 计算。普通 GMPay 不传时后台会存为 Gmpay;传 Epay(大小写不敏感)会统一存为 Epay 并使用 EPay 回调格式,且 PID 必须是数字。
signaturestring是GMPay 签名。

token 和 network 必须同传或同缺。两者同缺时只建立包含 amount/currency 的占位订单,状态为 4,不会分配钱包、不会计算链上支付金额,也不会锁定交易金额;后续由收银台调用 /pay/switch-network 选择具体链和币种或 OkPay。只缺其中一个会返回引数错误。

建议先调用 /payments/gmpay/v1/config 获取可用的 network 和 token 组合。

GMPay 成功响应 ​

json
{
  "status_code": 200,
  "message": "success",
  "data": {
    "trade_id": "20260523171652123456001",
    "order_id": "ORD202605230001",
    "amount": 100,
    "currency": "CNY",
    "actual_amount": 14.29,
    "receive_address": "TTestTronAddress001",
    "token": "USDT",
    "status": 1,
    "expiration_time": 1779530812,
    "payment_url": "https://pay.example.com/pay/checkout-counter/20260523171652123456001"
  },
  "request_id": "b1344d70-ff19-4543-b601-37abfb3b3686"
}
字段型别说明
trade_idstringEpusdt 交易号。
order_idstring商户订单号。
amountnumber商户提交的法币金额。
currencystring法币币种。
actual_amountnumber实际需支付的加密货币数量。
receive_addressstring收款地址。
tokenstring收款币种。
statusinteger订单状态。状态 4 表示等待用户选择 token/network。
expiration_timeinteger订单过期时间,秒级时间戳。
payment_urlstring收银台地址。该地址会跳转到前端收银台。

状态 4 占位订单的 actual_amount 为 0,receive_address 和 token 为空;过期任务或后台关闭只会把它改为状态 3,不会执行交易金额解锁。第一次成功调用 /pay/switch-network 时,如果选择普通链上 token/network,同一个父订单会原地补全链上字段并变为状态 1,此时才会建立真实交易锁;如果选择 network=okpay,同一个父订单会原地变为 OkPay 订单并返回 OkPay 托管支付连结,不建立子订单,也不会分配本系统钱包地址或链上锁。占位父单首次补全后 is_selected 仍为 false,后续同目标选择才会把父单标记为已选中;如果后续切到其它支付目标,则建立唯一一条子订单。

获取公开支付配置 ​

GET /payments/gmpay/v1/config

返回收银台展示配置、可用链/币种、EPay 默认配置和 OkPay 公共配置。

公开配置成功响应示例 ​

json
{
  "status_code": 200,
  "message": "success",
  "data": {
    "supported_assets": [
      {
        "network": "tron",
        "display_name": "TRON",
        "tokens": ["TRX", "USDT"]
      },
      {
        "network": "solana",
        "display_name": "Solana",
        "tokens": ["SOL", "USDC", "USDT"]
      }
    ],
    "site": {
      "cashier_name": "Acme Cashier",
      "logo_url": "https://cdn.example.com/logo.png",
      "website_title": "Acme Payments",
      "support_link": "https://example.com/support",
      "background_color": "#0f172a",
      "background_image_url": "https://cdn.example.com/background.png"
    },
    "epay": {
      "default_token": "",
      "default_currency": "cny",
      "default_network": ""
    },
    "okpay": {
      "enabled": false,
      "allow_tokens": ["USDT", "TRX"]
    },
    "version": "v1.0.1"
  },
  "request_id": "b1344d70-ff19-4543-b601-37abfb3b3686"
}

supported_assets 只包含同时满足以下条件的组合:

  • 链已启用。
  • 该链有可用钱包地址。
  • 该链至少有一个启用中的 token。

收银台页面 ​

GET /pay/checkout-counter/{trade_id}

用于浏览器开启收银台。当前实现会返回 301,并跳转到:

text
/cashier/{trade_id}

建立交易接口返回的 payment_url 即为该地址。

收银台初始化数据 ​

GET /pay/checkout-counter-resp/{trade_id}

用于前端收银台读取订单展示数据。该接口只确认订单存在并返回基础数据;当前支付状态请调用 /pay/check-status/{trade_id}。

收银台初始化成功响应示例 ​

json
{
  "status_code": 200,
  "message": "success",
  "data": {
    "trade_id": "20260523171652123456001",
    "amount": 100,
    "actual_amount": 14.29,
    "token": "USDT",
    "currency": "CNY",
    "receive_address": "TTestTronAddress001",
    "network": "tron",
    "status": 1,
    "payment_type": "gmpay",
    "expiration_time": 1779530812000,
    "redirect_url": "https://merchant.example/return",
    "payment_url": "",
    "created_at": 1779530212000,
    "server_time": 1779530312000,
    "is_selected": false
  },
  "request_id": "b1344d70-ff19-4543-b601-37abfb3b3686"
}

注意:该接口的 expiration_time、created_at 和 server_time 是毫秒级时间戳。server_time 是服务端目前时间,托管收银台可用它计算倒数,避免依赖客户端时钟。

如果订单是状态 4 占位订单,返回的仍是同一个父订单 trade_id,但链上支付字段尚未生成。该状态可能来自 GMPay 空 token/network 建立,也可能来自 EPay submit.php 在请求和数据库默认值都没有完整 token/network 时建立:

json
{
  "status_code": 200,
  "message": "success",
  "data": {
    "trade_id": "20260523171652123456001",
    "amount": 100,
    "actual_amount": 0,
    "token": "",
    "currency": "CNY",
    "receive_address": "",
    "network": "",
    "status": 4,
    "payment_type": "gmpay",
    "expiration_time": 1779530812000,
    "redirect_url": "https://merchant.example/return",
    "payment_url": "",
    "created_at": 1779530212000,
    "server_time": 1779530312000,
    "is_selected": false
  },
  "request_id": "b1344d70-ff19-4543-b601-37abfb3b3686"
}

payment_type 是归一化后的接入型别:底层订单储存为 Epay/Gmpay,该接口转为小写 epay/gmpay 返回;epay 会走 EPay 回调格式,gmpay 走默认 GMPay JSON 回调格式。

前端看到 status=4 时,应展示选择网络和币种/支付通道的接口,并在用户选择后调用 /pay/switch-network。选择链上支付成功后,该父订单会变为 status=1,actual_amount、token、network、receive_address 会被补全,但 is_selected 保持 false,由后续同目标选择流程标记为已选中。选择 OkPay 成功后,接口返回同一个父订单 trade_id 和第三方 payment_url;父订单会变为 status=1、is_selected=false、pay_provider=okpay、network=okpay、receive_address=OKPAY。

查询支付状态 ​

GET /pay/check-status/{trade_id}

支付状态成功响应示例 ​

json
{
  "status_code": 200,
  "message": "success",
  "data": {
    "trade_id": "20260523171652123456001",
    "status": 1
  },
  "request_id": "b1344d70-ff19-4543-b601-37abfb3b3686"
}

订单状态:

值说明
1等待支付
2支付成功
3已过期
4等待选择支付网络/币种

切换支付网络/通道 ​

POST /pay/switch-network

该接口通常由收银台前端调用,用于切换到另一个链上收款地址,或切换到 OkPay 托管收银台。

切换网络请求示例 ​

json
{
  "trade_id": "20260523171652123456001",
  "token": "USDT",
  "network": "solana"
}

切换到 OkPay:

json
{
  "trade_id": "20260523171652123456001",
  "token": "USDT",
  "network": "okpay"
}

切换网络请求引数 ​

字段型别必填说明
trade_idstring是父订单交易号。
tokenstring是目标币种。
networkstring是目标网络,或特殊值 okpay。

切换网络成功响应 ​

返回结构与收银台初始化数据一致。链上订单的 payment_url 为空;OkPay 订单的 payment_url 是 OkPay 返回的托管支付连结。若父订单仍是 status=4,首次切换链上或 OkPay 都会原地补全父订单并返回同一个 trade_id。

说明:

  • 只能对父订单切换网络,不能对子订单继续切换。
  • 父订单必须处于等待支付状态 1,或占位状态 4。
  • 状态 4 第一次选择具体链和币种时,会原地补全父订单并返回同一个 trade_id,不会建立子订单。
  • 状态 4 第一次选择 network=okpay 时,不要求父订单已有链上字段;系统会原地把父订单补成 OkPay 订单并返回同一个 trade_id 与 OkPay payment_url,不会建立子订单。
  • 状态 4 补全后订单变为状态 1,但 is_selected 保持 false;之后同目标选择会返回父单并标记选中,切到其它支付目标才建立子订单。
  • 每个父订单最多建立 1 个子订单;已经建立过子订单后,不能再用该父单建立第二个新子订单。子订单本身不能继续切换网络。
  • 如果切换到同一组 token + network,会返回已有订单。

EPay 兼容建立交易 ​

GET /payments/epay/v1/order/create-transaction/submit.php

POST /payments/epay/v1/order/create-transaction/submit.php

该接口兼容传统 EPay/易支付接入方式。成功后不会返回 JSON,而是 HTTP 302 跳转到:

text
/pay/checkout-counter/{trade_id}

EPay 请求引数 ​

字段位置型别必填说明
pidquery/formstring是商户 PID。建议使用数字 PID;EPay 回调会按数字 PID 输出。
moneyquery/formnumber是法币金额。
out_trade_noquery/formstring是商户订单号。
notify_urlquery/formstring是异步回调地址。
return_urlquery/formstring否支付完成后的同步跳转地址。
namequery/formstring否商品/订单名称。
typequery/formstring否alipay 或有效的 token.network 选择器(如 usdt.tron)。有效选择器会决定实际链上币种和网络,并覆盖 EPay 默认 token/network。
tokenquery/formstring否可选收款币种。优先顺序高于后台 epay.default_token;传了就必须参与 EPay 签名。
networkquery/formstring否可选收款网络。优先顺序高于后台 epay.default_network;传了就必须参与 EPay 签名。
currencyquery/formstring否可选法币币种。优先顺序高于后台 epay.default_currency;传了就必须参与 EPay 签名。
signquery/formstring是EPay 签名。
sign_typequery/formstring否通常为 MD5。

签名规则:

  • 使用 pid 对应的 secret_key。
  • 排除 sign 和 sign_type。
  • 其他非空引数按 ASCII 字典序拼接后追加 secret_key 并 MD5;如果接入外挂额外传了 sitename 等字段,也要一起参与签名。

示例待签名字串:

text
money=100&name=VIP&notify_url=https://merchant.example/notify&out_trade_no=ORD202605230001&pid=1000&return_url=https://merchant.example/return&type=alipayepusdt_secret_key

得到:

text
sign=b865b0acbb2b01554c35a1bd33351452

EPay 接口解析 type/token/network/currency 的优先顺序:

  • type=token.network:如果是当前可用的链上组合(如 usdt.tron),优先决定 token/network;如果 type 既不是有效选择器也不是 alipay,返回引数错误。
  • token / network:未使用有效 type 选择器时,读取请求引数;显式传入的字段必须参与 EPay 签名。
  • epay.default_token / epay.default_network:请求未提供对应字段时使用后台默认值;有效 type 选择器会绕过这两个默认值。
  • currency:请求引数 currency > 数据库 epay.default_currency > cny;即使用了有效 type 选择器,币种回退规则也不变。
  • 最终 token/network 同时有值时,建立具体链上订单;同时为空时,建立状态 4 占位订单;只缺一个时返回引数错误。
  • 服务端会在 EPay 签名校验通过后内部注入 payment_type=Epay,该字段不参与 EPay 入站签名;但请求里显式传入的 type/token/network/currency 属于原始 EPay 引数,必须参与签名。

后台默认配置可通过 /payments/gmpay/v1/config 的 epay 字段检视;新安装默认只预置 epay.default_currency=cny,epay.default_token 和 epay.default_network 为空,因此 EPay 未显式传 token/network 时会建立状态 4 占位订单。已有数据库的配置不会被 seed 覆盖,删除或置空 epay.default_token 和 epay.default_network 后,这两个字段会返回空字串。

直接指定链和币种 ​

支持传递 type=token.network 直接建立指定链上订单。适合上游「New API」或自定义支付方式列表把不同链/币种拆成独立支付选项的场景。

示例支付方式配置:

json
[
  {
    "color": "rgba(var(--semi-blue-5), 1)",
    "name": "GM Pay",
    "type": "custom1"
  },
  {
    "color": "rgba(var(--semi-blue-5), 1)",
    "name": "GM Pay usdt.binance",
    "type": "usdt.binance"
  },
  {
    "color": "rgba(var(--semi-blue-5), 1)",
    "name": "GM Pay usdt.tron",
    "type": "usdt.tron"
  }
]

其中:

  • type=usdt.binance 会直接解析为 token=usdt、network=binance。
  • type=usdt.tron 会直接解析为 token=usdt、network=tron。
  • 这类 type 必须是当前服务端可用的 token.network 组合;可用组合以 /payments/gmpay/v1/config 返回的 supported_assets 为准。
  • custom1 不是 Epusdt 的链上选择器;如果上游用于「GM Pay 通用入口」,应由上游外挂对映为不传 type、传 type=alipay,或走普通 GMPay 占位订单流程。不要把 custom1 原样提交到 EPay submit.php,否则当前服务端会按引数错误拒绝。

提交到 EPay submit.php 时,type 是原始入站引数,必须参与 EPay 签名。

商户异步回调 ​

订单支付成功后,Epusdt 会向订单的 notify_url 传送异步通知。目标服务器处理完成后需返回 HTTP 200,响应体为 ok 或 success(大小写不敏感)。否则会按伫列配置重试:首次失败后最多重试 order_notice_max_retry 次,重试间隔按 callback_retry_base_seconds 指数退避,最大 5 分钟。

GMPay 回调 ​

普通 GMPay 订单使用 POST JSON 回调。

json
{
  "pid": "1000",
  "trade_id": "20260523171652123456001",
  "order_id": "ORD202605230001",
  "amount": 100,
  "actual_amount": 14.29,
  "receive_address": "TTestTronAddress001",
  "token": "USDT",
  "block_transaction_id": "0xabc123...",
  "signature": "a1b2c3d4e5f6...",
  "status": 2
}
字段型别说明
pidstring订单所属 API Key 的 PID。商户应使用该 PID 查本地密钥验签。
trade_idstringEpusdt 交易号。
order_idstring商户订单号。
amountnumber商户提交的法币金额。
actual_amountnumber实际到账的加密货币数量。
receive_addressstring收款地址。
tokenstring收款币种。
block_transaction_idstring链上交易哈希或第三方支付订单号。
signaturestring回调签名。
statusinteger当前仅支付成功时回调,值为 2。

GMPay 回调验签方式与建立订单相同,均使用 HMAC-SHA256,并排除 signature 字段。

EPay 兼容回调 ​

通过 EPay 兼容接口建立的订单,会使用 GET 请求回调 notify_url,引数如下:

EPay 回调会把 pid 输出为数字;使用 EPay 兼容接口或 payment_type=Epay 时,请确保 API Key 的 PID 是数字。

text
pid=1000
trade_no=20260523171652123456001
out_trade_no=ORD202605230001
type=alipay
name=VIP
money=100.0000
trade_status=TRADE_SUCCESS
sign=a1b2c3d4...
sign_type=MD5

验签时排除 sign 和 sign_type,其余非空引数按 ASCII 字典序拼接后追加 secret_key 并 MD5。

OkPay 平台回调 ​

POST /payments/okpay/v1/notify

这是 OkPay/OkayPay 平台通知 Epusdt 的接口,不是商户系统主动调用的接口。配置 OkPay 时,回调地址应填写该路径。

支持 JSON、application/x-www-form-urlencoded、multipart form 和原始 query-string 风格 body。成功返回纯文字:

text
success

失败返回 HTTP 400:

text
fail

Epusdt 会按配置的 OkPay shop token 验证 OkPay 签名,成功后将对应 OkPay 订单标记为已支付,并触发商户回调;这个 OkPay 订单可能是由 status=4 占位父单原地补全而来,也可能是后续切换建立的子订单。

status_code 返回状态码及含义 ​

状态码HTTP 状态说明
200200成功
400400系统错误,或普通引数/验证错误
401401签名认证错误
10001400钱包地址已存在
10002400支付交易已存在,请勿重复建立
10003400无可用钱包地址,无法发起支付
10004400支付金额有误,无法满足最小支付单位
10005400无可用金额通道
10006400汇率计算错误
10007400订单区块已处理
10008400订单不存在
10009400无法解析引数
10010400订单状态已变化
10011400超过子订单数量上限
10012400不能对子订单切换网络
10013400订单不是等待支付状态
10014400链未启用
10016400支持的资产不存在
10017400支付服务商未启用
10018400支付服务商配置不完整
10019400支付服务商不支持该币种或网络
最近更新