Back to Blog
Growth
10 min read
January 10, 2024

Building a Referral Program with Deep Linking and Install Attribution

Create a powerful referral system that tracks installs, attributes users to referrers, and provides seamless onboarding experiences. Learn how to build a complete referral program with deep linking and deferred deep linking.

Overview & Benefits

Why Use Deep Linking for Referrals?

Traditional referral programs often lose track of users between click and install. With deep linking and deferred deep linking, you can track the complete user journey from referral click to app install to first action, ensuring accurate attribution and rewards.

Key Benefits

  • • Complete user journey tracking
  • • Accurate install attribution
  • • Seamless onboarding experience
  • • Real-time analytics and insights
  • • Fraud prevention and validation
  • • Automated reward distribution

Use Cases

  • • User acquisition campaigns
  • • Viral growth strategies
  • • Influencer partnerships
  • • Social media marketing
  • • Event-based promotions
  • • Cross-platform referrals

System Architecture

Referral Flow

1

User Shares Referral Link

Existing user shares personalized referral link via social media, messaging, etc.

2

New User Clicks Link

Prospect clicks referral link, gets redirected to app store or web page

3

App Installation

New user installs app, deferred deep linking system tracks the install

4

Attribution & Rewards

System attributes install to referrer and triggers reward distribution

Backend Implementation

1. Generate Referral Link

Create personalized referral links for users:

javascript
app.post('/api/generate-referral-link', async (req, res) => {
  try {
    const { userId } = req.body;
    
    // 1. Get user profile
    const user = await getUserById(userId);
    if (!user) {
      return res.status(404).json({ error: 'User not found' });
    }
    
    // 2. Create referral link with metadata
    const referralLink = await createReferralLink(userId, user.username);
    
    // 3. Store referral link in database
    await storeReferralLink(userId, referralLink);
    
    res.json({
      success: true,
      referralLink: referralLink,
      shareText: `Join me on ${appName}! Use my referral link: ${referralLink}`
    });
    
  } catch (error) {
    console.error('Referral link generation error:', error);
    res.status(500).json({ error: 'Failed to generate referral link' });
  }
});

async function createReferralLink(userId, username) {
  try {
    const response = await redirectly.post('/links', {
      slug: `ref-${username}-${Date.now()}`,
      target: `https://yourapp.com/onboarding?ref=${userId}`,
      metadata: {
        type: 'referral',
        referrerId: userId,
        referrerUsername: username,
        campaign: 'user_referral'
      }
    });
    
    return response.data.url;
  } catch (error) {
    console.error('Failed to create referral link:', error);
    throw new Error('Failed to create referral link');
  }
}

2. Handle App Install Attribution

Track app installs and attribute them to referrers:

javascript
// Webhook endpoint for app install events
app.post('/api/webhook/app-install', async (req, res) => {
  try {
    const { deviceId, installData } = req.body;
    
    // 1. Check if this install is attributed to a referral
    const attribution = await checkInstallAttribution(deviceId);
    
    if (attribution && attribution.referrerId) {
      // 2. Record successful referral
      await recordSuccessfulReferral(attribution);
      
      // 3. Trigger reward distribution
      await distributeReferralReward(attribution.referrerId, attribution.referredUserId);
      
      // 4. Send notifications
      await notifyReferralSuccess(attribution);
    }
    
    res.json({ success: true });
    
  } catch (error) {
    console.error('App install attribution error:', error);
    res.status(500).json({ error: 'Attribution failed' });
  }
});

async function checkInstallAttribution(deviceId) {
  // Check if device was previously tracked from a referral link
  const attribution = await db.query(
    'SELECT * FROM referral_attributions WHERE device_id = ? AND status = "pending"',
    [deviceId]
  );
  
  return attribution.length > 0 ? attribution[0] : null;
}

async function recordSuccessfulReferral(attribution) {
  await db.query(
    'UPDATE referral_attributions SET status = "completed", completed_at = NOW() WHERE id = ?',
    [attribution.id]
  );
  
  // Update user referral stats
  await db.query(
    'UPDATE users SET referral_count = referral_count + 1 WHERE id = ?',
    [attribution.referrer_id]
  );
}

Flutter Integration

1. Referral Service

Create a service to handle referral functionality:

dart
class ReferralService {
  static final FlutterRedirectly _redirectly = FlutterRedirectly();
  
