Receipt Verification for Tiered Subscriptions
Use Real-Time Notifications (RTN) and Receipt Verification Service (RVS) together to help detect and validate tier changes:
- With RTN, you can detect the subscription tier or term change made by your app's users.
- With RVS, you can validate purchases made by your app's users.
- RTN for tiered subscriptions
- RVS for tiered subscriptions
- Cancel reason response codes
- Example RVS response
RTN for tiered subscriptions
Real-Time Notifications provides real-time server push notifications when a change in tier occurs. The following table provides details about tier change notifications.
Notification Type | Description |
---|---|
SUBSCRIPTION_MODIFIED_DEFERRED |
A subscription plan was modified with the "deferred" proration mode. The subscription plan is scheduled to change at the next renewal date. The current plan remains active until the renewal date. |
SUBSCRIPTION_MODIFIED_IMMEDIATE |
A subscription plan was modified with the "immediate" proration mode. The existing plan is canceled with a prorated refund, and the new plan is activated immediately. The notification includes the canceled receipt ID. |
Capture these events with RTN and use RVS to verify the change in subscription. For a complete list of notification types, see Supported Notification Types.
Example RTN responses
Amazon handles plan changes differently based on whether they are immediate or deferred.
- For immediate plan changes:
- Amazon cancels the current plan and activates the new one immediately.
- Amazon marks the current receipt ID as canceled.
- The
relatedReceipts
field of the RTN payload includes the canceled receipt ID.
- For deferred plan changes:
- The current receipt remains active and Amazon schedules the plan change for the upcoming billing cycle.
- The
relatedReceipts
field in the RTN payload is an empty array.
The following examples show RTN responses for the SUBSCRIPTION_MODIFIED_IMMEDIATE
and SUBSCRIPTION_MODIFIED_DEFERRED
notification types.
Example for SUBSCRIPTION_MODIFIED_IMMEDIATE
{
"Type" : "Notification",
"MessageId" : "723acf52-cb22-57f5-b13e-afa29908f61d",
"TopicArn" : "arn:aws:sns:us-east-1:033616359524:MyTopic",
"Message" : "{\"appPackageName\":\"com.example.amazonsdkapivalidator3\",\"notificationType\":\"SUBSCRIPTION_MODIFIED_IMMEDIATE\",\"appUserId\":\"io9oFdzmCSMuKk_pp9pYccoIHRfc6kSAAYaNo51xZrg=\",\"receiptId\":\"R4TWNm8Uspo4Ujio51B5_7xBnRFzr4B2k9Bv48_7mRY=:3:11\",\"relatedReceipts\":{"cancelledReceiptId": "IgThFebRSngPTn9JntrLMby52NqMjyMMQnrUFlczwV0=:3:11"},\"timestamp\":1752584166563,\"betaProductTransaction\":false}",
"Timestamp" : "2025-07-15T12:56:10.667Z",
"SignatureVersion" : "1",
"Signature" : "EXAMPLEw6JRN...",
"SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-9c6465fa7f48f5cacd23014631ec1136.pem",
"UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:033616359524:MyTopic:3c2cebb7-5dc3-4eca-9d55-4e8922144131"
}
Here is a closer look at the contents of the Message
field in JSON format.
{
"appPackageName": "com.example.amazonsdkapivalidator3",
"notificationType": "SUBSCRIPTION_MODIFIED_IMMEDIATE",
"appUserId": "io9oFdzmCSMuKk_pp9pYccoIHRfc6kSAAYaNo51xZrg=",
"receiptId": "R4TWNm8Uspo4Ujio51B5_7xBnRFzr4B2k9Bv48_7mRY=:3:11",
"relatedReceipts": {
"cancelledReceiptId": "IgThFebRSngPTn9JntrLMby52NqMjyMMQnrUFlczwV0=:3:11"
},
"timestamp": 1752584166563,
"betaProductTransaction": false
}
Notice the relatedReceipts
field includes the canceled receipt ID. For an immediate plan change, Amazon immediately cancels the current plan and activates the new one.
Example for SUBSCRIPTION_MODIFIED_DEFERRED
{
"Type" : "Notification",
"MessageId" : "64140cd1-13e4-57d8-baf6-6c2141c2646f",
"TopicArn" : "arn:aws:sns:us-east-1:033616359524:MyTopic",
"Message" : "{\"appPackageName\":\"com.example.amazonsdkapivalidator3\",\"notificationType\":\"SUBSCRIPTION_MODIFIED_DEFERRED\",\"appUserId\":\"io9oFdzmCSMuKk_pp9pYccoIHRfc6kSAAYaNo51xZrg=\",\"receiptId\":\"PnkS4FtcuGLylYyc_vNjrN_ucm9hhaur43iCacRAd14=:3:11\",\"relatedReceipts\":{},\"timestamp\":1752584161620,\"betaProductTransaction\":false}",
"Timestamp" : "2025-07-15T12:56:06.409Z",
"SignatureVersion" : "1",
"Signature" : "EXAMPLEw6JRN...",
"SigningCertURL" : "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-9c6465fa7f48f5cacd23014631ec1136.pem",
"UnsubscribeURL" : "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-1:033616359524:MyTopic:3c2cebb7-5dc3-4eca-9d55-4e8922144131"
}
Here is a closer look at the contents of the Message
field in JSON format.
{
"appPackageName": "com.example.amazonsdkapivalidator3",
"notificationType": "SUBSCRIPTION_MODIFIED_DEFERRED",
"appUserId": "io9oFdzmCSMuKk_pp9pYccoIHRfc6kSAAYaNo51xZrg=",
"receiptId": "PnkS4FtcuGLylYyc_vNjrN_ucm9hhaur43iCacRAd14=:3:11",
"relatedReceipts": {},
"timestamp": 1752584161620,
"betaProductTransaction": false
}
Notice the relatedReceipts
array is empty. For a deferred plan change, Amazon maintains the existing receipt and schedules the plan change for the upcoming billing cycle.
RVS for tiered subscriptions
Set up RVS for tiered subscription apps the same as you would for any other app. For more details, see Receipt Verification Service for Appstore SDK IAP.
For apps with tiered subscriptions, RVS uses an additional cancelReason
response code for canceled subscriptions.
Cancel reason response codes
The cancelReason
response code is a long integer that indicates why a product is canceled. Possible values are null, 0, 1, 2, or 4, where each integer represents a cancellation reason, described in the following table.
cancelReason Code | Description |
---|---|
null |
The purchase is not canceled. |
0 |
The cancel reason is currently unavailable and renders at a later time. |
1 |
Your customer canceled the order. |
2 |
Amazon's system canceled the purchase. For example, a customer purchases a subscription with invalid payment and the purchase isn't completed in the grace period. |
4 |
The subscription is replaced with a new subscription. For example, if a customer moves to a new tier, the original receipt is canceled and a new receipt is provided. |
cancelReason
response code 3
is an internal code used by Amazon.You can find a complete list of response fields in the RVS documentation.
Example RVS response
The following code is an example of a full RVS response.
{
"autoRenewing":false,
"betaProduct":true,
"cancelDate":1400784371000,
"cancelReason":4,
"countryCode":"US",
"freeTrialEndDate":null,
"gracePeriodEndDate":null,
"parentProductId":null,
"productId":"sub1",
"productType":"SUBSCRIPTION",
"purchaseDate":1400784241000,
"quantity":null,
"receiptId":"JyGJ5iEtYgFu1ngnQovTqSIHQxR53GsMLqkR1tKLp5c=:3:11",
"renewalDate":null,
"term":"1 Week",
"termSku":"sub1-weekly",
"testTransaction":true
}
The cancelReason
indicates that the app has changed to a different tier, which cancels the previous subscription.
For more RVS examples, see RVS Examples for Appstore SDK IAP.
Last updated: Jul 22, 2025