Integrate Tiered Subscriptions in Android Apps
After you assign separate SKUs for these IAP items, use the Modify Subscription API to implement tiered subscriptions in your app. The Modify Subscription API is part of a custom version of the Amazon Appstore SDK.
Modify Subscription API
The implementation process is similar to using the Purchase API.
When you call the purchase()
method, the Appstore SDK invokes the onPurchaseResponse()
callback. Similarly, when you call the modifySubscription()
method, the Appstore SDK invokes the onModifySubscriptionResponse()
callback.
The main differences between the Purchase API and the Modify Subscription API are as follows:
- The
modifySubscription()
method takes aProrationMode
parameter, which is a value specifying the time of plan modification, and a SKU parameter in the request, while apurchase()
method takes only SKU. - The
ModifySubscriptionResponse
object uses a list of receipts, while thePurchaseResponse
object uses only one receipt.
The modify subscription request uses the SKU of the term that the customer moves to. It also uses ProrationMode
, which is an enum with the value of IMMEDIATE
or DEFERRED
. The modifySubscription()
method identifies the corresponding customer subscription and modifies it with the new term SKU. The ProrationMode
value specifies when the modification takes effect. The ModifySubscriptionResponse
object provides a list of receipts associated with the modification of the plan.
modifySubscription()
method.Modify subscription proration modes
The proration mode of a subscription is set with the ProrationMode
enum. This section describes the two possible values for ProrationMode
, which are IMMEDIATE
and DEFERRED
, in more detail.
Immediate proration mode
With ProrationMode
set to IMMEDIATE
, the customer's current subscription plan ends, and the new plan takes effect immediately. The customer gets a refund for the remaining period of the ended subscription, and is charged for the new subscription plan. The customer also receives an email specifying the refund amount for the old plan and the details of the new plan.
Since the current plan ends with prorated refund, and the new plan starts with a different order, the API contains two receipts:
- The last active receipt for the subscription, which contains cancellation date confirming the termination of the old subscription plan
- The new receipt for the newly changed plan
You must process both receipts to deliver immediately what the customer paid for.
Immediate response sample
In this example, a customer moves from term SkuX
to term SkuY
, effective immediately. The purchase happens on January 16. The original purchase of SkuX
happened on January 2. In this scenario, Amazon returns a message that contains the following:
receipts: [{
"receiptId": "oeUY1ip2mJWgLoOuGtAxndQS1LDJRGvmKLr6kq4u9G8=:3:11",
"sku": "baseSku",
"itemType": "SUBSCRIPTION",
"purchaseDate": "Thu Jan 16 09:25:25 GMT+05:30 2020",
"termSku": "SkuY"
}, {
"receiptId": "1bxFJrJVLPr8qpub8SijMWdAqXqWWGNUYPDpynoSusE=:3:11",
"sku": "baseSku",
"itemType": "SUBSCRIPTION",
"purchaseDate": "Thu Jan 02 12:41:44 GMT+05:30 2020",
"endDate": "Thu Jan 16 09:25:26 GMT+05:30 2020",
"termSku": "SkuX"
}]
Deferred proration mode
With ProrationMode
set to DEFERRED
, the subscription plan changes at the time of the upcoming renewal. The customer continues to have access to the current plan until renewal. The customer will be charged for the new plan at the time of renewal. The customer also receives an email with the deferred subscription details and the date of the upcoming modification.
Because the previous subscription plan remains active with no plan termination, the modify subscription response object only contains the active receipt. This receipt contains the deferred term SKU and the deferred date. You must use the data in the receipt to verify and deliver access to the new plan on the specified date. After the renewal, the same receipt ID will still be valid, but will be updated with the latest subscription details.
Deferred response sample
In this example, a customer moves from SkuA
to term SkuB
, effective at the time of renewal as specified in deferredDate
.
receipts: [{
"receiptId": "oeUY1ip2mJWgLoOuGtAxndQS1LDJRGvmKLr6kq4u9G9=:3:11",
"sku": "baseSku",
"itemType": "SUBSCRIPTION",
"purchaseDate": "Thu Jan 16 10:25:25 GMT+05:30 2020",
"deferredDate": "Thu Jan 23 10:25:26 GMT+05:30 2020",
"deferredSku": "SkuA",
"termSku": "SkuB"
}]
Implement Modify Subscription API
The following code examples outline proper handling of the Modify Subscription API requests and responses within your app.
Sample request
RequestId requestId = PurchasingService.modifySubscription("SKU", ProrationMode);
Sample response
An onModifySubscriptionResponse()
method handles responses from the Modify Subscription API. The method stores the status in a ModifySubscriptionResponse.RequestStatus
variable by using getRequestStatus()
. Based on the status, it either outputs receipts by using getReceipts()
, or handles errors.
@Override
public void onModifySubscriptionResponse(ModifySubscriptionResponse response) {
final String requestId = response.getRequestId().toString();
final String userId = response.getUserData().getUserId();
final ModifySubscriptionResponse.RequestStatus status = response.getRequestStatus();
Log.d(TAG, "onModifySubscriptionResponse: requestId (" + requestId
+ ") userId ("
+ userId
+ ") modifySubscriptionRequestStatus ("
+ status
+ ")");
Log.d(TAG, "ModifySubscriptionResponse " + response.toString());
switch (status) {
case SUCCESSFUL:
for(Receipt receipt : response.getReceipts()) {
Log.d(TAG, "onModifySubscriptionResponse: Receipt in json:" + receipt.toJSON());
iapManager.handleReceipt(response.getRequestId().toString(), receipt, response.getUserData());
}
break;
case INVALID_SKU:
Log.d(TAG,
"onModifySubscriptionResponse: Invalid SKU, onProductDataResponse should have already disabled the buy button.");
break;
case FAILED:
case NOT_SUPPORTED:
Log.d(TAG, "onModifySubscriptionResponse: Failed, so remove purchase request from local storage.");
iapManager.purchaseFailed(response.getRequestId().toString());
break;
}
}
Last updated: Dec 03, 2024