# Payments & Subscriptions ## Stack Laravel Cashier (Stripe). Never implement custom billing logic — use Cashier methods. ## Stripe products Three recurring subscription products (monthly): - `basic` — £0.99/mo - `plus` — £2.49/mo - `pro` — £3.99/mo Price IDs stored in `config/services.php` under `stripe.prices.*`, loaded from .env: ``` STRIPE_PRICES_BASIC=price_xxx STRIPE_PRICES_PLUS=price_xxx STRIPE_PRICES_PRO=price_xxx ``` ## Tier helpers (SubscriptionService) ```php public function tier(User $user): string // Returns 'free' | 'basic' | 'plus' | 'pro' public function canReceiveSms(User $user): bool // true if tier is plus or pro public function smsRemainingThisMonth(User $user): int // checks alerts table count for current month ``` Never check tier inline in components or notification classes — always use SubscriptionService. ## Cashier conventions - Billable model: `User` (add `use Billable` trait) - Webhook route: `POST /stripe/webhook` — handled by Cashier automatically - Webhook secret in `.env` as `STRIPE_WEBHOOK_SECRET` - Always handle `customer.subscription.deleted` to downgrade user to free tier - Trial: none for v1 ## Upgrade / downgrade flow - User upgrades in account settings Livewire component - Swap plan with `$user->subscription()->swap($newPriceId)` - Cashier handles proration automatically - On downgrade to free: cancel subscription, remove WhatsApp/SMS notification preference ## Stripe test mode Use Stripe test keys in local `.env`. Never commit real Stripe keys. Test cards: 4242424242424242 (success), 4000000000000002 (decline).