Skip to main content

Redemption Links

⚠️Beta Feature

RevenueCat Billing and the RevenueCat Web SDK are currently in beta.

Overview​

Redemption Links is a Web2App feature that allows you to seamlessly connect web purchases with native mobile apps. This reduces friction from the purchase flow, increases conversion and can be useful for campaigns and other projects where handling purchases on the web is easier and more flexible.

πŸ“˜App User IDs no longer required for web purchases

Using web purchases with Redemption Links means that you do not need to provide an App User ID when initializing the purchase, and customers can therefore check out anonymously. The purchase is associated with the logged in customer when they're directed into the mobile app after the purchase is complete.

Here's how a purchase and redemption flow looks, once you've configured and enabled the feature:

  1. The RevenueCat Billing purchase flow is initialized, either through the web SDK purchase() method, or by linking to a Web Paywall Link (App User ID not required at this stage)
  2. The customer purchases a subscription or non-subscription product through the web checkout.
  3. The customer receives a redemption link at the end of the purchase flow, both on the success page, and in the email receipt for the purchase.
  4. On tapping the redemption link, customers are linked into the mobile app (using a custom URL scheme).
  5. The app handles associating the purchase with the customer, either by aliasing or transferring the purchase.
  6. The customer has access to their entitlements associated with the web purchase.

Update your mobile app(s) to register custom URL schemes from RevenueCat​

⚠️Updated mobile apps must be adopted

After Redemption Links are enabled, customers purchasing with an anonymous App User ID will be shown app deep links (to redirect the customer into your app and redeem the purchase). Any customers on older app versions that aren't configured to accept custom URL schemes will not be able to use these links. You should therefore make sure that as many customers as possible have updated to your new app version before sending them to a purchase flow without an App User ID.

The SDK versions supporting Redemption Links are:

RevenueCat SDKVersions supporting Redemption Links
purchases-android8.10.6 and above
purchases-ios5.14.1 and above
purchases-flutterComing soon
purchases-unityComing soon
react-native-purchasesComing soon
purchases-kmpComing soon
purchases-capacitorComing soon

In order to be able to redeem the redemption links in your mobile apps, follow these steps

1. Copy the custom URL scheme from the RevenueCat Dashboard​

You can find this in the RevenueCat dashboard, inside your RevenueCat Billing app’s settings, under β€œRedemption Links”. It is unique to your RevenueCat Billing app:

iOS​

In iOS, you need to define a custom URL schema. You can do this in Xcode, from your xcodeproj file, Info tab, URL Types section. Then add your custom scheme from Step 1 in the β€œURL Schemes” field. You can see a screenshot here, but remember to replace <YOUR_CUSTOM_SCHEME> with the one you obtained in step 1.

You can see official instructions by Apple here.

Android​

In Android, you need to add a deep linking intent filter for the provided scheme. You can do that by adding the following intent filter inside your AndroidManifest.xml activity and replacing <YOUR_CUSTOM_SCHEME> with the scheme you copied in step 1. Note that it’s fine to have multiple intent filters for the same activity.

<manifest>
<application>
<activity>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme=<YOUR_CUSTOM_SCHEME> />
</intent-filter>
</activity>
</application>
</manifest>

You can check out official docs from Google here.

3. Perform redemption using our SDKs​

Our SDKs provide APIs to perform the redemptions and provide you with the result of that redemption.

iOS​

If using SwiftUI, you can use the onWebPurchaseRedemptionAttempt modifier to automatically perform redemption of Redemption Links once the app is opened with them.

YourContent()
.onWebPurchaseRedemptionAttempt { result in
switch result {
case .success(customerInfo):
// Redemption was successful and entitlements were granted to the user.
updateUI(customerInfo)
case let .error(error):
// Redemption failed due to an error.
displayError(error)
case .invalidToken:
// The redemption link is invalid.
displayInvalidLinkError()
case .purchaseBelongsToOtherUser:
// The purchase associated to the link belongs to a different user and it cannot be redeemed.
displayBelongsToOtherUserError()
case let .expired(obfuscatedEmail):
// The redemption link has expired. A new one has been sent to the user to the provided obfuscated email.
displayExpiredMessage(obfuscatedEmail)
}
}

Alternatively, if you don’t want to perform the redemption automatically or if you're not using Swift UI, you can use the provided URL extension asWebPurchaseRedemption and then perform the redemption using Purchases.shared.redeemWebPurchase as follows:

YourContent()
.onOpenURL { url in
if let webPurchaseRedemption = url.asWebPurchaseRedemption {
Task {
let result = await Purchases.shared.redeemWebPurchase(webPurchaseRedemption)
// Handle result
}
}
}
Android​

