Skip to main content
Question

Clarification on PRODUCT_CHANGE webhook behavior during plan changes

  • August 20, 2025
  • 3 replies
  • 82 views

Forum|alt.badge.img

I’m integrating with RevenueCat webhooks to track subscription plan changes across iOS and Android. From the documentation, I can see the following events are emitted when a plan change occurs:

  • Android: PRODUCT_CHANGE,INITIAL_PURCHASE

  • iOS: PRODUCT_CHANGE,RENEWAL

My questions:

  1. Can I rely solely on the PRODUCT_CHANGE event to handle corresponding plan changes in the backend for both iOS and Android?

  2. Does the PRODUCT_CHANGE event guarantee that the payment has been processed successfully, or is it just an indication of the plan change attempt?

  3. In the case of a payment failure during a plan change, what happens to the subscription?

    • Does the existing subscription continue until the end of the billing period?

    • Or would RevenueCat emit an EXPIRATION event for the new subscription?

This post has been closed for comments

3 replies

jeffrey_bunn
RevenueCat Staff
Forum|alt.badge.img+6
  • RevenueCat Staff
  • August 20, 2025

Hi ​@sathya

Can I rely solely on the PRODUCT_CHANGE event to handle corresponding plan changes in the backend for both iOS and Android?

It depends what you plan on doing with this information. Product changes don’t necessarily mean that a payment has been taken and they should have access to a different entitlement. If you’re using webhooks to unlock entitlement access, it’s best to rely on initial_purchase, renewal, and expiration webhooks (as these events occur when the changes happen).

 

Does the PRODUCT_CHANGE event guarantee that the payment has been processed successfully, or is it just an indication of the plan change attempt?

Related to above, no, it isn’t the case that payments have necessarily gone through when a product_change webhook is sent. It’s best to wait for purchase events (initial_purchase, renewal, expiration) to know when to unlock/revoke entitlements.

 

In the case of a payment failure during a plan change, what happens to the subscription?

It depends whether this is an immediate product change or product change at period end, but in general, you’ll receive a product_change webhook, and if there’s a failure when the payment is attempted, then the usual billing issue flow will apply. Your grace period settings are relevant here.

 

Let me know if you have specific questions based on a flow you’re designing. Thanks!


Forum|alt.badge.img
  • Author
  • New Member
  • August 21, 2025

Hi ​@jeffrey_bunn ,

Thanks so much for getting back to me and for clarifying how the events work!

Here’s the flow we’re aiming for:

  • We use webhooks to manage entitlement access in our system based on the user’s active plan.

  • Upgrades (lower → higher tier): users should get immediate access to the new entitlements.

  • Downgrades (higher → lower tier): the downgrade should only take effect at the end of the current billing period, but we’d still like to reflect in our system that an upcoming downgrade has been scheduled and also display this information to the user.

From the docs, I understand that:

  • For downgrades scheduled at the end of a billing period, PRODUCT_CHANGE is sent immediately, while the corresponding RENEWAL (iOS) or INITIAL_PURCHASE (Android) is only sent when the billing period ends.

Based on your recommendations, I’m thinking of the following approach:

  • Upgrades: Listen for RENEWAL (iOS) and INITIAL_PURCHASE (Android). If the product_id in the event has changed, update our system and unlock new entitlements immediately.

  • Downgrades: Listen for the PRODUCT_CHANGE event on both iOS and Android, update our system to mark/schedule a downgrade, and display this to the user. Also, automatically switch the entitlement changes at the end of the billing period.

We’ve also configured a grace period in RevenueCat for payment failures. My understanding is that at the end of the billing period, if the user is moving to a lower-tier plan and the initial payment attempt fails, they would remain on the lower-tier plan during the grace period (with the chance to retry payment). If all retries fail, RevenueCat would then emit an EXPIRATION event for that downgraded plan.

Does this understanding sound correct? Really appreciate your feedback on this approach.


jeffrey_bunn
RevenueCat Staff
Forum|alt.badge.img+6
  • RevenueCat Staff
  • August 27, 2025

@sathya Happy to help! I think your flow makes sense, though this part from the Downgrades section:

Also, automatically switch the entitlement changes at the end of the billing period.

should probably not be implemented. Instead, rely on the actual payment events (renewal, initial purchase, etc) when a purchase actually goes through.

I’m curious why you’re reimplementing entitlement logic in your backend? I understand the use case of showing a user an upcoming downgrade, but I wonder if you can use the RevenueCat API to manage entitlements rather than duplicating status on your end? Happy to help further here!