mcpField
L
laravel-billing

laravel-billing

github.com/fusengine开发3457 次安装2 周前更新
代码仓库

关于 laravel-billing

这项技能介绍如何用 Laravel Cashier 和 Stripe 或 Paddle 实现计费,面向 Laravel 开发者。内容涵盖订阅、支付流程、安全处理及 SaaS 计费模式,也包括 FuseCore 集成。

主要功能

  1. 01Stripe 与 Paddle 选择指引
  2. 02订阅生命周期与试用管理
  3. 03Webhook 处理与签名验证
  4. 04结账、发票和支付方式
  5. 05按用量、团队及套餐计费
  6. 06FuseCore 集成参考与模板

适用场景

  1. 01在 Laravel 应用中实现订阅
  2. 02安全处理支付 Webhook
  3. 03添加按用量或按席位计费
  4. 04处理失败付款并按套餐控制功能

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/fusengine/agents --skill laravel-billing

安装后在 Claude Code 中输入/laravel-billing确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
checkout.md
dunning.md
feature-flags.md
invoices.md
metered-billing.md
paddle.md
payment-methods.md
stripe.md
subscriptions.md
team-billing.md
testing.md
webhooks.md
references/templates/
BillingRoutes.php.md
CheckoutController.php.md
DunningService.php.md
FeatureFlags.php.md
InvoiceController.php.md
MeteredBillingController.php.md
SubscriptionController.php.md
SubscriptionTest.php.md
TeamBillable.php.md
UserBillable.php.md
WebhookController.php.md

详细介绍

涵盖 Laravel Cashier for Stripe 和 Paddle:如何在两者之间选择 (支付处理商还是名义商户、税务处理、费用)、订阅生命周期(创建、 切换、取消、恢复、试用期、宽限期)、Webhook 和签名验证、发票、支付 方式、结账/客户门户、按量计费、团队/按席位计费、催缴(失败付款 补救),以及基于 Pennant 的计划功能标志。包含 FuseCore 模块化项目集成。对于多供应商/市场拆分付款,请改用 laravel-stripe-connect。

Laravel 账单(Cashier)

Agent 工作流(必须遵循)

在进行任何实现之前,并行启动 3 个 Agent,每个 Agent 调用各一次,并指定 name:

  1. fuse-ai-pilot:explore-codebase - 检查现有账单设置和 User 模型
  2. fuse-ai-pilot:research-expert - 通过 Context7 核实最新 Cashier 文档
  3. mcp__context7__query-docs - 查询特定模式(Stripe/Paddle)

实现完成后,运行 fuse-ai-pilot:sniper 进行验证。


概览

Laravel Cashier 提供基于 Stripe 或 Paddle 的订阅账单功能。根据需求选择:

提供商包最适合
Stripelaravel/cashier完全控制、高交易量、复杂账单
Paddlelaravel/cashier-paddle税务处理、合规、全球销售
主要区别:名义商户与支付处理商
方面StripePaddle
类型支付处理商名义商户
税费由你管理(或使用 Stripe Tax)Paddle 自动管理
发票你的公司名称Paddle + 你的名称
合规由你负责由 Paddle 处理
费用约 2.9% + $0.30约 5% + $0.50(全包)

关键规则

  1. 使用 Webhook - 切勿依赖客户端确认
  2. 处理宽限期 - 在订阅结束前允许访问
  3. 切勿存储银行卡详情 - 使用支付令牌/支付方式
  4. 使用测试密钥进行测试 - 始终在上线前测试
  5. 验证 Webhook 签名 - 防止伪造攻击
  6. 处理未完成的付款 - 3D Secure 需要用户操作

架构

app/
├── Http/
│   ├── Controllers/
│   │   └── Billing/              ← Billing controllers
│   │       ├── SubscriptionController.php
│   │       ├── CheckoutController.php
│   │       └── InvoiceController.php
│   └── Middleware/
│       └── EnsureSubscribed.php  ← Subscription check
├── Models/
│   └── User.php                  ← Billable trait
├── Listeners/
│   └── StripeEventListener.php   ← Webhook handling
└── Services/
    └── BillingService.php        ← Business logic

config/
├── cashier.php                   ← Stripe/Paddle config
└── services.php                  ← API keys

routes/
└── web.php                       ← Webhook routes (excluded from CSRF)

FuseCore 集成

在 FuseCore 项目中处理账单时,请遵循模块化结构:

FuseCore/
├── Core/                         # Infrastructure (priority 0)
│   └── App/Contracts/
│       └── BillingServiceInterface.php  ← Billing contract
│
├── User/                         # Auth module (existing)
│   └── App/Models/User.php       ← Add Billable trait here
│
├── Billing/                      # Billing module (new)
│   ├── App/
│   │   ├── Http/
│   │   │   ├── Controllers/
│   │   │   │   ├── SubscriptionController.php
│   │   │   │   ├── CheckoutController.php
│   │   │   │   └── WebhookController.php
│   │   │   └── Middleware/
│   │   │       └── EnsureSubscribed.php
│   │   ├── Listeners/
│   │   │   └── HandleWebhookEvents.php
│   │   └── Services/
│   │       └── BillingService.php
│   ├── Config/
│   │   └── cashier.php           ← Module-level config
│   ├── Database/Migrations/
│   ├── Routes/
│   │   ├── web.php               ← Webhooks (no CSRF)
│   │   └── api.php               ← Subscription management
│   └── module.json               # dependencies: ["User"]
FuseCore 账单检查清单
  • 账单代码位于 /FuseCore/Billing/ 模块中
  • User 模型(位于 /FuseCore/User/)使用 Billable trait
  • Webhook 路由位于 /FuseCore/Billing/Routes/web.php
  • 通过 preventRequestForgery(except: [...]) 将 Webhook 从 CSRF 检查中排除(L13 PreventRequestForgery)
  • 在 module.json 中声明 "User" 依赖项

