CryptoPayIn
开发者文档

构建链上结算的支付。

创建付款、将客户引导至托管结账页面、跟踪确认进度,以及在生产环境中处理已签名 webhook——您需要的一切都在这里。

API 基础 URL版本 1
https://cryptopayin.com/v1
协议REST / JSON
身份验证Bearer 密钥
模式仅限生产环境
简介

一个 API,一套托管流程

CryptoPayIn 按您选定的计价币种为订单定价,锁定经过验证的法币/USD 与加密货币/USD 快照,分配专属收款地址,并通过自有区块链节点监听付款。内部记账、手续费与余额始终以 USD 计算。您的后端会立即收到结账 URL,随后再收到已签名的生命周期事件。

基础 URL/v1
法币金额ISO 最小货币单位
加密货币数值十进制字符串
默认有效期30 分钟
!

这是一个生产环境 API。没有沙盒前缀。每次成功创建都会分配真实的链上地址。进行端到端测试时请使用小额的受支持币种金额,并将密钥保存在您的服务器端。

接入流程一览

1创建密钥

在控制台 -> 开发者 中生成一次密钥。

2创建付款

通过 POST 提交订单币种、金额与所选资产。

3打开结账页面

将客户引导至返回的托管 URL。

4处理事件

验证 HMAC 签名,并以幂等方式更新您的订单。

开始使用

创建您的第一笔付款

在商户控制台生成一个 API 密钥,将密钥保存在环境变量中,然后从您的后端创建付款。示例使用 ETH,因此无需选择代币网络即可测试。

curl --request POST https://cryptopayin.com/v1/payments \
  --header "Authorization: Bearer $CPI_SECRET_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: order_1042" \
  --data '{
    "amount": 49.99,
    "currency": "USD",
    "asset": "ETH",
    "order_ref": "order_1042",
    "redirect_url": "https://shop.example/orders/1042/paid"
  }'

使用响应数据

将付款 id 与您的订单一并保存,然后将客户重定向至 checkout_url。请勿自行计算加密货币金额或收款地址。

{
  "id": "P-9F27C1E4KD",
  "object": "payment",
  "status": "created",
  "amount": 49.99,
  "amount_decimal": "49.99",
  "amount_minor": 4999,
  "currency": "USD",
  "currency_minor_units": 2,
  "amount_usd": 49.99,
  "amount_usd_cents": 4999,
  "fx_rate_usd": "1.000000000000",
  "fx_source": "fixed:USD",
  "fx_observed_at": "2026-07-17T13:00:00+00:00",
  "fx_discrepancy_bps": 0,
  "asset": "ETH",
  "network": "mainnet",
  "crypto_amount": "0.01388612",
  "crypto_received": "0",
  "deposit_address": "0x71b8c3d4700000000000000000000000000084e2",
  "exchange_rate": "3600.00000000",
  "exchange_rate_currency": "USD",
  "exchange_rate_source": "median:cb,cg,cl",
  "exchange_rate_source_count": 3,
  "exchange_rate_observed_at": "2026-07-17T13:00:00+00:00",
  "exchange_rate_discrepancy_bps": 12,
  "confirmations": 0,
  "confirmations_required": 12,
  "order_ref": "order_1042",
  "checkout_url": "https://cryptopayin.com/i/P-9F27C1E4KD",
  "expires_at": "2026-07-17T13:30:00+00:00",
  "created_at": "2026-07-17T13:00:00+00:00",
  "completed_at": null
}
凭证

身份验证

每个 API 请求都在 HTTP Bearer 请求头中使用密钥。密钥以 csk_live_ 开头。配套的 cpk_live_ 值是用于控制台的公开标识符,不得用作 Bearer 凭证。

AUTHAuthorization: Bearer csk_live_...所有接口
仅显示一次

原始密钥仅在创建时返回一次。CryptoPayIn 存储的是密码哈希加带索引的 SHA-256 查找值,绝不存储明文密钥。

独立密钥

可为每个应用或环境创建独立密钥,并单独撤销。每个账户最多可持有 50 个有效密钥。

仅限服务器端

切勿将 csk_live_ 值放入浏览器 JavaScript、移动应用二进制文件、公开代码仓库或结账页面中。

Webhook 作用域

Webhook 端点可以是账户级别的,也可以绑定到某个 API 密钥,从而实现接入之间的隔离。

i

缺失、格式错误、已撤销或未知的密钥都会返回 401 unauthorized。被暂停或已关闭的商户账户也会以相同方式被拒绝。有效密钥若超出其被授予的权限范围使用,则返回 403 insufficient_scope

安全重试

幂等性

