不止 Stripe:全球 SaaS 该怎么选支付通道
By make1day
多数模板接完 Stripe 就停了。等你卖到卡不是默认支付方式的市场,或发现一个人算 VAT 等于第二份工作时,问题就来了。
Merchant of Record 与支付处理商的区别
处理商(Stripe、PayPal、Waffo Acquiring)负责搬钱,税务计算、开票与合规仍归你。Merchant of Record(Waffo Pancake、Lemon Squeezy,部分配置下的 Creem)是法律意义上的卖方,负责销售税/VAT、发票,通常还有退款。对没有公司主体却要全球收款的独立开发者,这个差别就是选择它的全部理由。
六个适配器
本项目带 Waffo Pancake(默认,MoR)、Waffo Acquiring、Stripe、Creem、PayPal、Lemon Squeezy,另有 none 供自带计费。在 Builder 里选一个,其余适配器会从 ZIP 中剪掉。六个实现同一份接口:创建结账、创建客户门户会话、验签 Webhook。
合同字段一律由 env 提供,代码绝不代填:Waffo Acquiring 的商户号、return/notify URL、商品 id、签名模式都来自 WAFFO_ACQUIRING_* 变量,需从商户合同复制。缺任何一个,配置层会抛出指名变量的错误。
一份验签契约,六份实现
每个适配器在签名缺失、无效或格式损坏时都抛错,路由转成 400。返回空列表只表示「合法已验签但无需处理」,对应 200 加 ignored 标记。写 license 或套餐之前按事件 id 去重。早期版本在验签失败时也返回空列表,等于五个网关都用 200 接受了伪造请求;现在这份契约由离线探测脚本守着。
没有六个沙箱账户怎么测
四层:只报告缺失变量(不返回密钥)的配置自检;离线验签探测(npm run probe:webhook),对合法、缺失、篡改、损坏四类请求断言 400/200;逐网关沙箱对照;上线前一次真实小额购买。前两层完全不需要凭据,应该进 CI;后两层才要各家的沙箱密钥。完整矩阵见 docs/payment-testing.md。
FAQ
支持哪些支付通道?+
Waffo Pancake(默认 Merchant of Record)、Waffo Acquiring、Stripe、Creem、PayPal、Lemon Squeezy,以及 none。生成的 ZIP 只包含选中的那一个适配器。
全球收款必须有公司主体吗?+
用 Merchant of Record 不必——Waffo Pancake 或 Lemon Squeezy 作为法律卖方处理税务。用普通处理商,税务、开票与合规由你自己承担。
代码会代填缺失的合同字段吗?+
不会。商户号、价格 id、notify URL、签名模式必须来自 env 或商户合同。缺少必填变量时会抛出指名变量的错误,而不是塞一个看起来合理的占位值。
All frequently asked questions · Markdown version (for AI agents)