# Flutter Referral System: Invite Links and Install Credit

> Build a Flutter referral system with invite links: redeem the invitation, claim the install with claimReferral, and get a signed webhook for the reward.

_Last updated: 2026-10-26_

To build a referral system in Flutter, mark a link as a referral link, let the new person open it, and call two static methods: `WarpLink.redeemInvitation` on iPhone and `WarpLink.claimReferral` at sign-up. The SDK matches the install to the sharing link. A signed webhook then tells your server to grant the reward.

This guide uses `warplink_flutter` 1.2.0. The reference version lives in the [Flutter referral quickstart](https://warplink.app/docs/guides/referrals/flutter).

## How a Flutter referral works

A friend shares an invite link. The new person taps it, installs the app, opens it, and signs up. Your app needs to know which link brought them. The two platforms differ:

- **Android.** Google Play stores the invitation in the install referrer, and the plugin reads it at first launch. The match is exact (`android_referrer`) and shows no screen. [Android install referrer referral code in Kotlin](https://warplink.app/blog/android-install-referrer-referral-code) shows what happens underneath.
- **iPhone.** An App Store install carries no data. The invite page puts the invitation on the clipboard, and your app asks the person to paste it. The match is exact (`install_token`). [Make a referral link survive the App Store on iPhone](https://warplink.app/blog/ios-referral-link-after-install) explains the iPhone side.

Both end in the same call, `claimReferral`, so the rest of your Dart code is one path.

## Install the SDK

```bash
flutter pub add warplink_flutter
```

This adds `warplink_flutter: ^1.2.0` to `pubspec.yaml`. SDK 1.1.x cannot read an invitation. You need Flutter 3.38 or later and Dart 3.10 or later, and the plugin runs on iOS and Android.

## Create a referral link

Any link that belongs to an app can be a referral link. Turn on **Referral link** in the dashboard, or send `is_referral` over REST:

```bash
curl -X POST https://api.warplink.app/v1/links \
  -H "Authorization: Bearer wl_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "app_id": "YOUR_APP_ID",
    "slug": "invite-ana",
    "destination_url": "https://example.com/invite",
    "is_referral": true
  }'
```

Store the returned link id with the user who shares it. The webhook names that link later, and the id tells you whose invitation earned the credit.

## Configure the SDK once

Call `configure` from your root widget's `initState`, so it runs once per launch:

```dart
import 'package:warplink_flutter/warplink_flutter.dart';

@override
void initState() {
  super.initState();
  WarpLink.configure(
    apiKey: 'wl_live_yoursdkkeyhere000000000000000000',
    onLink: (event) {
      if (event is LinkEvent && event.deepLink.isDeferred) {
        showWelcomeFromInvitation(event.deepLink);
      }
    },
  );
}
```

On Android, the referrer match arrives in `onLink` like any other deferred link.

## Redeem the invitation on iPhone

The Flutter package has no paste button widget. The SDK never reads the clipboard itself, and it sees only the text you pass in. Show a text field on your first screen, ask the person to paste the invitation, and pass the text to `redeemInvitation`:

```dart
final controller = TextEditingController();

Future<void> apply() async {
  try {
    final link = await WarpLink.redeemInvitation(controller.text);
    if (link != null) showApplied(); // null: not an invitation, or no match
  } on WarpLinkServerException catch (error) {
    showMessage(error.message); // says how to open the link again
  } on WarpLinkNetworkException {
    showMessage('Check your connection and try again.');
  }
  finishOnboardingStep();
}
```

```dart
Column(children: [
  TextField(
    controller: controller,
    decoration: const InputDecoration(hintText: 'Paste your invitation'),
    maxLines: 3,
  ),
  ElevatedButton(onPressed: apply, child: const Text('Apply')),
  TextButton(onPressed: finishOnboardingStep, child: const Text('Skip')),
])
```

Two rules keep this honest. The paste step is an offer, not a gate, so keep the skip button and let onboarding continue when `redeemInvitation` returns `null` or throws. And do not read the clipboard in the background to fill the field: iOS asks the person to allow a paste your app starts, and the person should see why.

After a `WarpLinkNetworkException`, the native SDK keeps the invitation and tries again on a later launch. That later result arrives through `getAttributionResult()` and `claimReferral`, not `onLink`.

## Claim the install at sign-up

When the new person signs up, call `claimReferral` with an installer id: a dedicated random id for that user, 1 to 128 characters. Do not use a primary key, an email address, or a phone number.

```dart
Future<ReferralClaimResult?> claimForNewUser(String installerId) async {
  try {
    return await WarpLink.claimReferral(installerId);
  } on WarpLinkException catch (error) {
    // Unreachable server, refused key, or an empty or too long installer id.
    reportError(error);
  }
  return null;
}
```

Failures arrive as subclasses of `WarpLinkException`, so one `on WarpLinkException` clause covers them all. Catch `WarpLinkNetworkException` first if you want to retry only when the server was unreachable.

`claimReferral` is safe to repeat. The first valid claim for an app and installer id wins, and the same call again returns the same claim. Handle each status:

```dart
final claim = await claimForNewUser(user.warplinkId);
switch (claim?.status) {
  case ReferralClaimStatus.claimed:
    break; // credited inside the window
  case ReferralClaimStatus.flagged:
    break; // credited after the window: claim.flags has "outside_window"
  case ReferralClaimStatus.ignored:
    break; // already credited: see claim.duplicateOf
  case ReferralClaimStatus.none:
  case null:
    break; // no referral link brought this install, or the call failed
}
```

`none` is an ordinary answer, not an error. The result also carries `referralId`, `linkId`, `matchMethod`, `isExact`, `matchConfidence`, `flags` and `duplicateOf`.

## Grant the reward from the webhook

Your server receives a signed `referral.claimed` event within seconds of the claim. Verify the signature on the raw body, skip an event id you have already seen, then grant the reward from your own rules:

```js
if (event.type === 'referral.claimed') {
  await grantReward({
    inviterLinkId: event.data.link.id,
    newUserId: event.data.installer_id,
    exact: event.data.match.exact,
  });
}
```

The reward itself stays in your system. [Receive a referral reward webhook in Node.js](https://warplink.app/blog/referral-reward-webhook-node) and [in Python](https://warplink.app/blog/referral-reward-webhook-python) show the receiver, and [Verify a referral before you grant the reward](https://warplink.app/blog/verify-referral-before-reward) lists the checks to run first. For rewards of value, claim from your backend with `POST /v1/referrals/claims` and let your own rules decide when a sign-up has earned one.

If the reward is store credit or a subscription month, read [App Store and Google Play referral reward rules](https://warplink.app/blog/app-store-referral-rewards-rules) first.

## Test it

Test on a real phone. On Android, install from a Google Play internal testing track. On iPhone, install from TestFlight or the App Store, then paste the invitation. [How to test the install referrer and referral links](https://warplink.app/blog/test-install-referrer-and-referral-links) has the full steps, the webhook test, and the Referrals report checks.

## Frequently Asked Questions

### How do I build a referral system in Flutter?

Add `warplink_flutter` 1.2.0, mark a link as a referral link, call `redeemInvitation` on iPhone, and call `claimReferral` when the new person signs up. A signed webhook then tells your server to grant the reward.

### How do I read the Google Play install referrer in Flutter?

You do not need to. The WarpLink plugin reads the Play install referrer on Android at first launch and matches it to the sharing link. The match is exact and shows no screen.

### What exceptions does claimReferral throw in Flutter?

Failures arrive as subclasses of `WarpLinkException`. `WarpLinkNetworkException` means the server was unreachable. `WarpLinkServerException` covers a refused claim, such as an empty installer id or a 4xx answer from the server.

### Does Flutter have a system paste button for the iPhone invitation?

The Flutter package has no paste button widget. Use a plain text field where the person pastes the invitation. The SDK never reads the clipboard and sees only the text you pass in.

### Can the same user claim a referral twice?

No. The first valid claim for an app and installer id wins. A later claim returns status `ignored` with a `duplicateOf` reference, so a reward is never granted twice from our side.

## Related Guides

- **Quickstart:** [Flutter referral quickstart](https://warplink.app/docs/guides/referrals/flutter) and the full [referrals guide](https://warplink.app/docs/guides/referrals).
- **Other platforms:** [Android install referrer referral code](https://warplink.app/blog/android-install-referrer-referral-code), [React Native referral program](https://warplink.app/blog/react-native-referral-program), and [referral links on iPhone](https://warplink.app/blog/ios-referral-link-after-install).
- **Test it:** [How to test the install referrer and referral links](https://warplink.app/blog/test-install-referrer-and-referral-links).
- **Flutter deep links:** [Flutter deep linking](https://warplink.app/blog/flutter-deep-linking) and [deferred deep linking in Flutter](https://warplink.app/blog/deferred-deep-linking-flutter).
- **Choosing an approach:** [Best ways to add a referral program to a mobile app](https://warplink.app/blog/best-ways-to-add-a-referral-program-to-a-mobile-app).

## How WarpLink Helps

One plugin covers both stores. The same two calls work on Android and iPhone, the match is exact on both, and every claim shows in the Referrals report with its webhook deliveries. The reward and its rules stay in your system.

One workflow, three pillars. Deep linking carries the invitation, install attribution credits the link that produced the new user, and real-time analytics shows referrals beside every other link. Sub-10ms redirects on the way in, one SDK on the way out.

[Create a free WarpLink account](https://dash.warplink.app/auth/signup) and get deep linking, install attribution, and real-time analytics in one SDK, with 10,000 clicks a month on the free plan.
