Developer Console

RVS for Subscriptions

The Receipt Verification Service (RVS) for the Appstore Billing Compatibility SDK lets you validate purchases made by your app's users. For an overview of RVS, see Receipt Verification Service Overview.

RVS for the Appstore Billing Compatibility SDK has two REST APIs, one for verifying consumable and entitlement purchases, and another for verifying subscription purchases. This page describes the requests and responses of the REST API used for subscription purchases.

purchases.subscriptionsv2.get API request

Use the purchases.subscriptionsv2.get API to verify the receipts of subscription purchases made through the Appstore Billing Compatibility SDK.

Upon successful purchase of an item, the Appstore Billing Compatibility SDK returns a Purchase object. To perform a server-side validation of the purchase, extract the purchase token from this object and pass it, along with the app package name and your shared secret to the RVS server. For security, when you make a request from your server, you must pass a shared secret to confirm your identity.

The request uses the following format:

https://appstore-sdk.amazon.com/version/{operation-version-number}/developer/{shared-secret}/applications/{package-name}/purchases/subscriptionsv2/tokens/{token}

The curly brackets contain placeholders for the request parameters. In your request, replace the placeholders with the values from the transaction you want to verify. The following table lists descriptions of the request parameters.

Request parameter Description
operation-version-number Version number of the purchases.subscriptionsv2.get operation. This version number is independent of the Appstore Billing Compatibility SDK version number. The current purchases.subscriptionsv2.get version number is "1.0".
shared-secret Shared secret used to identify the developer issuing the request. Your shared secret can be found on the Shared Key page in the Developer Console: https://developer.amazon.com/sdk/shared-key.html.
package-name The package name of the application in which the in-app product was sold. For example, 'com.amazon.sample.iap.consumable'. You can get the package name from your app by calling getApplicationContext().getPackageName() or you can find it in the AndroidManifest.xml file.
token Unique ID for the purchase obtained from the Purchase object's getPurchaseToken() method.

purchases.subscriptionsv2.get API response

The purchases.subscriptionsv2.get API provides a RESTful JSON API interface. As a best practice, use a JSON parser class, such as OkHttp or Apache HttpClient, for reading the JSON responses from the RVS server.

After you make a request to the RVS server to verify a transaction, the RVS server returns a response code indicating if the request was successful. If successful, the returned JSON response includes information about the transaction.

The following example shows a successful response:

{
    "cancelDate": 1638906732000,
    "canceledStateContext": {
        "developerInitiatedCancellation": null,
        "replacementCancellation": null,
        "systemInitiatedCancellation": {},
        "userInitiatedCancellation": null
    },
    "deferredDate": null,
    "freeTrialEndDate": null,
    "fulfillmentDate": null,
    "fulfillmentResult": null,
    "gracePeriodEndDate": null,
    "kind": "androidpublisher#subscriptionPurchaseV2",
    "lineItems": [
        {
            "autoRenewingPlan": {
                "autoRenewEnabled": true
            },
            "deferredItemReplacement": null,
            "expiryTime": "1638906732000",
            "offerDetails": {
                "basePlanId": "amzn1.appstore.iap.compatibility.baseplan.termsku.pom.subscription.weekly",
                "offerId": "amzn1.appstore.iap.compatibility.offer.termsku.pom.subscription.weekly"
            },
            "productId": "pom.subscription"
        }
    ],
    "promotions": null,
    "purchaseTimeMillis": "1638465681000",
    "purchaseToken": "s_gaorSDP-W8R0xucVkDIcR5gQuHrqX37cn8MzQoOHo=:3:14",
    "renewalDate": null,
    "startTime": "Tue Dec 07 17:21:21 UTC 2021",
    "subscriptionState": "SUBSCRIPTION_STATE_EXPIRED",
    "term": "1 Day",
    "testPurchase": null,
    "testTransaction": false
}

Response codes and error messages

The Receipt Verification Service responds with one of the following codes, which indicate the result of the validation check.

HTTP response code Description
200 The purchase is valid.
400 The purchase token is invalid.
401 The developer secret is invalid or doesn't match the given purchase token.
404 The package name is invalid or doesn't match the given purchase token.
410 The transaction represented by this receiptId is no longer valid. Treat it as a canceled receipt.
429 The request was throttled. Reduce your calling rate and retry after some time.
500 There was an Internal Server Error.

