Includes verified API authentication flow, correct base URL, all DB table schemas for stations, current prices, history, and archive. Fuel types corrected to match live API (B7_STANDARD, B7_PREMIUM). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1.6 KiB
1.6 KiB
Payments & Subscriptions
Stack
Laravel Cashier (Stripe). Never implement custom billing logic — use Cashier methods.
Stripe products
Three recurring subscription products (monthly):
basic— £0.99/moplus— £2.49/mopro— £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)
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(adduse Billabletrait) - Webhook route:
POST /stripe/webhook— handled by Cashier automatically - Webhook secret in
.envasSTRIPE_WEBHOOK_SECRET - Always handle
customer.subscription.deletedto 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).