# Stripe Integration Implementation Summary

## Overview

Complete Stripe integration for Xtablo with a single "Standard" subscription plan.

**Architecture:**

- ✅ **Webhook-based**: Stripe webhooks sync data to Supabase
- ✅ **Direct Supabase access**: Frontend queries Supabase directly (no API for reads)
- ✅ **API for actions**: Checkout and subscription management via Node.js API
- ✅ **RLS-protected**: Row Level Security ensures data privacy

## ✅ What Has Been Implemented

### 1. Database Schema (`sql/35_stripe_wrappers.sql`)

#### Tables (Synced via Webhooks)

- `public.stripe_customers` - Customer records with user mapping
- `public.stripe_subscriptions` - Subscription history
- `public.stripe_products` - Product catalog
- `public.stripe_prices` - Pricing information

#### Profile Enhancements

- `profiles.is_paying` - Boolean flag for quick checks
- `profiles.subscription_tier` - Current tier ('free' or 'standard')

#### Helper Functions

```sql
-- Check if user is paying
SELECT is_paying_user(auth.uid());

-- Get subscription details
SELECT * FROM get_user_subscription_status(auth.uid());

-- Get Stripe customer ID
SELECT get_user_stripe_customer_id(auth.uid());
```

#### Views

- `active_subscriptions` - All active subs with user info

#### Automatic Updates

- Triggers automatically update `profiles.is_paying` when subscriptions change
- `updated_at` timestamps managed automatically

### 2. Webhook Handlers (`sql/36_stripe_webhooks.sql`)

Includes functions to process all major Stripe events:

**Customer Events:**

- `handle_stripe_customer_created()`
- `handle_stripe_customer_updated()`
- `handle_stripe_customer_deleted()`

**Product Events:**

- `handle_stripe_product_upsert()`
- `handle_stripe_product_deleted()`

**Price Events:**

- `handle_stripe_price_upsert()`
- `handle_stripe_price_deleted()`

**Subscription Events:**

- `handle_stripe_subscription_upsert()`
- `handle_stripe_subscription_deleted()`

### 3. Backend API (`api/src/stripe.ts` & `api/src/stripe-webhook.ts`)

**Endpoints:**

- `POST /api/v1/stripe/webhook` - Stripe webhook handler (signature verified)
- `POST /api/v1/stripe/create-checkout-session` - Start subscription checkout
- `POST /api/v1/stripe/create-portal-session` - Open customer portal
- `POST /api/v1/stripe/cancel-subscription` - Cancel at period end
- `POST /api/v1/stripe/reactivate-subscription` - Reactivate subscription

**Note:** Subscription status queries (`is-paying`, `subscription`, `prices`) are handled directly by the frontend using Supabase client with RLS policies.

**Features:**

- ✅ Automatic customer creation with user mapping
- ✅ Secure webhook signature verification
- ✅ Complete subscription lifecycle management
- ✅ Customer portal access
- ✅ Subscription cancellation/reactivation
- ✅ Optimistic updates (API updates DB before webhook for instant UI feedback)

### 4. Frontend Hooks (`apps/main/src/hooks/stripe.ts`)

**Available Hooks:**

**Direct Supabase Queries (Fast, RLS-protected):**

- `useSubscription()` - Get subscription details from Supabase
- `useIsPayingUser()` - Check if user is paying (from user profile)
- `useStripePrices()` - Get available prices from Supabase

**API Calls (For Actions):**

- `useCreateCheckoutSession()` - Start checkout (calls API)
- `useCreatePortalSession()` - Open portal (calls API)
- `useCancelSubscription()` - Cancel subscription (calls API)
- `useReactivateSubscription()` - Reactivate subscription (calls API)

### 5. TypeScript Types (`packages/shared/src/types/stripe.types.ts`)

Complete type definitions:

- `StripeCustomer`
- `StripeSubscription`
- `StripeProduct`
- `StripePrice`
- Helper functions for formatting and status checks

### 6. Documentation (`docs/STRIPE_SETUP.md`)

Comprehensive setup guide including:

