---
title: "Affiliate Program for an Android App: Click to Payout"
description: "Set up an affiliate program for an Android app: the Play install referrer, Google's cut on subscriptions, and a $9.99 ledger that survives a refund."
canonical: https://www.myappaffiliate.com/blog/affiliate-program-android-app
published: 2026-09-15
author: "Cuma Ali Kesici"
category: "Programs"
tags: [Android, Google Play, RevenueCat]
source: MyAppAffiliate
---

# Affiliate Program for an Android App: Click to Payout

Google Play hands your app the string that sent the install. Apple hands you nothing. Building an affiliate program for an Android app is therefore three jobs rather than four: put a creator id in the Play Store URL, read it back on first launch, and bind it to the user id your billing provider reports. The fourth job, reconstructing a click the store refused to carry, is the one iOS cannot escape and Android mostly can. Every Google claim below was checked against Google's own pages on 2026-09-14.

## Key takeaways

- Google Play returns the referrer string you put in the store URL. Apple returns nothing.
- The referrer is exact. The deferred IP match is a guess, and ours declines when ambiguous.
- An auto-renewing subscription costs 10% plus a 5% billing fee, or 15% by market.
- Play settles a month's orders and refunds around the 15th of the next month.
- Google Play sends no refund-reversal event, so a restored charge is manual work.

## Why the hard part of iOS is already solved on Android

Because Play carries a value you chose from the click to the installed app, and the App Store carries nothing. That one difference removes the guessing step. On Android the question is what to put in the referrer; on iOS the question is how to live without one.

The Play Store URL takes a `referrer` query parameter. Google's [Play Games user acquisition guide](https://developer.android.com/games/playgames/user-acquisition) shows the shape, a URL-encoded string appended to a normal listing link:

```
https://play.google.com/store/apps/details?id=com.sample.package&referrer=utm_source%3Dsearch%26utm_medium%3Dcpc%26utm_campaign%3Dsummerpromo
```

