Management & Refunds

Making changes to a customer's subscription

Some parts of a customer's subscription can be managed directly through RevenueCat, other parts can only be managed by the customer directly in the respective stores (Apple, Google, Stripe, and Amazon). Learn how to upgrade/downgrade, cancel, and refund subscriptions here!

For information about Stripe, you can read more about working with web payments here.

Upgrade or Downgrade a Subscription

๐Ÿ“˜

Developers cannot change a customer's subscription directly

The app stores do not allow developers (you) to upgrade or downgrade a subscription on behalf of a customer. Only a customer can change their subscription.

App Store

There are no code changes required to support upgrades, downgrades, and crossgrades for iOS subscriptions in your app. A customer can choose to upgrade, downgrade, or crossgrade between subscriptions as often as they like.

According to Apple, when a customer changes their subscription level, access to the new product can vary depending on the change:

Upgrade. A user purchases a subscription that offers a higher level of service than their current subscription. They are immediately upgraded and receive a refund of the prorated amount of their original subscription. If youโ€™d like users to immediately access more content or features, rank the subscription higher to make it an upgrade.

Downgrade. A user selects a subscription that offers a lower level of service than their current subscription. The subscription continues until the next renewal date, then is renewed at the lower level and price.

Crossgrade. A user switches to a new subscription of the equivalent level. If the subscriptions are the same duration, the new subscription begins immediately. If the durations are different, the new subscription goes into effect at the next renewal date.

You can refer to this blog post for more information on how to set up subscription groups in App Store Connect.

๐Ÿ“˜

Upgrades during introductory periods

When a customer upgrades products during an introductory period (including a free trial), Apple does not cancel the introductory offer but instead keeps the introductory offer active in addition to the upgraded product. So in these cases you can expect two products in the same Subscription Group to be active simultaneously.

Google Play

In order to perform upgrades and downgrades for Google Play subscriptions, you need to pass the UpgradeInfo object to either purchaseProduct or purchasePackage. The UpgradeInfo is a small object containing the oldSKU (the SKU the user is changing from) and the prorationMode. Proration modes are documented here.

๐Ÿ“˜

Supported proration modes

RevenueCat currently only supports IMMEDIATE_WITH_TIME_PRORATION. This mode changes the subscription immediately and the remaining time will be prorated. Using alternate proration modes will work accurately for the customer subscription, but the pricing will not be correctly reflected in RevenueCat.

Amazon Appstore

Amazon does not support changing products. Customers will need to cancel their existing subscription and re-subscribe to a different product.

Considerations

PRODUCT_CHANGE events and webhooks

  • The expiration_at_ms will always be for the product the customer is changing from (old product).
  • The PRODUCT_CHANGE webhook should be considered informative, and does not mean that the product change has gone into effect. When the product change goes into effect you will receive a RENEWAL event on Apple or a INITIAL_PURCHASE event on Google Play.

Prorations and Revenue Metrics

App Store

For Apple transactions, prorated revenue will not be shown in the Customer History page. However, prorated revenue will be calculated for your chart and overview data.

Google Play

RevenueCat assumes the default proration mode, IMMEDIATE_WITH_TIME_PRORATION, for all pricing calculations. This mode will take effect immediately, and the new expiration time will be prorated and credited or charged to the user.

If you choose a different proration mode, the subscription status will be reflected correctly but the RevenueCat price calculation will be off.

Cancelling Subscriptions

Cancelling (or unsubscribing) from subscriptions is handled differently on each platform. Cancellations are automatically detected by RevenueCat within a few hours of occurring. This detection time can be increased to near real-time by enabling Platform Server Notifications.

Store

Behavior

Apple

Apple does not allow developers to manage subscriptions on behalf of users. Your customers have to manually opt-out of renewal. The Apple subscription terms require users to cancel subscriptions at least 24 hours before the next renewal.

Google Play

To revoke a Google Play subscription, you can use our REST API endpoint to do so. This will refund the last purchase, immediately expire the subscription, and remove entitlement access. This can also be done from the dashboard (see 'Refund a Subscription' below for more details).

