mcpField
L
laravel-billing

laravel-billing

github.com/fusengine開発3457 回インストール2 週間前に更新
リポジトリ

laravel-billing について

StripeまたはPaddleを使った課金実装を扱う、Laravel Cashier向けのスキルです。サブスクリプション、決済フロー、安全対策、SaaS課金パターンに加え、FuseCoreとの連携も説明します。

主な機能

  1. 01StripeとPaddleの選択指針
  2. 02サブスクリプションのライフサイクルとトライアル
  3. 03Webhook処理と署名検証
  4. 04チェックアウト、請求書、支払い方法
  5. 05従量課金、チーム課金、プラン別課金
  6. 06FuseCore連携の参考資料とテンプレート

活用シーン

  1. 01Laravelアプリへのサブスクリプション導入
  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

詳細

Stripe と Paddle 向けの Laravel Cashier を解説します。両者の選択(決済プロセッサーと Merchant of Record、税務処理、手数料)、サブスクリプションのライフサイクル(作成、プラン変更、キャンセル、再開、トライアル、猶予期間)、Webhook と署名検証、請求書、支払い方法、チェックアウト/カスタマーポータル、従量課金、チーム/ユーザー単位の課金、督促(支払い失敗からの回復)、プランごとの Pennant ベースの機能フラグが含まれます。FuseCore のモジュール型プロジェクトとの統合にも対応しています。複数ベンダー/マーケットプレイスの分割決済については、代わりに laravel-stripe-connect をご覧ください。

Laravel Billing(Cashier)

エージェントのワークフロー(必須)

実装の前に、必ず 3 つのエージェントを並行して起動します。それぞれ name を指定して Agent を 1 回呼び出してください。

  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税務処理、コンプライアンス、グローバル販売
主な違い:MoR と決済プロセッサー
項目StripePaddle
種類決済プロセッサーMerchant of Record
税金自社で管理(または Stripe Tax)Paddle が自動管理
請求書自社の会社名Paddle と自社の名前
コンプライアンス自社の責任Paddle が対応
手数料約 2.9% + $0.30約 5% + $0.50(すべて込み)

重要なルール

  1. Webhook を使用する - クライアント側の確認に依存しないでください
  2. 猶予期間を処理する - サブスクリプションが終了するまではアクセスを許可してください
  3. カード情報を保存しない - 支払いトークン/支払い方法を使用してください
  4. テストキーでテストする - 本番環境に移行する前に必ずテストしてください
  5. Webhook の署名を検証する - なりすまし攻撃を防止します
  6. 未完了の支払いを処理する - 3D セキュアではユーザーの操作が必要です

アーキテクチャ

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/ モジュールに配置する
  • /FuseCore/User/ の User モデルに Billable トレイトを追加する
  • Webhook のルートを /FuseCore/Billing/Routes/web.php に配置する
  • preventRequestForgery(except: [...]) を使って CSRF から Webhook を除外する(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

主な概念

概念説明参照先
Billableモデルで課金を有効にするトレイトstripe.md
サブスクリプション定期的な課金サイクルsubscriptions.md
Price IDStripe/Paddle の価格識別子stripe.md
猶予期間キャンセル後もアクセスできる期間subscriptions.md
Webhookサーバー間の支払い通知webhooks.md
カスタマーポータルセルフサービスでの課金管理checkout.md

リファレンスガイド

概念(理由とアーキテクチャ)
トピックリファレンス参照するタイミング
Stripe Cashierstripe.mdStripe のセットアップ、設定
Paddle Cashierpaddle.mdPaddle のセットアップ、相違点
サブスクリプションsubscriptions.md作成、キャンセル、プラン変更、一時停止
Webhookwebhooks.mdWebhook のセキュリティ、処理
請求書invoices.mdPDF の生成、領収書
支払い方法payment-methods.mdカード、ウォレット、更新
チェックアウトcheckout.mdホスト型チェックアウト、ポータル
テストtesting.mdテストカード、Webhook のテスト
高度な SaaS 機能
トピックリファレンス参照するタイミング
従量課金metered-billing.md使用量ベースの料金設定(API、ストレージ)
チーム課金team-billing.md組織の課金、ユーザーごとの料金設定
督促dunning.md失敗した支払いの回収
機能フラグfeature-flags.mdプランに応じた機能アクセス
テンプレート(完全なコード)
テンプレート使用するタイミング
UserBillable.php.mdBillable トレイトを持つユーザーモデル
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.mdプランごとの Laravel 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/*',
    ]);
})

コメント