# Dodo Payments Testing Checklist ## Pre-Testing Setup - [ ] Ensure `DODO_PAYMENTS_API_KEY` is set correctly (test mode for testing) - [ ] Verify all subscription product IDs are configured in environment variables - [ ] Confirm webhook endpoint is accessible and configured in Dodo dashboard - [ ] Have test payment methods available in Dodo test mode ## Scenario 1: Upgrade Between Paid Plans ### Test: Starter → Professional 1. [ ] User starts with active Starter subscription 2. [ ] Navigate to Settings page 3. [ ] Change plan dropdown to "Professional" 4. [ ] Click "Save Changes" 5. [ ] Verify confirmation modal shows upgrade message with immediate charge explanation 6. [ ] Click "Confirm" 7. [ ] **Expected**: - Status shows "Changing subscription plan..." - API calls `POST /api/account` with new plan - Server calls Dodo `POST /subscriptions/{id}/change-plan` - User is charged the price difference - Plan updates immediately to Professional - Success message: "Subscription plan changed successfully!" - Page shows updated plan without reload ### Test: Starter → Enterprise 1. [ ] Follow same steps as above but select "Enterprise" 2. [ ] Verify larger price difference is charged 3. [ ] Verify plan updates correctly ## Scenario 2: Downgrade Between Paid Plans ### Test: Professional → Starter 1. [ ] User starts with active Professional subscription 2. [ ] Navigate to Settings page 3. [ ] Change plan dropdown to "Starter" 4. [ ] Click "Save Changes" 5. [ ] Verify confirmation modal shows downgrade message with credit explanation 6. [ ] Click "Confirm" 7. [ ] **Expected**: - Status shows "Changing subscription plan..." - API calls Change Plan API with `difference_immediately` proration - Credit applied to subscription for future renewals - Plan updates immediately to Starter - Success message shown - Subscription continues without interruption ### Test: Enterprise → Professional 1. [ ] Follow same steps as above 2. [ ] Verify larger credit is applied ## Scenario 3: Downgrade to Free Plan ### Test: Any Paid Plan → Hobby 1. [ ] User starts with active paid subscription (Starter/Professional/Enterprise) 2. [ ] Navigate to Settings page 3. [ ] Change plan dropdown to "Hobby (free)" 4. [ ] Click "Save Changes" 5. [ ] Verify confirmation modal warns about feature loss 6. [ ] Click "Confirm" 7. [ ] **Expected**: - Status shows "Cancelling subscription..." - API calls `POST /api/account` with plan: hobby - Server calls `cancelDodoSubscription()` - Dodo subscription is cancelled (DELETE or PATCH with cancel_at_next_billing_date) - User plan set to "hobby" - Billing status set to "active" (for free plan) - subscriptionRenewsAt, billingCycle, subscriptionCurrency cleared - Success message: "Downgraded to free plan successfully" ### Verify in Dodo Dashboard - [ ] Subscription shows as "cancelled" or "cancel_at_next_billing_date" set to true - [ ] No future charges scheduled ## Scenario 4: Upgrade from Free to Paid ### Test: Hobby → Starter 1. [ ] User starts with free Hobby plan 2. [ ] Navigate to Settings page 3. [ ] Change plan dropdown to "Starter" 4. [ ] Click "Save Changes" 5. [ ] Verify confirmation modal indicates checkout required 6. [ ] Click "Confirm" 7. [ ] **Expected**: - Status shows "Starting checkout..." - API calls `POST /api/subscription/checkout` - Inline checkout modal opens - User completes payment in Dodo checkout - After payment, redirected back to app - Plan updates to Starter ## Scenario 5: Cancel Subscription Button ### Test: Cancel Active Subscription 1. [ ] User has active paid subscription 2. [ ] Navigate to Settings page 3. [ ] Click "Cancel Subscription" button 4. [ ] Verify confirmation modal warns about cancellation 5. [ ] Click "Confirm" 6. [ ] **Expected**: - Status shows "Updating subscription..." - API calls `POST /api/subscription/cancel` - Server calls `cancelDodoSubscription()` with reason: 'subscription_cancel' - Dodo subscription cancelled - billingStatus set to "cancelled" - Success message: "Subscription cancelled. Access will continue until end of billing period." - Cancel button changes to "Resume" or subscription status shows cancelled ### Verify Access Continuation - [ ] User retains access until current period ends - [ ] No automatic charges after current period ## Scenario 6: Billing Cycle Change ### Test: Monthly → Yearly (Same Plan) 1. [ ] User has monthly Professional subscription 2. [ ] Navigate to Settings page 3. [ ] Change billing cycle to "Yearly" 4. [ ] Keep plan as "Professional" 5. [ ] Click "Save Changes" 6. [ ] **Expected**: - This should likely redirect to checkout for the new billing cycle - OR handle as a plan change (depending on implementation) - Verify correct behavior based on business logic ## Scenario 7: Webhook Events ### After Upgrade (Starter → Professional) - [ ] `subscription.plan_changed` webhook received - [ ] Webhook handler updates user.plan in database - [ ] Email sent to user confirming plan change ### After Downgrade (Professional → Starter) - [ ] `subscription.plan_changed` webhook received - [ ] User plan updated - [ ] Email notification sent ### After Cancellation - [ ] `subscription.canceled` webhook received - [ ] User billing status updated - [ ] Cancellation email sent ### If Payment Fails on Upgrade - [ ] `subscription.on_hold` webhook received - [ ] User notified to update payment method - [ ] Plan change doesn't complete until payment succeeds ## Error Scenarios ### Test: Invalid Plan Change 1. [ ] User tries to change to invalid plan 2. [ ] **Expected**: Error message shown, no changes made ### Test: Network Failure During Plan Change 1. [ ] Simulate network error 2. [ ] **Expected**: Error message, user can retry ### Test: Insufficient Payment on Upgrade 1. [ ] Use test card with insufficient funds 2. [ ] **Expected**: - Payment fails - `subscription.on_hold` webhook - User notified - Plan doesn't change until payment succeeds ### Test: Change Plan Without Active Subscription 1. [ ] User on free plan tries paid-to-paid change 2. [ ] **Expected**: Error requiring checkout flow ## Database Verification After each test, verify in database: - [ ] `user.plan` updated correctly - [ ] `user.billingCycle` matches subscription - [ ] `user.subscriptionCurrency` correct - [ ] `user.dodoSubscriptionId` maintained (or cleared for free) - [ ] `user.billingStatus` appropriate ("active" or "cancelled") - [ ] `user.subscriptionRenewsAt` updated (or null for free) ## Dodo Dashboard Verification For each plan change: - [ ] Subscription status updated in Dodo dashboard - [ ] Correct product_id shown - [ ] Next billing date accurate - [ ] Payment method attached - [ ] Cancellation status correct if applicable ## Logs Verification Check server logs for: - [ ] "Dodo subscription plan changed" with correct details - [ ] "Dodo subscription cancelled" when cancelling - [ ] No error messages in logs - [ ] Proper userId, subscriptionId, and plan information logged ## User Experience - [ ] All confirmation modals display appropriate messages - [ ] Status messages are clear and accurate - [ ] No UI glitches or broken states - [ ] Loading states shown during API calls - [ ] Success/error states properly displayed - [ ] Page doesn't require manual refresh to show changes ## Edge Cases - [ ] **Rapid Plan Changes**: User changes plan multiple times quickly - [ ] **Concurrent Updates**: Two tabs open, changes made in both - [ ] **Expired Session**: Session expires during plan change - [ ] **Already Changed**: User tries to change to current plan - [ ] **Pending Payment**: Change plan while previous payment pending ## Performance - [ ] Plan change completes within 3 seconds - [ ] No unnecessary API calls - [ ] Proper error handling doesn't cause delays - [ ] Webhook processing is fast ## Security - [ ] CSRF token validated on all plan change requests - [ ] User can only change their own plan - [ ] Admin privileges not required for own plan changes - [ ] Webhook signatures verified - [ ] No sensitive data exposed in responses ## Documentation - [ ] DODO_PLAN_CHANGE_FIX.md accurately describes implementation - [ ] Code comments explain complex logic - [ ] Error messages are helpful - [ ] Logging provides adequate debugging information ## Post-Testing - [ ] All test scenarios passed - [ ] No errors in production logs - [ ] Dodo dashboard shows correct subscription states - [ ] Users receive appropriate email notifications - [ ] Credits from downgrades apply correctly to future renewals - [ ] Monitor for any user reports of issues ## Rollback Plan If issues are discovered: 1. [ ] Revert server.js changes 2. [ ] Revert settings.html changes 3. [ ] Notify users of temporary checkout requirement for plan changes 4. [ ] Fix issues in development 5. [ ] Re-test thoroughly 6. [ ] Re-deploy ## Success Criteria ✅ All upgrade scenarios work correctly with immediate charging ✅ All downgrade scenarios apply credits properly ✅ Free plan downgrades cancel subscriptions at Dodo ✅ Webhook events update user plans automatically ✅ No service interruption during plan changes ✅ Clear user messaging throughout all flows ✅ Proper error handling and recovery ✅ Dodo dashboard reflects all changes accurately