- Step-by-step configuration
- Edge Function example
- Frontend integration examples
- Testing instructions
- Troubleshooting tips

## 🎯 Key Features

### Security

- ✅ Row Level Security (RLS) on all tables
- ✅ Users can only see their own data
- ✅ Stripe API key stored securely in Vault
- ✅ Webhook signature verification
- ✅ Service role functions for webhooks

### Performance

- ✅ Indexed on user_id, customer_id, status
- ✅ Efficient queries for subscription checks
- ✅ Cached subscription status in profiles table

### Data Integrity

- ✅ Foreign key relationships
- ✅ Cascading deletes
- ✅ Automatic timestamp management
- ✅ Transaction safety in webhook handlers

## 📊 How to Check if User is Paying

### Method 1: From Profile (Fastest)

```typescript
const user = useUser();
if (user.is_paying) {
  // User has active Standard subscription
  console.log(`User is on ${user.subscription_tier} plan`); // 'standard'
}
```

### Method 2: Using Hook (Same as Profile)

```typescript
const { data: isPaying } = useIsPayingUser();
// Returns user.is_paying directly
```

### Method 3: Direct Supabase Query

```typescript
const { data: subscription } = await supabase
  .from("stripe_subscriptions")
  .select("*")
  .eq("user_id", userId)
  .in("status", ["active", "trialing"])
  .single();

const isPaying = !!subscription;
```

## 🔄 Data Flow

### Subscription Creation Flow

1. **User Clicks "Subscribe to Standard"**
   → Frontend calls `useCreateCheckoutSession({ priceId })`
   → Calls API: `POST /api/v1/stripe/create-checkout-session`
2. **API Creates Checkout**
   → Creates/retrieves Stripe customer (with `user_id` in metadata)
   → Creates Stripe checkout session
   → Returns checkout URL
   → Frontend redirects to Stripe

3. **User Completes Payment**
   → Stripe processes payment
   → Fires `customer.subscription.created` webhook

4. **Webhook Received**
   → API endpoint `POST /api/v1/stripe/webhook` receives event
   → Verifies signature
   → Calls `handle_stripe_subscription_upsert()` database function

5. **Database Updated**
   → Function inserts into `stripe_subscriptions`
   → Trigger fires: `update_profile_on_subscription_change`
   → Updates `profiles.is_paying = true` and `subscription_tier = 'standard'`

6. **Frontend Queries Supabase**
   → `useSubscription()` queries `stripe_subscriptions` table directly
   → `useUser()` shows updated `is_paying` and `subscription_tier`
   → UI automatically reflects new status

### Read Flow (No API Needed)

```
Frontend → Supabase Client → RLS Policies → stripe_subscriptions table → User's data
```

Benefits:

- ⚡ **Fast**: Direct database access, no API hop
- 🔒 **Secure**: RLS ensures users only see their data
- 📊 **Real-time**: Can use Supabase realtime subscriptions if needed

## 🚀 Next Steps to Complete Implementation

### Required Setup:

1. **Update Vault Key ID**

   - Get key_id after storing Stripe API key
   - Update in `sql/35_stripe_wrappers.sql` line 27

2. **Install Stripe SDK**

   ```bash
   cd apps/api
   npm install stripe @stripe/stripe-js
   ```

3. **Configure API Environment Variables**
   Add to `api/.env`:

   ```env
   STRIPE_SECRET_KEY=sk_test_xxxxx
   STRIPE_WEBHOOK_SECRET=whsec_xxxxx
   SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
   ```

4. **Configure Frontend Environment**
   Add to `apps/main/.env`:

   ```env
   VITE_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx
   ```

5. **Create "Standard" Plan in Stripe**

   - Create product named exactly **"Standard"**
   - Add pricing (monthly/yearly)
   - Note price IDs for frontend

6. **Configure Webhook in Stripe Dashboard**
   - Add endpoint: `https://your-api.com/api/v1/stripe/webhook`
   - Select all customer/subscription/product/price events
   - Copy webhook signing secret

### Frontend Implementation:

