# ๐ŸŽ‰ Final Stripe Setup - Using Official Library ## Overview We're using the official **@supabase/stripe-sync-engine** library from Supabase. This handles ALL webhook processing automatically - we just add custom profile integration on top! **Repository**: [https://github.com/supabase/stripe-sync-engine](https://github.com/supabase/stripe-sync-engine) ## ๐Ÿ“ฆ What's Implemented ### โœ… Files That Matter **Backend:** - `api/src/stripe.ts` - Webhook + action endpoints (uses StripeSync) - `sql/35_stripe_wrappers.sql` - Profile integration & RLS policies **Frontend:** - `apps/main/src/hooks/stripe.ts` - React hooks (queries Supabase directly) - `apps/main/src/components/SubscriptionCard.tsx` - Ready-to-use UI **Documentation:** - `docs/STRIPE_WITH_SYNC_ENGINE.md` - Main guide โญ - `docs/TESTING_WITH_FAKE_ACCOUNTS.md` - Testing guide ### โŒ Files Deleted (Not Needed Anymore) - ~~`api/src/stripe-webhook.ts`~~ - Library handles this! - ~~`sql/36_stripe_webhooks.sql`~~ - Library handles this! ## ๐Ÿš€ Setup Steps ### 1. Install Library ```bash cd apps/api npm install @supabase/stripe-sync-engine ``` โœ… Already done! ### 2. Run Library Migrations The library needs to create its tables first. Either: **Option A: Via Code** (recommended for first time) ```typescript import { runMigrations } from "@supabase/stripe-sync-engine"; await runMigrations({ databaseUrl: "postgresql://postgres:[password]@db.[project].supabase.co:5432/postgres", }); ``` **Option B: Manually** Copy migrations from `node_modules/@supabase/stripe-sync-engine/dist/migrations/*.sql` and run in Supabase SQL Editor. ### 3. Run Custom SQL After library migrations, run: ```sql \i sql/35_stripe_wrappers.sql ``` This adds: - `user_id` columns for RLS - `profiles.is_paying` and `subscription_tier` fields - Automatic triggers - Helper functions ### 4. Configure Environment **API (`.env`):** ```env STRIPE_SECRET_KEY=sk_test_xxxxx STRIPE_WEBHOOK_SECRET=whsec_xxxxx DATABASE_URL=postgresql://postgres:[password]@db.[project].supabase.co:5432/postgres FRONTEND_URL=http://localhost:5173 ``` **Frontend (`apps/main/.env`):** ```env VITE_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx VITE_STRIPE_STANDARD_MONTHLY_PRICE_ID=price_xxxxx ``` ### 5. Create "Standard" Product in Stripe 1. Stripe Dashboard โ†’ **Test Mode** โ†’ Products 2. Add product: **"Standard"** 3. Monthly price: โ‚ฌ9.99/month 4. Copy the `price_id` 5. Add to frontend `.env` ### 6. Configure Webhook 1. Stripe Dashboard โ†’ Developers โ†’ Webhooks 2. Add endpoint: `https://your-api.com/api/v1/stripe/webhook` 3. Select **all events** (library handles them all!) 4. Copy signing secret โ†’ Add to API `.env` ### 7. Add UI to Settings In `apps/main/src/pages/settings.tsx`: ```typescript import { SubscriptionCard } from "../components/SubscriptionCard"; // Add in your cards section: ; ``` ## ๐ŸŽฏ How It Works ### Webhook Flow ``` Stripe event โ†’ API webhook endpoint โ†’ StripeSync library โ†’ Database tables โ†’ Triggers โ†’ Profile updated ``` ### Read Flow (From Frontend) ``` Frontend โ†’ Supabase Client โ†’ RLS policies โ†’ stripe_subscriptions โ†’ User's data ``` **No custom webhook code needed!** The library handles everything. ## ๐Ÿงช Testing ### Quick Test 1. **Start API**: `cd apps/api && npm run dev` 2. **Start Frontend**: `cd apps/main && npm run dev` 3. **Start Webhook Forwarding**: ```bash stripe listen --forward-to http://localhost:3000/api/v1/stripe/webhook ``` 4. **Create test account**: `test@example.com` 5. **Subscribe**: Use card `4242 4242 4242 4242` 6. **Verify**: Check `user.is_paying === true` ## ๐Ÿ“Š What Tables Are Created ### By stripe-sync-engine Library: - `stripe_customers` - `stripe_subscriptions` - `stripe_subscription_items` - `stripe_products` - `stripe_prices` - `stripe_invoices` - `stripe_charges` - `stripe_payment_intents` - `stripe_payment_methods` - ... and 30+ more! ### By Our SQL (35_stripe_wrappers.sql): - Adds `user_id` to customers/subscriptions - Adds `is_paying` to profiles - Adds `subscription_tier` to profiles - Creates RLS policies - Creates triggers - Creates helper functions ## โšก Key Advantages | Aspect | Before | After (with library) | | -------------- | -------------- | -------------------- | | Webhook code | 267 lines | ~15 lines | | Event coverage | 8 events | 100+ events | | Maintenance | You | Supabase | | Schema updates | Manual | Automatic | | Backfilling | Custom scripts | Built-in | | Battle-tested | No | โœ… Yes | ## ๐ŸŽ“ Using the Library Features ### Backfill Historical Data ```typescript // Sync all existing Stripe data await stripeSync.syncBackfill({ object: "all" }); // Or sync specific objects await stripeSync.syncProducts(); await stripeSync.syncCustomers(); await stripeSync.syncSubscriptions(); ``` ### Sync Single Entity ```typescript // Sync a specific customer await stripeSync.syncSingleEntity("cus_xxxxx"); // Sync a specific subscription await stripeSync.syncSingleEntity("sub_xxxxx"); ``` ## โœ… Success Criteria Your integration works when: 1. โœ… Library installed: `npm list @supabase/stripe-sync-engine` 2. โœ… Library migrations run 3. โœ… Custom SQL (35) run 4. โœ… Environment variables configured 5. โœ… Webhook endpoint configured in Stripe 6. โœ… Test subscription creates data in `stripe_subscriptions` 7. โœ… `profiles.is_paying` updates automatically 8. โœ… Frontend shows subscription status 9. โœ… RLS policies work (users see only their data) ## ๐Ÿ› Troubleshooting ### Library Not Found ```bash cd apps/api && npm install @supabase/stripe-sync-engine ``` ### Migrations Failing Make sure to run **library migrations first**, then `sql/35_stripe_wrappers.sql` ### user_id Not Populating Ensure customer is created with metadata: ```typescript stripe.customers.create({ email: user.email, metadata: { user_id: user.id }, // โ† Important! }); ``` This is already handled in `api/src/stripe.ts` create-checkout-session endpoint. ## ๐Ÿ“ž Support - **Library Issues**: https://github.com/supabase/stripe-sync-engine/issues - **Library Docs**: https://supabase.github.io/stripe-sync-engine - **Our Implementation**: See `docs/STRIPE_WITH_SYNC_ENGINE.md` --- **Status**: โœ… Fully Implemented **Complexity**: Minimal (library does the heavy lifting) **Maintenance**: Low (library handles updates) **Ready to Deploy**: Yes!