Proration
How to prorate mid-cycle plan changes so customers pay only for what they use, without surprising charges.
Why
Proration is the math of mid-cycle plan changes: if a customer on a $29/mo plan upgrades to $99/mo on day 15, they should pay $14.50 (half of $29, for the first 15 days) + $49.50 (half of $99, for the last 15 days) = $64, not $99 (full new plan) or $128 (both plans in full). Stripe handles this automatically when you change a subscription, but the customer experience matters: if the customer sees a $70 charge on their card with no explanation, they dispute it. The right design shows a proration preview before the upgrade ('upgrading today will charge $35.50 to your card — you will pay $99/mo going forward'), sends a clear invoice that breaks out the prorated amounts, and never charges more than the new plan's monthly price on a mid-cycle upgrade. The most common mistake is disabling proration (charging the full new plan on upgrade) — this feels like a penalty for upgrading and reduces upgrade rate by 30%. The second mistake is not showing a preview — the surprise charge triggers chargebacks.
When
Whenever you offer mid-cycle plan changes (upgrades, downgrades, seat additions). If you only allow changes at renewal, proration is not needed.
How
1. Enable proration in Stripe (it is on by default) — when you change a subscription mid-cycle, Stripe automatically calculates the prorated charge or credit 2. Show a proration preview before the customer confirms the change: 'upgrading to Pro today will charge $35.50 (prorated for 15 days) — your next invoice on Nov 1 will be $99' 3. Use Stripe's InvoiceItem preview API to get the proration amount before the change — display this to the customer so they know exactly what will be charged 4. For upgrades, charge the prorated amount immediately (the customer is getting more value now) — for downgrades, apply a credit to the next invoice (do not refund to the card, which creates a refund fee) 5. Set proration to 'creation_prorations' mode in Stripe — this prorates the plan change but not the usage (for usage-based pricing, prorating usage is complex and error-prone) 6. Send a clear invoice for the prorated charge: 'Pro plan upgrade — Oct 15 to Nov 1 (17 days) — $56.10' — the line item must show the period and the prorated amount 7. For seat additions, prorate the new seat for the remaining days: adding a seat on day 15 of a $29/mo plan charges $14.50 for that seat for the current cycle 8. Test proration with a sandbox subscription: upgrade on day 1, day 15, and day 30, and verify the charge matches the expected prorated amount — off-by-one errors are common
Example
# Proration preview (before upgrade)
const preview = await stripe.invoices.retrieveUpcoming({
customer: customerId,
subscription_items: [{ price: "price_pro", quantity: 1 }],
});
// preview.total = 3550 ($35.50 prorated for 15 days)
// Show to customer: "Upgrade today: $35.50 (prorated) + $99/mo going forward"
# Upgrade with proration (Stripe handles automatically)
const subscription = await stripe.subscriptions.update(subId, {
items: [{ id: itemId, price: "price_pro" }],
proration_behavior: "create_prorations", // default
});
// Stripe charges $35.50 immediately, next invoice is $99 on Nov 1
# Downgrade with proration (credit to next invoice)
const subscription = await stripe.subscriptions.update(subId, {
items: [{ id: itemId, price: "price_starter" }],
proration_behavior: "create_prorations",
});
// Stripe applies a credit of $35 to the next invoice
// (customer paid $99 for the full month, downgrades to $9 on day 15)
// Next invoice: $9 - $35 credit = $0 + $9/mo going forward
# Invoice line item (what the customer sees)
# Pro plan upgrade — Oct 15 to Nov 1 (17 days) $56.10
# Prorated from Starter ($9) to Pro ($29) for 17 daysCommon Problems
- ⚠Disabling proration and charging the full new plan on upgrade — this feels like a penalty and reduces upgrade rate by 30%. Enable proration so customers pay only for what they use.
- ⚠Not showing a proration preview before the change — the customer sees a surprise $35 charge and disputes it. Always show the preview and get confirmation.
- ⚠Refunding proration credits to the card on downgrade — this incurs a refund fee and creates a confusing statement. Apply the credit to the next invoice instead.
Best Practices
- ✓Enable Stripe's automatic proration and show a preview before every plan change — this makes mid-cycle upgrades feel fair and prevents surprise-charge disputes.
- ✓Charge prorated amounts immediately on upgrade (customer gets value now), apply credits to the next invoice on downgrade (avoids refund fees).
- ✓Test proration in a sandbox for upgrades on day 1, 15, and 30 — off-by-one errors are common and result in customers being overcharged or undercharged by one day.