summaryrefslogtreecommitdiff
path: root/Biz/PodcastItLater/STRIPE_TESTING.md
diff options
context:
space:
mode:
Diffstat (limited to 'Biz/PodcastItLater/STRIPE_TESTING.md')
-rw-r--r--Biz/PodcastItLater/STRIPE_TESTING.md366
1 files changed, 366 insertions, 0 deletions
diff --git a/Biz/PodcastItLater/STRIPE_TESTING.md b/Biz/PodcastItLater/STRIPE_TESTING.md
new file mode 100644
index 0000000..00910ec
--- /dev/null
+++ b/Biz/PodcastItLater/STRIPE_TESTING.md
@@ -0,0 +1,366 @@
+# Stripe Testing Guide for PodcastItLater
+
+This guide covers end-to-end Stripe billing integration testing.
+
+## Prerequisites
+
+1. Stripe account (sign up at stripe.com)
+2. Stripe CLI installed (`brew install stripe/stripe-cli/stripe` or download from stripe.com/docs/stripe-cli)
+
+## Setup Steps
+
+### 1. Get Stripe Test Mode API Keys
+
+1. Go to https://dashboard.stripe.com/test/apikeys
+2. Copy your test mode keys:
+ - **Publishable key** (starts with `pk_test_`)
+ - **Secret key** (starts with `sk_test_`)
+
+### 2. Create Products and Prices in Stripe Dashboard
+
+#### Personal Plan ($9/month)
+1. Go to https://dashboard.stripe.com/test/products
+2. Click "+ Add product"
+3. Fill in:
+ - Name: `PodcastItLater Personal`
+ - Description: `50 articles per month`
+ - Pricing model: `Standard pricing`
+ - Price: `$9.00`
+ - Billing period: `Monthly`
+ - Payment type: `Recurring`
+4. Click "Save product"
+5. **Copy the Price ID** (starts with `price_`) - you'll need this for `STRIPE_PRICE_ID_PERSONAL`
+
+#### Pro Plan ($29/month)
+1. Repeat above steps with:
+ - Name: `PodcastItLater Pro`
+ - Description: `Unlimited articles`
+ - Price: `$29.00`
+ - Billing period: `Monthly`
+2. **Copy the Price ID** - you'll need this for `STRIPE_PRICE_ID_PRO`
+
+### 3. Configure Environment Variables
+
+Create or update your `.envrc.local` file:
+
+```bash
+# Stripe Test Mode Keys
+export STRIPE_SECRET_KEY="sk_test_YOUR_SECRET_KEY_HERE"
+
+# Price IDs from Stripe dashboard
+export STRIPE_PRICE_ID_PERSONAL="price_YOUR_PERSONAL_PRICE_ID"
+export STRIPE_PRICE_ID_PRO="price_YOUR_PRO_PRICE_ID"
+
+# Other required vars (if not already set)
+export BASE_URL="http://localhost:8000"
+export SESSION_SECRET="dev-secret-key-for-testing"
+export SECRET_KEY="dev-secret-key-for-magic-links"
+export AREA="Test" # Important for test mode behavior
+```
+
+Reload environment:
+```bash
+direnv allow
+```
+
+### 4. Set Up Webhook Testing
+
+#### Option A: Stripe CLI (Recommended for local testing)
+
+1. Login to Stripe CLI:
+ ```bash
+ stripe login
+ ```
+
+2. Start webhook forwarding:
+ ```bash
+ stripe listen --forward-to http://localhost:8000/stripe/webhook
+ ```
+
+3. **Copy the webhook signing secret** shown in the output (starts with `whsec_`)
+
+4. Add to `.envrc.local`:
+ ```bash
+ export STRIPE_WEBHOOK_SECRET="whsec_YOUR_WEBHOOK_SECRET"
+ ```
+
+5. Reload environment:
+ ```bash
+ direnv allow
+ ```
+
+#### Option B: Deploy and Use Stripe Dashboard Webhooks
+
+1. Deploy to production or staging environment
+2. Go to https://dashboard.stripe.com/test/webhooks
+3. Click "+ Add endpoint"
+4. Enter your webhook URL: `https://your-domain.com/stripe/webhook`
+5. Select events to listen for:
+ - `checkout.session.completed`
+ - `customer.subscription.created`
+ - `customer.subscription.updated`
+ - `customer.subscription.deleted`
+ - `invoice.payment_failed`
+6. Copy the signing secret and add to your environment
+
+### 5. Initialize Database
+
+```bash
+# Make sure DATA_DIR is set (defaults to _/var/podcastitlater/)
+export DATA_DIR="_/var/podcastitlater/"
+mkdir -p $DATA_DIR
+
+# Start the web server to initialize database
+bild --time 0 Biz/PodcastItLater/Web.py
+python Biz/PodcastItLater/Web.py
+```
+
+## Testing the Complete Flow
+
+### Test 1: User Registration and Free Tier
+
+1. Start the web server:
+ ```bash
+ python Biz/PodcastItLater/Web.py
+ ```
+
+2. Open http://localhost:8000 in your browser
+
+3. Login with `demo@example.com` (auto-approved in test mode)
+
+4. Verify:
+ - ✓ Logged in as demo@example.com
+ - ✓ Plan shows "Free"
+ - ✓ Billing button visible
+
+5. Click "Billing" button
+
+6. Verify billing page shows:
+ - ✓ Current Plan: Free
+ - ✓ Usage: 0 / 10 articles
+ - ✓ Period dates (current month)
+ - ✓ Three pricing cards (Free, Personal, Pro)
+ - ✓ "Upgrade" buttons on Personal and Pro plans
+
+### Test 2: Stripe Checkout Flow (Personal Plan)
+
+1. On billing page, click "Upgrade" button under Personal plan
+
+2. Verify redirected to Stripe Checkout page:
+ - ✓ Shows "PodcastItLater Personal"
+ - ✓ Shows $9.00/month
+ - ✓ Can enter test card details
+
+3. Use Stripe test card:
+ - Card number: `4242 4242 4242 4242`
+ - Expiry: Any future date (e.g., `12/34`)
+ - CVC: Any 3 digits (e.g., `123`)
+ - Email: Use same email as logged in user
+
+4. Complete checkout
+
+5. Verify:
+ - ✓ Redirected back to `/billing?status=success`
+ - ✓ Success message shown
+ - ✓ Plan updated to "Personal" (may take a few moments)
+ - ✓ Usage shows "0 / 50 articles"
+ - ✓ "Manage Subscription" button appears
+ - ✓ "Current Plan" badge on Personal plan
+
+### Test 3: Webhook Events
+
+Check your terminal running `stripe listen` to verify webhook events received:
+
+```
+✓ checkout.session.completed [evt_xxx]
+✓ customer.subscription.created [evt_xxx]
+✓ customer.subscription.updated [evt_xxx]
+```
+
+Check database to verify subscription data:
+
+```bash
+sqlite3 _/var/podcastitlater/podcast.db
+```
+
+```sql
+-- Check user subscription details
+SELECT id, email, plan_tier, subscription_status,
+ stripe_customer_id, stripe_subscription_id
+FROM users WHERE email = 'demo@example.com';
+
+-- Should show:
+-- plan_tier: personal
+-- subscription_status: active
+-- stripe_customer_id: cus_xxx
+-- stripe_subscription_id: sub_xxx
+```
+
+### Test 4: Billing Portal (Manage Subscription)
+
+1. On billing page (now showing Personal plan), click "Manage Subscription"
+
+2. Verify redirected to Stripe Billing Portal:
+ - ✓ Shows current subscription: PodcastItLater Personal
+ - ✓ Can update payment method
+ - ✓ Can cancel subscription
+ - ✓ Can view invoices
+
+3. Test cancellation:
+ - Click "Cancel plan"
+ - Select cancellation option (e.g., "Cancel at end of period")
+ - Confirm
+
+4. Return to billing page
+
+5. Verify:
+ - ✓ Subscription shows as active but set to cancel
+ - ✓ Still can use service until period ends
+
+### Test 5: Usage Limits Enforcement
+
+1. Login as a free user (or create new user)
+
+2. Try to submit more than 10 articles in the current month
+
+3. On the 11th submission, verify:
+ - ✓ Error message shown: "You've reached your limit of 10 articles per period. Upgrade to continue."
+ - ✓ Submit button disabled or shows error
+ - ✓ Upgrade prompt shown
+
+4. Upgrade to Personal or Pro plan
+
+5. Verify:
+ - ✓ Can submit articles again
+ - ✓ New usage limit applies
+
+### Test 6: Subscription Upgrade Flow
+
+1. Start with Personal plan
+
+2. Go to billing page
+
+3. Click "Upgrade" on Pro plan
+
+4. Complete checkout with test card
+
+5. Verify:
+ - ✓ Plan upgraded to Pro
+ - ✓ Usage shows "0 / ∞ articles"
+ - ✓ Billing reflects pro-rated charges
+
+### Test 7: Payment Failure Handling
+
+1. Use Stripe test card that triggers payment failure:
+ - Card number: `4000 0000 0000 0341` (charge fails)
+
+2. After first payment succeeds, wait for next billing cycle or trigger failure manually
+
+3. Verify:
+ - ✓ Subscription status updates to "past_due"
+ - ✓ User still has access during grace period
+ - ✓ Webhook event processed: `invoice.payment_failed`
+
+### Test 8: Subscription Cancellation
+
+1. Cancel subscription from Billing Portal
+
+2. Wait for end of billing period OR manually expire in Stripe dashboard
+
+3. Verify:
+ - ✓ Webhook event: `customer.subscription.deleted`
+ - ✓ User downgraded to free tier
+ - ✓ Usage limit reset to 10 articles/month
+ - ✓ Stripe subscription data cleared
+
+## Common Test Cards
+
+| Card Number | Scenario |
+|-------------|----------|
+| 4242 4242 4242 4242 | Successful payment |
+| 4000 0000 0000 0341 | Charge fails |
+| 4000 0000 0000 9995 | Card declined |
+| 4000 0025 0000 3155 | Requires authentication (3D Secure) |
+
+Full list: https://stripe.com/docs/testing#cards
+
+## Troubleshooting
+
+### Webhooks not received
+
+- Check Stripe CLI is running: `stripe listen --forward-to ...`
+- Verify webhook secret matches in environment
+- Check web server logs for webhook processing errors
+- Verify web server is accessible at the forwarding URL
+
+### Database not updating
+
+- Check web server logs for errors
+- Verify webhook events are being processed (check stripe_events table)
+- Check database schema is up to date (run Web.py to trigger migrations)
+
+### Checkout session not creating
+
+- Verify STRIPE_SECRET_KEY is set and valid
+- Check STRIPE_PRICE_ID_PERSONAL and STRIPE_PRICE_ID_PRO are correct
+- Look for errors in web server logs
+- Verify price IDs exist in Stripe dashboard
+
+### User not upgrading after checkout
+
+- Verify webhooks are being received and processed
+- Check that customer email in checkout matches user email in database
+- Look for errors in webhook processing logs
+- Check stripe_events table for duplicate processing
+
+## Production Deployment
+
+Before going to production:
+
+1. Switch to live mode keys (remove `_test_` from keys)
+2. Create products/prices in live mode Stripe dashboard
+3. Set up live webhook endpoint in Stripe dashboard
+4. Update STRIPE_WEBHOOK_SECRET to live mode secret
+5. Set AREA=Live in production environment
+6. Test with real payment methods (or use test mode in production at first)
+7. Monitor webhook events and logs closely
+
+## Monitoring
+
+### Check Webhook Events in Database
+
+```sql
+SELECT * FROM stripe_events
+ORDER BY created_at DESC
+LIMIT 10;
+```
+
+### Check Subscription States
+
+```sql
+SELECT email, plan_tier, subscription_status,
+ current_period_start, current_period_end
+FROM users
+WHERE plan_tier != 'free';
+```
+
+### Check Usage Stats
+
+```sql
+SELECT u.email, u.plan_tier, COUNT(e.id) as articles_this_month
+FROM users u
+LEFT JOIN episodes e ON e.user_id = u.id
+ AND e.created_at >= date('now', 'start of month')
+GROUP BY u.id, u.email, u.plan_tier;
+```
+
+## Next Steps
+
+After successful testing:
+
+1. Mark task t-1pIV0ZF as done
+2. Update AGENTS.md with Stripe setup documentation
+3. Create production deployment checklist
+4. Set up error monitoring (Sentry)
+5. Configure email notifications for payment failures
+6. Add analytics for conversion tracking