Solved

Some RENEWAL webhook events are missing (at least in Sandbox)

  • 6 January 2022
  • 7 replies
  • 57 views

Badge +4

Hei there.

We are getting closer and closer to finally launch the app :)

But yesterday we found that not all RENEWAL events are send to our server.

For one test purchase I got 8 Emails from Google (initial purchase, 6 renewing and cancelling)

In the RC Dashboard I only see 3 events for this user, INITIAL_PURCHASE, RENEWAL, CANCELLATION.

In a previous test I got 4 events from RC, this time there were 2 RENEWAL events inbetween INITIAL_PURCHASE and CANCELLATION.

Why is this happening?

 

And a Bonus question is about the BILLING_ISSUE and the CANCELLATION events. When the subscription ends, like in this case because the user did not pay anymore, shouldn’t there be both events fired? Or do they just show up as one event in the RC dashboard?

icon

Best answer by tina 7 January 2022, 02:09

View original

7 replies

Badge +4

I have a second Bonus question, is the UNCANCELLATION event working (in sandbox)?

I would expect it to fire when a paused subscription is resumed, but this seams not to be the case. Instead a RENEWAL event is fired.

 

Also, it seams that I have to open the app on device to cause some of the events to fire. Might this be the reason why I don\t see all the RENEWAL events in the sandbox, because they are too close together and if I don\t open the app inbetween the renewals, RC does not detect them? (Assuming that opening the app causes a manual update of the subscription status)

Userlevel 4
Badge +9

Hey @Felix B 

Due to sandbox’s accelerated renewal and expirations time, sometimes not all renewals will be reflected in the RevenueCat Customer History page. We also have a section about this in the documentation.

 

And a Bonus question is about the BILLING_ISSUE and the CANCELLATION events. When the subscription ends, like in this case because the user did not pay anymore, shouldn’t there be both events fired? Or do they just show up as one event in the RC dashboard?

The BILLING_ISSUE event will trigger if and only if Google encountered issues charging a customer’s card. Note that in sandbox the number of renewals is random. The Billing Library documentation states “test subscriptions can renew a maximum of six times.” Meaning it’s an arbitrary number between 1 and 6. The app stores will randomly throw billing issues your way, but this is not guaranteed.

 To simulate a BILLING_ISSUE, you can change your test cards before the next renewal. Billing Library documentation for more information on the steps to simulate a billing issue. Pasting here for convenience:

  1. Sign up for an in-app subscription using your licensed test account and the payment method of "Test instrument always approves"
  2. Go to the Account > Subscriptions section of the Google Play app, click your test subscription, and change payment method to "Test instrument, always declines"

 

I have a second Bonus question, is the UNCANCELLATION event working (in sandbox)?

I would expect it to fire when a paused subscription is resumed, but this seams not to be the case. Instead a RENEWAL event is fired.

The SUBSCRIPTION_PAUSED is an event type to detect a paused subscription on your server. There is no "resumed" event, will just be the next renewal. The UNCANCELLATION event will trigger if a customer opts out of renewal and later reenables it. Note that SUBSCRIPTION_PASUED AND CANCELLATION are two different event types. To read more about paused subscriptions and cancellations

 

Also, it seams that I have to open the app on device to cause some of the events to fire. Might this be the reason why I don\t see all the RENEWAL events in the sandbox, because they are too close together and if I don\t open the app inbetween the renewals, RC does not detect them? (Assuming that opening the app causes a manual update of the subscription status)

When the app is opened, the SDK will send our servers any transactions that were completed in the queue. To reduce data delivery times, I recommend setting up Platform Server Notifications. When Platform Server Notifications are set up, the app does not need to be opened in order for RevenueCat to detect these subscription updates. 

 

Hope this helps!

Badge +4

Hei Tina, 

thanks a lot for this great answer! It helps a lot.

So I misunderstood the uncalleation event. Will test this right away.

I saw the documentation, but it states that not all events might show up in the DASHBOARD, but I assumed that all events would be sent to my webhook. And in regard to the number of renewals, as mentioned, I got 6 emails from google, so I am sure that there actually were 6 renewal events. And I always got 6 renewal events. Are you sure that this number is random?

But I have found a new problem. On Android, the EXPIRATION event comes together with the CANCELLATION event when the user cancels the subscription, even if there is a grace period set and the subscription actually lasts for longer.

On iOS it behaves as I would expect it and as the documentation states: First the CANCELLATION event fires and the EXPIRATION event only comes when the grace period is over.

Or might is this also related the the platform server notifications?

 

Thanks in advance,

Felix

Badge +4

Update:

Enabling the server push notifications resolved most of our problems.

One thing that is left now is that on Android the CANCELLATION event fires together with the BILLING_ERROR event in case of problems with the billing. This seams wrong, as the user did not cancel the subscription and it actually continues active for a certain period, especially if the grace period is enabled.

For now I am ignoring the CANCELLATION event when the cancel_reason is BILLING_ERROR. 