每次创建付款时都应发送唯一的 Idempotency-Key。如果提交后连接中断,请使用相同的密钥重试相同的 JSON:CryptoPayIn 会返回原始付款,而不会分配另一个地址。

情形结果HTTP
首次使用创建并返回一笔新付款。201
相同密钥 + 相同 JSON返回带有 Idempotent-Replayed: true 的现有付款。200
相同密钥 + 不同 JSONidempotency_conflict 拒绝该请求。409

密钥的作用域限定于该 API 凭证内,可包含 1 到 128 个字母、数字、点、下划线、冒号或短横线。使用持久的订单 UUID 是不错的选择。同一机制也保护提现操作,因此重试的提现请求绝不会导致资金被转移两次。

REST API

API 参考

该 API 涵盖付款、支付链接、店铺、产品、余额与提现。响应通过 HTTPS 以 UTF-8 JSON 格式返回;任何创建或更新操作都需要 Content-Type: application/json。写操作受调用密钥的权限限制。我们有意不提供浏览器 CORS 工作流:调用应始终在您的后端进行。

GET/v1/assets查询可用资产
GET/v1/currencies查询可用法币计价币种
POST/v1/payments创建付款
GET/v1/payments列出并筛选付款
GET/v1/payments/{id}获取付款
i

版本 1 可能会新增向后兼容的字段与接口。若发生破坏性的接口变更,将启用新的基础路径,而不会悄然更改 /v1

API 参考

列出资产

GET/v1/assets需要 Bearer 身份验证

请将此接口作为结账可选项的权威数据源。它会返回已启用的目录条目、当前经过独立核验的汇率、最低 USD 等值金额,以及节点与行情源是否就绪。当节点正在同步或价格无法核实时,某条目仍可能以 available: false 状态保留在列表中。

curl https://cryptopayin.com/v1/assets \
  --header "Authorization: Bearer $CPI_SECRET_KEY"
{
  "object": "list",
  "data": [{
    "asset": "USDT",
    "network": "TRC20",
    "type": "token",
    "decimals": 6,
    "minimum_amount": 1,
    "currency": "USD",
    "base_confirmations": 19,
    "available": true,
    "rate_usd": "1.00000000",
    "rate_source": "median:cb,cg,cl",
    "rate_source_count": 3,
    "rate_discrepancy_bps": 4,
    "rate_status": "healthy",
    "rate_updated_at": "2026-07-17T13:00:00+00:00"
  }]
}

目录与网络标识符

资产网络值简写基础确认数
BTCmainnetBTC2
ETHmainnetETH6
USDTTRC20 / ERC20USDT.TRC2019 / 6
USDCERC20USDC.ERC206
DAIERC20DAI6
SHIBERC20SHIB6
PEPEERC20PEPE6
LTCmainnetLTC6
TRXmainnetTRX19
DOGEmainnetDOGE20
XMRmainnetXMR10
SOLmainnetSOL32
!

可用性是动态变化的。请勿将上表硬编码为实时白名单。对于像 USDT 这样存在多个网络的代码,请显式发送 network,或使用 ASSET.NETWORK 简写。

API 参考

列出法币币种

GET/v1/currencies需要 Bearer 身份验证

返回已启用的计价币种、其 ISO 精度以及当前 USD 换算状态。只应展示带有 available: true 的行。USD 是内在基准币种;其他所有币种都需要实时最新报价与独立参考核验。minimum_amount 会将已启用资产中配置的最低下限换算为该币种金额;所选资产可能要求更高的金额,因此请务必同时读取 GET /v1/assets

curl https://cryptopayin.com/v1/currencies \
  --header "Authorization: Bearer $CPI_SECRET_KEY"
{
  "object": "list",
  "accounting_currency": "USD",
  "data": [{
    "currency": "EUR",
    "name": "Euro",
    "symbol": "€",
    "minor_units": 2,
    "available": true,
    "minimum_amount": "0.86",
    "rate_usd": "1.160000000000",
    "rate_source": "coinbase+ecb",
    "rate_source_count": 2,
    "rate_discrepancy_bps": 18,
    "rate_updated_at": "2026-07-17T13:00:00+00:00",
    "rate_reference_at": "2026-07-16T00:00:00+00:00"
  }]
}
i

为保持向后兼容,POST /v1/payments 上省略币种仍表示 USD。零小数位币种(如 JPY)拒绝接受小数金额。请将目录中的最低金额与汇率视为实时数据,切勿硬编码为常量。

API 参考

创建付款

POST/v1/payments每个密钥每分钟 120 次请求

以请求的计价币种创建发票,锁定经过核验的最新法币/USD 与加密货币/USD 快照,计算精确的加密货币金额,并绑定专属的链上收款地址。

