What does the App Store notification DID_CHANGE_RENEWAL_STATUS mean?
The App Store notification DID_CHANGE_RENEWAL_STATUS means the customer changed whether their subscription renews automatically.
Quick facts#
| Notification | notificationType DID_CHANGE_RENEWAL_STATUS |
| Where | App Store Server Notifications v2 (responseBodyV2DecodedPayload) |
| Sent by | The App Store server, to your notification URL |
| What Apple says | The customer changed the subscription's renewal status. AUTO_RENEW_ENABLED means auto-renew was turned on; AUTO_RENEW_DISABLED means it was turned off, by the customer or by the App Store after a refund request. |
What triggers it#
- Subtype
AUTO_RENEW_DISABLED: the customer cancelled from the App Store Subscriptions page, or the App Store turned off auto-renew after the customer started a refund through your app's refund request API. - Subtype
AUTO_RENEW_ENABLED: the customer subscribed again after cancelling, which turns auto-renew back on. - Apple also sends it without a subtype when the customer cancels after a price increase notice.
What your server should do#
- Verify the
signedPayloadwith Apple's App Store Server Library (SignedDataVerifier.verifyAndDecodeNotification) before you act on anything in it. - Keep access until
expiresDate: the customer paid for the period. - On
AUTO_RENEW_DISABLED, start your win-back flow. Apple suggests this notification as one input for deciding who is eligible for a promotional offer. - On
AUTO_RENEW_ENABLED, stop the win-back flow. - Answer HTTP 200 (any code from 200 to 206) once you have stored the notification. Apple retries other answers five times, at 1, 12, 24, 48 and 72 hours after the previous attempt, so make your handler safe to run twice (the payload carries a
notificationUUID).
Example#
// Run on the decoded payload, after you verified Apple's signature.
const notification = {"notificationType":"DID_CHANGE_RENEWAL_STATUS","subtype":"AUTO_RENEW_DISABLED","data":{"environment":"Sandbox","bundleId":"com.example.app"}};
function decide(n) {
if (n.notificationType !== "DID_CHANGE_RENEWAL_STATUS") return "ignore";
if (n.subtype === "AUTO_RENEW_DISABLED") return "keep access to the end of the period, start win-back";
if (n.subtype === "AUTO_RENEW_ENABLED") return "stop win-back";
return "check the renewal info";
}
console.log(decide(notification));Run-checked: npm run check:snippets runs this snippet with Node and compares its output with start win-back (checked 2026-10-03).
How RevenueDot handles it#
RevenueDot verifies Apple's signature, checks the bundle ID, stores the notification and answers 200. A purchase RevenueDot has not seen is applied only when the app's Track new purchases from server-to-server notifications setting is on. Type overrides set auto-renew from the subtype. Turning it off gives a CANCELLATION event with cancel_reason: UNSUBSCRIBE (or the store's reason, or BILLING_ERROR when a billing issue exists); turning it back on gives UNCANCELLATION. Access is not touched, so no EXPIRATION is sent until the period ends.
Related#
- What does the App Store notification DID_CHANGE_RENEWAL_STATUS with subtype AUTO_RENEW_DISABLED mean?
- What does the App Store notification EXPIRED mean?
- What does the App Store notification DID_CHANGE_RENEWAL_PREF mean?
- Which webhook events does RevenueDot send?
- Set up App Store notifications in RevenueDot
Source#
- Apple: notificationType
- Apple: Responding to App Store Server Notifications
- Apple: app-store-server-library-node (SignedDataVerifier)
- RevenueDot server: stores/apple/notifications.ts (how the notification is applied)
- RevenueDot server: stores/apple/map.ts (how the transaction becomes a stored purchase)
- RevenueDot core: events.ts (how a change becomes a webhook event)
Checked: 2026-10-03