Response fields for successful transactions

The following table describes the fields included in a purchases.subscriptionsv2.get response for a successful transaction. Some fields have the same name and data type as Google's purchases.subscriptionsv2.get API. Those fields are listed under Fields that match Google's purchases.subscriptionsv2.get API. Fields listed under Additional fields are different from Google APIs and present purchase details provided by the Amazon Appstore.

Field Data type Description
Fields that match Google's purchases.subscriptionsv2.get API
kind String Represents a SubscriptionPurchaseV2 object in the androidpublisher service.
lineItems List<SubscriptionPurchaseLineItem> Item-level information for a subscription purchase.
startTime String Time at which the subscription was granted.
subscriptionState Enum (SubscriptionState) The current state of the subscription.
canceledStateContext CanceledStateContext Additional context around canceled subscriptions. Only present if the subscription currently has subscriptionState SUBSCRIPTION_STATE_EXPIRED.
testPurchase TestPurchase Indicates whether this subscription purchase is a test purchase.
Additional fields
purchaseTimeMillis String The date of the purchase, stored as the number of milliseconds since the epoch (Jan 1, 1970). purchaseTimeMillis represents the initial purchase date, not the purchase date of subsequent renewals.
cancelDate Long integer The date the purchase was canceled, or the subscription expired. The field is null if the purchase was not canceled. Time is in milliseconds.
testTransaction Boolean Indicates whether this purchase was made as a part of Amazon's publishing and testing process.
renewalDate Boolean The date that a subscription purchase needs to be renewed. The date is stored as the number of milliseconds since the epoch.
purchaseToken String Unique identifier for the purchase.
term String Duration of the subscription period for the IAP item. The term starts on the date of purchase. The term consists of a number and a time period (which can be Day, Week, Month, or Year), such as 1 Week or 2 Months.
deferredDate Long integer Date when the current productId will be replaced by a new productId.
freeTrialEndDate Long integer Indicates that the subscription is in a free trial. Provides the free trial end date of the subscription in epoch (milliseconds). The field is null if the subscription is not in a free trial period.
gracePeriodEndDate Long integer Indicates that the subscription is in grace period. Provides the grace period end date of the subscription in epoch (milliseconds). The field is null if the subscription is not in a grace period.
purchaseMetadataMap Map <String, String> Always null. Reserved for future use.
promotions List<Promotion> Details of the retention offer of a subscription purchase. Null if there is no retention offer. See Promotions in RVS.
fulfillmentDate String In a subscription purchase, the date of the acknowledgement of fulfillment. Stored as the number of milliseconds since the epoch. Null if subscription fulfillment isn't confirmed.
fulfillmentResult Long integer In a subscription purchase, the status of fulfillment. Valid values:
  • FULFILLED: You provided the content and the customer consumed the content.
  • UNAVAILABLE: You were unable to provide the content to the customer.
Null if subscription fulfillment isn't confirmed.

Promotions in RVS

The JSON response described in the previous section includes a promotions field. This section explains the promotions field in more detail. If a customer is renewing a subscription with a retention offer discount, the receipt returned through RVS includes the promotion details. For details on how to set up a retention offer, see Retention Offers.

Promotion details are present only on a receipt that corresponds to a customer's purchase of a retention offer discount. The promotions field is null if there is no promotion associated with the receipt. Otherwise, the field contains a list of Promotion objects, with the following fields.

Field Data Type Description
promotionType String Type of promotion. Valid values:
Retention Offer
promotionStatus String Status of the promotion for this customer. Valid values:
InProgress - The customer is currently enjoying a retention offer.

Example:

"promotions": [
    {
        "promotionType":"Retention Offer",
        "promotionStatus":"InProgress"
    }
]

Data types

The following sections describe data types you might encounter in the purchases.subscriptionsv2.get response.

SubscriptionPurchaseLineItem

Item-level information for a subscription purchase.

Field Data type Description
productId String The product ID of the purchased product.
expiryTime String Time at which the subscription expired or will expire unless the access is extended (the subscription is renewed).
autoRenewingPlan AutoRenewingPlan The item is auto-renewing.
offerDetails OfferDetails The offer details for this item.
deferredItemReplacement DeferredItemReplacement Always null. Reserved for future use.