请求体

字段类型是否必填说明
amount数字或十进制字符串必填currency 表示的数值,精度遵循该币种的 ISO 标准。其锁定的 USD 等值不得超过 $1,000,000.00;同时也适用各资产的最低金额限制。
currency字符串可选来自 GET /v1/currencies 的已启用三字母币种代码。默认为 USD
asset字符串必填代码,如 ETH,或简写,如 USDT.TRC20
network字符串视情况而定当某代码存在于多个网络时为必填。例如:ERC20
order_ref字符串可选您的订单标识符,最多 128 个字符。会在 API 响应与事件中返回。
customer_email字符串可选有效的电子邮箱地址,最多 190 个字符。随商户付款记录一并存储。
redirect_url字符串可选HTTPS URL,最多 255 个字符,在结账成功后提供。

响应字段

字段类型说明
id字符串P- 开头的稳定付款标识符。
status字符串当前生命周期状态。
amount / amount_decimal / amount_minor数字 / 字符串 / 整数以便捷数值、精确十进制与 ISO 最小单位三种形式表示的请求计价数值。
currency / currency_minor_units字符串 / 整数锁定的计价币种及其精度。
amount_usd / amount_usd_cents数字 / 整数不可变的内部 USD 记账数值。
fx_rate_usd / fx_source / fx_observed_at十进制字符串 / 字符串 / ISO 8601锁定的每计价单位 USD 汇率快照及其审计元数据。
asset / network字符串已解析的链上资产。
crypto_amount十进制字符串客户必须发送的精确金额。切勿将加密货币小数值解析为二进制浮点数。
crypto_received十进制字符串当前在收款地址观察到的总金额。
deposit_address字符串为此笔付款分配的专属地址。
exchange_rate十进制字符串用于计算 crypto_amount 的锁定加密货币/USD 汇率;该字段沿用其在 v1 中的原始含义。
exchange_rate_source / exchange_rate_observed_at字符串 / ISO 8601不可变的加密货币汇率审计快照。
confirmations整数当前网络确认数。
confirmations_required整数此笔付款所需的确认数阈值。较高的 USD 金额档位可能需要更多确认数。
checkout_urlURL展示给客户的托管发票页面。
expires_atISO 8601未付款发票的截止时间。
completed_atISO 8601 / null完成后的最终结算时间。

两项实时汇率在创建前都会经过新鲜度、来源数量与偏离度校验。若校验失败,创建操作将返回错误,而不会使用过期汇率。加密货币金额会按对应资产的实用精度向上取整,因此舍入永远不会让商户少收。

API 参考

列出付款

GET/v1/payments每个密钥每分钟 240 次请求

为已认证的商户账户返回最新的付款,最新的排在最前。请使用游标分页进行对账,并使用精确筛选条件定位订单,而无需遍历完整历史。

查询参数

参数默认值说明
limit20分页大小,范围为 1 到 100。
starting_after上一页返回的 next_cursor 中的付款 ID。
status精确的生命周期状态,例如 pendingcompletedexpired
order_ref精确的商户订单标识,最多 128 个字符。
curl "https://cryptopayin.com/v1/payments?status=completed&limit=20" \
  --header "Authorization: Bearer $CPI_SECRET_KEY"
{
  "object": "list",
  "data": [{
    "id": "P-9F27C1E4KD",
    "object": "payment",
    "status": "completed",
    "amount": 49.99,
    "currency": "USD",
    "asset": "ETH",
    "network": "mainnet",
    "crypto_amount": "0.01388612",
    "crypto_received": "0.01388612",
    "order_ref": "order_1042",
    "confirmations": 12,
    "confirmations_required": 12,
    "completed_at": "2026-07-17T13:12:42+00:00"
  }],
  "has_more": true,
  "next_cursor": "P-9F27C1E4KD"
}
i

has_more 为 true 时,请原样将 next_cursor 作为 starting_after 传递。未知或重复的数组风格查询参数会被拒绝,而不是被忽略。

API 参考

获取付款

GET/v1/payments/{id}每个密钥每分钟 240 次请求

返回与创建时相同的付款对象,并附带最新的状态、已收金额、交易哈希与确认数。密钥只能获取其所属商户账户下的付款。

curl https://cryptopayin.com/v1/payments/P-9F27C1E4KD \
  --header "Authorization: Bearer $CPI_SECRET_KEY"
i

常规订单更新应由 webhook 驱动。获取接口可用于超时后的对账、事件核验、渲染后端状态页面,或修复遗漏的投递。

状态模型

付款生命周期

