每一家接受加密货币的企业,迟早都会注意到同一个矛盾。用比特币或Monero收款,全部意义就在于你和客户之间没有任何机构——然而,接受加密货币的常规做法,却是去一家公司注册:它先收下款项、替你保管、帮你兑换、核验你的身份,再把剩下的转给你。你不过是把银行换成了一家记性更差、违禁行业清单却更长的初创公司。
替代方案一点也不神秘。自托管支付网关就是运行在你租用的服务器上的一款开源软件:它为每笔订单生成一个新地址,在链上盯着款项是否到账,在账单付清时通知你的网站,而且永远没有权限动用哪怕一枚币。它早已在生产环境中成熟运行多年。下面是完整的搭建过程——它能消除什么、消除不了什么、机器该怎么选配,以及哪里有坑。
支付处理商真正让你付出的代价
手续费是最不值得关注的一项。你从托管式加密货币支付处理商那里真正买到的,是一组依赖关系;在认定它们可以接受之前,值得先把它们一一点明。
| 处理商拿走了什么 | 为什么重要 |
|---|---|
| 资金托管,短则几分钟,长则几天 | 从客户付款到你收到钱的这段时间里,钱是他们的。这个行业里的每一次破产、冻结和卷款跑路,都发生在这个空档里 |
| 一个绑定身份的账户 | 处理商知道你的法定姓名、开户银行、交易量,以及你客户的付款规律。无需KYC的主机配上需要KYC的收款页面,就是玻璃墙上一扇上了锁的门 |
| 决定你能卖什么的权力 | 可接受使用政策会在没有预警的情况下变更,并且追溯执行。上个季度还能用的账户,到这个季度就被冻结了 |
| 一个你无法检查的依赖 | 他们宕机,就是你的收款页面宕机;他们的汇率来源,就是你的定价;他们的Bug,就是你丢失的订单 |
| 每一笔销售的永久记录 | 一张发给他们的传票,就能调出你的全部订单记录。而你不会收到任何通知 |
这些都不是在指责谁居心不良。中间商本来就是这个样子。如果你的业务毫无争议、资金充足,也乐于表明身份,那么用中间商完全是一笔理性的交易——你能得到退款、客服支持,以及由别人负责的在线率。本指南的其余部分,写给所有对这笔交易说“不”的人。

