Skip to main content
RapidDev - Software Development Agency
flutterflow-tutorials

How to Build an Affiliate Marketing Platform in FlutterFlow

Build an affiliate platform in FlutterFlow with three Firestore collections: affiliates (code, userId, commissionRate), referral_clicks (refCode, timestamp, sessionId), and conversions (affiliateId, orderId, amount, status). Generate unique referral codes, capture the ref URL parameter on app open, store it in Secure Storage to survive page refreshes, and attribute conversions in a Cloud Function that calculates and records commissions.

What you'll learn

  • How to design the Firestore schema for affiliates, clicks, and conversions
  • Why you must persist referral codes in Secure Storage, not URL parameters alone
  • How to attribute conversions to the correct affiliate using a Cloud Function
  • How to build an affiliate dashboard showing clicks, conversions, and earnings
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Beginner10 min read45-60 minFlutterFlow Pro+ (code export required for Secure Storage)March 2026RapidDev Engineering Team
TL;DR

Build an affiliate platform in FlutterFlow with three Firestore collections: affiliates (code, userId, commissionRate), referral_clicks (refCode, timestamp, sessionId), and conversions (affiliateId, orderId, amount, status). Generate unique referral codes, capture the ref URL parameter on app open, store it in Secure Storage to survive page refreshes, and attribute conversions in a Cloud Function that calculates and records commissions.

Building Referral Tracking That Actually Works

Most affiliate system tutorials show you how to read a URL parameter — and that is only 10% of the problem. The real challenge is attribution: the user clicks a referral link, browses for 20 minutes, and finally signs up. By that time the URL parameter is gone. You need to persist the referral code across navigation, page refreshes, and app restarts. This tutorial builds a complete affiliate pipeline: unique code generation, persistent attribution via Secure Storage, click tracking, conversion recording in a Cloud Function, commission calculation, and a dashboard showing earnings.

Prerequisites

  • FlutterFlow Pro plan with code export enabled
  • Firebase project with Firestore and Authentication configured
  • Firebase Cloud Functions with Blaze billing plan
  • Basic familiarity with FlutterFlow Custom Actions and App State

Step-by-step guide

1

Design the three Firestore collections for affiliate tracking

In FlutterFlow's Firestore panel, create three collections. The affiliates collection stores one document per affiliate with: userId (String), code (String — unique 8-character code), commissionRate (Number — e.g., 0.10 for 10%), status (String — 'active' or 'suspended'), totalEarnings (Number), totalClicks (Integer), and totalConversions (Integer). The referral_clicks collection logs each link click with: refCode (String), sessionId (String), ipHash (String), userAgent (String), and created_at (Timestamp). The conversions collection records completed purchases with: affiliateId (String), orderId (String), orderAmount (Number), commissionAmount (Number), status (String — 'pending', 'approved', 'paid'), and created_at (Timestamp).

Expected result: Three Firestore collections are visible in FlutterFlow's schema editor with all fields typed correctly.

2

Generate unique affiliate codes and onboard affiliates

Create a Cloud Function named createAffiliateAccount that accepts a userId and an optional requested code. The function generates a random 8-character alphanumeric code (or validates the requested one for uniqueness), creates the affiliates document, and returns the code to the app. In FlutterFlow, add an 'Apply to Become Affiliate' button on your settings or profile page. When tapped, it calls a Custom Action that invokes the createAffiliateAccount Cloud Function and stores the returned code in the user's Firestore profile. Display the referral link as: https://yourapp.com?ref=YOURCODE in a copyable Text widget.

Expected result: After tapping the affiliate application button, the user sees their unique referral URL displayed in a copyable text field on their profile page.

3

Capture the ref URL parameter and persist it in Secure Storage

When a new user opens your app via a referral link, you must capture the ref parameter immediately and store it somewhere that survives navigation and page refreshes. In FlutterFlow, create a Custom Action named captureReferralCode. This action reads the current URL's query parameters using Uri.base.queryParameters['ref'] (web) or the initial route (mobile via uni_links package). If a ref code is found, write it to Secure Storage using flutter_secure_storage with the key 'pending_ref_code'. Also log a click event to the referral_clicks collection. Call this action from your app's first page On Page Load event — before any navigation logic runs.

capture_referral_code.dart
1// Custom Action: captureReferralCode
2import 'package:flutter_secure_storage/flutter_secure_storage.dart';
3import 'package:cloud_firestore/cloud_firestore.dart';
4import 'dart:html' as html show window; // web only
5
6Future<String?> captureReferralCode() async {
7 final storage = const FlutterSecureStorage();
8
9 // Check if we already have a pending ref
10 final existing = await storage.read(key: 'pending_ref_code');
11 if (existing != null) return existing;
12
13 // Parse ref from URL (web)
14 String? refCode;
15 try {
16 final uri = Uri.parse(html.window.location.href);
17 refCode = uri.queryParameters['ref'];
18 } catch (_) {}
19
20 if (refCode == null || refCode.isEmpty) return null;
21
22 // Verify the code exists
23 final doc = await FirebaseFirestore.instance
24 .collection('affiliates')
25 .doc(refCode.toUpperCase())
26 .get();
27
28 if (!doc.exists) return null;
29
30 // Persist to survive navigation
31 await storage.write(key: 'pending_ref_code', value: refCode.toUpperCase());
32
33 // Log the click
34 await FirebaseFirestore.instance.collection('referral_clicks').add({
35 'refCode': refCode.toUpperCase(),
36 'created_at': FieldValue.serverTimestamp(),
37 'userAgent': html.window.navigator.userAgent,
38 });
39
40 // Increment click counter on affiliate doc
41 await FirebaseFirestore.instance
42 .collection('affiliates')
43 .doc(refCode.toUpperCase())
44 .update({'totalClicks': FieldValue.increment(1)});
45
46 return refCode.toUpperCase();
47}