Swap the marketing parameters for a creator id and the same mechanism is an affiliate link. After the install, the [Install Referrer API](https://developer.android.com/google/play/installreferrer) returns that string to your app, along with the click and install timestamps.

We wrote the iOS half of this problem first, in [how to start an affiliate program for an iOS app](/blog/start-affiliate-program-ios-app), and the contrast is the reason both posts exist. Android wins on the install. It ties on everything after it.

![What Google Play and the App Store each hand your app about a creator install](https://www.myappaffiliate.com/blog-images/affiliate-program-android-app/affiliate-program-android-app-ios-vs-android.webp "The mirror image: one store carries the click, the other drops it.")

| What reaches your app | Android, via Google Play | iOS, via the App Store |
| --- | --- | --- |
| An id attached to the install itself | The referrer string you set, returned after install | Nothing |
| How long it stays readable | 90 days, unchanged unless reinstalled | Not applicable |
| Exactness | Exact: the value you set is the value you get | No equivalent exists |
| Direct link into an installed app | App Links, verified by `assetlinks.json` | Universal Links |
| Typed creator code | Exact, no store involvement | Exact, no store involvement |
| Fallback when the store carries nothing | Deferred match on a hashed IP, probabilistic | Deferred match on a hashed IP, probabilistic |
| Store fee on an auto-renewing subscription | 10% + 5% billing fee, or 15% by market | Covered in the iOS post |

## What the install referrer gives a creator program, at program level

An exact creator id on installs that came through a Play link, readable once, on first launch. It is not an attribution system. It is one field you control both ends of, which is more than Apple offers and less than a ledger needs.

Two rules from [Google's library guide](https://developer.android.com/google/play/installreferrer/library) shape the integration. The information "will be available for 90 days and won't change unless the application is reinstalled", and you "should invoke the API only once during the first execution after install". Read early, store the result, never poll.

We do not bundle the Install Referrer library. You add `com.android.installreferrer:installreferrer:2.2` yourself, read the string, and pass it in:

```kotlin
MyAppAffiliate.applyInstallReferrer(referrerString)
```

That call hands the string to the same query-string reader our SDK uses for links, so a referrer of `maa_code=JESS20&utm_source=podcast` yields the code `JESS20`, and a tracked link's `claim_token` yields the token. At most one of the two comes back, which keeps a link that carries both from attributing twice.

The connection lifecycle, the `ReferrerDetails` fields, the response codes and the install paths that quietly return nothing are a separate subject, written up in [the Install Referrer API for affiliate attribution](/blog/android-install-referrer-affiliate-attribution). Read that one before you write the code.

## Where the creator id has to be before the purchase happens

On your server, already bound to the user id your billing provider will report. The referrer solves the install. It does nothing for the subscription, which arrives later as a webhook carrying a user id and a price, from a system that has never heard of the creator.

On Android the first call can be zero lines of Kotlin. Put the key in the manifest and the SDK starts when the process does, using the ContentProvider that Android instantiates before `Application.onCreate`:

```xml
<application>
  <meta-data android:name="com.myappaffiliate.API_KEY" android:value="pk_live_…" />
</application>
```

That start persists a device id in `SharedPreferences`, with no advertising id and no fingerprinting, and retries a referral an earlier launch captured but failed to send. Then one call, once you know who the user is:

```kotlin
MyAppAffiliate.identify(userId)
```

The string must be the one your billing provider sends back: RevenueCat's `logIn` id, Adapty's customer user id, Superwall's app user id, or your Stripe or Paddle custom data. Get it wrong and both halves look healthy forever while no commission is created. That is the most common broken setup we see, on either platform.

There is no third step. You do not set an affiliate attribute on the subscriber; attribution joins on the user id, which is the whole argument of [the RevenueCat setup](/blog/revenuecat-affiliate-tracking).

## What about installs that never touched a Play link?

They arrive with nothing, and there are more of them than the referrer documentation suggests. Sideloads, other Android stores, preloads, and anyone who watched the creator's video and then typed your app name into Play search all produce an install with no referrer.

Three answers, in the order we recommend reaching for them.

**A typed creator code is exact and needs no store cooperation.** Ship a "Got a code?" field wired to `MyAppAffiliate.applyCode("LUMI")`. A code survives a screenshot, a repost that strips your URL, a viewer who installs on a tablet instead, and a Play search. For creator traffic specifically, we think this is the most underrated route on either platform.

**App Links catch users who already have the app.** A creator link then opens your app directly, and you pass the Intent to `MyAppAffiliate.attribute(intent)`. This needs a verified Digital Asset Links file: Android "queries the corresponding websites for the Digital Asset Links file at https://hostname/.well-known/assetlinks.json", and `android:autoVerify="true"` on the intent filter. Skip it and codes still work.

**The deferred match is the last resort, and it is a guess.** On a fresh install with no link and no code, our SDK asks the API to match the install against recent unattributed clicks using a salted hash of the click IP inside a short window. One distinct creator means attribute. Two or more means nothing.

Be clear with yourself about which is which. The referrer is deterministic: the value you put in the URL is the value that comes back. The IP match is probabilistic and fails where you would expect, on office NAT and carrier-grade NAT, and it misses anyone who installs after the window closes. Every row records the method it used. If your dashboard shows mostly IP matches, your codes are not visible enough and your links are not going through Play.

## What Google actually takes, and what that does to "twenty percent"

Not one number, and Google says so first: "There isn't a single service fee as Google Play takes into account that developers operate in different situations." For a subscription app, two entries in the [service fees table](https://support.google.com/googleplay/android-developer/answer/112622) matter, both verified on 2026-09-14.

For transactions with users in the EEA, UK or US starting 30 June 2026, auto-renewing subscriptions are listed at **10% plus a 5% billing fee**, for new and existing installs alike, on the first $1M of annual earnings and on the standard row. The billing fee applies when the purchase goes through Google Play Billing. For all remaining markets, until the updated fees roll out globally, the table lists **15% for automatically renewing subscription products purchased by subscribers, regardless of revenue earned by the developer each year**.

So a subscription app selling through Play Billing keeps 85 cents on the dollar in both regimes today, assembled differently. Note what the table does not contain: no rate that steps at the subscriber's first anniversary. Apple's does, as [the iOS post](/blog/start-affiliate-program-ios-app) sets out, which is why a net-based commission drifts there and holds still here.

On a $9.99 monthly plan, you receive $8.49 (9.99 x 0.85 = 8.4915, truncated to the cent). Here is what the base choice costs you at a 20% rate.

| Structure | Creator earns on one $9.99 month | Forecastable | The Android catch |
| --- | --- | --- | --- |
| Flat bounty per paying install | A fixed amount, once | Yes | The referrer makes bulk attempts cheap, because one URL scales to as many device ids as someone can create |
| 20% of gross | $2.00 | Yes | That is 23.6% of the $8.49 you actually keep |
| 20% of net after Play's fee | $1.70 | Yes | RevenueCat's `commission_percentage` is an estimate and can be null, so keep a configured fallback |
| 20% of net, capped at 12 periods | $1.70 per period, 12 at most | Yes | The cap must live on the commission row, not on the creator record |
| Tiered by creator volume | Rate rises at thresholds | No | A retroactive tier change rewrites a ledger you already paid out |

We default to 20% of net, capped at 12 billed periods, behind a 14 day hold. The cap turns an open-ended liability into a number you can write on one line. The base question in full is in [net versus gross on the app stores](/blog/affiliate-commission-net-vs-gross-app-store), and the structure argument in [affiliate commissions and payouts](/blog/affiliate-commissions-payouts-subscriptions).

## Which billing events move a creator's balance, and what a refund does

Four events matter and the rest are noise. A first payment and a renewal create commission. A trial start is worth zero. A refund reverses. Cancellations and expirations change nothing, because the charges that already happened still stand.

RevenueCat sends no event called `REFUND`. A Play refund arrives as `CANCELLATION` carrying `cancel_reason: CUSTOMER_SUPPORT`, which RevenueCat's [event reference](https://www.revenuecat.com/docs/integrations/webhooks/event-types-and-fields) documents as covering the case where "a Google Play subscription was refunded through RevenueCat". Key a mapping on a `REFUND` event and that branch never fires: every refund is filed as ordinary churn and the creator keeps money you no longer have.

One asymmetry is Android-specific. RevenueCat's `REFUND_REVERSED` event is listed for the App Store only, with Google Play marked unsupported. If Google reverses a refund on Play, nothing reaches your ledger and the commission stays reversed until somebody fixes it by hand.

Google's own rules set the window you are insuring against. Google "doesn't give refunds for most Google Play purchases", but within 48 hours a user "may be able to get a refund depending on the details of the purchase", and after 48 hours the [refund policy](https://support.google.com/googleplay/answer/15574908) sends them to the developer, who "can process refunds according to their policies and applicable laws".

The number that should set your hold period sits on [Play Console's order processing page](https://support.google.com/googleplay/android-developer/answer/137997): "Any orders processed, refunded, or charged-back from the 1st of a given month to the end of the month will get paid out around the 15th of the following month." Google pays you in arrears, netting the month's refunds first. Pay a creator faster than that and you are financing the program from your own balance, then chasing the difference. Raising the hold from its 14 day default to 30 is not caution here, it is matching your outflow to your inflow.

## A worked example on a $9.99 plan, with one refund

One subscriber, 20% of net, a 30 day hold raised from the 14 day default, four charges and one refund. The creator ends with $5.10 and you keep $20.37. Our engine computes in integer cents, as `amount_usd_cents x rate_bps / 10000`, with the rate snapshotted onto the row so a later rate change cannot rewrite history.

Per charge: Google takes 15%, you receive 849 cents, and 849 x 2000 / 10000 = 169.8, so $1.70. On gross it would be 999 x 2000 / 10000 = 199.8, or $2.00, which is 23.6% of what you keep rather than 20%.

![A creator commission ledger across four Google Play charges and one refund](https://www.myappaffiliate.com/blog-images/affiliate-program-android-app/affiliate-program-android-app-ledger.webp "Four charges, one refund inside the hold, and the balance that survives.")

| Date | Event | Gross | Your net | Commission | Creator balance |
| --- | --- | --- | --- | --- | --- |
| 1 Mar | `INITIAL_PURCHASE` | $9.99 | $8.49 | +$1.70 pending | $1.70 |
| 31 Mar | Hold expires, no webhook |  |  | Matures | $1.70 |
| 1 Apr | `RENEWAL` | $9.99 | $8.49 | +$1.70 pending | $3.40 |
| 1 May | `RENEWAL` | $9.99 | $8.49 | +$1.70 pending | $5.10 |
| 12 May | `CANCELLATION`, `cancel_reason: CUSTOMER_SUPPORT` | -$9.99 | -$8.49 | -$1.70 | $3.40 |
| 1 Jun | `RENEWAL` | $9.99 | $8.49 | +$1.70 pending | $5.10 |

Three charges survive, so three commissions do: 3 x $1.70 = $5.10. You keep 3 x $8.49 = $25.47, of which $20.37 stays with you.

Watch the dates rather than the totals. The 1 May charge is refunded on 12 May, so the commission it created is still pending and simply flips status. Google settles May's orders and May's refunds together around 15 June, so that charge never reaches your bank as revenue either. The hold and the payout schedule line up, which is the point.

Run the same subscriber for three years and the Android number stays at $1.70 a month, because Play's subscription rate does not step at the anniversary. The iOS equivalent moves when Apple's does, which is one more reason the two programs need one ledger and not two. Windows and late conversions are their own subject, in [how attribution windows work](/blog/how-attribution-windows-work).

## What has to exist before you pay anybody

Six things, and only one is code: written terms, an approval step, a hold period, a statement a creator can read without asking you, a payout rail, and a record of what you sent. Self-referral and bidding on your brand name are the two exclusions to write down on day one, before anyone tests them.

Payout rails are the boring part. Our customers use PayPal and Wise for cross-border creators and a plain bank transfer when everyone shares a country. We do not move money: the export matures the due commissions, records a payout, marks them paid and returns a CSV that reconciles to the total, which is the input to [payout automation](/blog/affiliate-payout-automation).

Then the part that is not ours to answer. Creators are usually engaged as independent contractors rather than employees, and what a payer has to collect or report depends on your country, the creator's country and the amounts. Programs commonly collect a tax form before the first payment. That is common practice, not a statement about your obligations, and nothing here is tax or legal advice. Ask an accountant before the first payout.

Four things break Android programs around month six, in our experience of cleaning them up:

- **The referrer is read too late.** It lasts 90 days, but the app has to ask, and an app that asks on a screen most users never reach attributes a fraction of what it could.
- **A code and a referrer both attribute one install**, from a creator who published both, so the ledger shows two sources for one device and nobody trusts it.
- **Rates stored on the creator instead of snapshotted on the commission**, so raising a rate silently repays history.
- **No hold period**, which turns every refund into a recovery email and costs you the creator as well as the money.

## The Android setup, in order

Twelve steps, assuming the app ships on Play and bills through RevenueCat, Adapty, Superwall, Stripe or Paddle. Steps 8 and 11 are the ones that catch everything above.

1. **Fix the offer before you touch Gradle.** Rate, base, window, hold, cap. Five numbers.
2. **Write the terms on one page**, with the two exclusions and what a refund does.
3. **Add the SDK**: `implementation("com.myappaffiliate:sdk:0.2.0")`, a plain Kotlin library with no Play Services dependency and minSdk 24.
4. **Put the API key in the manifest** and let the SDK start itself, or call `start` from `Application.onCreate` if your key comes from a secret store.
5. **Call `identify(userId)`** with the exact string your billing provider reports back.
6. **Register the billing webhook** and paste the signing secret.
7. **Ship the "Got a code?" field** wired to `applyCode`. This is the route that needs nothing from Google.
8. **Run one real purchase end to end** on a test track and confirm a single commission row, at the rate and the creator you expect.
9. **Add the Install Referrer library** and pass the string to `applyInstallReferrer` on first launch, once.
10. **Verify `assetlinks.json`** so creator links open the installed app instead of bouncing to the browser.
11. **Recruit five creators, not fifty**, and pay the first round by hand against the Play payout report.
12. **Only then change the rate.** Cheap now, expensive once two hundred creators have terms.

## Where MyAppAffiliate fits

We sit between the click and the payout, and we are specific about which parts are exact. The Android SDK is one manifest line and one call, plus two optional extras: a creator code field and the install referrer string. Revenue from RevenueCat, Adapty, Superwall, Stripe or Paddle normalizes to one event vocabulary, and a commission is created pending with its rate snapshotted, maturing after the hold so a refund inside the window never pays out.

Two things we do not do. We read no advertising id and fingerprint nothing, which is why the deferred match will always be the weakest route in the stack rather than a secret weapon. And we do not send money; we produce the ledger and the export your bank or PayPal acts on.

Pricing is a flat monthly fee with no share of tracked revenue, so [flat pricing](/pricing) means a creator program that works does not quietly raise its own bill.

## FAQ

### Does Google Play come with an affiliate program?

No. Play gives you a `referrer` parameter on the store URL and returns its value to your app after the install. Play Console reports installs and revenue. Nothing in either place knows a creator exists, computes a rate, or pays anyone.

### What happens if the user does not install from a Play link?

Then no referrer exists. Sideloads, other Android stores, preloads and installs from an untracked Play search all arrive with nothing attached. A typed creator code covers those exactly, and our deferred IP match covers some of them approximately.

### What is Google's cut on an auto-renewing subscription?

It depends on the market. For EEA, UK and US transactions from 30 June 2026, Play's [fee table](https://support.google.com/googleplay/android-developer/answer/112622) lists 10% plus a 5% billing fee for auto-renewing subscriptions on new and existing installs. Remaining markets list 15%. Verified 2026-09-14.

### How long can I wait before reading the install referrer?

Google says the information is available for 90 days and will not change unless the app is reinstalled, and advises calling the API only once, on the first run after install. Read it on first launch and store the result yourself.

### If Google reverses a refund, does the commission come back?

Not on its own. RevenueCat's `REFUND_REVERSED` event is listed for the App Store only, so a reversed Google Play refund sends nothing. We treat that as a manual adjustment and check reversals against the Play payout report each month.

## Ship the code field, then the referrer

Put the "Got a code?" field in front of your first five creators this week. It is exact, it needs nothing from Google, and it will carry the program while you wire the referrer properly behind it. The manifest line and the two calls are in the [Android SDK documentation](https://docs.myappaffiliate.com/sdk-android), and the referrer itself is a one-evening job once you have read [the Install Referrer API post](/blog/android-install-referrer-affiliate-attribution).
