Apache-3 BidOps · Docs · 05

Webhook events (Stripe)

Event types Apache-3's payment pipeline handles and the corresponding Supabase table writes.

Stripe webhook endpoint: https://learntrainai.com/api/webhooks/stripe. All payment events flow through it.

Subscribed events

Stripe event Trigger Supabase write
checkout.session.completed (metadata.product = "prompt_to_product_book") Direct book purchase ($19.95) book_orders upsert
checkout.session.completed (metadata.product = "cohort_qualifying_deposit") $1k cohort deposit cohort_deposits upsert
checkout.session.completed (metadata.product = "alumni_coaching_subscription") Initial subscription alumni_subscriptions upsert
customer.subscription.created Subscription created (often duplicates checkout.session.completed) alumni_subscriptions update
customer.subscription.updated Plan change, status change, cancel-at-period-end alumni_subscriptions update
customer.subscription.deleted Subscription canceled at period end or hard-canceled alumni_subscriptions update (status = canceled)

Required env (Vercel)

  • STRIPE_SECRET_KEY (sk_test_... or sk_live_...)
  • STRIPE_WEBHOOK_SECRET (whsec_... from Stripe Dashboard webhook configuration)
  • SUPABASE_SERVICE_ROLE_KEY (service role for the learntrainai Supabase project)
  • NEXT_PUBLIC_SUPABASE_URL
  • RESEND_API_KEY (for confirmation emails)

Idempotency

All inserts use upsert with onConflict: stripe_session_id (for checkout-derived rows) or stripe_subscription_id (for subscription lifecycle). Stripe retries on 5xx responses; the upsert ensures repeated processing is safe.

Email side-effects

Each successful webhook event triggers Resend emails:

  • Book order: confirmation to buyer with fulfillment timeline (24h digital, 5 business days paperback)
  • Cohort deposit: confirmation to buyer + notification to apache3corp@gmail.com for fit-call scheduling
  • Alumni subscription: welcome to subscriber + admin notification

RLS posture

All three tables are RLS-locked:

  • No anon access
  • authenticated users can SELECT only if their JWT email is on the admin allowlist (s@apache-3.com, naveen@apache-3.com, apache3corp@gmail.com, snake@apache-3.com)
  • Writes are exclusively via the service-role key in the webhook handler

How to test locally

stripe listen --forward-to localhost:3000/api/webhooks/stripe
# In a separate shell:
curl -X POST localhost:3000/api/checkout/book -d '{}' -H 'content-type: application/json'
# Click the resulting URL in a browser and use card 4242 4242 4242 4242

Production webhook URL

Configure at: https://dashboard.stripe.com/test/webhooks (test mode) or https://dashboard.stripe.com/webhooks (live).

Endpoint: https://learntrainai.com/api/webhooks/stripe

Events to subscribe to (minimum):

  • checkout.session.completed
  • customer.subscription.created
  • customer.subscription.updated
  • customer.subscription.deleted

← All docs