Expected result: When the app is opened with ?ref=CODE in the URL, the code is stored in Secure Storage and a click event is logged. Refreshing the page or navigating away does not lose the attribution.

4

Record conversions in a Cloud Function at purchase time

When a user completes a purchase (or sign-up, depending on your model), trigger a Cloud Function named recordConversion. This function reads the pending_ref_code from the user's profile or the order document (set it when the order is created from the app state), calculates the commission as orderAmount * commissionRate from the affiliate document, writes a conversion document, increments the affiliate's totalConversions and totalEarnings, and clears the pending referral attribution from the user's profile. Using a Cloud Function here (rather than a direct Firestore write from the app) prevents clients from manually inflating their own commissions.

record_conversion.js
1// functions/index.js — recordConversion Cloud Function
2const functions = require('firebase-functions');
3const admin = require('firebase-admin');
4
5exports.recordConversion = functions.https.onCall(async (data, context) => {
6 if (!context.auth) {
7 throw new functions.https.HttpsError('unauthenticated', 'Login required');
8 }
9
10 const { orderId, orderAmount, refCode } = data;
11
12 if (!refCode) return { success: false, reason: 'no_referral' };
13
14 const db = admin.firestore();
15 const affiliateRef = db.collection('affiliates').doc(refCode);
16 const affiliateDoc = await affiliateRef.get();
17
18 if (!affiliateDoc.exists || affiliateDoc.data().status !== 'active') {
19 return { success: false, reason: 'invalid_affiliate' };
20 }
21
22 const rate = affiliateDoc.data().commissionRate || 0.10;
23 const commission = parseFloat((orderAmount * rate).toFixed(2));
24
25 const batch = db.batch();
26
27 batch.set(db.collection('conversions').doc(), {
28 affiliateId: affiliateDoc.id,
29 affiliateUserId: affiliateDoc.data().userId,
30 referredUserId: context.auth.uid,
31 orderId,
32 orderAmount,
33 commissionAmount: commission,
34 status: 'pending',
35 created_at: admin.firestore.FieldValue.serverTimestamp(),
36 });
37
38 batch.update(affiliateRef, {
39 totalConversions: admin.firestore.FieldValue.increment(1),
40 totalEarnings: admin.firestore.FieldValue.increment(commission),
41 });
42
43 await batch.commit();
44 return { success: true, commission };
45});

Expected result: After a purchase, a new conversion document appears in Firestore with the correct commission amount, and the affiliate's totalEarnings field increases accordingly.

5

Build the affiliate dashboard page in FlutterFlow

Create a new page in FlutterFlow named AffiliatesDashboard. Query the affiliates collection filtering by userId == currentUser.uid to fetch the current user's affiliate document. Display totalClicks, totalConversions, and totalEarnings as metric cards using Column and Container widgets with large number text. Add a second query on the conversions collection filtered by affiliateId == affiliateDoc.id and ordered by created_at descending. Show each conversion in a ListView with the order date, amount, commission earned, and status badge (Pending, Approved, or Paid). Add a Share button that copies the referral URL to the clipboard using the Clipboard action in FlutterFlow.

Expected result: Affiliates can view their referral link, total clicks, conversion count, pending earnings, and a history of all conversions with their commission amounts.

Complete working example

affiliate_attribution.dart
1// Custom Action: applyReferralAtSignUp
2// Call this immediately after a new user registers
3import 'package:flutter_secure_storage/flutter_secure_storage.dart';
4import 'package:cloud_firestore/cloud_firestore.dart';
5import 'package:cloud_functions/cloud_functions.dart';
6import 'package:firebase_auth/firebase_auth.dart';
7
8Future<void> applyReferralAtSignUp() async {
9 final user = FirebaseAuth.instance.currentUser;
10 if (user == null) return;
11
12 // Read the persisted referral code from Secure Storage
13 const storage = FlutterSecureStorage();
14 final refCode = await storage.read(key: 'pending_ref_code');
15
16 if (refCode == null || refCode.isEmpty) return;
17
18 final db = FirebaseFirestore.instance;
19
20 // Verify affiliate is still active
21 final affiliateDoc = await db.collection('affiliates').doc(refCode).get();
22 if (!affiliateDoc.exists || affiliateDoc.data()?['status'] != 'active') {
23 await storage.delete(key: 'pending_ref_code');
24 return;
25 }
26
27 // Prevent self-referral
28 if (affiliateDoc.data()?['userId'] == user.uid) {
29 await storage.delete(key: 'pending_ref_code');
30 return;
31 }
32
33 // Store referral on the new user's profile for later conversion tracking
34 await db.collection('users').doc(user.uid).set(
35 {
36 'referredBy': refCode,
37 'referredAt': FieldValue.serverTimestamp(),
38 },
39 SetOptions(merge: true),
40 );
41
42 // If your model pays on sign-up (not just purchase), record conversion now
43 // final callable = FirebaseFunctions.instance.httpsCallable('recordConversion');
44 // await callable.call({'orderId': 'signup_${user.uid}', 'orderAmount': 0, 'refCode': refCode});
45
46 // Clear the pending code after attribution
47 await storage.delete(key: 'pending_ref_code');
48}

