如何用 REST API 搭建加密货币发票系统:从部署到自动收款

教程 API 发票

2026 年 6 月,Coinbase 正式进入印度 30 亿美元加密货币市场,支持本地印度卢比交易——全球加密支付需求正在从欧美向拉美、东南亚、南亚扩散。但托管支付平台的地域覆盖有限:你的客户很可能在 Coinbase Commerce 不支持的国家。自建加密货币发票系统,让世界任何地方的客户都能用加密货币付款——不需要等平台扩张到你的市场,不需要付 1% 手续费,更不需要把私钥交出去。

为什么不直接用托管平台的发票功能?

Coinbase Commerce、CoinGate、OpenNode 这些托管平台都有发票 API——注册账号、拿个 API Key、几行代码就能创建发票。对个人开发者来说确实方便。但三个月后你会遇到三个问题:

问题一:手续费吃掉利润

托管平台统一收 1% 手续费。月流水 5 万美元的商户,一年付 6000 美元——买三台 VPS 绰绰有余。而且 1% 只是明面的:汇率差(平台报价比市场价低 0.5-1%)、提现门槛(Coinbase Commerce 最低提现 0.001 BTC,小商户可能几周才能提一次)都是隐形成本。真实成本接近 2%,只是没有写在定价页上。

问题二:你的客户可能不在服务区

Coinbase Commerce 不支持中国大陆、伊朗、古巴、叙利亚等数十个国家。OpenNode 主要覆盖北美和欧洲。如果你做跨境电商或服务全球客户,总有一部分人打不开付款页面——他们不会告诉你"你的支付页面打不开",只会去别家。自建发票系统只受你自己的服务器所在地影响,不依赖第三方平台的地域政策。

问题三:平台冻结你的账户不需要解释

2025 年 Coinbase 因合规原因冻结了数千个账户,部分用户几周后才恢复访问。托管方案下,支付网关的私钥在平台手里——平台封你的账号,你就收不到钱。自部署发票系统:私钥在你服务器上,网关软件是开源的,没有中间人能单方面切断你的收款通道。见 为什么非托管比托管更安全

托管发票 vs 自部署发票:一张表说清楚

方案 API 方式 手续费 私钥控制 地域限制 自定义程度
Coinbase CommerceREST API1%Coinbase 持有不支持 30+ 国家低——只能用 Coinbase UI
CoinGateREST API1%CoinGate 持有不支持部分国家低——固定的付款页面
OpenNodeREST API1%OpenNode 持有仅覆盖部分国家低——比特币/闪电网络为主
自部署 XcashREST API✅ 你持有✅ 全球可用✅ 完全自定义

托管方案的优势是开箱即用——但你用 1% 的手续费和私钥控制权换了这个便利。而且一旦你的业务跑起来、月流水超过几千美元,那 1% 就开始疼了。

发票系统的三个核心组件

一个完整的加密货币发票系统只需要三样东西,都不复杂:

  • 支付网关。负责生成地址、监听链上交易、确认到账。这是自部署方案的核心——Xcash 用 Docker 部署,支持比特币和 100+ EVM 链
  • REST API。你的后端通过 API 创建发票、查询付款状态、获取交易详情。标准 REST 接口,任何语言都能调用
  • Webhook 通知。链上付款确认后,网关主动通知你的后端"这笔发票已收款"。不需要你的后端轮询——等通知就行

架构很简单:客户下单 → 你的后端调用 API 创建发票 → 网关返回付款地址 + 金额 → 客户付款 → 网关检测到链上交易 → Webhook 通知你的后端 → 订单状态更新为"已付款"。全程没有第三方参与。

第一步:Docker 部署支付网关

以 Xcash 为例,部署只需要一个 docker-compose 文件。在你的服务器上运行:

docker pull xcash/xcash:latest
docker run -d -p 8000:8000 \
  -v xcash-data:/data \
  -e XCASH_BTC_ENABLED=true \
  -e XCASH_EVM_ENABLED=true \
  -e XCASH_API_KEY=替换成你的安全密钥 \
  xcash/xcash:latest

两条命令,3 分钟。部署完成后访问 http://你的服务器IP:8000/health 确认运行状态。完整的部署细节(Nginx 反向代理、HTTPS、防火墙规则)见 三分钟用 Docker 部署加密货币支付网关

第二步:用 REST API 创建第一张发票

网关跑起来之后,创建发票只需要一个 POST 请求。以下示例用 curl,实际使用时换成你后端的 HTTP 客户端:

curl -X POST https://your-server:8000/api/v1/invoices/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": "100.00", "currency": "USDT", "chain": "bsc", "order_id": "ORDER-12345", "callback_url": "https://your-site.com/webhook"}'

API 返回 JSON 响应,包含付款地址、金额、过期时间:

{
  "id": "inv_a1b2c3d4",
  "status": "pending",
  "address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1",
  "amount": "100.00",
  "currency": "USDT",
  "chain": "bsc",
  "expires_at": "2026-06-01T10:00:00Z",
  "payment_url": "https://your-server:8000/pay/inv_a1b2c3d4"
}

payment_url 展示给客户——点击后是付款页面,客户能看到金额、链、地址,扫码或用钱包付款即可。核心字段说明:

  • amount:付款金额,字符串格式避免浮点精度问题
  • currency:代币符号——USDT、USDC、ETH、BTC、DAI 等
  • chain:链标识——ethereum、bsc、polygon、arbitrum、optimism、tron 等。不指定则由网关选择默认链
  • order_id:你自己的订单号,用于对账。网关不关心这个值是什么——纯透传
  • callback_url:Webhook 地址,付款确认后网关会 POST 到这个 URL

第三步:处理 Webhook 付款通知

