一人公司支付系统:Stripe、Paddle、Lemon Squeezy 与微信支付怎么选

"Paddle:通过 webhook 开通访问并同步订阅状态"
免责声明:本文不提供税务、法律、公司注册、外汇或主体资格建议。涉及 MoR(Merchant of Record)、VAT/GST/sales tax、境内外主体和提现路径,以服务商条款和专业顾问意见为准。
pricing.ts 里定义了 starter_monthly、pro_yearly、lifetime_license、wechat_one_time 四个价格,但数据库里只留了一个 is_paid 字段。你收到 checkout.session.completed webhook,用户也从 success_url 跳回来了,查数据库却发现 entitlements 还是空的。这不是支付按钮的问题,而是支付系统没有把产品、订单、订阅和权益连起来。
一人公司的支付系统选型,应先回答五个问题:卖什么、怎么计费、卖给谁、谁承担交易与销售税责任、付款后由谁开通权益。Stripe、Paddle、Lemon Squeezy 和微信支付不是同一层面的四个按钮;它们覆盖的责任边界不同。
先确认售卖模型,再谈支付系统
一次性购买关注订单和交付;订阅 SaaS 关注整个 billing lifecycle;用量计费还要保证 usage 数据可追溯。先把模型写进 products、prices 和本地表,再比较服务商。
| 售卖模型 | 可评估的起点 | 关键异步事件 | 本地核心表 |
|---|---|---|---|
| 一次性数字产品 | Stripe / Paddle / Lemon Squeezy | checkout.session.completed / transaction.completed / order_created | orders + entitlements |
| 订阅 SaaS | Stripe Billing / Paddle Billing / Lemon Squeezy | customer.subscription.* / subscription.* | subscriptions + entitlements + usage_events(如有用量计费) |
| 混合(订阅 + 一次性) | Stripe Billing / Paddle Billing | 多事件监听 | orders + subscriptions + entitlements |
| 中国境内或微信生态 | 微信支付(JSAPI/H5/Native) | 支付回调通知与查单结果 | orders + wechat_prepay |
判断时注意三点:
- 一次性产品主要处理订单、交付、退款和补发,不需要完整的订阅生命周期。
- 订阅 SaaS 需要
subscriptions表记录current_period_start/end、cancel_at和status;用量计费还需要可审计的usage_events。 - 微信支付是支付通道和商户系统,不是全球 MoR 或 SaaS billing 的替代品。
Stripe Billing、Paddle Billing 和微信支付的产品能力都可能变化。正式接入前应重新核对账户地区、产品模式、支付方式、API 版本和服务条款。
MoR 不是免除全部责任:先划清交易边界
MoR 是在交易中作为记录商户的一方。Paddle 和 Lemon Squeezy 都以 Merchant of Record 模式销售符合其政策的数字产品,并在其交易范围内处理支付、销售税、退款或争议等工作。它降低了全球销售税和账单运营的复杂度,但不等于创作者或公司从此没有所得税、主体、产品合规、数据保护和会计责任。
Stripe 路线通常由商户自己作为记录商户。Stripe Tax 可以帮助计算 sales tax、VAT、GST,并提供阈值监控和注册相关工具,但它不把 Stripe 自动变成你的 MoR。实际注册、申报和主体责任应按所在地区与具体交易确认。
选择 MoR 时不要套用固定交易额阈值。更稳妥的比较维度是:
| 维度 | 自建支付与 billing stack | Merchant of Record |
|---|---|---|
| 定制能力 | 可以组合 Checkout、Billing、Tax、发票和内部流程 | 受平台商品政策、checkout、合同和结算规则约束 |
| 税务与账单运营 | 商户自行确认注册、申报、发票、退款和争议流程 | MoR 在约定交易范围内承担销售税、支付和部分合规工作 |
| 成本口径 | 支付费率之外还要计算税务工具、工程、财务与客服成本 | 不能只看平台费,还要看结算、退款、附加费用和平台限制 |
| 适用情况 | 需要强定制、已有运营能力或特殊合同流程 | 希望减少全球销售税和订阅运营负担,且产品符合平台政策 |
最终合同和税务责任高度依赖主体、地区、商品与客户类型。平台营销页只能说明产品定位,不能替代服务条款或专业建议。
Stripe、Paddle、Lemon Squeezy、微信支付怎么选
如果你想做订阅,又想覆盖微信支付,先把问题拆开:订阅生命周期、全球支付与中国境内支付不一定由同一个服务商完成。支付方式出现在某个平台,也不等于该方式支持所有账户地区、Checkout 模式或自动续费。
| 服务商 | 责任模式 | 订阅与一次性购买 | 中国支付场景 | 原生授权 | 更适合的起点 |
|---|---|---|---|---|---|
| Stripe | 支付、Billing、Tax 工具;通常不是 MoR | Checkout 与 Billing,定制空间大 | Alipay/WeChat Pay 受账户地区、币种和产品模式限制 | 无通用 License Key 产品 | 需要控制支付、订阅、税务工具和内部流程的 SaaS |
| Paddle | Merchant of Record | Paddle Billing 与 Checkout | 以 Dashboard 和当前文档的账户/地区支持为准 | 应用自行维护权益 | 希望降低全球销售税和订阅运营负担的软件业务 |
| Lemon Squeezy | Merchant of Record | 一次性数字产品、简单订阅与用量计费 | 一次性购买可显示 Alipay/WeChat Pay;订阅方式更受限 | License Keys | 数字产品、license 和早期订阅 |
| 微信支付 | 支付通道与商户系统 | JSAPI/H5/Native 等支付场景;计费生命周期需自建 | 中国境内与微信生态 | 无 | 人民币一次性购买或微信生态收款 |
截至 2026-07-18 的官方文档可确认:
- Stripe Checkout 支持托管页、嵌入式页面和可组合组件;支付方式会受地区、币种和 Checkout 模式影响。
- Paddle webhook 是 at-least-once delivery,若端点未在五秒内返回
200会重试;事件可能重复或乱序,应使用event_id去重,并参考occurred_at判断先后。 - Lemon Squeezy 当前列出 Cards、PayPal、Apple Pay、Google Pay、Alipay、WeChat Pay、Cash App Pay 和 bank debits,但订阅产品当前只支持 Cards、Apple Pay、Google Pay 和 PayPal。
- 微信支付 H5 流程需要后端下单、接收支付回调并主动查单确认状态,不能只信任浏览器回跳。
费率、支付方式、结算周期、支持国家和商品政策都可能变化。做最终预算时应打开当日官方定价与合同页面,而不是复制文章中的旧百分比。
Webhook 才是权益同步入口
两个常见反例:
checkout.session.completed已收到,success_url也跳转了,但entitlements没更新,用户付款后仍不能用。webhook_events表里同一个事件进来两次,处理器却重复发了两张 license。
这两个问题都来自同一个误区:把一次 HTTP 请求或成功页面当成最终业务事实。实际支付事件可能重复、乱序、延迟,某些状态还要通过查单或后续事件确认。
Webhook 端点设计原则
| 原则 | Stripe | Paddle | Lemon Squeezy | 微信支付 |
|---|---|---|---|---|
| HTTPS endpoint | 必须 | 必须 | 必须 | 必须 |
| 签名验证 | Stripe-Signature | Paddle-Signature | X-Signature | 微信支付 API v3 签名 |
| 幂等键 | event id 或业务对象 ID | event_id | 事件类型 + 对象 ID 或自定义唯一键 | out_trade_no 与平台交易号 |
| 响应策略 | 验签和落事件后尽快响应,再异步处理 | 五秒内返回 200 | 返回成功状态后异步处理 | 按当前 API 文档返回应答 |
| 补偿方式 | 查询支付/订阅状态 | 查询实体与 reconciliation | 查询订单/订阅状态 | 查单、对账与人工补单 |
核心原则:
- webhook 或支付回调才是权益同步入口,
success_url只用于显示“正在确认”,不直接开通权限。 - 先验签,再把事件原文或必要字段写入
webhook_events;复杂业务放入异步任务。 - 使用唯一约束保证幂等,记录
event_id、source、occurred_at、processed_at、status和payload_hash。 - 处理乱序时比较服务商事件发生时间、对象更新时间或状态版本,不按服务器收到请求的先后盲目覆盖。
- 定期 reconciliation,主动查询订单或订阅状态,并保留人工补单入口。
订单、订阅、权益与事件表
| 表名 | 核心字段 | Stripe 映射 | Paddle 映射 | Lemon Squeezy 映射 |
|---|---|---|---|---|
orders | provider_order_id, customer_id, amount, currency, status, created_at | Checkout Session / PaymentIntent | transaction | order |
subscriptions | provider_subscription_id, customer_id, status, current_period_end, cancel_at | subscription | subscription | subscription |
entitlements | user_id, product_id, feature_key, source, status, expires_at | 由订单或订阅派生 | 由 transaction/subscription 派生 | 由 order/subscription/license 派生 |
webhook_events | provider, event_id, occurred_at, processed_at, status, payload_hash | 幂等与审计 | 幂等与乱序判断 | 幂等与审计 |
本地字段不要照搬某一家 API 的全部对象。先确定访问判断需要哪些稳定字段,再保存服务商对象 ID,以便查单和 reconciliation。
权益同步策略
| 策略 | 适用场景 | 实现要点 |
|---|---|---|
| Lean cache | 大多数订阅 SaaS | 只存访问判断需要的 customer、subscription、status、price 和 product 字段;以服务商事件持续更新。 |
| State mirror | 需要离线账单展示或复杂运营后台 | 复制更完整的订阅数据,同时记录更新时间并运行 reconciliation,避免本地镜像漂移。 |
| License key | 一次性数字产品或桌面软件 | 激活后保存实例 ID,验证 store、product、variant 和 customer 映射,不能把 license key 当成完整用户系统。 |
Paddle 的官方 provisioning 文档推荐多数应用从 lean cache 开始;需要更完整本地查询时再使用 state mirror。Lemon Squeezy license key 也需要应用端验证产品与客户信息,并把实例映射到自己的账户和设备模型。
各服务商接入要点
以下内容给出第一版接入边界,不替代各平台的完整代码教程。
Stripe 接入要点
早期 SaaS 可以从托管 Checkout + Customer Portal 开始,避免先维护自定义卡表单。Stripe Billing 负责订阅、发票、用量计费和收入恢复等生命周期能力;Stripe Tax 是税务计算和流程工具,不是 Merchant of Record。
产品和价格要映射到本地权益:product_id 表示产品或权益包,price_id 表示月付、年付、seat 或 usage 模型。不要只在 users 上保留一个 is_paid。
可继续阅读 Next.js 电商购物车与 Stripe 支付教程,其中包含 Checkout Session、webhook endpoint 与订单处理示例。
Paddle 接入要点
先确认教程针对 Paddle Billing,而不是 Paddle Classic。两者的 API、webhook、Paddle.js 和 Product/Price 模型不同。
Paddle Checkout 负责呈现收银台,应用仍负责 provisioning。多数应用只需保存 customer、subscription、status、price、product 与 scheduled change 等访问相关字段;如果运营后台确实需要完整账单数据,再建立 state mirror。
无论采用哪种缓存,都要通过 webhook 更新并运行 reconciliation,不能认为接入 MoR 后应用会自动知道谁能使用什么功能。
Lemon Squeezy 接入要点
Lemon Squeezy 适合早期数字产品、license 和相对简单的订阅。它提供 Merchant of Record、checkout、订阅、usage-based billing、webhook 与 License Keys,但具体费用和支持方式应以当前 store plan 与官方文档为准。
License key 激活后要保存实例 ID,并校验 store_id、product_id、variant_id 和 customer;不要让另一个产品的 key 或转卖 key 直接映射到 Pro 权益。
如果目标是微信支付订阅,必须单独核对订阅支付方式。当前文档中 WeChat Pay 和 Alipay 属于可用支付方式,但订阅产品只支持 Cards、Apple Pay、Google Pay 和 PayPal。
微信支付边界
微信支付适合中国境内或微信生态收款,但它不是全球 Merchant of Record,也不替你提供完整 SaaS billing lifecycle。商户仍需建立订单状态机、回调验签、查单、退款、对账、发票和权益同步流程。
H5、JSAPI、小程序和 Native 是不同支付场景,不是不同订阅系统。以 H5 为例,后端下单后把 h5_url 交给前端拉起支付;浏览器返回页面后仍应由后端查单,并用支付回调更新同一笔 out_trade_no 对应的订单。
具体产品权限、商户主体、域名、费率和 API 参数以微信支付商户平台当前文档为准。
下一步:把支付按钮变成可验收的状态机
选好服务商后,把接入任务拆成可验证的工程清单:
- 建立
orders、subscriptions、entitlements和webhook_events;有用量计费时增加usage_events。 - 为每个 webhook 或支付回调实现验签、幂等、乱序处理、快速应答和失败重试。
- 把成功页面改成查询本地订单状态,而不是直接写入
is_paid=true。 - 增加查单、reconciliation、退款、续费失败和人工补单的测试用例。
- 在沙箱中重复发送事件、倒序发送状态更新,并验证权益不会重复发放或错误回退。
后端承载位置和数据库选型可继续参考 Supabase Edge Functions 实战 与本系列的后端、数据库文章。真正的完成标准不是支付页成功跳转,而是订单、订阅和权益在重复、延迟、乱序与退款场景下仍能收敛到正确状态。
一人公司支付系统选型与落地步骤
从售卖模型、责任边界和目标市场出发,确定支付服务商并建立可审计的权益同步链路。
⏱️ 预计耗时: 45 分钟
- 1
步骤 1: 确认售卖模型
先写清楚产品是一次性购买、订阅 SaaS、用量计费还是混合模式,并列出退款、续费、升级降级和访问截止规则。 - 2
步骤 2: 划分税务与运营责任
决定自己组合支付、Billing 与 Tax 工具,还是采用 Merchant of Record;具体税务和主体问题以服务商条款与专业意见为准。 - 3
步骤 3: 按市场选择支付通道
全球卡支付和订阅评估 Stripe、Paddle、Lemon Squeezy;中国境内或微信生态的一次性购买评估微信支付,并逐项核对账户地区、品类和支付方式支持。 - 4
步骤 4: 建立本地状态模型
创建 orders、subscriptions、entitlements 和 webhook_events,使用服务商事件或订单 ID 唯一约束承载幂等和审计。 - 5
步骤 5: 验收异步权益同步
验证签名、重复事件、乱序、超时、退款、续费失败与人工补单路径;成功页只展示处理状态,不直接授予权限。
常见问题
Stripe、Paddle 和 Lemon Squeezy 的核心区别是什么?
一人公司早期应该先选 MoR 还是 Stripe?
Paddle 或 Lemon Squeezy 会自动给用户开通 SaaS 权限吗?
Lemon Squeezy 支持微信支付,是否就能做微信支付订阅?
微信支付能替代 Stripe 做全球 SaaS billing 吗?
webhook 重复、乱序或漏发怎么办?
个人开发者最小支付系统需要哪些表?
12 分钟阅读 · 发布于: 2026年10月21日



评论
使用 GitHub 账号登录后即可评论