Creem 是一个专为独立开发者和小团队设计的支付平台,类似于 LemonSqueezy、Paddle。主打简单易用,帮助开发者快速接入支付功能,无需担心税务合规问题。
为什么选择 Creem#
| 特性 | 说明 |
|---|---|
| 开发者友好 | 简洁的 API,快速集成 |
| 税务托管 | 自动处理增值税、销售税 |
| 无主体限制 | 个人开发者可直接使用 |
| 全球支付 | 支持多种货币和支付方式 |
| 订阅管理 | 内置订阅计费功能 |
快速开始#
1. 注册账户#
- 访问 creem.io
- 创建账户并完成验证
- 添加收款方式(银行账户/PayPal)
2. 创建产品#
Dashboard → Products → Create Product
名称: Pro Plan描述: 专业版订阅定价: $19/月类型: 订阅 或 一次性3. 获取 API 密钥#
Settings → API Keys
API Key: creem_xxxxxWebhook Secret: whsec_xxxxxCheckout 集成#
创建 Checkout 会话#
export async function POST(req: Request) { const { productId, email } = await req.json()
const response = await fetch('https://api.creem.io/v1/checkouts', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.CREEM_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ product_id: productId, customer_email: email, success_url: `${process.env.NEXT_PUBLIC_URL}/success`, cancel_url: `${process.env.NEXT_PUBLIC_URL}/cancel`, }), })
const data = await response.json() return Response.json({ url: data.url })}客户端跳转#
async function handleCheckout() { const response = await fetch('/api/checkout', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ productId: 'prod_xxx', email: user.email, }), })
const { url } = await response.json() window.location.href = url}Checkout 链接#
也可以直接使用产品的 Checkout 链接:
https://checkout.creem.io/p/prod_xxx?email=user@example.com订阅管理#
获取订阅状态#
async function getSubscription(subscriptionId: string) { const response = await fetch( `https://api.creem.io/v1/subscriptions/${subscriptionId}`, { headers: { Authorization: `Bearer ${process.env.CREEM_API_KEY}`, }, } )
return response.json()}取消订阅#
async function cancelSubscription(subscriptionId: string) { await fetch( `https://api.creem.io/v1/subscriptions/${subscriptionId}/cancel`, { method: 'POST', headers: { Authorization: `Bearer ${process.env.CREEM_API_KEY}`, }, } )}客户门户#
让用户自助管理订阅:
async function getPortalUrl(customerId: string) { const response = await fetch( 'https://api.creem.io/v1/billing-portal/sessions', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.CREEM_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ customer_id: customerId, return_url: `${process.env.NEXT_PUBLIC_URL}/account`, }), } )
const data = await response.json() return data.url}Webhook 处理#
配置 Webhook#
Settings → Webhooks → Add Endpoint
URL: https://your-domain.com/api/webhookEvents: checkout.completed, subscription.updated, ...处理事件#
import crypto from 'crypto'
export async function POST(req: Request) { const body = await req.text() const signature = req.headers.get('creem-signature')
// 验证签名 const expectedSignature = crypto .createHmac('sha256', process.env.CREEM_WEBHOOK_SECRET!) .update(body) .digest('hex')
if (signature !== expectedSignature) { return new Response('Invalid signature', { status: 400 }) }
const event = JSON.parse(body)
switch (event.type) { case 'checkout.completed': await handleCheckoutCompleted(event.data) break
case 'subscription.created': await handleSubscriptionCreated(event.data) break
case 'subscription.updated': await handleSubscriptionUpdated(event.data) break
case 'subscription.canceled': await handleSubscriptionCanceled(event.data) break
case 'payment.failed': await handlePaymentFailed(event.data) break }
return new Response('OK')}常用事件#
| 事件 | 触发时机 |
|---|---|
| checkout.completed | 支付成功 |
| subscription.created | 新建订阅 |
| subscription.updated | 订阅更新 |
| subscription.canceled | 订阅取消 |
| payment.succeeded | 付款成功 |
| payment.failed | 付款失败 |
实战示例#
Next.js 完整集成#
const CREEM_API_URL = 'https://api.creem.io/v1'
export async function createCheckout(productId: string, email: string) { const response = await fetch(`${CREEM_API_URL}/checkouts`, { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.CREEM_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ product_id: productId, customer_email: email, success_url: `${process.env.NEXT_PUBLIC_URL}/success`, cancel_url: `${process.env.NEXT_PUBLIC_URL}/pricing`, }), })
if (!response.ok) { throw new Error('Failed to create checkout') }
return response.json()}
export async function getCustomerSubscriptions(customerId: string) { const response = await fetch( `${CREEM_API_URL}/customers/${customerId}/subscriptions`, { headers: { Authorization: `Bearer ${process.env.CREEM_API_KEY}`, }, } )
return response.json()}定价页面#
'use client'
import { useState } from 'react'
const plans = [ { id: 'prod_free', name: 'Free', price: 0, features: ['基础功能'] }, { id: 'prod_pro', name: 'Pro', price: 19, features: ['全部功能', '优先支持'] },]
export default function PricingPage() { const [loading, setLoading] = useState<string | null>(null)
async function handleSubscribe(productId: string) { setLoading(productId)
const response = await fetch('/api/checkout', { method: 'POST', body: JSON.stringify({ productId }), })
const { url } = await response.json() window.location.href = url }
return ( <div className="grid grid-cols-2 gap-4"> {plans.map((plan) => ( <div key={plan.id} className="border p-6 rounded-lg"> <h3>{plan.name}</h3> <p>${plan.price}/月</p> <ul> {plan.features.map((f) => ( <li key={f}>{f}</li> ))} </ul> <button onClick={() => handleSubscribe(plan.id)} disabled={loading === plan.id} > {loading === plan.id ? '处理中...' : '订阅'} </button> </div> ))} </div> )}Creem vs LemonSqueezy vs Paddle#
| 特性 | Creem | LemonSqueezy | Paddle |
|---|---|---|---|
| 目标用户 | 独立开发者 | 独立开发者 | SaaS 公司 |
| 费率 | 5% + $0.5 | 5% + $0.5 | 5-8% |
| 税务处理 | ✅ | ✅ | ✅ |
| 订阅管理 | ✅ | ✅ | ✅ |
| 客户门户 | ✅ | ✅ | ✅ |
| API 复杂度 | 简单 | 中等 | 复杂 |
| 文档质量 | 好 | 优秀 | 优秀 |
选择建议:
- 快速上手、个人项目 → Creem
- 功能完整、社区活跃 → LemonSqueezy
- 企业级、复杂需求 → Paddle
最佳实践#
1. 存储客户信息#
// 在数据库中关联 Creem 客户 IDawait db.user.update({ where: { id: userId }, data: { creemCustomerId: event.data.customer_id, subscriptionId: event.data.subscription_id, subscriptionStatus: 'active', },})2. 处理支付失败#
async function handlePaymentFailed(data) { // 发送提醒邮件 await sendEmail(data.customer_email, { subject: '支付失败提醒', body: '您的订阅付款失败,请更新支付方式。', })
// 更新用户状态 await db.user.update({ where: { creemCustomerId: data.customer_id }, data: { subscriptionStatus: 'past_due' }, })}3. 验证 Webhook 签名#
始终验证签名,防止伪造请求。
常见问题#
支持哪些支付方式?#
- 信用卡/借记卡
- Apple Pay / Google Pay
- PayPal(部分地区)
如何处理退款?#
Dashboard 中手动处理,或通过 API:
await fetch(`https://api.creem.io/v1/payments/${paymentId}/refund`, { method: 'POST', headers: { Authorization: `Bearer ${process.env.CREEM_API_KEY}`, },})收款周期是多久?#
通常 7-14 个工作日到账,具体取决于收款方式。