laravel-billing

Laravel Billing (Cashier)

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "laravel-billing" with this command: npx skills add fusengine/agents/fusengine-agents-laravel-billing

Laravel Billing (Cashier)

Agent Workflow (MANDATORY)

Before ANY implementation, use TeamCreate to spawn 3 agents:

  • fuse-ai-pilot:explore-codebase - Check existing billing setup, User model

  • fuse-ai-pilot:research-expert - Verify latest Cashier docs via Context7

  • mcp__context7__query-docs - Query specific patterns (Stripe/Paddle)

After implementation, run fuse-ai-pilot:sniper for validation.

Overview

Laravel Cashier provides subscription billing with Stripe or Paddle. Choose based on your needs:

Provider Package Best For

Stripe laravel/cashier

Full control, high volume, complex billing

Paddle laravel/cashier-paddle

Tax handling, compliance, global sales

Key Difference: MoR vs Payment Processor

Aspect Stripe Paddle

Type Payment Processor Merchant of Record

Taxes You manage (or Stripe Tax) Paddle manages automatically

Invoices Your company name Paddle + your name

Compliance Your responsibility Paddle handles

Fees ~2.9% + $0.30 ~5% + $0.50 (all-inclusive)

Critical Rules

  • Use webhooks - Never rely on client-side confirmations

  • Handle grace periods - Allow access until subscription ends

  • Never store card details - Use payment tokens/methods

  • Test with test keys - Always before production

  • Verify webhook signatures - Prevent spoofing attacks

  • Handle incomplete payments - 3D Secure requires user action

Architecture

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 Integration

When working in a FuseCore project, billing follows the modular structure:

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 Billing Checklist

  • Billing code in /FuseCore/Billing/ module

  • Billable trait on User model in /FuseCore/User/

  • Webhook routes in /FuseCore/Billing/Routes/web.php

  • Exclude webhook from CSRF in VerifyCsrfToken

  • Declare "User" dependency in module.json

→ See fusecore skill for complete module patterns.

Decision Guide

Stripe vs 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

Subscription vs One-Time

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

Key Concepts

Concept Description Reference

Billable Trait that enables billing on a model stripe.md

Subscription Recurring billing cycle subscriptions.md

Price ID Stripe/Paddle price identifier stripe.md

Grace Period Time after cancellation with access subscriptions.md

Webhook Server-to-server payment notifications webhooks.md

Customer Portal Self-service billing management checkout.md

Reference Guide

Concepts (WHY & Architecture)

Topic Reference When to Consult

Stripe Cashier stripe.md Stripe setup, configuration

Paddle Cashier paddle.md Paddle setup, differences

Subscriptions subscriptions.md Create, cancel, swap, pause

Webhooks webhooks.md Webhook security, handling

Invoices invoices.md PDF generation, receipts

Payment Methods payment-methods.md Cards, wallets, updates

Checkout checkout.md Hosted checkout, portal

Testing testing.md Test cards, webhook testing

Advanced SaaS Features

Topic Reference When to Consult

Metered Billing metered-billing.md Usage-based pricing (API, storage)

Team Billing team-billing.md Organization billing, per-seat

Dunning dunning.md Failed payment recovery

Feature Flags feature-flags.md Plan-based feature access

Templates (Complete Code)

Template When to Use

UserBillable.php.md User model with Billable trait

SubscriptionController.php.md CRUD subscription operations

WebhookController.php.md Custom webhook handling

CheckoutController.php.md Stripe Checkout + Portal

InvoiceController.php.md Invoice download

BillingRoutes.php.md Complete route definitions

SubscriptionTest.php.md Pest tests for billing

MeteredBillingController.php.md Usage tracking and reporting

TeamBillable.php.md Team model with seat management

DunningService.php.md Payment recovery automation

FeatureFlags.php.md Laravel Pennant per-plan features

Quick Reference

Check Subscription Status

// 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();

Create Subscription

// Simple subscription $user->newSubscription('default', 'price_monthly') ->create($paymentMethodId);

// With trial $user->newSubscription('default', 'price_monthly') ->trialDays(14) ->create($paymentMethodId);

Manage Subscription

$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();

Billing Portal

// Redirect to customer portal (Stripe) return $user->redirectToBillingPortal(route('dashboard'));

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

Best Practices

DO

  • Use webhooks for payment confirmation

  • Implement grace periods for cancelled subscriptions

  • Set up webhook signature verification

  • Handle IncompletePayment exceptions

  • Test with Stripe CLI locally

  • Prune old data regularly

DON'T

  • Trust client-side payment confirmations

  • Store card numbers (PCI compliance)

  • Skip webhook verification

  • Ignore failed payment webhooks

  • Forget to handle 3D Secure

  • Hardcode prices (use env or config)

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

laravel-livewire

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

laravel-blade

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

laravel-architecture

No summary provided by upstream source.

Repository SourceNeeds Review