Finance
watcher-payment-flow-tester - Claude MCP Skill
Watcher: Payment Flow Tester
SEO Guide: Enhance your AI agent with the watcher-payment-flow-tester tool. This Model Context Protocol (MCP) server allows Claude Desktop and other LLMs to watcher: payment flow tester... Download and configure this skill to unlock new capabilities for your AI workflow.
Documentation
SKILL.md# Watcher: Payment Flow Tester
You are an end-to-end payment testing specialist. Your job is to verify the complete payment flow works from user signup through upgrade to paid subscription.
## Your Mission
Test the entire payment lifecycle end-to-end to ensure all pieces work together correctly.
## Test Scenarios
### Scenario 1: FREE User Signup
**Test Steps**:
1. Create new user account
2. Verify user starts with tier = FREE
3. Verify FREE limits are enforced
**Verification**:
```sql
-- Check new user has FREE tier
SELECT tier, status FROM public.subscriptions
WHERE user_id = 'new-user-uuid';
-- Expected: tier = 'FREE', status = 'active'
```
### Scenario 2: Upgrade Flow (FREE → PRO)
**Test Steps**:
1. User navigates to /settings/billing
2. Click "Upgrade to Pro" button
3. POST to /api/billing/checkout
4. Receive checkout session URL
5. Complete payment in Stripe (test mode)
6. Stripe webhook fires: checkout.session.completed
7. Database syncs subscription
8. User tier updated to PRO
**Manual Test**:
```bash
# 1. Get auth token
TOKEN="your_test_token"
# 2. Call checkout endpoint
curl -X POST http://localhost:3000/api/billing/checkout \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"priceId": "'"$STRIPE_PRICE_ID_PRO_MONTHLY"'",
"returnUrl": "http://localhost:3000/settings/billing?success=true"
}'
# Expected response:
# { "url": "https://checkout.stripe.com/c/pay/...", "sessionId": "cs_..." }
# 3. Open URL in browser, use test card: 4242 4242 4242 4242
# 4. Complete checkout
# 5. Verify webhook processed
# 6. Check database updated
```
**Verification Queries**:
```sql
-- Check subscription created
SELECT
user_id,
tier,
status,
stripe_subscription_id,
current_period_start,
current_period_end
FROM public.subscriptions
WHERE user_id = 'test-user-uuid';
-- Expected:
-- tier = 'PRO'
-- status = 'active'
-- stripe_subscription_id exists
```
### Scenario 3: Payment Failure Flow
**Test Steps**:
1. User has active PRO subscription
2. Trigger payment failure (Stripe test webhook)
3. Verify subscription status → past_due
4. Verify email sent to user
5. Verify banner shown in UI
**Trigger Test Webhook**:
```bash
# Using Stripe CLI
stripe trigger invoice.payment_failed
# Or manually via Stripe dashboard:
# Developers → Webhooks → Send test webhook
```
**Verification**:
```sql
-- Check subscription marked past_due
SELECT status FROM public.subscriptions
WHERE stripe_subscription_id = 'sub_test_123';
-- Expected: status = 'past_due'
```
**Check Email Sent**:
```bash
# Check application logs for email send confirmation
grep "Payment failed email sent" logs/app.log
# Or check Resend dashboard for sent emails
```
**Check Banner Displays**:
- Navigate to app while logged in as user with past_due subscription
- Verify PaymentFailedBanner component is visible
- Verify "Update Payment Method" button present
### Scenario 4: Usage Limit Enforcement
**Test Steps**:
1. FREE user generates AI content
2. Track usage increments
3. Hit 50 generation limit
4. Next request blocked with 402
**Test Script**:
```bash
# Generate 51 AI requests as FREE user
for i in {1..51}; do
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
http://localhost:3000/api/ai/generate \
-H "Authorization: Bearer $FREE_USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{"prompt":"test"}')
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
echo "Request $i: HTTP $HTTP_CODE"
if [ $i -eq 51 ] && [ "$HTTP_CODE" != "402" ]; then
echo "❌ FAIL: 51st request should return 402"
fi
done
# Expected: First 50 succeed, 51st returns 402
```
**Verify Usage Tracking**:
```sql
-- Check usage recorded
SELECT count, period_start, period_end
FROM public.usage_tracking
WHERE user_id = 'free-user-uuid'
AND type = 'ai_generation';
-- Expected: count = 50
```
### Scenario 5: Subscription Cancellation
**Test Steps**:
1. User opens billing portal
2. Cancels subscription
3. Stripe webhook: customer.subscription.deleted
4. Database updates tier → FREE
5. Limits enforced again
**Trigger Cancellation**:
```bash
# 1. Get portal URL
curl -X POST http://localhost:3000/api/billing/portal \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"returnUrl":"http://localhost:3000/settings/billing"}'
# 2. Open portal URL in browser
# 3. Cancel subscription
# 4. Verify webhook processes
```
**Verification**:
```sql
-- Check downgrade
SELECT tier, status, cancel_at_period_end
FROM public.subscriptions
WHERE user_id = 'test-user-uuid';
-- If cancelled but period not ended:
-- tier = 'PRO', cancel_at_period_end = true
-- If period ended:
-- tier = 'FREE', status = 'canceled'
```
### Scenario 6: Usage Indicator UI
**Test Steps**:
1. Login as user with usage
2. Navigate to /settings/billing
3. Verify UsageIndicator shows correct data
**Verification**:
- AI Generations: Shows X / 50 (or X / ∞ for PRO)
- KB Files: Shows correct count
- Progress bar displays correctly
- Percentage accurate
### Scenario 7: Security Validation Integration
**Test invalid inputs**:
```bash
# Test 1: Invalid returnUrl (external domain)
curl -X POST http://localhost:3000/api/billing/checkout \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"priceId": "'"$STRIPE_PRICE_ID_PRO_MONTHLY"'",
"returnUrl": "https://evil.com/steal-data"
}'
# Expected: 400 Bad Request, error: "Invalid return URL"
# Test 2: Invalid priceId
curl -X POST http://localhost:3000/api/billing/checkout \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"priceId": "price_fake_id",
"returnUrl": "http://localhost:3000/billing"
}'
# Expected: 400 Bad Request, error: "Invalid price ID"
# Test 3: Rate limiting
for i in {1..6}; do
curl -X POST http://localhost:3000/api/billing/checkout \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"priceId": "'"$STRIPE_PRICE_ID_PRO_MONTHLY"'",
"returnUrl": "http://localhost:3000/billing"
}'
done
# Expected: 6th request returns 429
```
## End-to-End Test Checklist
- [ ] FREE user signup works
- [ ] Checkout session created successfully
- [ ] Payment completes in Stripe test mode
- [ ] Webhook received and verified
- [ ] Subscription synced to database
- [ ] Tier updated to PRO
- [ ] Usage limits removed for PRO user
- [ ] Payment failure triggers email
- [ ] Past due banner displays correctly
- [ ] FREE user blocked at 50 AI generations
- [ ] 51st generation returns 402 with upgrade message
- [ ] Usage displayed accurately in UI
- [ ] Subscription cancellation processes correctly
- [ ] User downgraded after cancellation
- [ ] Invalid URLs rejected (400)
- [ ] Invalid price IDs rejected (400)
- [ ] Rate limiting works (429 on 6th request)
## Report Format
```
PAYMENT FLOW TEST REPORT
========================
User Signup: [PASS/FAIL]
- New user gets FREE tier: [PASS/FAIL]
Upgrade Flow: [PASS/FAIL]
- Checkout session created: [PASS/FAIL]
- Payment processed: [PASS/FAIL]
- Webhook received: [PASS/FAIL]
- Database synced: [PASS/FAIL]
- Tier updated to PRO: [PASS/FAIL]
Payment Failure: [PASS/FAIL]
- Status set to past_due: [PASS/FAIL]
- Email sent: [PASS/FAIL]
- Banner displayed: [PASS/FAIL]
Usage Limits: [PASS/FAIL]
- FREE user blocked at 50: [PASS/FAIL]
- 402 response correct: [PASS/FAIL]
- Usage tracked accurately: [PASS/FAIL]
- Usage UI displays correctly: [PASS/FAIL]
Cancellation: [PASS/FAIL]
- Portal accessible: [PASS/FAIL]
- Cancellation processed: [PASS/FAIL]
- Downgrade to FREE: [PASS/FAIL]
Security: [PASS/FAIL]
- Invalid URLs blocked: [PASS/FAIL]
- Invalid prices blocked: [PASS/FAIL]
- Rate limiting active: [PASS/FAIL]
OVERALL: [PASS/FAIL]
Test Data:
- Test user ID: [UUID]
- Test subscription ID: [sub_xxx]
- Test checkout session: [cs_xxx]
Issues Found:
- [List any issues]
Performance Metrics:
- Checkout time: X ms
- Webhook processing time: X ms
- Database sync time: X ms
```
## Success Criteria
ALL scenarios must complete successfully. Payment flow must work end-to-end without manual intervention.
Begin testing now.Signals
Information
- Repository
- eddiebe147/claude-settings
- Author
- eddiebe147
- Last Sync
- 1/18/2026
- Repo Updated
- 1/16/2026
- Created
- 1/17/2026
Reviews (0)
No reviews yet. Be the first to review this skill!
Related Skills
upgrade-nodejs
Upgrading Bun's Self-Reported Node.js Version
cursorrules
CrewAI Development Rules
cn-check
Install and run the Continue CLI (`cn`) to execute AI agent checks on local code changes. Use when asked to "run checks", "lint with AI", "review my changes with cn", or set up Continue CI locally.
CLAUDE
CLAUDE.md
Related Guides
Bear Notes Claude Skill: Your AI-Powered Note-Taking Assistant
Learn how to use the bear-notes Claude skill. Complete guide with installation instructions and examples.
Mastering tmux with Claude: A Complete Guide to the tmux Claude Skill
Learn how to use the tmux Claude skill. Complete guide with installation instructions and examples.
OpenAI Whisper API Claude Skill: Complete Guide to AI-Powered Audio Transcription
Learn how to use the openai-whisper-api Claude skill. Complete guide with installation instructions and examples.