Built for startups,
scaled for unicorns
Successfully submitted!
Error! Please try again

Plan upgrades are a powerful referral reward for SaaS businesses β they give referrers access to premium features without you paying cash out. When a referrer hits a milestone (like 5 successful referrals), automatically upgrading their Chargebee subscription plan creates a win-win: the referrer gets more value, you deepen their product engagement, and premium feature usage often leads to permanent plan upgrades even after the referral reward expires.
This guide covers building an automated plan upgrade system triggered by GrowSurf referral milestones, using Chargebee's Subscription API. You'll learn how to upgrade plans, set temporary upgrades with automatic reversion, and handle edge cases like mid-cycle plan changes and prorated billing.
Plan which subscription plan changes map to which referral milestones.
Create special subscription plans in Chargebee for referral rewards.
Create a webhook handler that upgrades Chargebee subscriptions when GrowSurf milestones are reached.
PARTICIPANT_REACHED_REWARD or track referral counts via PARTICIPANT_REFERREDFor time-limited upgrade rewards, set up automatic reversion to the original plan.
chargebee.subscription.update()subscription.update({ changes_scheduled_at: revertDate })Manage the financial impact of mid-cycle plan changes.
prorate: false option for free upgradesend_of_term: true to revert at the next billing cycle (no prorated refund)Send clear communication about the plan upgrade, its benefits, and its duration.
// Chargebee Plan Upgrade for Referral Milestones
const chargebee = require('chargebee');
chargebee.configure({
site: process.env.CHARGEBEE_SITE,
api_key: process.env.CHARGEBEE_API_KEY
});
const UPGRADE_MILESTONES = {
3: { planId: 'starter-plan', permanent: true },
5: { planId: 'pro-plan-referral', durationMonths: 3 },
10: { planId: 'enterprise-plan-referral', durationMonths: 6 }
};
async function upgradeSubscription(referrerEmail, milestone) {
const upgradeConfig = UPGRADE_MILESTONES[milestone];
if (!upgradeConfig) return null;
// Find customer
const customers = await chargebee.customer.list({
'email[is]': referrerEmail, limit: 1
}).request();
if (customers.list.length === 0) return null;
const customerId = customers.list[0].customer.id;
// Find active subscription
const subs = await chargebee.subscription.list({
'customer_id[is]': customerId,
'status[is]': 'active',
limit: 1
}).request();
if (subs.list.length === 0) return null;
const subscription = subs.list[0].subscription;
// Store current plan for potential reversion
await db.planUpgrades.create({
customerId: customerId,
subscriptionId: subscription.id,
originalPlan: subscription.plan_id,
upgradePlan: upgradeConfig.planId,
milestone: milestone,
permanent: upgradeConfig.permanent || false,
revertDate: upgradeConfig.durationMonths
? addMonths(new Date(), upgradeConfig.durationMonths)
: null
});
// Apply the upgrade
const result = await chargebee.subscription.update(subscription.id, {
plan_id: upgradeConfig.planId,
prorate: false // Free upgrade, no proration charge
}).request();
// If temporary, schedule reversion
if (upgradeConfig.durationMonths) {
const revertDate = addMonths(new Date(), upgradeConfig.durationMonths);
await scheduleReversion(subscription.id, subscription.plan_id, revertDate);
}
return result.subscription;
}
app.post('/webhooks/growsurf/plan-upgrade', async (req, res) => {
const { event, participant, referrer } = req.body;
if (event !== 'PARTICIPANT_REFERRED' || !referrer) {
return res.json({ skipped: true });
}
const count = referrer.referralCount;
if (UPGRADE_MILESTONES[count]) {
const upgraded = await upgradeSubscription(referrer.email, count);
if (upgraded) {
console.log(`Upgraded ${referrer.email} to ${upgraded.plan_id} at milestone ${count}`);
// Send notification email
await sendUpgradeEmail(referrer, UPGRADE_MILESTONES[count]);
}
}
res.json({ success: true });
});Instead of changing the entire subscription plan, consider using Chargebee add-ons to unlock specific premium features. This is less disruptive to billing, easier to revert, and lets referrers keep their current plan while getting bonus features. Create a "Referral Bonus Features" add-on with the desired premium capabilities.
For temporary plan upgrades, send emails at 14 days, 7 days, and 1 day before the plan reverts. Include a CTA to permanently upgrade at a discounted rate. Many users who've experienced premium features will choose to keep them β converting referral rewards into permanent revenue.
Monitor which premium features the upgraded referrer actually uses during their reward period. If they heavily use certain features, mention those features in your reversion warning emails. Showing them what they'll lose is more effective than generic "your upgrade is ending" messaging.
By default, Chargebee prorates plan changes β charging or crediting the difference for the remaining billing period. For referral rewards, set prorate: false to avoid charging the customer for the upgrade. For reversions, use end_of_term: true to revert at the next billing cycle without mid-cycle disruption.
Check the customer's current plan before attempting an upgrade. If they're already on the target plan (or a higher plan), skip the upgrade and offer an alternative reward like account credits or extended billing cycle. Log this for your records and notify the referrer of their alternative reward.
Yes, strategically. Calculate the lifetime value increase from having a deeply engaged user on a premium plan β they're less likely to churn and more likely to refer others. Many SaaS companies find that users who earn a free plan upgrade through referrals have 40% lower churn rates than users who never engaged with the referral program.
Trusted by marketing and product teams at fast-growing B2C, fintech, and SaaS companies
