Blog
Tutorial
March 17, 20269 min

React Native Referral System: A Complete Guide in 1 Day

I spent 8 hours coding something completely unrelated to the product itself. No new features. No bug fixes. No optimizations. A complete referral system — Android deep links, Play Store Install Referrer, stacked rewards, push notifications in 6 languages — 22 files modified, 1324 lines added. In one day. Here's how I built a complete referral system in React Native, the technical pitfalls to avoid, and why it's the most profitable marketing investment for a solo dev.

Key takeaways:
- A referral system requires 3 capture sources (web deep links, Android App Links, Play Store Install Referrer) to cover all installation scenarios.
- The Play Store Install Referrer is the most underestimated source: it captures the code even if the installation happens 3 days after the click.
- Stacked rewards (queue of free months) are more motivating than a single reward but add complexity with RevenueCat.
- Android App Links verification is fragile: the SHA256 in assetlinks.json must exactly match the signing key.
Two people sharing a smartphone screen with a referral code in a cafe
Referral is the most natural acquisition channel: a friend recommends to a friend.

Why is a referral system the best investment for a solo dev?

I'm developing TAMSIV, a voice task manager for Android. Solo dev, 660+ commits, 6 months of work. I have 12 alpha testers on the Play Store and I need that number to grow — organically.

Traditional user acquisition options for a mobile app are expensive:

  • Paid advertising: 1 to 5 EUR per install on Google Ads, with no guarantee of retention.
  • ASO (App Store Optimization): long-term, uncertain results without a marketing budget.
  • Influencers: out of budget for a solo dev.

Referral is different. As ReferralCandy shows, users acquired through referral have a 37% higher retention rate and a 16% higher LTV (Lifetime Value). The reason is simple: a friend's recommendation is the most reliable form of marketing.

The concept is simple: each user has a unique referral code. You share it. When someone signs up with it, both earn 1 free Pro month. And it stacks — 10 referrals = 10 free months, queued one after the other.

What are the 3 essential capture sources for an Android referral system?

The hardest part isn't generating the codes. It's capturing them reliably. On Android, there are three completely different installation scenarios, and each requires its own capture mechanism.

Android phone screen showing a deep link in the browser address bar
Deep links are the foundation of a reliable referral system — but their implementation on Android is full of pitfalls.

Source 1: Deep links via the website

When someone visits tamsiv.com/invite/CODE, Next.js redirects to the Play Store with the referral code embedded. This is the simplest flow:

  1. User A shares their link tamsiv.com/invite/ABC123
  2. User B clicks — Next.js detects the code and redirects to the Play Store
  3. The code is passed via the referrer parameter of the Play Store URL
  4. The app retrieves it upon installation via the Install Referrer API

Source 2: Android App Links (direct opening)

If the app is already installed, tamsiv://invite/CODE opens it directly. This is the case where an existing user shares their code with someone who already has the app. This requires:

  • Configuring AndroidManifest.xml with intent-filters for the tamsiv:// scheme
  • An assetlinks.json file on the site for domain verification by Google
  • The exact SHA256 of the signing key in the assetlinks file

This is where things get complicated. Android App Links verification is fragile. If the SHA256 doesn't match exactly — and there's a difference between the debug key and the production key — the link opens in the browser instead of the app. No error, no message. It just doesn't work.

Source 3: Play Store Install Referrer

This is the most underestimated and powerful source. When someone clicks on a Play Store link with a &referrer=CODE parameter, Android stores this string. Even if the person installs the app 3 days later, we can still read the code.

The Play Install Referrer API allows retrieving this parameter on the first launch. Most tutorials skip this method, but it's the only reliable way to capture referrals via delayed installations.

How to implement stacked rewards with RevenueCat?

Golden gift boxes stacked in a pyramid with ribbons, rewards program concept
Stacked rewards are more motivating: each referral adds a free month to the queue.

Most referral systems give a single reward. "Refer a friend, get a free month." That's it. No motivation for a second referral.

I wanted the rewards to accumulate. Each referral adds 30 days of Pro, queued after the previous one expires. 10 referrals = 10 free months. The incentive remains constant.

Technical complexity with RevenueCat

RevenueCat manages TAMSIV's subscriptions (Free, Pro, Team). But RevenueCat doesn't have a native concept of "stacked free time credit." It needs to be managed server-side:

  1. Rewards table: each referral creates a row in privat.referral_rewards with a status (pending, active, used, expired).
  2. Queue: when an active reward expires, the next one in the queue is automatically activated via a backend cron job.
  3. RevenueCat synchronization: the backend uses the RevenueCat API to grant a 30-day promotional entitlement, automatically renewed if other rewards are pending.
  4. Duplicate verification: a user cannot refer the same person twice. The code is verified backend-side before granting the reward.