Stripe

Subscriptions can be cancelled through the Stripe dashboard or REST API. Refer to Stripe documentation for more info.

Amazon

Amazon does not allow developers to cancel subscriptions on behalf of users. Once a subscription is purchased for a period, it is valid through that period and cannot be cancelled.

Using the managementURL to Help Customers Cancel a Subscription

As of August 27, Google requires developers to allow customers to cancel a subscription within apps. You can do this by displaying a link in your app that takes the user directly to Google Play's subscription management screen where they can immediately cancel their subscription. RevenueCat helps you do this by providing a managementURL property on the CustomerInfo object in the SDK and in our REST API.

๐Ÿ“˜

Include the managementURL on iOS

The managementURL is a great way to allow customers to check the status of and manage their subscriptions on both iOS and Android. RevenueCat will automatically provide your app with the correct managementURL based on the platform of the customer's device and original store they purchased their subscription from.

Purchases.shared.getCustomerInfo { (customerInfo, error) in
    let managementURL = customerInfo.managementURL
    // display the managementURL in your app
}
Purchases.sharedInstance.getCustomerInfo({ error -> /* Optional error handling */ }) { customerInfo ->
    val managementURL = customerInfo.managementURL
    // display the managementURL in your app
}

๐Ÿšง

Deleting a User

Deleting a user from RevenueCat WILL NOT cancel their subscription. The user can still trigger the Restore Purchases method to re-sync their transactions with RevenueCat servers.

Refunding Purchases

Refunds are handled differently on each platform. It's recommended to set up Platform Server Notifications for the best performance.

Platform

Subscriptions

Non-subscriptions

Apple

โœ… RevenueCat will automatically detect when a refund has been issued by Apple, but Apple does not allow developers to issue refunds on behalf of customers

If a customer requests a refund, you can direct them to the Apple support page: https://support.apple.com/en-us/HT204084

๐Ÿšง RevenueCat requires Platform Server Notifications to be enabled in order to detect when a non-subscription refund has been issued by Apple. Apple does not allow developers to issue refunds on behalf of customers

If a customer requests a refund, you can direct them to the Apple support page: https://support.apple.com/en-us/HT204084

Google Play

๐Ÿšง Active Google Play subscriptions may be refunded directly through the RevenueCat dashboard. Click on the respective transaction event on the customer page and hit "Refund" in the upper right. Documentation for reference.

Refunds can also be granted programmatically through the RevenueCat REST API. This will immediately revoke access to the Google subscription and issue a refund for the last purchase.

If a refund is granted by Google or initiated through the Google Play console, it will not be detected as a refund in RevenueCat and the subscription will remain active until the end of the current billing period.

๐Ÿšง Google Play non-subscriptions can be refunded directly through the RevenueCat dashboard or REST API (see refunding Google Play Subscriptions for more info on how to do this).

If a non-subscription refund is granted by Google or initiated through the Google Play console, it will not be detected as a refund in RevenueCat, and the purchase will remain active.

Stripe

โœ… RevenueCat will automatically detect when a refund has been issued through Stripe. Note that you have the option in Stripe to refund, or refund and revoke access. See Stripe's docs for more info.

โœ… RevenueCat will automatically detect when a refund has been issued through Stripe. Note that you have the option in Stripe to refund, or refund and revoke access. See Stripe's docs for more info.

Amazon

โŒ Amazon does not allow developers to issue refunds on behalf of users.

If a user has a valid reason for a pro-rated refund, they should contact Amazon customer service through the Contact Us link at amazon.com.

Refunds granted through Amazon customer service will not be detected as a refund in RevenueCat and the subscription will remain active until the end of the current billing period.

โŒ Amazon does not allow developers to issue refunds on behalf of users.

If a user has a valid reason for a pro-rated refund, they should contact Amazon customer service through the Contact Us link at amazon.com.

Refunds granted through Amazon customer service will not be detected as a refund in RevenueCat, and the purchase will remain active.


Did this page help you?