API 参考

完整的 ChainPay 集成指南。几分钟即可开始接受加密货币付款。

Next.js 启动模板

完整的 Next.js 应用,已预先接入鉴权、定价页和 ChainPay 付款。克隆后 5 分钟即可运行。

在 GitHub 查看

快速开始

三步接受加密货币付款 —— 无需区块链知识。

1

创建付款订单

Node.js
const response = await fetch("https://chainpay.pro/api/v1/orders", {
  method: "POST",
  headers: {
    "Authorization": "Bearer sk_live_YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    amount: 29.99,
    currency: "USDT",
    chain: "trc20",
    externalId: "order_abc123",           // your internal order ID
    metadata: { userId: "user_456" }      // arbitrary JSON, returned in webhook
  })
});

const order = await response.json();
// order.checkoutUrl  → redirect user here
// order.payAddress   → or show the address directly
2

将用户重定向到收银台

JavaScript
// Server-side redirect
res.redirect(order.checkoutUrl);

// Or client-side
window.location.href = order.checkoutUrl;
3

付款确认后接收 Webhook

Webhook 负载(POST 到你的服务器)
{
  "event": "payment.completed",
  "orderId": "ord_a1b2c3d4e5f6",
  "externalId": "order_abc123",
  "amount": "29.99",
  "netAmount": "29.75",          // after 0.8% fee
  "currency": "USDT",
  "chain": "trc20",
  "txHash": "e3b0c44298fc1c149afb...",
  "completedAt": "2026-03-22T08:15:00Z",
  "metadata": { "userId": "user_456" }
}

处理前请先校验 X-ChainPay-Signature 请求头。验证代码见 章节。

鉴权

所有 API 请求都必须以 Bearer token 形式包含你的 API 密钥。

HTTP 请求头
Authorization: Bearer sk_live_YOUR_API_KEY
cURL 示例
curl -X POST https://chainpay.pro/api/v1/orders \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": 10, "currency": "USDT", "chain": "trc20"}'
密钥前缀环境区块链
sk_live_…生产真实交易
sk_test_…沙盒不动用真实资金
安全:切勿在客户端代码或公共仓库中暴露你的 API 密钥。请将其存储为环境变量,并仅在后端调用 API。

创建订单

POSThttps://chainpay.pro/api/v1/orders

请求参数

参数类型必填描述
amountnumber必填以 USD 计的付款金额(例如 29.99)。等值的加密货币金额会按当前市场汇率计算。
currencystring必填要收取的加密货币。取值之一:"USDT"、"ETH"、"BTC"、"SOL"。
chainstring必填区块链网络。取值之一:"trc20"、"erc20"、"btc"、"sol"。必须与所选 currency 兼容。
externalIdstring可选你的内部订单标识符。会原样在 Webhook 中返回。每个商户内必须唯一。
metadataobject可选任意 JSON 对象(最大 2 KB)。会在该订单的所有 Webhook 中返回 —— 适合传递用户 ID、购物车引用等。

支持的 currency + chain 组合

currencychain网络平均确认时间
USDTtrc20TRON (TRC-20)约 1 分钟
USDTerc20Ethereum (ERC-20)约 2 分钟
ETHerc20Ethereum约 2 分钟
BTCbtcBitcoin约 30 分钟
SOLsolSolana<5 秒

响应

201 Created
{
  "orderId":      "ord_a1b2c3d4e5f6g7h8",
  "payAddress":   "TXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "cryptoAmount": "29.99",
  "currency":     "USDT",
  "chain":        "trc20",
  "checkoutUrl":  "https://chainpay.pro/pay/ord_a1b2c3d4",
  "expiresAt":    "2026-03-22T09:00:00Z",
  "createdAt":    "2026-03-22T08:30:00Z"
}

收银流程