请始终以 API 返回的状态为准。切勿仅凭浏览器重定向或客户声称已付款就判断交易已完成。

created->pending->underpaidconfirming->completed/overpaid
状态含义商户操作
created发票与地址已分配;尚未检测到任何入账。展示托管结账页面。
pending等待可用的链上付款。保持订单处于开放状态。
underpaid到账金额低于商户设定的容差范围。请客户支付页面显示的差额。
confirming已检测到足额资金;等待确认。尚不应履约发货。
completed已达到所需金额与确认数。仅履约发货一次。
overpaid确认金额超出预期。正常履约发货,并核对多付部分。
expired在到期前未检测到符合条件的付款。创建一笔新的付款。
failed地址分配或处理失败。记录错误并创建新的付款。
!

链上转账不可逆,且 CryptoPayIn 不提供退款机制——已确认的付款即为最终结果。任何自愿性退款需由您与客户在平台之外自行协商处理。

客户体验

托管结账

每笔 API 付款都会附带一个响应式 checkout_url。页面会展示商户信息、请求的计价金额、相关情况下锁定的 USD 等值金额、精确的加密货币金额、收款地址、二维码、网络提示、倒计时以及实时确认进度。

汇率已锁定

在发票有效期内,客户看到的 crypto_amount 与 API 返回的完全一致。

无需客户账户

付款人无需创建 CryptoPayIn 账户,也无需提供任何凭证。

实时状态

页面会安全地轮询付款状态,依次经历等待、确认到完成的过程。

商户重定向

成功后会提供一个 HTTPS redirect_url;但它并不能作为付款凭证。

i

请将履约逻辑保留在您的后端。浏览器跳转可能被中止、重复触发或伪造;只有经过验证的 webhook 或已认证的 GET 请求才能证明付款状态。

凭证

权限 & 作用域

每个 API 密钥都拥有一组固定的权限,这些权限在您于 控制台 → 开发者 中创建密钥时选定。每个接口在执行任何操作前都会先检查密钥的作用域;超出密钥授权范围的调用会返回 403 insufficient_scope,并附带一个标明缺失权限的 X-Required-Scope 请求头。作用域仅在创建时设定一次,之后无法扩大 — 如需更多权限,请签发新密钥。在作用域功能上线之前创建的密钥,将完整保留其原有能力:payments:readpayments:write

作用域授予权限接口
payments:read列出并获取付款GET /v1/payments, GET /v1/payments/{id}
payments:write创建托管付款POST /v1/payments
links:read列出并获取支付链接GET /v1/links, GET /v1/links/{id}
links:write创建、编辑、暂停并删除支付链接POST/PATCH/DELETE /v1/links
shops:read列出并获取店铺及其产品GET /v1/shops, GET .../products
shops:write创建并编辑店铺、产品与规格POST/PATCH/DELETE /v1/shops 及产品接口
balance:read读取加密货币余额与 USD 估值GET /v1/balance
payouts:read列出并获取提现记录GET /v1/payouts, GET /v1/payouts/{id}
payouts:write发起链上提现POST /v1/payouts
!

payouts:write 会在链上转移资金,且不可撤销。请仅将该权限授予您完全信任的密钥,将这些密钥保存在服务器端,并为每个自动化流程配置专用密钥。GET /v1/account 会返回调用密钥的作用域以及您账户的各项限制。

机器买家

智能体结账

每一条有效的支付链接同时也是一个机器可读的结账入口:AI 智能体或任意脚本无需浏览器即可发现该链接、创建发票并读取交付内容——也无需任何 API 密钥,因为这些是链接域名下面向买家的公开接口,而非商户接口。完整协议与实操示例参见 cryptopayin.com/agents

GEThttps://cryptopaylink.co/pay/{link}.json公开 · 发现

返回状态、定价、可接受的资产,以及创建发票调用所需的精确输入契约(必填字段、配送信息结构、规格)。

POSThttps://cryptopaylink.co/pay/{link}/invoice公开 · 支持 Idempotency-Key

通过与托管页面相同的核心逻辑、定价快照与防滥用限制创建发票,并返回收款地址、精确的加密货币金额、钱包 URI 与收据 URL。随后智能体可使用其掌控的任意钱包完成链上付款。

GEThttps://cryptopaylink.co/pay/{link}/receipt?p={payment}公开 · 每 5–10 秒轮询一次

实时状态与确认数;一旦付款完成,响应中将包含交付内容——您的文本内容、私有 URL,或为该笔付款保留的授权密钥——以及您设置的成功提示信息与重定向 URL。

店铺遵循相同协议

店铺前台在自己的域名下暴露相同的流程:先是带有实时库存的商品目录,再通过单次调用完成购物车校验、库存预留并返回发票。

