# Stripe Integration Using @supabase/stripe-sync-engine

## 📦 Overview

We're using the official [@supabase/stripe-sync-engine](https://github.com/supabase/stripe-sync-engine) library to handle all Stripe webhook processing and data syncing.

**Benefits:**
- ✅ Battle-tested by Supabase
- ✅ Handles all Stripe webhook events automatically
- ✅ Automatic schema management
- ✅ Real-time sync of Stripe data
- ✅ No custom webhook handlers needed

## 🚀 Quick Setup

### 1. Install Package
```bash
cd apps/api
npm install @supabase/stripe-sync-engine
```

### 2. Configure Environment

Add to `api/.env`:
```env
# Stripe
STRIPE_SECRET_KEY=sk_test_xxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxx

# Database (direct Postgres connection)
DATABASE_URL=postgresql://postgres:[password]@db.[project].supabase.co:5432/postgres

# Or use Supabase connection string
SUPABASE_URL=https://[project].supabase.co
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
```

### 3. Run Library Migrations

The stripe-sync-engine library comes with its own migrations. Run them:

```typescript
// In a one-time setup script or manually
import { runMigrations } from '@supabase/stripe-sync-engine';

await runMigrations({ 
  databaseUrl: process.env.DATABASE_URL 
});
```

Or manually execute the migrations from: `node_modules/@supabase/stripe-sync-engine/dist/migrations/*.sql`

### 4. Integration is Already Done! ✅

The webhook handler in `api/src/stripe.ts` is already configured:

```typescript
import { StripeSync } from "@supabase/stripe-sync-engine";

const stripeSync = new StripeSync({
  stripeSecretKey: process.env.STRIPE_SECRET_KEY,
  stripeWebhookSecret: process.env.STRIPE_WEBHOOK_SECRET,
  schema: "public",
  poolConfig: {
    connectionString: process.env.DATABASE_URL,
    max: 10,
  },
  revalidateObjectsViaStripeApi: ['subscription', 'customer'],
});

// Webhook endpoint
stripeRouter.post("/webhook", async (c) => {
  const signature = c.req.header("stripe-signature");
  const rawBody = await c.req.text();
  
  await stripeSync.processWebhook(rawBody, signature);
  
  return c.json({ received: true });
});
```

## 📊 Database Schema

The library creates these tables in the `public` schema (with `stripe_` prefix):

### Core Tables (Auto-created)
- `stripe_customers`
- `stripe_subscriptions`
- `stripe_subscription_items`
- `stripe_products`
- `stripe_prices`
- `stripe_invoices`
- `stripe_charges`
- `stripe_payment_intents`
- `stripe_payment_methods`
- And many more...

### Custom Additions (From our SQL)
We still need our custom `sql/35_stripe_wrappers.sql` for:
- ✅ `profiles.is_paying` column
- ✅ `profiles.subscription_tier` column
- ✅ Triggers to auto-update profile when subscription changes
- ✅ RLS policies
- ✅ Helper functions (`is_paying_user()`, etc.)

**Note:** Delete `sql/36_stripe_webhooks.sql` - not needed, library handles webhooks!

## 🔄 How It Works

### 1. Webhook Received
```
Stripe → POST /api/v1/stripe/webhook → StripeSync.processWebhook()
```

### 2. Sync Engine Processes
```
1. Verifies signature
2. Determines event type
3. Syncs to appropriate table (stripe_subscriptions, stripe_customers, etc.)
4. Handles all edge cases automatically
```

### 3. Our Custom Trigger Fires
```
stripe_subscriptions updated → Trigger → profiles.is_paying updated
```

### 4. Frontend Queries
```
Frontend → Supabase Client → stripe_subscriptions (RLS) → User's data
```

## ✨ What the Library Handles

The stripe-sync-engine automatically handles:

- ✅ All webhook event types (100+ events)
- ✅ Signature verification  
- ✅ Idempotency (duplicate events)
- ✅ Foreign key relationships
- ✅ Deleted entities
- ✅ List expansion (fetching all items)
- ✅ Backfilling historical data
- ✅ Database schema migrations
- ✅ Connection pooling
- ✅ Error handling

## 🎯 What We Still Handle

We only need to maintain:

1. **Custom Profile Fields**
   - `profiles.is_paying`
   - `profiles.subscription_tier`

2. **Automatic Update Trigger**
   ```sql
   CREATE TRIGGER update_profile_on_subscription_change
     AFTER INSERT OR UPDATE ON stripe_subscriptions
     → Updates profile fields
   ```

3. **Action Endpoints** (in `api/src/stripe.ts`)
   - Create checkout session
   - Create portal session
   - Cancel subscription
   - Reactivate subscription

4. **RLS Policies**
   - Ensure users only see their own data

## 🧪 Testing

### Test Webhook Processing

```bash
# Terminal 1: Start your API
cd apps/api && npm run dev

# Terminal 2: Forward Stripe webhooks
stripe listen --forward-to http://localhost:3000/api/v1/stripe/webhook

# Terminal 3: Trigger test event
stripe trigger customer.subscription.created
```

**Watch the magic:**
1. Webhook arrives
2. stripe-sync-engine processes it
3. Data appears in `stripe_subscriptions` table
4. Trigger updates `profiles.is_paying`
5. Frontend sees update immediately

### Verify Sync

```sql
-- Check synced subscription
SELECT * FROM stripe_subscriptions;

-- Check synced customer
SELECT * FROM stripe_customers;

-- Check profile updated
SELECT email, is_paying, subscription_tier FROM profiles;
```

## 📝 Environment Variables Needed

```env
# Required
STRIPE_SECRET_KEY=sk_test_xxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxx
DATABASE_URL=postgresql://postgres:password@host:port/db

# Optional (if DATABASE_URL not set)
SUPABASE_URL=https://xxx.supabase.co
SUPABASE_SERVICE_ROLE_KEY=eyJxxx...
```

## 🔧 Backfilling Historical Data

If you have existing Stripe data, backfill it:

```typescript
// Run this once to sync all existing data
await stripeSync.syncBackfill({
  object: 'all', // or specific: 'customer', 'subscription', 'product', etc.
  created: {
    gte: 0 // Sync everything from the beginning
  }
});
```

Or sync specific objects:
```typescript
await stripeSync.syncProducts();
await stripeSync.syncPrices();
await stripeSync.syncCustomers();
await stripeSync.syncSubscriptions();
```

## 📚 Resources

- **Library Repo**: https://github.com/supabase/stripe-sync-engine
- **Library Docs**: https://supabase.github.io/stripe-sync-engine
- **Our Implementation**: `api/src/stripe.ts`
- **Custom SQL**: `sql/35_stripe_wrappers.sql` (profile fields & triggers only)

## ⚡ Benefits Over Custom Implementation

| Feature | Custom | stripe-sync-engine |
|---------|--------|-------------------|
| Webhook handlers | Manual | ✅ Automatic |
| Schema management | Manual | ✅ Automatic |
| Edge cases | You handle | ✅ Handled |
| Updates | You maintain | ✅ Library updates |
| Testing | Your responsibility | ✅ Battle-tested |
| Backfilling | Custom scripts | ✅ Built-in |

## 🎉 Summary

**Before:** 267 lines of custom webhook code + SQL handlers  
**After:** ~20 lines using the library

**What you maintain:**
- Profile integration (`is_paying`, `subscription_tier`)
- Action endpoints (checkout, portal, cancel)
- RLS policies
- Frontend hooks

**What the library handles:**
- Everything else! 🚀

---

**Status**: ✅ Integrated  
**Next**: Configure Stripe, test webhooks, add to settings page







