Lesson 15 / 25
Customer Portal, Upgrades and Proration
Self-service billing and plan changes.
Let customers manage billing
The customer portal is a Stripe-hosted page where customers update payment methods, view invoices, switch plans and cancel, according to options you configure in the Dashboard. Your server creates a portal session for a Customer and redirects to its URL. Plan changes can also be made through the API by updating the subscription item to a new price. By default Stripe prorates: it credits unused time on the old price and charges for the remaining time on the new one, usually on the next invoice. proration_behavior can be create_prorations, always_invoice (bill the difference now) or none. To cancel at the end of the paid period, set cancel_at_period_end: true.
Portal session and an upgrade
Server-side Node.js.
// self-service portal
const portal = await stripe.billingPortal.sessions.create({
customer: 'cus_...',
return_url: 'https://example.com/account',
});
res.redirect(303, portal.url);
// upgrade from Basic to Pro and invoice the prorated difference now
const sub = await stripe.subscriptions.retrieve('sub_...');
await stripe.subscriptions.update(sub.id, {
items: [{ id: sub.items.data[0].id, price: 'price_pro_...' }],
proration_behavior: 'always_invoice',
});
// cancel at the end of the current period
await stripe.subscriptions.update(sub.id, { cancel_at_period_end: true });
Preview before you charge
Show customers what an upgrade will cost before confirming. Stripe offers invoice preview endpoints for this; their names changed between API versions, so check the docs for your version.
Quick check: What does proration do when a customer upgrades mid-period?
- Credits unused time on the old price and charges the remaining time on the new price
- Refunds the whole previous invoice
- Waits until next year to apply the change
- Creates a second subscription
Answer
Credits unused time on the old price and charges the remaining time on the new price — Proration keeps billing fair across mid-period changes.