托管收银页的工作方式。

  1. 1
    重定向你的服务器将用户重定向到创建订单时返回的 checkoutUrl。
  2. 2
    收银页托管页面会展示二维码和钱包地址,并预填精确的加密货币金额。用户扫描二维码或将地址复制到钱包应用中。
  3. 3
    确认ChainPay 会监控区块链。一旦达到所需的确认数,订单状态将变为 confirming,随后变为 completed。
  4. 4
    重定向返回收银页会显示成功界面。如果你在 dashboard 中配置了 successUrl,用户会被自动重定向到那里。
  5. 5
    Webhook你的服务器会收到 payment.completed Webhook。请在校验 Webhook 签名后再履行订单。
有效期:订单在创建 30 分钟后过期。若在该时间窗内未检测到付款,状态将变为 expired,并发送 payment.expired Webhook。请创建新订单重试。

Webhook

当订单状态变化时,ChainPay 会向你的 Webhook URL 发送带签名的 HTTP POST 请求。

配置

1

进入 Dashboard → Apps → New App

2

填写你的 Webhook URL(例如 https://yourapp.com/api/webhooks/chainpay

3

复制生成的 Webhook Secret —— 用于校验签名

Webhook 事件

当前支持的事件:

事件触发时机
payment.completed订单已付款并在链上确认
payment.expired订单未付款而过期

负载格式

JSON
{
  "event": "payment.completed",
  "orderId": "ord_xxxxxxxx",
  "amount": "9.99",
  "currency": "USDT",
  "chain": "trc20",
  "txHash": "abc123...",
  "netAmount": "9.92",
  "completedAt": "2026-01-01T00:00:00.000Z",
  "metadata": {
    "userId": "your-user-id",
    "plan": "monthly"
  }
}

签名校验

每个 Webhook 请求都包含一个 X-ChainPay-Signature 请求头。请使用 HMAC-SHA256 和你的 App 的 Webhook Secret 进行校验:

Node.js / TypeScript
import crypto from 'crypto'

function verifyWebhook(rawBody: string, signature: string, secret: string): boolean {
  const computed = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex')
  return crypto.timingSafeEqual(
    Buffer.from(computed),
    Buffer.from(signature)
  )
}

// In your webhook handler:
export async function POST(req: Request) {
  const rawBody = await req.text()
  const signature = req.headers.get('x-chainpay-signature') ?? ''

  if (!verifyWebhook(rawBody, signature, process.env.CHAINPAY_WEBHOOK_SECRET!)) {
    return new Response('Unauthorized', { status: 401 })
  }

  const event = JSON.parse(rawBody)
  if (event.event === 'payment.completed') {
    const { userId, plan } = event.metadata
    // activate user's plan
  }

  return new Response('OK')
}
Python
import hmac, hashlib

def verify_webhook(raw_body: bytes, signature: str, secret: str) -> bool:
    computed = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(computed, signature)

测试你的 Webhook

1

进入 Dashboard → Apps → 选择你的 App

2

点击 “Send Test Event”

3

确认你的服务器已收到请求(预期 HTTP 200)

重试策略

失败的投递会以指数退避重试:1 分钟 → 5 分钟 → 30 分钟 → 2 小时 → 24 小时(共 5 次尝试)。

5 次尝试均失败后,该 Webhook 将被标记为失败。可在 Dashboard → Alerts 中查看失败的投递。

最佳实践

  • 处理前务必先校验签名
  • 尽快返回 HTTP 200 —— 繁重处理请异步执行
  • 使用 orderId 对事件去重(Webhook 可能会被投递多次)
  • 在解析前保存原始请求体,以确保签名校验准确

查询订单

GEThttps://chainpay.pro/api/v1/orders/:id
响应
{
  "id":          "ord_a1b2c3d4e5f6g7h8",
  "amount":      "29.99",
  "cryptoAmount":"29.99",
  "netAmount":   "29.75",
  "currency":    "USDT",
  "chain":       "trc20",
  "status":      "completed",
  "payAddress":  "TXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "txHash":      "e3b0c44298fc1c149afbf4c8996fb92...",
  "externalId":  "order_abc123",
  "metadata":    { "userId": "user_456" },
  "createdAt":   "2026-03-22T08:30:00Z",
  "expiresAt":   "2026-03-22T09:00:00Z",
  "completedAt": "2026-03-22T08:45:00Z"
}

订单状态取值

状态描述
pending订单已创建,等待用户付款。
confirming已在链上检测到交易,等待足够的区块确认。
completed付款已完全确认。可以安全履行订单。
expired已过 30 分钟仍未检测到付款。
failed发生意外错误。请凭 orderId 联系客服。

汇率 API

获取当前 USD 汇率。无需 API 密钥。

GEThttps://chainpay.pro/api/v1/rates
响应
{
  "USDT": 1.0,
  "ETH":  3450.00,
  "BTC":  87500.00,
  "SOL":  145.00,
  "updatedAt": "2026-03-22T08:00:00Z"
}

汇率每 60 秒从聚合市场数据更新一次。你传给创建订单接口的 amount 始终按 USD 解释;API 会在订单创建时按当时汇率换算为加密货币。

沙盒模式

在不动用真实资金的情况下测试完整集成。

在注册时附加 ?mode=test 即可获得 sk_test_ API 密钥。所有标准接口在沙盒模式下表现完全一致 —— 跳过区块链轮询,由你手动触发确认。

步骤 1 —— 获取沙盒 API 密钥

cURL
curl -X POST "https://chainpay.pro/api/auth/register?mode=test" \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]", "password": "yourpassword"}'

