6.2 KiB
6.2 KiB
💳 Stripe Integration for Xtablo
Complete Stripe subscription integration with a single "Standard" plan using your Node.js API.
📁 Files Created
Database (SQL)
sql/35_stripe_wrappers.sql- Database schema, tables, functions, triggerssql/36_stripe_webhooks.sql- Webhook handler functions
Backend (Node.js API)
api/src/stripe.ts- API routes for Stripe operationsapi/src/stripe-webhook.ts- Webhook event processorapi/src/routers.ts- ✅ Updated with Stripe routes
Frontend (React)
apps/main/src/hooks/stripe.ts- React hooks for Stripeapps/main/src/components/SubscriptionCard.tsx- Ready-to-use subscription UIpackages/shared/src/types/stripe.types.ts- TypeScript types
Documentation
docs/STRIPE_SETUP.md- Complete setup guidedocs/STRIPE_IMPLEMENTATION_SUMMARY.md- Technical overviewdocs/STRIPE_QUICK_REFERENCE.md- Quick reference guidedocs/STRIPE_README.md- This file
⚡ Quick Setup
1. Install Dependencies
cd apps/api && npm install stripe @stripe/stripe-js
cd ../apps/main && npm install @stripe/stripe-js
2. Run Database Migrations
Execute in Supabase SQL Editor:
\i sql/35_stripe_wrappers.sql
\i sql/36_stripe_webhooks.sql
3. Configure Stripe Dashboard
- Create product named "Standard"
- Add monthly/yearly pricing
- Save the price IDs
- Add webhook endpoint:
https://your-api.com/api/v1/stripe/webhook - Copy webhook signing secret
4. Set Environment Variables
API (.env):
STRIPE_SECRET_KEY=sk_test_xxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxx
SUPABASE_SERVICE_ROLE_KEY=your_key
FRONTEND_URL=http://localhost:5173
Frontend (apps/main/.env):
VITE_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx
VITE_STRIPE_STANDARD_MONTHLY_PRICE_ID=price_xxxxx
5. Add Subscription Card to Settings
In apps/main/src/pages/settings.tsx:
import { SubscriptionCard } from "../components/SubscriptionCard";
// Inside your settings page JSX, add:
<SubscriptionCard />
🎯 How It Works
User Journey
- Free User sees upgrade prompt in SubscriptionCard
- Clicks "Passer à Standard"
- Redirected to Stripe Checkout
- Completes payment
- Redirected back to settings with
?success=true - Webhook updates database
user.is_payingbecomestrueuser.subscription_tierbecomes'standard'- UI automatically updates
Data Sync
Stripe → Webhook → API → Database → Frontend
↓
profiles.is_paying = true
🎨 Using Subscription Card
The SubscriptionCard component shows:
For Free Users:
- "Plan Gratuit" badge
- "Passer à Standard" button
- Initiates Stripe Checkout
For Paying Users:
- "Actif" badge
- Current subscription details
- Renewal date
- "Gérer l'abonnement" button (opens Stripe portal)
- "Annuler" button
For Canceling Users:
- "Annulation en cours" warning
- Access until period end
- "Réactiver l'abonnement" button
🔍 Check Payment Status Anywhere
import { useUser } from '../providers/UserStoreProvider';
function PremiumFeature() {
const user = useUser();
if (!user.is_paying) {
return <UpgradePrompt />;
}
return <PremiumContent />;
}
🎣 Available Hooks
// Get subscription details
const { data: subscription } = useSubscription();
// Check if paying (boolean)
const { data: isPaying } = useIsPayingUser();
// Get available prices
const { data: prices } = useStripePrices();
// Create checkout session
const { mutate: checkout } = useCreateCheckoutSession();
checkout({ priceId: 'price_xxxxx' });
// Open customer portal
const { mutate: portal } = useCreatePortalSession();
portal();
// Cancel subscription
const { mutate: cancel } = useCancelSubscription();
cancel();
// Reactivate subscription
const { mutate: reactivate } = useReactivateSubscription();
reactivate();
🧪 Testing
Test Cards
Success: 4242 4242 4242 4242
Decline: 4000 0000 0000 0002
Test Webhooks Locally
stripe listen --forward-to http://localhost:3000/api/v1/stripe/webhook
Trigger Events
stripe trigger customer.subscription.created
stripe trigger customer.subscription.updated
stripe trigger customer.subscription.deleted
🔐 Security Features
✅ Webhook signature verification
✅ Row Level Security on all tables
✅ Users can only see their own subscriptions
✅ API keys never exposed to frontend
✅ Service role for database operations
📊 Database Schema
Tables
stripe_customers- Links Stripe customers to usersstripe_subscriptions- Subscription recordsstripe_products- Product catalogstripe_prices- Pricing information
Profile Fields
is_paying: boolean- Quick check for payment statussubscription_tier: 'free' | 'standard'- Current tier
Functions
is_paying_user(uuid)- Returns booleanget_user_subscription_status(uuid)- Returns subscription detailsget_user_stripe_customer_id(uuid)- Returns Stripe customer ID
🐛 Troubleshooting
Webhooks not working?
- Check API logs
- Verify webhook secret in
.env - Test with Stripe CLI
- Check Stripe Dashboard → Webhooks for delivery status
Subscription not showing?
- Check
stripe_subscriptionstable in Supabase - Verify webhook was received
- Check
profiles.is_payingfield - Ensure customer has
user_idin metadata
Can't create checkout?
- Verify
STRIPE_SECRET_KEYis set - Check
VITE_STRIPE_PUBLISHABLE_KEYin frontend - Ensure price ID is correct
- Check browser console for errors
📞 Support
See detailed docs:
- Setup Guide:
docs/STRIPE_SETUP.md - Technical Details:
docs/STRIPE_IMPLEMENTATION_SUMMARY.md - Quick Reference:
docs/STRIPE_QUICK_REFERENCE.md
🎉 Next Steps
- ✅ Database schema created
- ✅ API endpoints implemented
- ✅ Frontend hooks ready
- ✅ UI component created
- ⏳ Run migrations
- ⏳ Configure Stripe
- ⏳ Set environment variables
- ⏳ Test with test cards
- ⏳ Add SubscriptionCard to settings page
Status: ✅ Implementation Complete
Architecture: Node.js API + Supabase Database
Plan: Single "Standard" tier
Ready to Deploy: Yes, follow setup guide