A simple "give 1 free month" is easy. Queuing multiple rewards requires managing start and end dates, and the relationship with RevenueCat. This was the most time-consuming part of the day.

How to send referral push notifications in 6 languages?

When someone uses your code, you receive a push notification. In your language. Because TAMSIV supports 6 languages, the backend checks the referrer's language preference before sending via FCM (Firebase Cloud Messaging).

The notification template is translated into all 6 languages:

  • FR: "Ton ami {name} a utilise ton code ! Tu gagnes 1 mois Pro gratuit."
  • EN: "Your friend {name} used your code! You earn 1 free Pro month."
  • DE, ES, IT, PT: translated equivalents

It's a detail, but it's the kind of detail that makes the system professional. Receiving a referral notification in a language you don't understand kills the excitement of the moment. The notification should be as natural as a message from a friend.

What technical errors should be avoided with Android deep links?

After this day of development, here are the pitfalls I encountered:

Pitfall 1: the assetlinks.json file

The .well-known/assetlinks.json file must be served at the exact correct location (https://tamsiv.com/.well-known/assetlinks.json) with the exact SHA256 of your signing key. Beware: the debug key and the production key have different SHA256s. Google Play App Signing adds an extra layer — you must use the SHA256 of the upload certificate, not the signing one.

Pitfall 2: intent-filters caching

Android caches intent-filters. If you correct your assetlinks.json, the device may continue to use the old verification for hours. Solution: completely uninstall the app, clear the Chrome cache, and reinstall.

Pitfall 3: referrer URL encoding

The referrer parameter of the Play Store URL must be correctly encoded. Special characters in the code (if you use UUIDs) must be escaped. I lost 30 minutes because of a + in a code that was decoded as a space.

What results can be expected from a referral system for an app in alpha?

With 12 alpha testers, the absolute results are modest. But the system is ready to scale. The ROI is measured in two dimensions:

  • Acquisition cost: 0 EUR per user acquired via referral (vs 1-5 EUR in paid advertising).
  • User quality: a referred user already knows the concept thanks to the recommendation — the retention rate is mechanically higher.
  • Viral effect: each new user can refer others — the marginal acquisition cost tends towards zero.

For a solo dev without a marketing budget, this is exactly the type of mechanism that allows growth without paying. It complements the internationalization as an acquisition channel strategy I've implemented.

What is the technical assessment of this development day?

In numbers:

  • 22 files modified (backend, frontend, website, Android manifest)
  • 1,324 lines added
  • 1 day of focused work (8 hours)
  • 6 languages supported for notifications
  • 3 capture sources for maximum coverage

The system touches all layers of the architecture: the monorepo (frontend, backend, website), the database (Supabase), notifications (FCM), and subscriptions (RevenueCat). This is what makes the feature complex — it's not isolated in a module, it spans everything.

Frequently Asked Questions

Does the Play Store Install Referrer work on all Android devices?

Yes, provided the Play Store is up to date (version 8.3.73+, which is >99% of active devices). The API is provided by Google via the com.android.installreferrer library. On the rare devices without Play Services (Huawei AppGallery), a fallback is needed.

How long is the referrer retained by the Play Store?

According to Google documentation, the referrer is retained for 90 days after the click. This is largely sufficient to capture delayed installations — even if the user waits several weeks before installing the app.

How to prevent abuse of the referral system (multiple accounts)?

Three protection mechanisms: (1) unique email verification — an email can only receive one referral reward, (2) rate limiting — maximum 5 referrals per hour per referrer, (3) backend verification — the code is valid and the referred person has never been referred before. TAMSIV's global rate limiting system protects against abuse attempts.

Does RevenueCat natively support promotional entitlements?

Yes, via the REST API (POST /subscribers/{app_user_id}/entitlements/{entitlement_id}/promotional). You can grant an entitlement for a defined duration (30 days in our case). However, managing the queue (stacking rewards) must be done server-side — RevenueCat only manages the active entitlement.

Is a backend necessary for a referral system, or can everything be done client-side?

A backend is essential for security. All validation logic (valid code, eligible user, anti-fraud) must be server-side. The frontend simply sends the code and receives the result. Code generation, reward attribution, and notification sending are done exclusively backend-side.