# Response includes:
# { "merchant": { "apiKey": "sk_test_xxxxxxxxxxxxxxxx" } }

步骤 2 —— 使用测试密钥创建订单

cURL
curl -X POST https://chainpay.pro/api/v1/orders \
  -H "Authorization: Bearer sk_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": 10, "currency": "USDT", "chain": "trc20", "externalId": "test_order_1"}'

步骤 3 —— 模拟一笔付款

cURL
curl -X POST https://chainpay.pro/api/v1/sandbox/simulate-payment \
  -H "Authorization: Bearer sk_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"orderId": "ord_abc123"}'

# Response:
{
  "success":   true,
  "orderId":   "ord_abc123",
  "txHash":    "sandbox_ord_abc123_1711000000000",
  "netAmount": "9.92000000"
}
# The order status is now "completed" and your webhook is fired.
沙盒交易哈希以 sandbox_ 为前缀。simulate-payment 接口仅对 sk_test_ 密钥可用。使用正式密钥调用将返回 403。

错误码

所有错误响应都使用统一的 JSON 结构:

错误响应结构
{
  "error": "INVALID_CHAIN",
  "message": "chain 'foo' is not supported for currency USDT",
  "status": 400
}
HTTP 状态常见错误码原因与解决
400INVALID_AMOUNT, INVALID_CURRENCY, INVALID_CHAIN, MISSING_FIELD请求体格式错误或缺少必填字段。请检查上方的请求参数表。
401UNAUTHORIZED, INVALID_API_KEY缺少或无效的 Authorization 请求头。请确保发送的是 Bearer <key>。
403FORBIDDEN, SANDBOX_ONLYAPI 密钥没有执行该操作的权限(例如用正式密钥调用 simulate-payment)。
404ORDER_NOT_FOUND不存在该 ID 的订单,或该订单不属于你的商户账号。
429RATE_LIMITED请求过多。默认限制为每个 API 密钥 60 req/min。请退避,并在 Retry-After 头指定的时间后重试。
500INTERNAL_ERROR意外的服务端错误。请以指数退避重试。如持续出现,请凭 request ID 联系客服。

结算

ChainPay 如何以及何时将收取的资金发送到你的钱包。

结算周期
每日 02:00 UTC
手续费
每笔交易 0.8%
最低结算
等值 $10

结算会将所有已完成、未结算的金额发送到你在 dashboard 的 Settings → Settlement Wallets 中配置的钱包地址。你可以为每种货币配置不同的收款地址。

提示:手续费按订单扣除 —— Webhook 中的 netAmount 已反映扣费后的金额。结算会转账当日所有 netAmount 的总和。

准备好集成了吗?

创建账号,几秒内获取你的 API 密钥。