What is the correct or recommended way of doing this?

Another problem that I am seeing is that (on ios) the EXPIRATION event is fired together with the CANCELLATION event. Is it normal to send two emails to the user in this case? Because cancellation does not necessary expire the subscription immediately. So currently the cancellation email contains the information until when the subscription continues valid, but it is strange if the time is now and at the same time comes the expiration email, telling that the user now does not more have a valid subscription.

How is this best handled?

Userlevel 4
Badge +9

Hey @Felix B 

And I always got 6 renewal events. Are you sure that this number is random?

RevenueCat will dispatch webhook events as soon as our servers detect it. Having Platform Server Notifications would allow our servers to be pinged by Google directly for any subscription updates. The app stores (iOS and Android) do throw random billing issues, so the renewal number can be less than 6 in these cases. The sandbox environment does have quirks due to the it’s accelerated renewals, so it is possible that some events are missed. Missed events shouldn’t happen in production unless there’s an issue on our side (extremely rare edge case) or your servers are down temporarily. Rest assured that we’ll attempt to redeliver any failed integration events up to 5 times. If events not dispatching is due to an issue on our side, our engineers will retry failed events once the issue has been fixed. Checking out the status page is a great source to check first if there are any issues on our end: https://status.revenuecat.com/ 

 

But I have found a new problem. On Android, the EXPIRATION event comes together with the CANCELLATION event when the user cancels the subscription, even if there is a grace period set and the subscription actually lasts for longer.

The EXPIRATION event should come when the event is actually expired. If you don’t mind sharing an example app user ID here, I can take a look into it.

 

One thing that is left now is that on Android the CANCELLATION event fires together with the BILLING_ERROR event in case of problems with the billing. This seams wrong, as the user did not cancel the subscription and it actually continues active for a certain period, especially if the grace period is enabled.

For now I am ignoring the CANCELLATION event when the cancel_reason is BILLING_ERROR. 

What is the correct or recommended way of doing this?

This is the expected behavior. This is actually how iOS does it, Apple considers the subscription as cancelled when a customer encounters a billing issue because their subscription will not renew unless they fix their billing. Due to this behavior, we’ll make it consistent across platforms. The CANCELLATION event is fired as soon as we know that “if nothing else happens, the subscription will expire”. The recommended way of handling this event is taking a look at the expiration_at_ms field to know when it will actually expire if no further actions is taken on the customer side.

 

Another problem that I am seeing is that (on ios) the EXPIRATION event is fired together with the CANCELLATION event. Is it normal to send two emails to the user in this case? Because cancellation does not necessary expire the subscription immediately. So currently the cancellation email contains the information until when the subscription continues valid, but it is strange if the time is now and at the same time comes the expiration email, telling that the user now does not more have a valid subscription.

How is this best handled?

If you have grace periods set up for iOS, the cancellation event will trigger first, then the expiration event will trigger once the grace period is over. If no grace period is enabled, BILLING_ISSUECANCELLATION (cancel_reason: BILLING_ERROR) and EXPIRATION (expiration_reason: BILLING_ERROR) all fire at the same time.

If you have grace periods, you can send an email about the CANCELLATION event informing the customer the subscription is set to expire if no further action is taken. Then send another email for EXPIRATION events when the subscription is no longer valid. 

If you do not have grace periods, you should just send 1 email, reacting to either the cancellation or expiration events, to prevent spamming your customers. 

Badge +4

Hei Tina.

Thanks again for the super detailed answer!

I now saw the random billing errors on iOS. On Android I did not encounter them until now. (And I think they don\t make too much sense as we can simulate the billing error by choosing a card that always fails).

Anyways, as I said, since we setup server push notifications all events came through properly.

 

About the other events. I think I will stick to the mentioned way of doing it, when the cancel_reason is BILLING_ERROR I do NOT send an email in the CANCELATION event, but just send an email for the BILLING_ISSUE, as they are fired at the same time and it seams more logic to me. Also, as far as I can tell, only the BILLING_ISSUE event contains the grace_period_expiration_at_ms parameter, which I need to tell the user until when he/she has time to fix the billing issue. Right?

We DO have grace periods setup for all platforms, so I think this is the correct way of doing it…

 

About this point:
But I have found a new problem. On Android, the EXPIRATION event comes together with the CANCELLATION event when the user cancels the subscription, even if there is a grace period set and the subscription actually lasts for longer.

It seams to be also working properly now. Will keep monitoring. If I see this again I will send you the appUserId.

 

Thanks and best regards,

Felix

Userlevel 4
Badge +9

Hey @Felix B 

Also, as far as I can tell, only the BILLING_ISSUE event contains the grace_period_expiration_at_ms parameter, which I need to tell the user until when he/she has time to fix the billing issue. Right?

That’s correct! The grace_period_expiration_at_ms is time that the grace period for the subscription would expire and is measured in milliseconds since Unix epoch.

If you have other issues, feel free to open a new post!

Reply