2026-03-31 打卡(第 28 次)
1. 今天学了什么 / 做了哪些具体操作
PayPal → Lemon Squeezy 支付系统迁移(全天核心工作)
为什么放弃 PayPal:
- PayPal 沙箱环境对中国用户极度不友好:登录后自动跳转 paypal.cn,沙箱支付流程无法走通;沙箱账户不能用卖家账户测试付款;Client ID/Secret 认证失败(401 invalid_client)
paypal.Buttons是构造函数,不能直接当对象调render(),未登录时只显示错误文字不跳转
为什么选 Lemon Squeezy:
- 个人开发者可用,不需要公司主体
- MoR(Merchant of Record)模式,自动处理全球税务
- 支持信用卡 + PayPal,自带订阅管理、优惠券、License Key
- 集成简单 — 一个 Checkout URL 搞定支付
Lemon Squeezy 账号配置:
- 注册并创建 Store(ID: 331780),货币从 CNY 改为 USD
- API Key 保存到
config/lemonsqueezy.json - 创建 3 个产品(Test Mode):
- AI Humanizer Basic $6/月(Variant 1469206)— 20,000 词/月
- AI Humanizer Pro $15/月(Variant 1469239)— 100,000 词/月
- AI Humanizer Lifetime $49 一次性(Variant 1469240)— 500,000 词
代码改动(11 个文件):
- 新增
lib/lemonsqueezy.ts— LS API 封装(createCheckout) - 新增
app/api/checkout/route.ts— 创建 checkout 并返回跳转 URL - 新增
app/api/webhook/route.ts— 接收 LS 支付通知,更新 D1 用户 credits - 新增
components/ui/checkout-button.tsx— 替代 PayPalButton - 更新
pricing-section.tsx— 已购套餐判断逻辑 + 字数计费 UI - 更新
humanize/route.ts— 按输入字数扣 credits(1 credit = 1 word) - 更新
db.ts— 注册免费额度从 5 次 → 3,000 词 - 更新
dashboard/page.tsx— "Credits" → "Words Remaining",千位分隔符 - 更新
humanize/page.tsx— 注册引导文案改为 3,000 free words - 简化
success/page.tsx— LS 处理支付,webhook 自动加 credits - 支付页面强制
locale: "en"避免自动跳其他国家语言
完整支付流程:
用户点击按钮 → 检查登录(未登录跳 Google 登录,callbackUrl 回 pricing)→
调 /api/checkout → LS API 创建 checkout → 返回 checkout URL →
浏览器跳转 LS 支付页(英文界面)→ 用户付款 →
LS 发 webhook → /api/webhook 更新 D1(plan + credits)→
LS 跳转 /success 页面
Webhook 事件处理(7 个事件全覆盖):
order_created→ 一次性付款成功,加 credits + 更新 plansubscription_created→ 首次订阅,加 credits + 更新 plansubscription_payment_success→ 每月续费,再加 credits(自动续额度)subscription_payment_failed→ 续费失败,记录日志,保留现有 creditssubscription_cancelled→ 取消,记录日志,保留到过期subscription_expired→ 过期,降级为 freeorder_refunded→ 退款,扣除对应 credits
Pricing 页面逻辑:
- 未登录 → 按钮正常显示,点击跳 Google 登录
- 当前 Pro → Basic 禁用(Downgrade),Pro 显示 Active,Lifetime 可买升级
- 当前 Lifetime → 全部禁用(Already Lifetime)
- 当前 Basic → Pro 可买升级,Lifetime 可买升级
- 当前套餐绿色高亮 + "Current Plan" 标签
竞品定价调研
- 调研了 Undetectable.ai、StealthWriter、QuillBot、Jasper 等产品
- 行业共识:全部用月订阅 + 字数额度制,没有按量付费的
- Undetectable.ai: 19/月(20K词) → $31/月(35K词),年付 5 折
- 原因:用户心智明确、API 成本可控、订阅 LTV 远高于按量付费
成本核算(GLM-4-Plus)
- 系统提示 ~2,500 tokens + 输入输出按字数计
- 每千词成本:¥0.0015($0.0002)
- 毛利率 99%+,LLM 成本极低
- 如果切 Gemini Flash(免费额度大)成本趋近于零
最终定价方案
| 方案 | 价格 | 额度 | 竞品对比 | |---|---|---|---| | Basic | 9.99/10K词 | | Pro | 19/20K词 | | Lifetime | 0 | 3,000 词(注册送) | — |
定价策略:低价获客,额度比竞品大 3-5 倍,价格低 30-50%;早期冲用户量;老用户锁定低价;Lifetime 限 50 万词防滥用;按量扣费 1 credit = 1 word。
测试结果
- ✅ Test Mode 支付成功(测试卡 4242 4242 4242 4242)
- ✅ Webhook 已配置(ID: 86412),8 个事件全部注册
- ✅ 首次购买后 plan 从 free 更新为 pro,credits +500
- ✅ Pricing 页面已购套餐逻辑正常
- ✅ 支付页面强制英文,不再跳其他国家语言
- ✅ 字数计费模式已部署
2. 解决了什么问题 / 有什么新认识 / 哪些地方需要改进
解决的问题:
- PayPal 沙箱在中国不可用 → 切换到 Lemon Squeezy,个人开发者友好
- 按次计费不够灵活 → 改为按字数计费(1 credit = 1 word),行业主流做法
- Pricing 页面没有已购套餐判断 → 加了完整的升降级逻辑
新认识:
- MoR 模式对个人出海开发者价值巨大:不需要公司主体就能全球收款,自动处理税务、发票、合规
- LLM 成本远低于预期:GLM-4-Plus 每千词 $0.0002,毛利率 99%+,定价空间非常大
- 竞品定价有明确规律:头部产品全部用订阅 + 额度制,因为 LTV 远高于按量付费
- Lemon Squeezy 的几个坑:Store 默认 CNY 需手动改 USD;API 不支持创建产品只能 Dashboard 操作;Test/Live Mode 完全隔离;价格单位是美分不是美元;产品需 publish 才能在 Live Mode 使用
需要改进:
- 部署后不自测就通知用户 — 连续两次部署有 bug 都是用户测出来的,以后必须用 Playwright/curl 冒烟测试再通知
- CF Pages 环境变量 PATCH 是全量替换 — secret 类型变量读不出来无法全量 PATCH,差点再踩一次
- Webhook 签名验证不完整 — 目前只检查 header 存在,不安全,上线前必须补上
3. 收获
- 完整跑通了「选支付平台 → 注册配置 → API 集成 → Webhook 全事件处理 → 测试验证」的支付闭环,这是出海变现最关键的一步
- 掌握了竞品定价调研的方法论:找头部产品 → 拆解定价结构 → 算自己的成本 → 定差异化策略
- 深入理解了 MoR(Merchant of Record)模式对个人开发者的价值
- 学会了 Lemon Squeezy 的完整接入流程和踩坑经验
4. 接下来要学什么 / 做什么(可执行的规划)
- [ ] Webhook 签名验证:用 LS 的签名密钥验证 webhook 真实性,防止伪造请求
- [ ] 切 Live Mode:生成 Live API Key,publish 3 个产品(Basic/Pro/Lifetime),替换代码中的 Test API Key
- [ ] 清理 PayPal 残留代码:删除
lib/paypal.ts、app/api/paypal/*、components/ui/paypal-button.tsx - [ ] Lifetime variant 修正:在 LS Dashboard 把 interval 从 year 改为 one-time
- [ ] SEO 优化:生成 sitemap.xml,补全各页面 meta tags(title/description/OG/Twitter Card)
- [ ] Product Hunt 发布准备:准备文案、截图、tagline,研究发布时机