GEThttps://shopycrypto.com/s/{shop}.json公开 · 商品目录
POSThttps://shopycrypto.com/s/{shop}/order公开 · 购物车 → 发票,支持 Idempotency-Key
GEThttps://shopycrypto.com/s/{shop}/o/{order}/receipt?p={payment}公开 · 每 5–10 秒轮询一次

卖家控制项

智能体结账默认开启,费用同样是固定的 1%。您可以在 控制台 → 设置 → 通用 → AI & 智能体结账 中按账户整体关闭该功能:关闭后,链接与店铺上的机器接口将返回 403 agents_disabled,而面向人类的结账页面仍照常工作。智能体创建的付款不带任何特殊标记——在您的控制台、webhook 与导出数据中,它们都是普通付款。

商户资源

店铺

一个托管店面,将产品汇集在一个带品牌的页面下。每个账户最多可持有 10 个店铺。产品通过下方的嵌套产品接口进行管理。

GET/v1/shopsshops:read
POST/v1/shopsshops:write
GET/v1/shops/{id}shops:read
PATCH/v1/shops/{id}shops:write
DELETE/v1/shops/{id}shops:write

请求体

字段类型是否必填说明
name字符串必填2–80 个字符。
tagline字符串可选最多 160 个字符。
theme字符串可选light(默认)或 dark
accent字符串可选取自店铺配色方案的十六进制强调色,作为 accent_paletteGET /v1/shops 中返回。
accepted_assets字符串数组可选店铺产品的默认资产,例如 ["BTC","LTC","XMR"]。修改后会应用到所有产品。
status字符串可选仅限 PATCHactivepaused
i

因政策原因被 CryptoPayIn 停用的店铺无法通过 API 重新激活或删除,将返回 admin_disabled(403)。删除店铺会移除其下的产品;已有的付款记录不受影响。

商户资源

产品 & 规格

产品归属于某个店铺。每个店铺最多可持有 50 个产品。产品可以是数字商品(即时交付)或实物商品(需设置配送国家),并且最多可暴露 30 种由 1–3 个选项组组合而成的规格。

GET/v1/shops/{shop}/productsshops:read
POST/v1/shops/{shop}/productsshops:write
GET/v1/shops/{shop}/products/{id}shops:read
PATCH/v1/shops/{shop}/products/{id}shops:write
DELETE/v1/shops/{shop}/products/{id}shops:write

请求体

字段类型是否必填说明
title字符串必填3–120 个字符。
description / blurb字符串可选完整描述,以及一行 ≤200 字符的店铺卡片摘要。
emoji字符串可选显示在产品卡片上的单个表情符号。
featured布尔值可选每个店铺最多可设置一个精选产品。
product_type字符串可选digital(默认)或 physical
shipping_countries字符串数组视情况而定仅限实物商品:ISO 代码,例如 ["FR","BE"],或使用 ["*"] 表示全球配送。
amount_type / currency / amount / min / max混合类型视情况而定基础定价,规则与支付链接相同。实物商品必须为 fixed
max_uses整数可选总销售数量上限(0 表示不限)。
delivery_type + delivery_text/url/keys混合类型可选基础产品的数字交付方式,结构与支付链接相同。
variant_options数组可选1–3 个 {name, values[]} 选项组,每组包含 2–10 个取值。组合总数不得超过 30 种。
variants数组视情况而定每种组合对应一个对象(见下文)。当存在 variant_options 时为必填且必须穷举所有组合。
status字符串可选仅限 PATCHactivepaused

规格对象

字段类型说明
options字符串数组每个选项组取一个值,按选项组顺序排列,例如 ["Pro","Lifetime"]
price数字或字符串该规格的价格,使用产品所用币种。
stock整数或 null剩余库存数量,null 表示不限量。
delivery_type + delivery_text/url/keys混合类型可选的按规格数字交付覆盖设置(默认 inherit)。密钥在整个产品范围内必须唯一。
curl -X POST https://cryptopayin.com/v1/shops/SH-JYRK8TFJ/products \
  -H "Authorization: Bearer $CPI_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Software license",
    "amount": 30,
    "currency": "USD",
    "variant_options": [
      {"name": "Edition", "values": ["Standard", "Pro"]},
      {"name": "Term", "values": ["1 year", "Lifetime"]}
    ],
    "variants": [
      {"options": ["Standard","1 year"], "price": 30, "delivery_type": "keys", "delivery_keys": ["S1Y-1"]},
      {"options": ["Standard","Lifetime"], "price": 79, "stock": 10, "delivery_type": "keys", "delivery_keys": ["SLT-1"]},
      {"options": ["Pro","1 year"], "price": 59, "delivery_type": "keys", "delivery_keys": ["P1Y-1"]},
      {"options": ["Pro","Lifetime"], "price": 149, "stock": 5, "delivery_type": "keys", "delivery_keys": ["PLT-1"]}
    ]
  }'