Common mistakes when building an Affiliate Marketing Platform in FlutterFlow

Why it's a problem: Attributing referrals via URL parameter only without persisting to Secure Storage

How to avoid: On app open, immediately read the ref URL parameter, verify it against Firestore, and write it to flutter_secure_storage. Read from Secure Storage at sign-up time to attribute the conversion correctly.

Why it's a problem: Allowing clients to write directly to the conversions collection

How to avoid: Only allow conversion records to be written by your Cloud Function. Set Firestore rules to deny direct writes to the conversions collection: 'allow write: if false;' for client access.

Why it's a problem: Not preventing self-referrals in the attribution logic

How to avoid: In your attribution action and Cloud Function, compare the affiliate's userId with the new user's uid. If they match, discard the referral code and log the attempt.

Why it's a problem: Storing commissionRate on the conversion document instead of calculating it at conversion time from the affiliates document

How to avoid: In the Cloud Function, read the current commissionRate from the affiliates document at conversion time and store both the rate and the calculated amount on the conversion record.

Best practices

  • Persist referral codes in Secure Storage immediately on app open so attribution survives navigation and page refreshes.
  • Use Cloud Functions for all commission calculations — never let clients write to conversions or update affiliate earnings directly.
  • Implement a self-referral prevention check comparing affiliate userId with the converting user's uid.
  • Add a 30-day attribution window: if the pending_ref_code in Secure Storage is older than 30 days, discard it rather than attributing a stale referral.
  • Set Firestore rules so only Cloud Functions (via Admin SDK) can write to the conversions collection — clients should have no write access.
  • Build an admin review step before paying out commissions — mark conversions as 'approved' only after confirming no fraud indicators.
  • Include a fraud detection rule that flags affiliates whose conversion rate exceeds 80% — legitimate referral programs rarely see conversion rates above 30%.

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I am building an affiliate marketing platform in FlutterFlow with Firebase. Explain the complete data architecture for tracking referral clicks, attributing conversions to the correct affiliate across page navigations, and calculating commissions in a Cloud Function.

FlutterFlow Prompt

Add affiliate tracking to my FlutterFlow app. When the app opens with ?ref=CODE in the URL, capture the code and persist it in Secure Storage. When a user signs up, read the code from storage and store it on their user profile. Call a Cloud Function to record the conversion and calculate commission.

Frequently asked questions

Why do I need Secure Storage for referral codes — can I just use App State?

App State is cleared when the app is force-closed or restarted. Secure Storage persists across app restarts and is encrypted on the device. If a user clicks a referral link, opens the app, then closes and reopens it before signing up, App State loses the code but Secure Storage keeps it.

What is a realistic affiliate commission rate?

Most SaaS affiliate programs pay 20-30% of the first payment or 10-15% recurring. One-time purchase apps typically offer 10-20%. Store the rate on the affiliate document so you can adjust individual affiliate rates without changing your code.

Can I track affiliate performance for mobile app installs?

Yes, but it requires a mobile deep link setup. Use Firebase Dynamic Links or Branch.io to create trackable install links. When the app is first opened after install, read the referral parameter from the deep link payload and write it to Secure Storage.

How do I pay affiliates their commissions?

The most common approach is manual Stripe transfers to affiliates' connected Stripe accounts, or using Stripe Payouts. Create a payout_requests collection where affiliates request withdrawals above a minimum threshold. An admin approves and triggers a Stripe transfer from a Cloud Function.

What happens if two affiliates try to claim the same conversion?

Your attribution logic should use last-click attribution: the most recently stored referral code wins. Since you clear the pending_ref_code from Secure Storage after the first sign-up attribution, subsequent referral attempts by the same user are ignored.

Do I need FlutterFlow Pro for an affiliate system?

The basic click tracking and Firestore writes can be done on Free plan. However, persisting referral codes to Secure Storage requires the flutter_secure_storage package — a Custom Action that needs code export, which is a Pro plan feature.

How do I display an affiliate's referral link in the app?

Build the URL dynamically: 'https://yourapp.com?ref=' + affiliateCode. Display it in a Text widget and add a Copy to Clipboard button using FlutterFlow's built-in Clipboard action. For mobile, add a Share button using the share_plus package.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.