→ 完整的模块模式请参阅 fusecore skill。


决策指南

Stripe 与 Paddle
Selling to businesses (B2B)? → Stripe
├── Need OAuth for third-party apps? → Stripe Connect
└── Selling to consumers (B2C) globally?
    ├── Want to handle taxes yourself? → Stripe + Stripe Tax
    └── Want tax compliance handled? → Paddle
订阅与一次性付款
Recurring revenue? → Subscription
├── Fixed plans? → Single-price subscription
└── Usage-based? → Metered billing (Stripe) or quantity-based
Single purchase? → One-time charge
├── Digital product? → Checkout session
└── Service fee? → Direct charge

核心概念

概念说明参考
可计费为模型启用账单功能的 traitstripe.md
订阅循环计费周期subscriptions.md
价格 IDStripe/Paddle 价格标识符stripe.md
宽限期取消后仍可访问的时段subscriptions.md
Webhook服务器到服务器的付款通知webhooks.md
客户门户自助式账单管理checkout.md

参考指南

概念(原因与架构)
主题参考资料适用场景
Stripe Cashierstripe.md设置和配置 Stripe
Paddle Cashierpaddle.md设置 Paddle、了解差异
订阅subscriptions.md创建、取消、更换、暂停
Webhookwebhooks.mdWebhook 安全、处理
发票invoices.md生成 PDF、收据
支付方式payment-methods.md卡片、电子钱包、更新
结账checkout.md托管结账、门户
测试testing.md测试卡、Webhook 测试
高级 SaaS 功能
主题参考资料适用场景
按用量计费metered-billing.md基于用量定价(API、存储)
团队计费team-billing.md组织计费、按席位计费
催收dunning.md追回失败的付款
功能标志feature-flags.md基于方案的功能访问
模板(完整代码)
模板使用场景
UserBillable.php.md带有 Billable trait 的用户模型
SubscriptionController.php.md订阅 CRUD 操作
WebhookController.php.md自定义 Webhook 处理
CheckoutController.php.mdStripe Checkout + Portal
InvoiceController.php.md下载发票
BillingRoutes.php.md完整路由定义
SubscriptionTest.php.md计费 Pest 测试
MeteredBillingController.php.md用量跟踪与报告
TeamBillable.php.md带有席位管理的团队模型
DunningService.php.md自动化付款追回
FeatureFlags.php.mdLaravel Pennant 按方案配置功能

快速参考

检查订阅状态
// Has active subscription?
$user->subscribed('default');

// Subscribed to specific price?
$user->subscribedToPrice('price_premium', 'default');

// On trial?
$user->onTrial('default');

// Cancelled but still active?
$user->subscription('default')->onGracePeriod();
创建订阅
// Simple subscription
$user->newSubscription('default', 'price_monthly')
    ->create($paymentMethodId);

// With trial
$user->newSubscription('default', 'price_monthly')
    ->trialDays(14)
    ->create($paymentMethodId);
管理订阅
$subscription = $user->subscription('default');

// Change plan
$subscription->swap('price_yearly');

// Cancel at period end
$subscription->cancel();

// Cancel immediately
$subscription->cancelNow();

// Resume cancelled subscription
$subscription->resume();
计费门户
// Redirect to customer portal (Stripe)
return $user->redirectToBillingPortal(route('dashboard'));

// Get portal URL
$url = $user->billingPortalUrl(route('dashboard'));

最佳实践

应该做
  • 使用 Webhook 确认付款
  • 为已取消的订阅设置宽限期
  • 设置 Webhook 签名验证
  • 处理 IncompletePayment 异常
  • 使用 Stripe CLI 在本地测试
  • 定期清理旧数据
不应该做
  • 信任客户端付款确认
  • 存储银行卡号(PCI 合规)
  • 跳过 Webhook 验证
  • 忽略付款失败的 Webhook
  • 忘记处理 3D Secure
  • 将价格硬编码(使用 env 或配置)

Laravel 13 注意事项

Cashier Stripe 16.x(当前版本为 16.8)和 Cashier Paddle 2.x(当前版本为 2.8)兼容 Laravel 13。注意事项:

  • Webhook:新的 [[laravel-auth]] PreventRequestForgery CSRF 保护必须通过 preventRequestForgery(except: [...]) 将 Webhook 路由(stripe/webhook、paddle/webhook)排除在外
  • cache.serializable_classes(L13 中默认为 false):如果缓存 Cashier 对象,请明确列出类
  • PHP:Cashier 支持 PHP 8.1+,但 Laravel 13 要求 PHP 版本至少为 8.3
// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
    $middleware->preventRequestForgery(except: [
        'stripe/*', 'paddle/*',
    ]);
})

评论

支持 Markdown