---
title: "What does the App Store notification DID_CHANGE_RENEWAL_PREF mean?"
description: "DID_CHANGE_RENEWAL_PREF means the customer changed their subscription plan. UPGRADE starts now, DOWNGRADE at the next renewal, and no subtype means they reverted a downgrade."
url: https://revenuedot.app/docs/notifications/apple-did-change-renewal-pref
---

# What does the App Store notification DID_CHANGE_RENEWAL_PREF mean?

The App Store notification DID_CHANGE_RENEWAL_PREF means the customer switched to a different subscription plan in the same group.

## Quick facts

| | |
|---|---|
| Notification | `notificationType` `DID_CHANGE_RENEWAL_PREF` |
| Where | App Store Server Notifications v2 (`responseBodyV2DecodedPayload`) |
| Sent by | The App Store server, to your notification URL |
| What Apple says | The customer changed their subscription plan. UPGRADE takes effect immediately, DOWNGRADE at the next renewal date, and an empty subtype means the customer reverted to the current plan, cancelling a downgrade. |

## What triggers it

- Subtype `UPGRADE`: the upgrade takes effect at once and starts a new billing period. Apple gives the customer a prorated refund for the unused part of the old period.
- Subtype `DOWNGRADE`: the change takes effect at the next renewal date and does not affect the active plan. A cross-grade to a different duration counts as a downgrade.
- No subtype: the customer changed the renewal preference back to the current plan, which cancels a scheduled downgrade.

## What your server should do

1. Verify the `signedPayload` with Apple's App Store Server Library (`SignedDataVerifier.verifyAndDecodeNotification`) before you act on anything in it.
2. On `UPGRADE`, switch the entitlement now, to the product in the new transaction.
3. On `DOWNGRADE`, keep the current plan and note the product in `autoRenewProductId` of the renewal info as the plan from the next renewal.
4. With no subtype, clear the scheduled change.
5. 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

```javascript
// Run on the decoded payload, after you verified Apple's signature.
const notification = {"notificationType":"DID_CHANGE_RENEWAL_PREF","subtype":"UPGRADE","data":{"environment":"Sandbox","bundleId":"com.example.app"}};

function decide(n) {
  if (n.notificationType !== "DID_CHANGE_RENEWAL_PREF") return "ignore";
  if (n.subtype === "UPGRADE") return "switch plan now";
  if (n.subtype === "DOWNGRADE") return "switch plan at the next renewal";
  return "clear the scheduled downgrade";
}

console.log(decide(notification));
```

*Run-checked: `npm run check:snippets` runs this snippet with Node and compares its output with `switch plan now` (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. The renewal info's `autoRenewProductId` is stored. A downgrade scheduled for the next renewal gives `PRODUCT_CHANGE` with `new_product_id` set to that product. An upgrade arrives as a transaction for the new product, which gives `PRODUCT_CHANGE` with `product_id` the old product, plus `RENEWAL` when the new product starts a new period.

## Related

- [What does the App Store notification OFFER_REDEEMED mean?](https://revenuedot.app/docs/notifications/apple-offer-redeemed.md)
- [What does the App Store notification DID_RENEW mean?](https://revenuedot.app/docs/notifications/apple-did-renew.md)
- [What does the App Store notification DID_CHANGE_RENEWAL_STATUS mean?](https://revenuedot.app/docs/notifications/apple-did-change-renewal-status.md)
- [Which webhook events does RevenueDot send?](https://revenuedot.app/docs/api/webhook-events.md)
- [Set up App Store notifications in RevenueDot](https://revenuedot.app/docs/guides/app-store.md)

## Source

- [Apple: notificationType](https://developer.apple.com/documentation/appstoreservernotifications/notificationtype)
- [Apple: Responding to App Store Server Notifications](https://developer.apple.com/documentation/appstoreservernotifications/responding-to-app-store-server-notifications)
- [Apple: app-store-server-library-node (SignedDataVerifier)](https://github.com/apple/app-store-server-library-node)
- [RevenueDot server: stores/apple/notifications.ts (how the notification is applied)](https://github.com/revenuedot/revenuedot/blob/main/apps/server/src/stores/apple/notifications.ts)
- [RevenueDot server: stores/apple/map.ts (how the transaction becomes a stored purchase)](https://github.com/revenuedot/revenuedot/blob/main/apps/server/src/stores/apple/map.ts)
- [RevenueDot core: events.ts (how a change becomes a webhook event)](https://github.com/revenuedot/revenuedot/blob/main/packages/core/src/events.ts)

Checked: 2026-10-03
