POST · Billing

Stripe checkout, customer portal, and webhook receiver.

The billing endpoints are thin wrappers around Stripe. Use them to start a paid subscription, manage an existing one, or accept Stripe webhooks.

POST /api/billing/checkout

Opens a Stripe Checkout session for upgrading to a paid plan.

curl -X POST https://www.mnueron.com/api/billing/checkout \
  -H "Authorization: Bearer $MNUERON_API_TOKEN"

Returns { url } — redirect the user to that URL.

400 when the org is already on a paid plan. The Stripe session has metadata.mnueron_org_id stamped on it so the webhook can attribute the eventual subscription back to your org.

POST /api/billing/portal

Opens the Stripe Customer Portal for an existing customer (change card, view invoices, cancel).

curl -X POST https://www.mnueron.com/api/billing/portal \
  -H "Authorization: Bearer $MNUERON_API_TOKEN"

Returns { url }. 404 when the org has no Stripe customer attached.

POST /api/billing/webhook

Receives Stripe events. Not for general use — only Stripe calls this. Signature verification uses stripe-signature (HMAC-SHA256 over the raw body).

Handled events:

  • checkout.session.completed — upgrade the org's plan
  • customer.subscription.created / updated / deleted
  • invoice.payment_failed
  • charge.refunded

Returns { ok: true, processed | duplicate | recorded: false }. Idempotent via billing_events.stripe_event_id UNIQUE constraint — replay storms are safe.

Last updated 2026-05-24edit