Billing

Billing

Keel uses Stripe-hosted Checkout and Billing Portal flows with webhook sync.

Required environment keys

STRIPE_SECRET_KEY=
STRIPE_PUBLISHABLE_KEY=
STRIPE_WEBHOOK_SECRET=
STRIPE_PRICE_PRO_MONTHLY=

Routes

$router->get('/billing/upgrade', [BillingController::class, 'showPlans']);
$router->post('/billing/checkout', [BillingController::class, 'checkout']);
$router->post('/billing/portal', [BillingController::class, 'portal']);
$router->post('/webhooks/stripe', [StripeWebhookController::class, 'handle']);

Operational notes

  • Checkout sessions are created in BillingService::createCheckoutSession().
  • Portal sessions are created in BillingService::createPortalSession().
  • Webhook signatures are verified against STRIPE_WEBHOOK_SECRET before sync logic runs.
  • Billing state is mirrored into the local subscriptions table.
  • Raw card data never passes through Keel application code.