5.1 KiB
5.1 KiB
| name | description | license | metadata | ||
|---|---|---|---|---|---|
| cashier-stripe-development | Handles Laravel Cashier Stripe integration including subscriptions, webhooks, Stripe Checkout, invoices, charges, refunds, trials, coupons, metered billing, and payment failure handling. Triggered when a user mentions Cashier, Billable, IncompletePayment, stripe_id, newSubscription, Stripe subscriptions, or billing. Also applies when setting up webhooks, handling SCA/3DS payment failures, testing with Stripe test cards, or troubleshooting incomplete subscriptions, CSRF webhook errors, or migration publish issues. | MIT |
|
Cashier Stripe Development
When to Apply
Activate this skill when:
- Installing or configuring Laravel Cashier Stripe
- Setting up subscriptions, trials, quantities, or plan swapping
- Handling webhooks or SCA/3DS payment failures
- Working with Stripe Checkout, invoices, or charges
- Testing billing scenarios with Stripe test cards or tokens
Documentation
Use search-docs for detailed Cashier patterns and documentation covering subscriptions, webhooks, Stripe Checkout, invoices, payment methods, and testing.
For deeper guidance on specific topics, read the relevant reference file before implementing:
references/subscriptions.mdcovers subscription creation, status checks, swapping, trials, quantities, and multiple productsreferences/webhooks.mdcovers webhook setup, custom handlers, CSRF exclusion, and local development with the Stripe CLIreferences/testing.mdcovers Stripe test cards, payment method tokens, and feature test patterns
Basic Usage
Installation
php artisan vendor:publish --tag="cashier-migrations"
php artisan migrate
php artisan vendor:publish --tag="cashier-config"
Environment Variables
STRIPE_KEY=pk_test_...
STRIPE_SECRET=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
CASHIER_CURRENCY=usd
CASHIER_CURRENCY_LOCALE=en_US
Billable Model
use Laravel\Cashier\Billable;
class User extends Authenticatable
{
use Billable;
}
For a non-User model, register it in a service provider:
// In AppServiceProvider::boot()
Cashier::useCustomerModel(Team::class);
Creating a Subscription
use Laravel\Cashier\Exceptions\IncompletePayment;
try {
$user->newSubscription('default', 'price_xxxx')->create($paymentMethodId);
} catch (IncompletePayment $e) {
return redirect()->route('cashier.payment', [$e->payment->id, 'redirect' => route('home')]);
}
Always wrap subscription creation in a try/catch for IncompletePayment. When a card requires 3DS authentication, Cashier throws this exception. The cashier.payment route is auto-registered and handles the confirmation flow.
Verification
- Run migrations and confirm
stripe_id,pm_type,pm_last_four, andtrial_ends_atcolumns exist on the billable model table - Test the webhook endpoint with
stripe listen --forward-to localhost/stripe/webhookif you use the default path, or swapstripefor your configuredCASHIER_PATH - Confirm
$user->subscribed('default')returns the expected value for active and incomplete subscriptions
Common Pitfalls
- The migration publish tag is
cashier-migrations, notcashier. Runningmigratebefore publishing results in missing columns and tables. CASHIER_CURRENCYmust be set explicitly. It defaults to USD, which silently breaks non-US apps.- The Stripe CLI generates its own webhook signing secret. It is different from the Dashboard endpoint secret. Using the wrong one causes signature verification failures.
- The webhook route must be excluded from CSRF verification using your configured
cashier.path. If you changeCASHIER_PATHfromstripetobilling, excludebilling/*, notstripe/*. canceled()returns true as soon ascancel()is called, but the user still has access during the grace period. Useended()to confirm access is fully revoked.subscribed()returns true during the grace period even though the subscription is canceled.subscribed()returns false forincompleteandpast_duesubscriptions by default.- Prices cannot be swapped and quantity cannot be updated while a subscription has an incomplete payment.
- When extending
WebhookController, callCashier::ignoreRoutes()in a service provider and re-register bothcashier.paymentandcashier.webhookunder the configuredcashier.path. - Use
Cashier::useCustomerModel()in a service provider to set a custom billable model. There is noCASHIER_MODELenv var. trial_ends_atis a local database column synced via webhooks. It will be stale if webhooks are not configured in production.- In MySQL, the
stripe_idcolumn must useutf8_bincollation to avoid case-sensitivity issues. noProrate()has no effect when combined withswapAndInvoice(). That method always prorates.- Methods like
withPromotionCode()require the Stripe API ID such aspromo_xxxx, not the customer-facing code. UsefindPromotionCode()to resolve a code to its ID. - Always use
search-docsfor the latest Cashier documentation rather than relying on this skill alone.