i

PATCH 会保留现有订单与已交付的密钥。若需调整价格或库存,请重新发送对应的 variants 数组;被省略的组合,如果已有订单则会被暂停,否则将被移除。一个产品的基础规格与各变体合计最多可持有 10,000 个有效授权密钥,且每个密钥在该产品内必须唯一。

商户资源

余额

GET/v1/balancebalance:read

返回按资产划分的已结算加密货币余额,并附上尽力而为的 USD 估值以及提现时收取的网络费用。内部记账始终以 USD 为准;余额来自已完成付款、扣除商户手续费后的净额累积。

{
  "object": "list",
  "accounting_currency": "USD",
  "minimum_payout_usd": 25,
  "data": [{
    "asset": "USDT",
    "network": "TRC20",
    "amount": "99.099",
    "usd_estimate": 99.02,
    "payout_network_fee": "2.445463"
  }]
}
i

当经过核验的实时汇率暂时不可用时,usd_estimate 会为 null;但底层余额本身依然精确。这些数值可用于决定是否提现,但不应作为最终记账依据。

商户资源

提现

将已结算的加密货币转出至外部钱包。由于提现操作不可撤销,此接口会强制执行与控制台相同的每一项安全保障:面向该资产的有效目的地址、经过核验的实时汇率、账户最低限额、包含网络费用在内的充足余额,以及在账户已启用双因素验证时的二次确认。

GET/v1/payoutspayouts:read
POST/v1/payoutspayouts:write · 每个密钥每分钟 30 次
GET/v1/payouts/{id}payouts:read

请求体

字段类型是否必填说明
asset字符串必填代码或简写,例如 LTCUSDT.TRC20
network字符串视情况而定当该代码存在于多个网络时为必填。
amount数字或字符串必填要发送的金额,不含网络费用,按该资产的精度表示。其 USD 等值必须达到账户最低限额。
address字符串必填目的地址,会针对该资产所在链进行校验。
note字符串可选您自己的备注信息,最多 255 个字符。
totp_code字符串视情况而定当前的 6 位验证码或恢复代码。账户启用双因素验证时为必填。
curl -X POST https://cryptopayin.com/v1/payouts \
  -H "Authorization: Bearer $CPI_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: withdraw-2026-07-19-01" \
  -d '{
    "asset": "USDT.TRC20",
    "amount": "50",
    "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
    "note": "weekly settlement"
  }'
{
  "id": "W-EM64ZCJB",
  "object": "payout",
  "status": "requested",
  "asset": "USDT",
  "network": "TRC20",
  "amount": "50",
  "fee": "2.445463",
  "total_debited": "52.445463",
  "address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
  "txid": null,
  "confirmations": 0,
  "created_at": "2026-07-19T19:10:00+00:00"
}

状态流转

状态含义
requested已从您的余额中预留;等待运营审核或自动批准。
approved / processing已审核通过,正排队等待执行器广播。
sent已在链上广播;txid 字段已填充。
confirmed已达到所需确认数,为最终状态。
failed发送失败;failure_message 会说明原因,且余额将被退回。
cancelled在广播前被取消;预留的余额将被退回。

请发送 Idempotency-Key,以确保网络重试永远不会产生第二笔提现:相同密钥配合相同请求体会返回原始的提现记录(Idempotent-Replayed: true);相同密钥配合不同请求体会返回 409 idempotency_conflict。双因素验证码被特意排除在幂等指纹之外,以避免因验证码轮换而触发误判的冲突。预留操作会立即扣减您的余额;提现失败或被取消后,该余额将被退回。

商户资源

账户

GET/v1/account任意有效密钥

返回您的账户资料、调用密钥的作用域、您的平台手续费以及所有实时限制 — 适用于自适应配置的接入方案或上线前检查。

{
  "object": "account",
  "id": "MC67T3PHQZ",
  "fee_bps": 100,
  "fee_percent": 1,
  "default_currency": "USD",
  "two_factor_enabled": false,
  "api_key": {"label": "production", "scopes": ["payments:read","payments:write"]},
  "limits": {
    "shops": {"used": 1, "max": 10},
    "payment_links": {"used": 0, "max": 50},
    "products_per_shop_max": 50,
    "variant_combinations_per_product_max": 30,
    "license_keys_per_product_max": 10000,
    "active_api_keys_max": 50,
    "checkout_fields_per_link_max": 5
  },
  "minimum_payout_usd": 25
}
服务器间事件

