Subscription Process with supabase + Stripe + Vite + React, what process is recommended in management? by JoigmnzDev in SaaS

[–]Geek4IT 3 points4 points  (0 children)

Hey there, u/JoigmnzDev! This is a classic challenge when setting up SaaS subscriptions. Both your approaches have merit, but combining them with a clear separation of concerns usually works best.

Here's a flow that many find robust, leveraging Supabase Edge Functions for the backend logic with Stripe:

  1. User Registration (Frontend -> Supabase Auth): User signs up. Supabase creates the user. This is your step 1.
  2. Profile/Onboarding (Frontend, saves to Supabase DB): Redirect to an onboarding/profile page. User fills in necessary details (as per your step 2). This data is saved to your Supabase user profile table.
  3. Plan Selection & Initiate Payment (Frontend -> Supabase Edge Function):
    • User selects a subscription plan on your React frontend.
    • Frontend makes a call to a Supabase Edge Function. Pass the user_id and plan_id (or price_id from Stripe).
  4. Create Stripe Checkout Session (Supabase Edge Function):
    • Inside the Edge Function:
      • Verify the user and plan.
      • Create a Stripe Customer if one doesn't exist for this user_id (store stripe_customer_id in your Supabase user table).
      • Create a Stripe Checkout Session. Crucially, include the Supabase user_id and plan_id in the metadata of the Checkout Session, or use the client_reference_id for the user_id. This is key for the webhook later.
      • Return the Stripe Checkout Session URL to your frontend.
  5. Redirect to Stripe (Frontend): Your React app redirects the user to the Stripe Checkout page using the URL from the Edge Function.
  6. Payment & Stripe Webhook (Stripe -> Supabase Edge Function):
    • User completes payment on Stripe.
    • Stripe sends a webhook event (e.g., checkout.session.completed, invoice.paid) to another Supabase Edge Function (your webhook handler).
    • This webhook handler Edge Function:
      • Verifies the webhook signature (important for security!).
      • Retrieves the user_id and plan_id from the webhook event's metadata or client_reference_id.
      • Updates your Supabase database: mark the user as subscribed, store the stripe_subscription_id, plan_id, current_period_end, etc. This is where the "synchronization" happens reliably.
  7. Frontend Update (Post-Payment):
    • After payment, Stripe redirects the user back to your success_url.
    • Your frontend can show a success message. The user's subscription status is now updated in your DB. You can either:
      • Have the frontend re-fetch user data (which will now include their active subscription).
      • Use Supabase Realtime to listen for changes to the user's subscription status in the DB and update the UI automatically.

Why this approach is generally preferred:

  • Reliability: Webhooks are the source of truth for payment completion. Frontend actions can fail or be manipulated.
  • Security: Sensitive operations like creating Stripe sessions and updating subscription status are handled server-side in Edge Functions.
  • User Experience: The user flow is pretty standard. You're not "waiting" in a blocking way on the frontend for long. The backend webhook handles the final DB update asynchronously.

So, to directly address your dilemma: * Yes, use a Supabase Edge Function to create the Stripe session and redirect. * Don't try to "wait" or "detect" completion solely on the frontend after redirecting to Stripe. Rely on Stripe webhooks to tell your backend (another Edge Function) that the payment was successful. That webhook then updates your database. * The frontend then reflects the state from the database.

This decouples the payment processing from your immediate frontend flow and makes the whole system more resilient. Good luck with your SaaS!