Built for startups,
scaled for unicorns
Successfully submitted!
Error! Please try again
Account credits are one of the most flexible referral rewards you can offer. Unlike percentage discounts or fixed coupons, credits accumulate in the referrer's Stripe customer balance and automatically apply to their next invoice. This makes them ideal for SaaS businesses that want to let users "earn" free usage through referrals.
This guide walks you through setting up automated referral credits using GrowSurf's webhook system and Stripe's Customer Balance Transactions API. You'll learn how to credit referrers instantly when a referral converts, track credit balances, and handle edge cases like refunds and churned customers. By the end, you'll have a fully automated credit-based referral reward system.
Before building, decide on your credit amounts and rules. Common structures include flat credits (e.g., $10 per referral), percentage-of-first-payment credits, or tiered credits that increase with more referrals.
Set up your GrowSurf campaign to fire a webhook when referrals convert. Navigate to the Campaign Builder and configure the reward delivery method.
Create a server-side endpoint that receives GrowSurf webhook events and applies credits to the referrer's Stripe customer balance.
/api/referral-credit)Use Stripe's Customer Balance Transactions API to add a negative balance (credit) to the referrer's account. Negative balances in Stripe are applied automatically to the next invoice.
stripe.customers.createBalanceTransaction() with a negative amountImplement monitoring to track outstanding credit balances and detect anomalies. This helps you forecast revenue impact and catch potential abuse.
Build logic to handle situations where a referred customer refunds, churns within a trial period, or the referrer's account is closed.
charge.refunded events to claw back credits if needed// Apply referral credit to Stripe customer balance
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
async function applyReferralCredit(referrerEmail, creditAmount, referralId) {
// Find or create the Stripe customer
let customers = await stripe.customers.list({
email: referrerEmail,
limit: 1
});
let customer;
if (customers.data.length === 0) {
customer = await stripe.customers.create({
email: referrerEmail,
metadata: { source: 'growsurf_referral' }
});
} else {
customer = customers.data[0];
}
// Create a negative balance transaction (credit)
const transaction = await stripe.customers.createBalanceTransaction(
customer.id,
{
amount: -creditAmount, // Negative = credit
currency: 'usd',
description: `Referral credit for referral ${referralId}`,
metadata: {
referral_id: referralId,
source: 'growsurf'
}
}
);
return transaction;
}
// Webhook handler
app.post('/api/referral-credit', async (req, res) => {
const { event, referrer, participant } = req.body;
if (event === 'CAMPAIGN_REFERRAL_CONVERTED') {
const transaction = await applyReferralCredit(
referrer.email,
1000, // $10.00 in cents
participant.id
);
res.json({ success: true, transactionId: transaction.id });
}
});Always include GrowSurf referral IDs in Stripe balance transaction metadata. This creates a clear audit trail and makes it easy to reconcile credits with specific referrals during accounting reviews.
Set a maximum credit balance to protect your revenue. Before applying new credits, check the customer's current balance and skip or reduce the credit if they've hit the cap. Communicate this cap clearly in your referral program terms.
Use GrowSurf's reward delay feature to wait 7-14 days before issuing credits. This gives you time to verify the referred customer is legitimate and reduces fraud risk from self-referrals or low-quality sign-ups.
When a customer has a negative balance (credit) in Stripe, it's automatically applied to their next invoice. If the credit exceeds the invoice amount, the remaining balance carries forward to subsequent invoices. This happens automatically β no additional code is needed.
Stripe customer balance credits don't have built-in expiration. To implement expiry, you'll need to track credit creation dates in your database and create a scheduled job that reverses expired credits by creating positive balance transactions.
Create a positive balance transaction for the same amount with a description noting the reversal reason. Use the original transaction's metadata to link the reversal to the original credit for clear accounting records.
Trusted by marketing and product teams at fast-growing B2C, fintech, and SaaS companies