Webhook

在控制台 -> 开发者中最多可添加 10 个公开 HTTPS 端点。每个端点都会获得专属的 whsec_... 签名密钥,仅显示一次。端点可以监听整个账户,也可以绑定到某个特定的有效 API 密钥;绑定密钥的端点只会收到使用该密钥创建的付款事件。

解析前先验证

CryptoPayIn 使用端点密钥对原始请求体本身进行签名。版本 1 对 timestamp + "." + raw_body 进行签名。请在接受事件前拒绝过期的时间戳。

import crypto from "node:crypto";

const timestamp = req.headers["x-cpi-timestamp"];
const signature = req.headers["x-cpi-signature"];
const rawBody = req.rawBody; // Buffer captured before JSON parsing

if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) {
  throw new Error("stale webhook");
}
const expected = "sha256=" + crypto
  .createHmac("sha256", process.env.CPI_WEBHOOK_SECRET)
  .update(Buffer.concat([Buffer.from(`${timestamp}.`), rawBody]))
  .digest("hex");
const valid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
if (!valid) throw new Error("invalid webhook signature");

投递请求头

请求头示例用途
Content-Typeapplication/jsonUTF-8 JSON 请求体。
X-CPI-Timestamp1784293200包含在已签名消息中的 Unix 时间戳(秒)。
X-CPI-Signaturesha256=...十六进制 HMAC-SHA256 值。
X-CPI-Signature-Versionv1签名方案版本。
X-CPI-Event-Idevt_a12b...稳定的逻辑事件 ID;重试时保持不变。
X-CPI-Delivery-Id1842稳定的端点投递记录 ID。

付款事件负载

{
  "event_id": "evt_a12b34c56d78e90f12345678",
  "event": "payment.completed",
  "id": "P-9F27C1E4KD",
  "status": "completed",
  "order_ref": "order_1042",
  "amount": 49.99,
  "amount_decimal": "49.99",
  "amount_minor": 4999,
  "currency_minor_units": 2,
  "currency": "USD",
  "amount_usd": 49.99,
  "amount_usd_cents": 4999,
  "fx_rate_usd": "1.000000000000",
  "fx_source": "fixed:USD",
  "fx_observed_at": "2026-07-17T13:00:00Z",
  "fx_discrepancy_bps": 0,
  "exchange_rate": "3600.00000000",
  "exchange_rate_currency": "USD",
  "exchange_rate_source": "median:cb,cg,cl",
  "exchange_rate_source_count": 3,
  "exchange_rate_observed_at": "2026-07-17T13:00:00Z",
  "exchange_rate_discrepancy_bps": 12,
  "asset": "ETH",
  "network": "mainnet",
  "crypto_amount": "0.01388612",
  "crypto_received": "0.01388612",
  "txid": "0x9d81...75af",
  "confirmations": 12,
  "confirmations_required": 12,
  "deposit_address": "0x71b8c3d4700000000000000000000000000084e2",
  "sent_at": "2026-07-17T13:12:42Z"
}

重试与端点安全

返回任意 2xx

HTTP 200-299 均视为投递成功。请将耗时操作放到异步处理,并尽快返回响应。

共计 6 次尝试

原始请求体与事件 ID 会被保留;失败后将分别在约 1 分钟、5 分钟、30 分钟、2 小时与 6 小时后重试。

不跟随重定向

不会跟随 3xx 响应。请直接注册最终的 HTTPS URL。

仅限公开目标地址

私有地址、环回地址、链路本地地址与保留 IP 均会被拦截;每个 DNS 解析结果都会被校验,且连接会被固定。

!

投递保证至少送达一次。请在履约前先以唯一约束记录 event_id,从而让您的处理逻辑具备幂等性。在核对意外事件时,请调用 API 获取对应对象。

Webhook

事件参考

payment.completed预期金额已确认。
payment.overpaid确认金额超出预期。
payment.underpaid检测到入账金额低于容差范围。
payment.expired未付款发票的有效期已结束。
payment.failed付款创建或处理失败。
payout.sent提现已在链上广播。
payout.confirmed提现已达到所需确认数。
payout.failed提现未能完成。
webhook.test手动连通性测试。

提现事件结构

{
  "event_id": "evt_b98c76d54e32a10f87654321",
  "event": "payout.sent",
  "id": "W-8J2K7M4RQP",
  "status": "sent",
  "asset": "ETH",
  "network": "mainnet",
  "amount": "0.25",
  "fee": "0.00081768",
  "address": "0x84f2...9bc1",
  "txid": "0xa1c4...07ee",
  "confirmations": 0,
  "note": "weekly treasury",
  "sent_at": "2026-07-17T14:08:31Z"
}
可靠性