客户付款后(链上确认),网关会向你指定的 callback_url 发送一个 POST 请求。你的后端需要监听这个端点:

POST https://your-site.com/webhook
Content-Type: application/json
X-Signature: sha256=abc123...

{
  "event": "invoice.paid",
  "invoice_id": "inv_a1b2c3d4",
  "order_id": "ORDER-12345",
  "amount_paid": "100.00",
  "currency": "USDT",
  "tx_hash": "0x7a1b...3f2e",
  "chain": "bsc",
  "confirmations": 3
}

收到这个 Webhook 后,你的后端应该:

  1. 验证 X-Signature 头——用你的 API Key 做 HMAC-SHA256,确认这条通知确实来自你的网关,不是伪造的
  2. order_id 找到对应订单
  3. 对比 amount_paid 和订单金额——客户可能少付(只付了部分)
  4. 把订单状态更新为"已付款"
  5. 返回 HTTP 200,告诉网关"收到了,别再发了"

如果你没有返回 200,网关会在 5 秒、30 秒、5 分钟后重试。三次都失败则标记为 delivery_failed,你可以在网关管理面板手动重新推送。

进阶:发票管理的实用功能

发票过期自动取消

创建发票时设置 expires_in 参数(秒)。超过时间未付款,网关自动标记为 expired 并发送 Webhook invoice.expired。你的后端可以据此释放库存、取消订单预留。典型值:数字商品 600 秒(10 分钟),实体商品 3600 秒(1 小时)。

处理少付和多付

链上付款金额很少和订单金额完全一致——gas 费消耗、客户手误、或者是分批付款。API 返回的 amount_paid 是实际到账金额。你的后端自行决定容差:

  • 少付超过 5%:订单保持 pending,触发人工审核或退款
  • 少付 5% 以内:接受为全额付款——对回头客友好
  • 多付:记录差额,作为账户余额或自动退款(需额外实现退款逻辑)

多币种发票:客户用 USDT 付 BTC 账单

现实中客户持有的代币可能和你的定价币种不一样。Xcash 支持在发票上指定多个 accepted_currencies

curl -X POST https://your-server:8000/api/v1/invoices/ \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": "100.00", "currency": "USD", "accepted_currencies": ["USDT", "USDC", "BTC", "ETH"], "chain": "bsc", "order_id": "ORDER-12346"}'

客户在付款页面可以选 USDT、USDC、BTC 或 ETH——网关自动按实时汇率换算等值金额。你的后端按美元记账,客户付什么币都可以。

和其他自部署方案的对比

BTCPay Server 也有发票 API,功能完整,是同类方案里的老大哥。两者的关键区别:

  • 部署复杂度:BTCPay 需要比特币全节点(600GB+ 存储)和 Lightning 节点,首次同步需要几天。Xcash 不用全节点,Docker 部署 3 分钟启动
  • 链覆盖:BTCPay 以比特币和闪电网络为强项,EVM 链需要额外配置。Xcash 原生支持 100+ EVM 链
  • API 设计:BTCPay 的 API 功能更强(支持 pull payment、crowdfund 等),但学习曲线更陡。Xcash 的 API 只做一件事:创建发票 + 收付款

如果你主要用比特币收款且需要闪电网络,BTCPay 是更好的选择。如果你需要多链覆盖、快速部署、零学习成本,Xcash 更顺手。详细对比见 BTCPay Server vs Xcash 全面对比

完整流程回顾

  1. Docker 部署 Xcash(3 分钟)
  2. POST /api/v1/invoices 创建发票(一行 curl)
  3. 把 payment_url 给客户
  4. 等 Webhook 通知 invoice.paid
  5. 更新订单状态、发货

五步,从零到自动化加密货币收款。不依赖 Coinbase、CoinGate 或任何第三方平台。你的服务器、你的私钥、你的客户数据——全部掌握在你手里。

Xcash 是一个 MIT 协议开源自部署多链加密货币支付网关,支持比特币和 100+ EVM 链。零平台费,私钥完全在你手里,Docker 一条命令部署。代码全开源在 GitHub,API 文档见 使用文档

常见问题

发票系统需要多少技术投入?

部署网关 3 分钟。对接 API 取决于你的后端框架——Python/Node.js/Go 各写一个 HTTP 调用和一个 Webhook 端点,加起来不超过 50 行代码。如果你已经有一个能处理 HTTP 请求的后端,一下午就能跑通完整流程。

链上确认慢(比特币 10 分钟),客户等不了怎么办?

对时效要求高的场景,用稳定币(USDT/USDC)在快速链上结算——BSC 3 秒出块、Polygon 2 秒、TRC-20 3 秒。客户付款后几秒内你就能收到 Webhook 通知。只有大额结算(> $1000)才建议等比特币 1-3 个确认。API 支持设置 confirmations 参数,0-conf 即时通知、3-conf 安全确认——你按业务需要选。

支持哪些加密货币?

比特币以及所有 EVM 兼容链上的代币:以太坊、BSC、Polygon、Arbitrum、Optimism、Base、Avalanche C-Chain、Fantom、Gnosis Chain、Linea、Scroll 等 100+ 条链。USDT、USDC、DAI 和所有 ERC-20 代币自动支持。完整对比见 BTCPay Server vs Xcash 全面对比

这和 Stripe 的加密货币收款有什么区别?

Stripe 的加密货币收款通过第三方托管(本质上是 Stripe 帮你对接了一个托管支付商),收 1-2% 手续费,且 Stripe 掌握你的客户付款数据。自部署发票系统:零平台费、客户付款数据在你自己的服务器上、没有中间人。如果你在意的是"少写代码",用 Stripe。如果你在意的是"少付手续费"和"控制自己的数据",自建。


相关阅读