  static Future<void> initialize() async {
    await _redirectly.initialize(RedirectlyConfig(
      apiKey: 'YOUR_API_KEY',
      baseUrl: 'https://redirectly.app',
      enableDebugLogging: true,
    ));
    
    // Listen for app install events
    _redirectly.onAppInstalled.listen(_handleAppInstall);
    
    // Listen for incoming referral links
    _redirectly.onLinkClick.listen(_handleReferralLink);
  }
  
  static void _handleAppInstall(AppInstallEvent event) {
    if (event.matched && event.username != null && event.slug != null) {
      // This is a successful referral install
      _processSuccessfulReferral(event);
    } else {
      // Organic install
      _processOrganicInstall(event);
    }
  }
  
  static void _handleReferralLink(LinkClickEvent event) {
    if (event.error != null) return;
    
    final uri = Uri.parse(event.originalUrl);
    final referrerId = uri.queryParameters['ref'];
    
    if (referrerId != null) {
      // Store referral attribution
      _storeReferralAttribution(referrerId);
    }
  }
  
  static Future<void> _processSuccessfulReferral(AppInstallEvent event) async {
    try {
      // Notify backend of successful referral
      await http.post(
        Uri.parse('${ApiConfig.baseUrl}/api/referral-success'),
        headers: {'Content-Type': 'application/json'},
        body: jsonEncode({
          'referrerUsername': event.username,
          'referralSlug': event.slug,
          'installData': event.toJson(),
        }),
      );
      
      // Show referral success message
      _showReferralSuccessMessage(event.username!);
      
    } catch (e) {
      print('Referral processing error: $e');
    }
  }
  
  static Future<String?> generateReferralLink() async {
    try {
      final response = await http.post(
        Uri.parse('${ApiConfig.baseUrl}/api/generate-referral-link'),
        headers: {'Content-Type': 'application/json'},
        body: jsonEncode({'userId': AuthService.currentUserId}),
      );
      
      if (response.statusCode == 200) {
        final data = jsonDecode(response.body);
        return data['referralLink'];
      }
    } catch (e) {
      print('Referral link generation error: $e');
    }
    return null;
  }
  
  static void _showReferralSuccessMessage(String referrerUsername) {
    Get.snackbar(
      'Welcome!',
      'You were referred by $referrerUsername. Thanks for joining!',
      backgroundColor: Colors.green,
      colorText: Colors.white,
      duration: Duration(seconds: 5),
    );
  }
}

2. Referral UI Components

Create UI components for sharing referral links:

dart
class ReferralShareWidget extends StatefulWidget {
  @override
  _ReferralShareWidgetState createState() => _ReferralShareWidgetState();
}

class _ReferralShareWidgetState extends State<ReferralShareWidget> {
  String? _referralLink;
  bool _isLoading = false;
  
  @override
  void initState() {
    super.initState();
    _loadReferralLink();
  }
  
  Future<void> _loadReferralLink() async {
    setState(() => _isLoading = true);
    _referralLink = await ReferralService.generateReferralLink();
    setState(() => _isLoading = false);
  }
  
  @override
  Widget build(BuildContext context) {
    return Card(
      child: Padding(
        padding: EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Invite Friends',
              style: Theme.of(context).textTheme.headlineSmall,
            ),
            SizedBox(height: 8),
            Text(
              'Share your referral link and earn rewards when friends join!',
              style: Theme.of(context).textTheme.bodyMedium,
            ),
            SizedBox(height: 16),
            
            if (_isLoading)
              Center(child: CircularProgressIndicator())
            else if (_referralLink != null)
              Column(
                children: [
                  Container(
                    padding: EdgeInsets.all(12),
                    decoration: BoxDecoration(
                      color: Colors.grey[100],
                      borderRadius: BorderRadius.circular(8),
                    ),
                    child: Row(
                      children: [
                        Expanded(
                          child: Text(
                            _referralLink!,
                            style: TextStyle(fontFamily: 'monospace'),
                          ),
                        ),
                        IconButton(
                          icon: Icon(Icons.copy),
                          onPressed: () {
                            Clipboard.setData(ClipboardData(text: _referralLink!));
                            ScaffoldMessenger.of(context).showSnackBar(
                              SnackBar(content: Text('Link copied to clipboard!')),
                            );
                          },
                        ),
                      ],
                    ),
                  ),
                  SizedBox(height: 16),
                  Row(
                    children: [
                      Expanded(
                        child: ElevatedButton.icon(
                          onPressed: () => _shareReferralLink(),
                          icon: Icon(Icons.share),
                          label: Text('Share'),
                        ),
                      ),
                      SizedBox(width: 8),
                      Expanded(
                        child: OutlinedButton.icon(
                          onPressed: () => _showReferralStats(),
                          icon: Icon(Icons.analytics),
                          label: Text('Stats'),
                        ),
                      ),
                    ],
                  ),
                ],
              ),
          ],
        ),
      ),
    );
  }
  
  void _shareReferralLink() {
    Share.share(
      'Join me on ${AppConfig.appName}! Use my referral link: ${_referralLink}',
      subject: 'Join ${AppConfig.appName}!',
    );
  }
  
  void _showReferralStats() {
    Get.toNamed('/referral-stats');
  }
}

