We are seeking clarification on the behavior of App Store Server Notifications V2.
Summary
In our production environment, we received a notification with notificationType: DID_FAIL_TO_RENEW and subtype: GRACE_PERIOD. However, the gracePeriodExpiresDate field in the payload was null.
We understand this notification indicates that a user's subscription has entered a grace period. The null value for its expiration date is unexpected, and we are looking for an official explanation of this behavior and the correct way to handle it.
The Scenario
Here are the details of the notification we received:
Notification Type: DID_FAIL_TO_RENEW
Notification Subtype: GRACE_PERIOD
Environment: Production
Upon decoding the signedRenewalInfo JWS from the responseBodyV2, we found that the gracePeriodExpiresDate field inside the JWSRenewalInfoDecodedPayload was null.
The notificationUUID for this event was in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
Our Implementation and its Impact
Our backend is designed to ensure service continuity during a grace period, as recommended in the documentation.
Current Logic:
Receive the DID_FAIL_TO_RENEW / GRACE_PERIOD notification.
Extract the gracePeriodExpiresDate.
Extend the user's subscription expiration date in our database to match this date.
Because the gracePeriodExpiresDate was null in this case, our logic failed, creating a risk of service interruption for the user.
Context and Investigation
We have performed the following checks:
App Store Connect Settings: We have confirmed that Billing Grace Period is enabled for the relevant subscription group.
Sandbox Environment: We have been unable to reproduce this scenario in the Sandbox.
User Context: We believe the user in this case was experiencing a failed payment when attempting to renew for the first time after a free trial period.
Questions
To ensure we handle this scenario correctly, we would appreciate clarification on the following points:
Conditions for Null: Under what specific conditions does a DID_FAIL_TO_RENEW notification with a GRACE_PERIOD subtype contain a null gracePeriodExpiresDate?
Expected Behavior: Is this null value an expected behavior for certain scenarios, such as the first failed renewal after a free trial?
Best Practice: If this is an expected behavior, what is the correct way to handle it? How should our backend interpret a null gracePeriodExpiresDate to ensure service continuity for the user?
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
In-App Purchase
App Store Server Notifications