7. **Hooks Already Created** ✅

   - `useSubscription()` - Get subscription details
   - `useIsPayingUser()` - Check payment status
   - `useCreateCheckoutSession()` - Initiate checkout
   - `useCreatePortalSession()` - Customer portal
   - `useCancelSubscription()` - Cancel subscription
   - `useReactivateSubscription()` - Reactivate

8. **Build UI Components**

   - Pricing page
   - Subscription management page
   - Payment status badges
   - Upgrade prompts

9. **Add Feature Gates**
   ```typescript
   if (!user.is_paying) {
     return <PremiumFeatureLockedPrompt />;
   }
   ```

## 📝 Environment Variables Needed

### API (`api/.env`)

```env
# Stripe
STRIPE_SECRET_KEY=sk_test_xxxxx (or sk_live_xxxxx)
STRIPE_WEBHOOK_SECRET=whsec_xxxxx

# Supabase
SUPABASE_URL=https://xxx.supabase.co
SUPABASE_SERVICE_ROLE_KEY=eyJxxx...

# Frontend URL (for redirects)
FRONTEND_URL=http://localhost:5173 (or https://app.xtablo.com)
```

### Frontend (`apps/main/.env`)

```env
# Stripe
VITE_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx (or pk_live_xxxxx)
```

## 🧪 Testing Checklist

- [ ] Run database migrations (35 & 36)
- [ ] Install Stripe SDK in API: `npm install stripe @stripe/stripe-js`
- [ ] Install Stripe SDK in frontend: `npm install @stripe/stripe-js`
- [ ] Configure environment variables (API + Frontend)
- [ ] Create "Standard" product in Stripe Dashboard
- [ ] Configure webhook endpoint in Stripe
- [ ] Test webhook with Stripe CLI
- [ ] Can create checkout session from frontend
- [ ] Payment redirects back to app
- [ ] Webhook syncs subscription to database
- [ ] `profiles.is_paying` updates automatically
- [ ] Users can only see their own subscription data
- [ ] `is_paying_user()` function returns correct status
- [ ] Can access customer portal
- [ ] Subscription cancellation updates status
- [ ] Test cards work in test mode

## 📚 Reference

- **Database Schema**: `sql/35_stripe_wrappers.sql`
- **Webhook Handlers**: `sql/36_stripe_webhooks.sql`
- **API Routes**: `api/src/stripe.ts`
- **Webhook Handler**: `api/src/stripe-webhook.ts`
- **Frontend Hooks**: `apps/main/src/hooks/stripe.ts`
- **TypeScript Types**: `packages/shared/src/types/stripe.types.ts`
- **Setup Guide**: `docs/STRIPE_SETUP.md`
- **Stripe API Docs**: https://stripe.com/docs/api
- **Supabase Wrappers**: https://supabase.github.io/wrappers/stripe/

## 🎉 Benefits

1. **Direct Stripe Access** - Query Stripe data without API calls
2. **Instant Status Checks** - `is_paying` flag on user profile
3. **Automatic Sync** - Webhooks keep data current
4. **Secure** - RLS ensures data privacy
5. **Type-Safe** - Full TypeScript support
6. **Scalable** - Handles thousands of subscriptions
7. **Historical Data** - Keep subscription history

---

## 🎯 Single "Standard" Plan Architecture

This implementation is optimized for a single subscription tier:

**Plan Structure:**

- **Free** - Default tier, `is_paying = false`
- **Standard** - Paid tier, `is_paying = true`, `subscription_tier = 'standard'`

**Why This Works:**

- Simple pricing model
- Easy to check: just `user.is_paying`
- Future-proof: can add more tiers later by updating the tier logic
- Webhook automatically handles upgrades/downgrades

**API Endpoints Specific to Standard:**

- `GET /api/v1/stripe/prices` - Returns only "Standard" plan prices
- Creates customers with metadata linking to user_id
- All subscriptions automatically set tier to 'standard'

---

**Implementation Status**: ✅ Complete (Database, API, Frontend, Types)  
**Next Step**: Configure Stripe and test webhook integration