Analytics & Tracking

Key Metrics to Track

Referral Metrics

  • • Total referral links generated
  • • Click-through rates by channel
  • • Conversion rates (click to install)
  • • Time to install after click
  • • Referral completion rates
  • • Revenue per referral

User Behavior

  • • Referrer engagement levels
  • • Referred user retention
  • • Viral coefficient (K-factor)
  • • Network effects analysis
  • • Channel performance comparison
  • • Geographic distribution

Analytics Dashboard

Create analytics endpoints to track referral performance:

javascript
app.get('/api/referral-analytics', async (req, res) => {
  try {
    const { userId, timeRange = '30d' } = req.query;
    
    const analytics = await getReferralAnalytics(userId, timeRange);
    
    res.json({
      success: true,
      analytics: {
        totalReferrals: analytics.totalReferrals,
        successfulReferrals: analytics.successfulReferrals,
        conversionRate: analytics.conversionRate,
        totalRewards: analytics.totalRewards,
        topChannels: analytics.topChannels,
        dailyStats: analytics.dailyStats,
        viralCoefficient: analytics.viralCoefficient
      }
    });
    
  } catch (error) {
    console.error('Analytics error:', error);
    res.status(500).json({ error: 'Failed to fetch analytics' });
  }
});

async function getReferralAnalytics(userId, timeRange) {
  const startDate = getStartDate(timeRange);
  
  const [referrals, successful, rewards, channels] = await Promise.all([
    db.query('SELECT COUNT(*) as count FROM referral_attributions WHERE referrer_id = ? AND created_at >= ?', [userId, startDate]),
    db.query('SELECT COUNT(*) as count FROM referral_attributions WHERE referrer_id = ? AND status = "completed" AND created_at >= ?', [userId, startDate]),
    db.query('SELECT SUM(amount) as total FROM referral_rewards WHERE referrer_id = ? AND created_at >= ?', [userId, startDate]),
    db.query('SELECT channel, COUNT(*) as count FROM referral_attributions WHERE referrer_id = ? AND created_at >= ? GROUP BY channel ORDER BY count DESC', [userId, startDate])
  ]);
  
  return {
    totalReferrals: referrals[0].count,
    successfulReferrals: successful[0].count,
    conversionRate: referrals[0].count > 0 ? (successful[0].count / referrals[0].count) * 100 : 0,
    totalRewards: rewards[0].total || 0,
    topChannels: channels,
    dailyStats: await getDailyReferralStats(userId, startDate),
    viralCoefficient: await calculateViralCoefficient(userId, startDate)
  };
}

Best Practices

Growth Optimization

  • • Offer meaningful rewards for referrals
  • • Make sharing easy with pre-written messages
  • • Track and optimize conversion funnels
  • • A/B test different reward structures
  • • Implement gamification elements
  • • Use social proof and testimonials

Fraud Prevention

  • • Implement device fingerprinting
  • • Set reasonable reward limits
  • • Monitor for suspicious patterns
  • • Require email verification
  • • Implement cooldown periods
  • • Use machine learning for detection
Pro Tips for Success
  • • Start with a simple referral program and iterate based on data
  • • Focus on quality over quantity - engaged users refer better users
  • • Use deep linking to create seamless onboarding experiences
  • • Track the complete user journey from click to first value
  • • Regularly analyze and optimize your referral funnel
  • • Consider seasonal campaigns and special events for referral boosts

🚀 Your Referral Program is Ready!

You now have a complete referral program with deep linking, install attribution, and comprehensive analytics. This system will help you grow your user base organically while providing excellent user experiences.

Related Articles