How to Let Users Manage or Cancel a Subscription
Overview
RevenueCat cannot cancel a subscription for the user. Cancellations and plan changes always happen on the store side (the App Store or Google Play). Your job is to send the user to the correct management screen. There are two ways to do this:
- iOS (native):
showManageSubscriptions()presents the App Store manage subscriptions sheet directly inside your app. - Cross-platform:
customerInfo.managementURLis a URL you open yourself. This is the approach to use on Android and React Native, where there is no native manage screen method.
Purchases.configure(...). See the iOS codelab and the
Configure the SDK guide for setup. You also need a way to fetch
CustomerInfo; see Get CustomerInfo.
iOS: showManageSubscriptions() (Native)
On iOS, RevenueCat exposes a native helper that opens the App Store manage subscriptions sheet
without you having to build or open a URL. Call it from a Restore or
Manage Subscription button:
import RevenueCat
func openManageSubscriptions() async {
do {
// Presents the native App Store manage subscriptions sheet.
try await Purchases.shared.showManageSubscriptions()
} catch {
print("Could not open manage subscriptions: \(error.localizedDescription)")
}
}
From SwiftUI you can call it from a button action:
Button("Manage Subscription") {
Task {
do {
try await Purchases.shared.showManageSubscriptions()
} catch {
print("Manage subscriptions failed: \(error)")
}
}
}
showManageSubscriptions() presents the App Store sheet and is
specific to the iOS SDK. On Android and React Native, use managementURL instead
(covered below). The Android SDK does not provide a native manage subscriptions method.
Cross-platform: customerInfo.managementURL
Every CustomerInfo object carries a managementURL property. This URL points
to the store's subscription management page: the App Store page for App Store subscriptions, and the
Google Play page for Google Play subscriptions. You fetch CustomerInfo with
getCustomerInfo() and then open the URL yourself with the platform's standard URL
opener.
This is the right approach when:
- You are on Android, where there is no native manage screen method.
- You are on React Native, where you open the URL with
Linking. - You want a single code path that works the same way across stores.
null when there is no active store
subscription to manage, or when the active subscription was purchased on a different platform than the
current device. Always check for null before opening it. See the
When managementURL is null section.
React Native: Open managementURL with Linking
Fetch CustomerInfo with getCustomerInfo(), then open
managementURL with React Native's Linking API. Guard against a
null URL first:
import { Linking } from 'react-native';
import Purchases from 'react-native-purchases';
async function openManageSubscriptions() {
try {
const info = await Purchases.getCustomerInfo();
if (info.managementURL) {
await Linking.openURL(info.managementURL);
} else {
// No active store subscription to manage on this platform.
console.log('No management URL available.');
}
} catch (e) {
console.log('Failed to open manage subscriptions', e);
}
}
In a component, wire it to a button and disable the button when there is nothing to manage:
import { useEffect, useState } from 'react';
import { Button, Linking } from 'react-native';
import Purchases from 'react-native-purchases';
export function ManageSubscriptionButton() {
const [managementURL, setManagementURL] = useState<string | null>(null);
useEffect(() => {
Purchases.getCustomerInfo().then((info) => {
setManagementURL(info.managementURL);
});
}, []);
return (
<Button
title="Manage Subscription"
disabled={!managementURL}
onPress={() => {
if (managementURL) Linking.openURL(managementURL);
}}
/>
);
}
Android: Open managementURL with an Intent
The RevenueCat Android SDK does not have a native
showManageSubscriptions method. Instead, read customerInfo.managementURL
and open it with a standard ACTION_VIEW intent, which routes to the Google Play
subscription management page:
import android.content.Intent
import android.net.Uri
import com.revenuecat.purchases.Purchases
import com.revenuecat.purchases.getCustomerInfoWith
fun openManageSubscriptions(context: Context) {
Purchases.sharedInstance.getCustomerInfoWith(
onError = { error ->
Log.e("Purchases", "Could not load CustomerInfo: ${error.message}")
},
onSuccess = { customerInfo ->
val url = customerInfo.managementURL
if (url != null) {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url.toString()))
context.startActivity(intent)
} else {
// No active subscription to manage on this device.
Log.d("Purchases", "managementURL is null")
}
}
)
}
With coroutines you can use the suspend variant awaitCustomerInfo() instead:
lifecycleScope.launch {
try {
val customerInfo = Purchases.sharedInstance.awaitCustomerInfo()
val url = customerInfo.managementURL
if (url != null) {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url.toString())))
} else {
showMessage("No subscription to manage on this device.")
}
} catch (e: PurchasesException) {
Log.e("Purchases", "Failed to load CustomerInfo: ${e.message}")
}
}
When the Management URL is null
managementURL is not always present. Handle these cases so your UI never tries to open a
missing URL:
| Situation | managementURL |
|---|---|
| Active store subscription on the current platform | A URL to the store management page |
| No active store subscription to manage | null |
| Subscription purchased on a different platform | null |
managementURL will be null on the
current device because the store on this device cannot manage a subscription bought elsewhere. In that
case, tell the user to manage the subscription from the original store, or link to the store's generic
subscription settings page.
managementURL is null and,
on iOS, the user has no manageable subscription, hide or disable the manage button rather than showing
an error. The URL points to the App Store or Google Play page depending on where the subscription was
purchased, so there is nothing to open when it is absent.
FAQ
How do I open the manage subscriptions screen on iOS?
Call try await Purchases.shared.showManageSubscriptions(). It presents the native App
Store manage subscriptions sheet where the user can change or cancel their plan.
Does React Native have a showManageSubscriptions method?
No. The native showManageSubscriptions() helper is part of the iOS SDK. On React Native
and Android, open customerInfo.managementURL instead. On React Native that means
Linking.openURL(info.managementURL).
Can RevenueCat cancel a subscription for me?
No. Cancellations always happen on the store (App Store or Google Play). RevenueCat only sends the
user to the correct management page, either through showManageSubscriptions() on iOS or
through managementURL elsewhere.
Why is managementURL null?
Because there is no active store subscription to manage, or because the active subscription was bought
on a different platform than the current device. Check for null and hide the manage
button when it is missing.
Related Guides
- Get CustomerInfo & Refresh the Cache: fetch the CustomerInfo that holds managementURL
- Restore Purchases on iOS (Swift): the companion restore flow on iOS
- Restore Purchases on Android (Kotlin): the companion restore flow on Android
- Check Subscription Status on iOS: read active entitlements before showing a manage button
- iOS In-App Purchases Tutorial: full end-to-end RevenueCat iOS integration
- RevenueCat Docs: official reference