AutoRenewingPlan

Information related to an auto-renewing plan.

Field Data type Description
autoRenewEnabled Boolean Indicates if customer's subscription will auto-renew.

OfferDetails

Offer details information related to a purchase line item.

Field Data type Description
basePlanId String The base plan ID. Present for all base plan and offers.
offerId String The offer ID. Only present for discounted offers.

SubscriptionState

Indicates the current state of a subscription. For example, whether a subscription is active or expired.

Enum Description
SUBSCRIPTION_STATE_UNSPECIFIED Unspecified subscription state
SUBSCRIPTION_STATE_ACTIVE Subscription is active
SUBSCRIPTION_STATE_IN_GRACE_PERIOD Subscription is in grace period
SUBSCRIPTION_STATE_EXPIRED Subscription is expired

CanceledStateContext

Information specific to a subscription in canceled state.

Field Data type Description
userInitiatedCancellation UserInitiatedCancellation Subscription was canceled by user.
systemInitiatedCancellation SystemInitiatedCancellation Subscription was canceled by the system, for example because of a billing problem.
developerInitiatedCancellation DeveloperInitiatedCancellation Always null. Reserved for future use.
replacementCancellation ReplacementCancellation Always null. Reserved for future use.

UserInitiatedCancellation

Information specific to cancellations initiated by users.

Field Data type Description
cancelTime String The time at which the subscription was canceled by the user.

SystemInitiatedCancellation

This type has no fields.

Information specific to cancellations initiated by Amazon system.

TestPurchase

This type has no fields.

If the subscription purchase is a test purchase, this appears as an empty object {}. Null if not a test purchase.

Unsupported fields for purchases.subscriptionsv2.get API

The following fields that are available in the Google Play Developer API, aren't supported in the Appstore Billing Compatibility RVS API.

  • regionCode
  • lineItems[].autoRenewingPlan.priceChangeDetails
  • lineItems[].prepaidPlan
  • lineItems[].offerDetails.offerTags
  • latestOrderId
  • linkedPurchaseToken
  • pausedStateContext
  • canceledStateContext.userInitiatedCancellation.cancelSurveyResult
  • acknowledgementState
  • externalAccountIdentifiers
  • subscribeWithGoogleInfo

Cancel date and renewal date

The cancelDate field contains the date that a subscription purchase expired or that Amazon customer service canceled the purchase. The cancel date represents the date when the customer lost access to the content. When a customer cancels their subscription by turning off autorenew, the cancel date is when the renewal date would have been.

The renewalDate field contains the date that an autorenew subscription purchase next needs to be renewed. This field applies to subscription purchases only. If a customer has a monthly subscription, the subscription renews monthly on the same date the customer first subscribed. In the case where the next month does not include the exact date, the renewal date is the closest prior date. For example:

  • If a customer subscribed on January 2, the next three renewal dates are February 2, March 2, and April 2.
  • If a customer subscribed on January 31, the next three renewal dates are February 28 (or February 29 if it is a leap year), March 31, and April 30.

The renewalDate and cancelDate fields are stored as time in milliseconds. You can use java.util.Date(timeInMillis) to convert the value into a date object.

Consumable or entitlement purchase

In a valid receipt, the cancel date and renewal date both contain the null value. If the cancel date field is not null, it contains the date that Amazon customer service canceled the purchase.

Subscription purchase

In a valid subscription receipt, the cancel date is null. If the cancelDate field is not null, it contains the date that the subscription expired, or that Amazon customer service canceled the purchase.

The renewalDate field contains the date that an autorenew subscription purchase next needs to be renewed. The field value will be null if the subscription is not set to autorenew.

In the following example, the user has a subscription that was canceled:

  • The subscription was active from January 1, 2023 to March 1, 2023. In this receipt, the purchaseDate for this subscription is set to January 1, 2023, and the cancelDate is set to March 3, 2023.
  • If this subscription is subsequently reactivated on April 1, 2023, the subscription will have a second receipt. The second receipt will show a purchaseDate of April 1, 2023 and a cancelDate of null.

Portions of this page are modifications based on work created and shared by Google and used according to terms described in the Creative Commons 4.0 Attribution License. Sources: https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.subscriptionsv2/get, https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.subscriptionsv2.


Last updated: Oct 14, 2024