Why Billing Testing Is Critical

Billing bugs have direct financial impact. An incorrect proration calculation that overcharges users by $5 multiplied by 10,000 subscribers equals $50,000 in potential refunds — plus damage to trust, churn risk, and possible legal issues. Undercharging is equally problematic: it creates revenue loss that may go undetected for months.

Subscription billing is one of the most complex areas in web application testing because it involves time-dependent logic, third-party payment provider integration, tax calculations, and multiple state transitions.

The Subscription Lifecycle

stateDiagram-v2 [*] --> Trial: Sign up Trial --> Active: Convert/Payment Trial --> Expired: Trial ends, no payment Active --> PastDue: Payment failed PastDue --> Active: Payment recovered PastDue --> Cancelled: Max retries exceeded Active --> Cancelled: User cancels Cancelled --> Active: Re-subscribe Active --> Active: Upgrade/Downgrade Active --> Active: Renewal

Each transition is a test scenario.

Key Testing Areas

Plan Creation and Selection

  • All available plans display correct pricing (monthly, annual)
  • Annual discount is calculated correctly
  • Currency is correct based on user location
  • Free trial clearly states its duration and what happens after
  • Comparison table accurately reflects feature differences

Proration

When a user changes plans mid-cycle:

ScenarioExpected Behavior
Upgrade mid-cycleCharge the prorated difference immediately
Downgrade mid-cycleApply credit toward next billing period
Upgrade on last day of cycleCharge nearly full price of new plan
Downgrade on first day of cycleCredit nearly full amount of old plan

Example calculation:

  • Current plan: $20/month, Day 15 of 30-day cycle
  • New plan: $50/month
  • Remaining days: 15
  • Prorated charge: ($50 - $20) × (15/30) = $15

Renewals

  • Subscription renews on the correct date
  • Correct amount is charged
  • Invoice is generated and sent
  • Access continues uninterrupted after renewal
  • Annual subscriptions renew after exactly 12 months (handling leap years)

Cancellation

  • Cancellation takes effect at end of billing period (not immediately)
  • Access continues until the paid period ends
  • User can re-subscribe before period ends (cancel the cancellation)
  • User receives cancellation confirmation email
  • Data is retained for a specified period after cancellation

Payment Failures and Dunning

DayActionUser Communication
0Payment failsEmail: “Payment failed, please update your card”
3First retryEmail: “Second attempt failed”
7Second retryEmail: “Action required — update payment method”
14Third retryEmail: “Final notice — subscription will be cancelled”
21Cancel subscriptionEmail: “Subscription cancelled due to payment failure”

Tax Calculations

  • VAT/GST applied correctly based on customer location
  • Tax-exempt customers are not charged tax
  • Tax amount appears on invoices
  • Different tax rates for different regions/countries

Exercise: Subscription Billing Test Suite

You are testing a SaaS application with three plans using Stripe as the payment provider.

Test Environment Setup

Use Stripe test mode with these test cards:

Card NumberScenario
4242 4242 4242 4242Successful payment
4000 0000 0000 0002Card declined
4000 0000 0000 32203D Secure required
4000 0025 0000 3155Insufficient funds
4000 0000 0000 0341Attaching fails

Scenario 1: Complete Lifecycle

StepActionExpected Result
1Sign up for 14-day free trialTrial starts, no charge, full features
2Check on day 13Reminder email: “Trial ends tomorrow”
3Convert to Pro Monthly ($29/month)First charge of $29, subscription active
4On day 15, upgrade to Enterprise ($99/month)Prorated charge: ($99-$29) × (15/30) = $35
5Wait for renewal$99 charged on next billing date
6Cancel subscriptionAccess continues until end of period
7Period endsFeatures downgraded, data retained 90 days

Scenario 2: Payment Failure Recovery

StepActionExpected Result
1Subscribe with successful cardSubscription active
2Update to card 4000 0000 0000 0002 (decline)Card updated
3Wait for renewal attemptPayment fails, “Past Due” status
4Check dunning email“Please update your payment method”
5Update to successful cardPayment retried and succeeds
6Verify subscription statusBack to “Active”

Scenario 3: Proration Calculations

StepActionExpected Result
1Subscribe to Basic ($10/month) on Jan 1Charged $10
2Upgrade to Pro ($29/month) on Jan 16Prorated: ($29-$10) × (15/31) = $9.19
3Check next invoice preview$29 on Feb 1
4Downgrade to Basic on Jan 25Credit: ($29-$10) × (6/31) = $3.68
5Check next invoice$10 - $3.68 credit = $6.32
Solution: Common Billing Bugs

Bug 1: Proration off by one day Proration calculated using calendar days including the change day, resulting in overcharge. The change day should count toward the new plan, not the old.

Bug 2: Cancellation takes effect immediately User cancels on day 5 of a paid month but loses access immediately instead of at the end of the billing period. Users have paid for the full month and should retain access.

Bug 3: Annual renewal charges monthly price Annual subscriptions ($290/year) renewed at the monthly rate ($29/month) due to a plan lookup error.

Bug 4: Dunning emails sent after manual cancellation User manually cancelled but still received “payment failed” dunning emails because the dunning workflow was not cancelled when the subscription was.

Bug 5: Tax applied twice on upgrade When upgrading mid-cycle, tax was calculated on both the full new price and the prorated amount. Tax should only apply to the prorated charge.

Bug 6: Free trial converts without consent Trial automatically converted to paid plan without explicit user action. Some jurisdictions require explicit opt-in for conversion.

Bug 7: Discount code applied to wrong plan A 20% discount code for annual plans was also working on monthly plans.

Billing Testing Best Practices

  1. Use time manipulation — Test date-dependent logic by adjusting the system clock or using Stripe’s test clock feature to simulate time progression
  2. Test with real payment flows — Always go through the full UI payment flow, not just API calls
  3. Verify invoices — Check that every transaction generates a correct invoice with proper line items
  4. Test currency handling — If your app supports multiple currencies, verify conversion and display
  5. Document every calculation — For proration and tax tests, show the math so anyone can verify

Key Takeaways

  • Billing testing requires testing every state transition in the subscription lifecycle
  • Proration is the most calculation-intensive area — verify the math for every mid-cycle change
  • Always test with payment provider test cards to simulate success, failure, and edge cases
  • Dunning flows are critical for revenue recovery — test the full retry and notification sequence
  • Tax calculations vary by jurisdiction and must appear correctly on invoices
  • Cancellation should not take effect until the end of the paid period