In Android, you first need to obtain the link and make sure it’s a Redemption Link, then redeem it using the redeemWebPurchase method. You can see an example of this in the following code block:

class MainActivity : Activity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
handleWebPurchaseRedemption(intent)
}

// This allows to respond to the intent if setting certain launch modes in the AndroidManifest.xml.
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
handleWebPurchaseRedemption(intent)
}

private fun handleWebPurchaseRedemption(intent: Intent) {
// This allows to obtain the Redemption Link from the intent if any.
val webPurchaseRedemption = intent.asWebPurchaseRedemption()

if (webPurchaseRedemption != null) {
// This will perform the actual redemption and return a result you can use to update your UI.
Purchases.sharedInstance.redeemWebPurchase(webPurchaseRedemption) { result ->
when (result) {
is RedeemWebPurchaseListener.Result.Success -> {
// Redemption was successful and entitlements were granted to the user.
updateUI(result.customerInfo)
}
is RedeemWebPurchaseListener.Result.Error -> {
// Redemption failed due to an error.
displayError(result.error)
}
RedeemWebPurchaseListener.Result.InvalidToken -> {
// The redemption link is invalid.
displayInvalidLinkError()
}
RedeemWebPurchaseListener.Result.PurchaseBelongsToOtherUser -> {
// The purchase associated to the link belongs to a different user and it cannot be redeemed.
displayBelongsToOtherUserError()
}
is RedeemWebPurchaseListener.Result.Expired -> {
// The redemption link has expired. A new one has been sent to the user to the provided obfuscated email.
displayExpiredMessage(result.obfuscatedEmail)
}
}
}
}
}
}

4. Verify your setup​

Once you’ve followed the steps above, in order to verify that your integration worked correctly you can open your app using a deep link in the format: <YOUR_CUSTOM_SCHEME>://redeem_web_purchase?redemption_token=<ANY_TOKEN>

For example, rc-d458f1e3a2://redeem_web_purchase?redemption_token=invalid_token.

You can use a deep link test app or write the deep link in a notes app and click on it. Alternatively, if you’re using an iOS simulator you can run this command in your mac terminal: xcrun simctl openurl booted "<YOUR_CUSTOM_SCHEME>://redeem_web_purchase?redemption_token=<ANY_TOKEN>", and on android you can follow the instructions here.

Then, you need to make sure that you display the appropriate UI in your app. In this case, an invalid link error.

πŸ“˜Test redemption links in sandbox mode before enabling for production purchases

Use the "Enable only for Sandbox" setting to test the full purchase flow, including deep-linking into your app. This will ensure that you don't send redemption links to customers before they're functioning and tested.

  1. Navigate to your project in the RevenueCat dashboard, and then the RevenueCat Billing app.

  2. Under App Information in the Settings tab, make sure you have added: App icon, App name, and at least one store link for either the App Store or Google Play Store:

  1. Under Redemption Links, set the feature to "Enable only for Sandbox":

  1. Use the sandbox purchase flow to make a test purchase on a mobile device where your app is installed (either through Web Paywall Links sandbox URL, or the Web SDK with a sandbox API key).

Purchase Association Behavior​

πŸ“˜Terminology

In this context, Identified means a Custom App User ID has been set, while Anonymous refers to an App User ID automatically generated by RevenueCat.

When a customer redeems a web purchase in your app, RevenueCat will automatically handle associating the purchase based on the App User IDs involved:

Current App User IDWeb Purchase OwnerResult
AnonymousAnonymousApp customer and Web Purchase Owner have CustomerInfo merged (aliased)
AnonymousIdentifiedApp customer and Web Purchase Owner have CustomerInfo merged (aliased)
IdentifiedAnonymousApp customer and Web Purchase Owner have CustomerInfo merged (aliased)
IdentifiedIdentifiedFollows project's restore behavior (default: transfer the purchase to the new App User ID)

In most cases, the App User IDs will be merged (aliased) and treated as the same customer going forward. The exception is when both App User IDs are identified - in this case, it follows your project's configured restore behavior.

After successful redemption, the customer will immediately have access to their entitlements regardless of which association method was used.

FAQs​

A redemption link is only valid for one single redemption of a purchase β€”Β once redeemed, it's no longer valid.

Can my customers redeem their purchases on multiple devices?​

Customers can redeem a single purchase multiple times (i.e. on a different devices) β€”Β on each occasion they'll be sent a new redemption link to their billing email address, valid for one new redemption.