DEV Community

Haskell Thurber
Haskell Thurber

Posted on

How I Built a Referral System That Pays Users in Telegram Stars (And Actually Drives Growth)

Most referral systems are an afterthought. A "Share with friends" button buried in settings that nobody ever clicks. I wanted mine to be different — and the results surprised me.

The Problem With Traditional Referrals

I built WhisprMe, an anonymous messaging Telegram Mini App. The concept is simple: you share your personal link, people send you anonymous messages, you read and reply.

The traditional approach would be: build the app, add a referral page later, offer some discount. But here's the thing — the referral IS the product.

Users can't receive anonymous messages without sharing their link. Every single user becomes a distribution channel by default. There's no separate "invite friends" flow because sharing is the core action.

How the Referral Revenue Works

When User A shares their link and User B signs up through it:

User B signs up → A becomes B's referrer
User B buys premium (50 Telegram Stars) → A earns 15% (7 Stars)
User B buys anything else → A earns 15% of that too
Enter fullscreen mode Exit fullscreen mode

The key insight: pay referrers in the same currency users spend. Telegram Stars are the native payment method, so referral earnings are also in Stars. No PayPal, no bank transfers, no minimum thresholds. It's frictionless.

The Database Schema

Here's how I track referrals in PostgreSQL:

-- Users table has referral fields
ALTER TABLE users ADD COLUMN referred_by BIGINT REFERENCES users(telegram_id);
ALTER TABLE users ADD COLUMN referral_earnings INTEGER DEFAULT 0;

-- Track the chain: who referred who
-- When user B purchases, find their referrer and credit 15%
Enter fullscreen mode Exit fullscreen mode

The referral is captured at signup time from a deep link parameter:

// Bot handles /start with referral parameter
bot.command('start', async (ctx) => {
  const referralCode = ctx.message.text.split(' ')[1];
  if (referralCode) {
    const referrer = await db.query(
      'SELECT telegram_id FROM users WHERE telegram_id = $1',
      [referralCode]
    );
    if (referrer.rows.length > 0) {
      // Store the referral relationship
      await db.query(
        'UPDATE users SET referred_by = $1 WHERE telegram_id = $2',
        [referrer.rows[0].telegram_id, ctx.from.id]
      );
    }
  }
});
Enter fullscreen mode Exit fullscreen mode

Payment Flow with Telegram Stars

When a referred user makes a purchase, the referrer's earnings update automatically:

bot.on('successful_payment', async (ctx) => {
  const payment = ctx.message.successful_payment;
  const amount = payment.total_amount; // in Stars
  const buyerId = ctx.from.id;

  // Find referrer
  const user = await db.query(
    'SELECT referred_by FROM users WHERE telegram_id = $1',
    [buyerId]
  );

  if (user.rows[0]?.referred_by) {
    const referralEarning = Math.floor(amount * 0.15);
    await db.query(
      'UPDATE users SET referral_earnings = referral_earnings + $1 WHERE telegram_id = $2',
      [referralEarning, user.rows[0].referred_by]
    );
  }
});
Enter fullscreen mode Exit fullscreen mode

The beauty of Telegram Stars: createInvoiceLink() handles the entire payment flow. No Stripe webhooks, no payment provider configuration. One API call.

What I Learned About Viral Coefficients

After launching, here's what the data showed:

  • Average shares per user: ~3.2 (users share their link in stories, groups, DMs)
  • Conversion from link click to signup: ~18%
  • K-factor: ~0.58 (each user brings 0.58 new users on average)

A K-factor below 1.0 means the app doesn't grow purely virally. But combined with organic discovery and content marketing, it creates a compounding effect. Each new user from content marketing multiplies through referrals.

The Leaderboard Effect

One thing that massively boosted sharing: a public leaderboard showing top users by messages received. People compete to get more anonymous messages, which means more sharing, which means more signups.

// Leaderboard query
const topUsers = await db.query(`
  SELECT username, display_name, 
         (SELECT COUNT(*) FROM messages WHERE recipient_id = u.telegram_id) as msg_count
  FROM users u
  WHERE is_banned = false
  ORDER BY msg_count DESC
  LIMIT 20
`);
Enter fullscreen mode Exit fullscreen mode

This gamification layer turned passive users into active promoters without any additional incentive.

Key Takeaways

  1. Build referrals INTO the product, not alongside it. If sharing is optional, most users won't.
  2. Pay in native currency. Telegram Stars → Star earnings. No friction.
  3. 15% is the sweet spot. High enough to motivate, sustainable enough to maintain margins.
  4. Leaderboards drive sharing better than referral bonuses alone. Social proof > monetary incentive.
  5. Track K-factor obsessively. Even sub-1.0 is valuable — it's a multiplier on every other growth channel.

The Tech Stack

For anyone curious about the full setup:

  • Backend: Node.js + Express + PostgreSQL
  • Frontend: React (Telegram Mini App)
  • Bot: Telegraf.js
  • Payments: Telegram Stars (no external providers)
  • Hosting: $5/mo VPS with nginx

The entire referral system was about 200 lines of code. The hardest part wasn't building it — it was designing a product where sharing is the natural first action.


If you're building a Telegram Mini App and want to see how this works in practice, check out WhisprMe. Send yourself an anonymous message — the referral link on your profile page is how the viral loop starts.

Top comments (0)