错误与速率限制

错误响应始终使用同一种 JSON 封装格式。请基于 error.type 进行分支处理;面向人类阅读的提示信息可能会在不改变版本号的情况下被改进。联系支持团队时,请引用 error.request_id 或对应的 X-Request-Id 响应头。

{
  "error": {
    "type": "ambiguous_asset",
    "message": "specify network (e.g. USDT.ERC20 or USDT.TRC20)",
    "request_id": "b942e21f8dca4b06b8672eb9"
  }
}
HTTP常见类型含义
400invalid_request, unknown_parameterJSON、查询参数或幂等请求头格式有误。
401unauthorized凭证/账户缺失、无效或未激活。
403insufficient_scope, admin_disabled有效密钥缺少所需权限(参见 X-Required-Scope),或资源已被管理员锁定。
404not_found未知接口,或资源不属于该商户账户。
405method_not_allowed请使用 Allow 请求头中标明的方法。
409idempotency_conflict同一密钥搭配了不同的 JSON 重复使用。
413request_too_largeJSON 请求体超过 64 KiB。
415unsupported_media_typePOST 请求体未声明为 application/json
422invalid, limit, invalid_amount, below_minimum, bad_address, 2fa_required, unsupported_asset请求格式正确,但未通过确定性校验,或触及资源上限。
429rate_limited请等待 Retry-After
500server_error意外故障;可使用相同的幂等密钥安全重试。
503maintenance, temporarily_unavailable, asset_unavailable, no_rate, price_stale, fiat_rate_unavailable, fiat_rate_stale, derive_failed平台、节点、行情或地址分配出现暂时性故障。系统不会以过期汇率进行替代。

当前限制

范围限制窗口
Nginx 单 IP 安全上限10 次请求/秒,突发上限 30持续生效
未认证 IP 上限300 次请求60 秒
POST /v1/payments, links, shops, products每个 API 密钥 120 次请求60 秒
POST /v1/payouts每个 API 密钥 30 次请求60 秒
GET 接口每个 API 密钥 240 次请求60 秒

账户限制

资源上限
每账户店铺数10
每账户支付链接数50
每店铺产品数50
每产品规格组合数30
每产品/链接授权密钥数10,000
每链接结账问题数5
每账户有效 API 密钥数50

可通过 GET /v1/account 查看您当前用量相对于这些上限的实时情况。

成功但受应用层限流影响的响应会携带 X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset。对于 429500503 状态,请采用指数退避加抖动的策略重试。对于 POST 请求,请始终复用原始的 Idempotency-Key 与完全相同的 JSON。

生产安全

接入安全

将 API 密钥保存在密钥管理系统中

在运行时加载密钥;切勿记录完整密钥值,也不得将其提交到源码仓库。

从后端调用 API

浏览器或移动端客户端无法安全地持有商户密钥。

验证原始 webhook 请求体

在解析 JSON 之前,先检查时间戳的新鲜度,并使用恒定时间比较验证签名。

让履约逻辑具备幂等性

以事务方式记录已处理的事件/订单,确保重试不会导致重复发货。

以 API 的最终状态为准,而非重定向结果

当事件出乎预期,或与您的本地状态不一致时,请调用接口获取该付款的最新状态。

以重叠方式轮换密钥

创建替换密钥,部署上线,确认流量正常后再删除旧密钥。

!

账户访问由一个不可找回的 16 位商户密钥控制,并可选择性地通过 TOTP 加以保护。请以对待钱包凭证同等的谨慎程度,妥善保管商户访问密钥与 API 密钥。

上线

上线检查清单

1
创建专用的生产环境 API 密钥

请勿在多个服务之间复用开发者的个人密钥。

2
查询两份实时目录

使用 GET /v1/assetsGET /v1/currencies;只渲染同时存在且 available: true 的条目。

3
添加并测试您的 webhook 端点

妥善保存一次性显示的签名密钥;验证时间戳与签名,然后对稳定的事件 ID 去重。

4
为每笔订单使用幂等密钥

模拟一次重复重试,确认只存在一个付款 ID。

5
测试汇率中断、少付与过期情形

在法币汇率过期、资产不可用、确认延迟等各种非正常路径下,您的订单状态都应保持安全一致。

6
每日对账

将您的订单与 API 付款状态、webhook 日志以及商户账本进行核对。

准备好开始接入了吗?

几秒钟内即可开户,生成密钥,并将本文档留在手边随时参考。

开户