自托管能给你什么——以及给不了什么
对收益要说得精确,因为夸大收益,正是人们建立错误威胁模型的根源。自托管网关恰好改变三件事,同时有几件重要的事完全不受影响。
真正改变的。钱从客户那里直接进入只有你控制的地址,所以既没有托管方,也没有需要熬过去的冻结。没有任何第三方会得知你的客户是谁、你在卖什么。也没有人能取消你收款的能力,因为根本没有可以注销的账户——只有你自己运行的软件。
不会改变的。比特币区块链仍然是一本公开账本,你的服务器发出的每一个地址仍然永久可见。你的纳税和申报义务和以前完全一样。而一旦你把这些币兑换成本国货币,就会碰上一家受监管的交易所,它会要你的护照——所以对大多数人来说,隐私真正终结的地方是出金,而不是收款。
直白地说,最大的优点是:配置正确的自托管网关不持有任何私钥。即使服务器被入侵、被查扣,或者干脆被收回,攻击者拿到的也只是你的账单历史和地址列表——而不是花掉哪怕一聪的能力。这和丢失热钱包是截然不同的灾难,也正是这种架构值得投入精力的原因。
技术栈:BTCPay Server到底是什么
事实上的标准答案是BTCPay Server:免费、采用MIT许可证、自托管;它的诞生,源于某家知名处理商的政策决定惹恼了足够多的商家,以至于大家干脆做出了一个替代品。它不是单个程序,而是一小组一起启动的容器;在凌晨两点出故障之前,先弄清楚每个部分负责什么,会很有帮助。
- 比特币节点。你自己的一份区块链副本。正是它让整套方案无需信任他人——你不必问别人自己有没有收到钱,也没有其他人知道你在监视哪些地址。
- 索引器,负责跟踪从你的钱包派生出的地址,并报告有哪些款项到账,这样节点本身就不需要持有钱包。
- BTCPay应用——也就是你实际看到的部分。商店、账单、汇率、POS收银页面、支付按钮、众筹页面、退款、REST API和Webhook。
- 数据库,保存商店、账单和设置。这是机器上唯一无法替代的状态,到了做备份时,这一点至关重要。
- 带自动TLS的反向代理,让收款页面通过HTTPS提供服务,无需你手动拼装。
- 可选的守护进程——Lightning节点、Monero节点和钱包、其他链——每一个都会给机器增加实打实的负担。要有意识地添加,而不是默认全装。
部署方式是一个由环境变量文件驱动的Docker Compose栈:你声明需要哪些可选组件,运行安装脚本,编排配置就会自动生成。比起手工拼装六个服务,这是实实在在的优势,也正因如此,这台机器需要的磁盘比你预想的要多。
服务器选型:一切取决于磁盘
CPU几乎从来不是瓶颈。一个每天处理几百张账单的网关,大部分时间都处于空闲状态;负载主要来自初始区块下载,之后就只剩涓涓细流。内存更重要一些,而磁盘决定一切。下单之前,先弄清楚自己属于下表的哪一行。
| 配置 | 需预留的磁盘 | 合理的内存 | 适合谁 |
|---|---|---|---|
| 比特币修剪节点,仅链上 | 总计约40–60 GB,含操作系统 | 4 GB | 大多数商家。正确的默认选择 |
| 修剪节点加Lightning | 约60–80 GB | 8 GB | 小额高频支付,否则手续费会占大头 |
| 完整、未修剪的比特币节点 | 约1 TB,并为未来几年的增长留出余量 | 8 GB | 还想让节点服务于其他软件,或看重拥有完整区块链的人 |
| 加装Monero节点 | 修剪模式另加约120 GB,未修剪约300 GB | +4 GB | 任何希望自己的付款不被公开账本公之于众的人 |
| 全部组件,均不修剪 | 1.5 TB起 | 16 GB | 很少见,通常意味着该把网关拆分到两台机器上 |
有两个细节常让人栽跟头,而且两者耗费的都是时间而不是金钱。第一,修剪节省的是磁盘,不是带宽:节点在初始同步时仍然会下载并验证整条链,然后丢弃不再需要的旧区块。无论最终占用多少磁盘,都要为第一次同步预留几百GB的流量——这正是不限流量应该写进需求清单的原因。第二,在这里,NVMe不是奢侈品。初始区块下载是极其密集的随机读写;同样的同步,在NVMe上只需一天,在机械硬盘上可能要一周,而这一周里你会一直怀疑它是不是坏了。
先修剪,以后再扩容——反过来会很痛苦。从修剪节点改成全节点,意味着要从创世区块重新同步。从全节点改成修剪节点,只需修改配置并重启。如果拿不准,就从修剪模式开始:网关的表现完全相同,你失去的只是向其他节点提供历史区块的能力。
第1步:开通并加固主机
在真正需要之前就把服务器订好,让区块链在你处理其他事情时同步。带完整root权限的KVM VPS是合适的形态:Docker需要内核级别的控制权,而且你希望这台机器真正属于你,而不是某个共享平台上的一个容器。用你打算收款的方式来付款——我们关于用比特币购买VPS的教程讲的就是这一环,而司法辖区指南则讨论把它放在哪里。
趁服务器还空着的时候完成加固,因为它不会空太久,而且这台机器从设计上就是一则公开广告:有钱从这里经过。SSH只允许密钥登录、禁用密码认证、防火墙默认拒绝且只开放22、80和443端口、启用无人值守的安全更新;如果条件允许,再把SSH端口本身限制为只允许你控制的地址访问。第一小时加固清单正是这份清单,在网关还不存在时完成它只需二十分钟,而不是一个下午。
安装之前,先把一个主机名指向这台机器——安装脚本需要域名,以便在首次启动时申请证书。用一个专用子域名就行,大多数人也是这么做的。请记住,这个主机名会成为你公开收款页面的一部分,所以证书一签发,它就会出现在Certificate Transparency(证书透明度)日志中,永久保留,且可被搜索。选一个你不介意被永远收录的名字;如果这个名字与你主站之间的关联本身就很敏感,那么在选定之前,先读一读我们关于主机名会暴露什么的说明。
第2步:安装网关
安装过程刻意做得很无聊:克隆部署仓库,导出几个描述你需求的环境变量,然后运行安装脚本。关键的变量是主机名、你需要的链,以及可选的配置片段——用哪种Lightning实现、是否启用修剪、是否添加其他守护进程。另外也有一个功能完整的网页安装器,但环境变量这条路,是你半年后还能照着笔记原样复现的那一条,而在这里,可复现性比方便更有价值。
接下来就是等待。整套服务几分钟内就能启动;随后,比特币节点要花几个小时到一两天的时间追上区块链,而BTCPay会老老实实地告诉你它还在同步,而不是假装已经在正常工作。这段时间不要创建账单,也不要据此对任何事情下结论。好好利用这段时间:立即创建管理员账户并开启双重身份验证,因为这个界面就是你收入的控制面板,而且整个互联网都能访问到它。
等待期间,有两项设置值得关注。把账单有效期设为符合现实确认时间的值——默认是一刻钟,对Lightning来说没问题,但对手续费飙升时的链上付款就太紧了。再设置付款容差,它决定少付了几美分的账单是算作结清还是一直挂着。零容差会招来一堆客服工单;设一个小百分比,则一张都不会有。仅这一个字段挡掉的客户邮件,就比其他任何设置都多。
第3步:连接钱包,但不把密钥放到服务器上
这一步决定了自托管到底值不值得做,也是最常在匆忙中做错的一步。
BTCPay可以替你在服务器上生成一个钱包,私钥也存放在服务器上。对于要收真金白银的商店,千万别这么做。正确的做法是在别处创建钱包——硬件钱包,或者另一台机器上的桌面钱包——只把扩展公钥(也就是xpub)交给服务器。仅凭这一串字符,网关就能派生出无限序列的收款地址并监视它们,同时在数学上完全不可能花掉任何东西。你的密钥留在你放置它们的地方;服务器则成了一个消息极其灵通的旁观者。
连接之后,要验证,而不是想当然。创建一张一美分的账单,用你控制的钱包付款,然后确认三件事:这个地址出现在你自己的钱包里;账单在BTCPay中显示已结清;这笔资金在你自己的钱包软件里可见、可花,而不只是显示在网关界面上。这种三方核对,能让你在五分钟内发现错误的派生路径,而不是等到第一位真实客户之后。
不要用第二个钱包从这个账户里花钱。索引器只监视最后一个已使用地址之后有限范围内的未使用地址。如果另一个钱包悄悄用掉了同一账户里的地址,网关就可能盯错序列中的位置,从而漏掉一笔实际已经到账的付款。让商店的账户专供商店使用;如果你需要一笔用于退款或打款的热余额,就另开一个只放少量备用金的独立钱包,而不要去破坏主钱包。
第4步:按需添加Lightning和Monero
两者都值得拥有,但都不是免费的,所以要因为有客户提出需求才添加,而不是因为存在这么一个复选框。
Lightning让小额支付变得可行——即时、几乎免费,而且不受手续费飙升的影响,否则一张四美元的链上账单就会显得荒唐。麻烦不在软件,整套服务会替你装好;麻烦在于入站流动性。你能收到的金额取决于你的通道还有多少接收空间,所以一个刚启动、没有入站容量的节点,在你开通道、购买入站容量或使用流动性服务之前,什么都收不了。为此预留一个下午和一些资金。另外,要把这个节点的备份当作与机器上其他一切都不同的单独问题来处理:Lightning通道状态是实时状态,用旧快照恢复可能让你损失通道余额,而保护你的那个恢复文件必须保持最新,并且存放在这台机器之外。
Monero则是相反的取舍:没有通道、没有流动性、没有路由——只是多一条区块链及其守护进程,外加公开账本不会向任何旁观者透露的付款。BTCPay通过一个插件支持Monero,插件背后是你自己的Monero节点和一个仅查看钱包,原理与xpub相同:你把地址和私有查看密钥交给服务器,让它能看到入账的付款,而花费密钥则保存在别处。有两个运维上的事实需要提前规划:Monero资金需要十个确认才能花费,大约二十分钟,所以你的账单有效期和订单履约逻辑必须能容忍这一点;另外,这个守护进程会占用相当多的磁盘。如果你还在权衡到底要提供哪些币种,我们对Monero、比特币和USDT的比较是更快做出决定的捷径。
第5步:接入你的网站
在你的应用知道账单已付之前,网关毫无用处。集成方式有三种,按工作量和掌控程度从低到高排列。
- 插件,适用于使用常见电商平台的情况。安装插件、粘贴API密钥,一个下午就能搞定。绝大多数实际部署都属于这种情况,刻意回避它也不会有人给你颁奖。
- 支付按钮或托管收款页面,适用于只卖少数几样东西或接受捐赠的情况。复制一段HTML代码片段,BTCPay就会在它自己的域名上处理整个付款流程。
- REST API,适用于你有自定义应用的情况。以编程方式创建账单,在账单状态变化时接收Webhook,并掌控整个体验。
无论走哪条路,履约规则都是一样的,而且没有商量余地:绝不要依据未经验证的Webhook发货。Webhook使用共享密钥签名——对每个请求都要校验签名,然后再回头调用API,确认账单确实处于Webhook所声称的状态。一个未经认证、却能把订单标记为已付款的端点,就是一台免费商品生成器,拿着扫描器的人会比你早得多发现它。
然后,决定“已付款”对你的业务意味着什么。在交易未确认时就结算是即时的,但会让你面临交易被替换的风险;等待一个确认平均会让客户多等十分钟,却几乎消除了全部风险。即时交付的数字商品值得等一个确认。明天才发货的实体商品则不必——区块还没出来,包裹也不会先动。
日常运维:备份、升级与故障模式
支付网关是基础设施,而评判基础设施要看糟糕的日子,而不是顺利的日子。三个习惯几乎涵盖了所有可能出问题的情形。
备份该备份的东西。区块链不在其列——那是几百GB的数据,互联网很乐意再发给你一遍。真正无法替代的,是存有商店、账单和设置的数据库、配置,以及所有与Lightning相关的材料。部署中自带一个备份脚本,正好能捕获这些内容;需要坚持的纪律是:按计划运行它,把结果送到别处,在送出之前加密,并且至少恢复一次以证明它可用。异地加密备份与本站其他地方介绍的做法如出一辙,而在这里,备份归档就是你全部收入的完整记录——所以加密不是可选项。
有计划地升级。这套服务自带更新脚本,表现也很规矩,但一个在无人看管时自行更新的网关,就是一个可能在你睡觉时宕机的网关。先读发布说明,先备份数据库,再挑清闲时段更新。促销期间绝对不要更新。
弄清宕机真正的代价。这是让人安心的部分。如果网关宕机,新客户就无法生成账单——这是可用性问题,而且是实实在在的问题。但已经发到你地址上的钱不会丢失、不会延迟,也不会有风险:它们就在一个私钥从未上过这台机器的钱包里,等节点恢复并重新扫描后,它们依然在那里。宕机让你损失的是销售额,而不是资金。这个区别值得牢记,因为它能把凌晨三点的紧急事故变成一件可以等到早饭后再处理的事。
隐私的现实:链上依然能看到什么
去掉处理商,去掉的只是处理商。它不会让比特币变得私密,而且如果你不留心,自托管网关还可能悄无声息地让你的链上隐私变得更糟。
| 泄露了什么 | 原因 | 怎么应对 |
|---|---|---|
| 你全部的收入历史,暴露给任何持有xpub的人 | 一个扩展公钥就能派生出你的商店将会使用的每一个地址 | 把xpub当作商业机密。绝不要把它粘贴到区块浏览器或客服工单里 |
| 哪些客户向你付过款,并被相互关联起来 | 把多笔账单付款合并到一笔交易里,就证明了这些款项都是同一个实体收到的 | 尽量少合并,要合并就大批量、在清淡时段进行——或者干脆不合并 |
| 你的收款页面与主站之间的关联 | Certificate Transparency、DNS记录,以及嵌入付款表单的那个页面 | 默认这种关联是公开的。如果它绝不能公开,这个约束就应该写进设计里,而不是留给日后的补丁 |
| 你自己的管理会话 | 服务器访问日志会记录是谁在管理这台机器、从哪里管理 | 绝不要从能识别你身份的地址访问网关。我们的服务器OpSec指南有更完整的说明 |
| 最终,一切都会在交易所暴露 | 兑换成法币是受监管的咽喉要道,它能看到这些币的历史 | 任何技术手段都解决不了这个问题。要么提前做好规划,要么接受账本不会公开的币种付款 |
有两项缓解措施值得投入,而且都已内置。开启payjoin式的协作支付,可以打破“一笔交易的所有输入都属于同一个人”这一朴素假设,而这正是链上分析人员最依赖的一条启发式规则。在比特币之外同时提供Monero,则意味着最在意隐私的客户从一开始就不会往公开账本上写任何东西。两者都不是魔法,但都能提高监视你的成本。
没人爱看的法律部分
简短版本,且不构成法律建议:运行这款软件本身并不是受监管的行为。但你如何处理这些钱,则可能是。
在大多数司法辖区,接受加密货币作为你自己商品和服务的付款,是一笔普通的商业交易。你是收款的商家,而不是金融机构。随之而来的义务都是你本来就有的:按收款当天的价值确认收入,适用与刷卡付款相同的销售税或增值税,并保存经得起审计的记录。自托管网关会让这些事情更容易而不是更难,因为账单历史完全归你所有,而且完整无缺。
界线会在你开始替别人经手资金时移动。代表第三方兑换、转移或持有加密货币,几乎在任何地方都是需要牌照的业务,而“可我是自托管的”并不能成为辩护理由。制裁方面的合规义务也完全不会因为架构改变而消失。另外,在无需KYC的情况下收款,与接受你明知涉及犯罪的付款,是截然不同的两个问题——前者在世界上大多数地方合法,后者在任何地方都不合法。我们关于离岸主机是否合法的指南,对同样的区别做了更深入的分析。
整个搭建过程,一页看完
去掉所有解释,这就是一个周末项目,而且大部分时间都花在等待上:
- 确定架构:修剪节点还是全节点,要不要Lightning,要不要Monero。这决定了磁盘,而磁盘决定了套餐。
- 订购服务器——NVMe、不限流量、完整root权限——并用你打算接受的币种付款。
- 趁服务器还空着时完成加固,然后把主机名指向它,等待证书签发。
- 部署整套服务(基于环境变量文件),然后等待节点同步完成。同步期间不要对任何事情下结论。
- 在别处创建钱包,只把扩展公钥交给服务器。在做其他任何事情之前,先用一张一美分的账单验证。
- 添加Lightning或Monero,但前提是确实会有客户使用,并相应预留流动性或磁盘。
- 完成集成,可以用插件、按钮或API——在发出任何一笔订单之前,务必对照API校验每个Webhook的签名。
- 安排定时备份,加密后送出这台机器,并恢复一次,确认它可用。
最终你得到的东西并不光鲜,却悄然意义重大:一个没有任何公司参与其中的收款流程。钱直接进入只有你能动用的地址;没有账户可以被关闭,因为根本就没有账户;而整套方案的成本只是一台小服务器。如果你希望它底下的那台机器也拥有同样的独立性,这正是用比特币付费的主机服务存在的意义——令人欣慰的是,这两个决定其实是同一个决定,只是做了两次。