How to determine if a subscription has been cancelled?

I am having a subscription in-app in my app. 
In the test API(using Amazon Test Client), once I cancel my subscription, how do I know if the subscription has been cancelled?

Let me describe my workflow a bit : 

1.User clicks on subscription and buys it(sandbox mode).
2.Corona’s store API gets triggered. I get the receipt and userId from the event in store listener.
3.I add this receipt and userId to a database in my server. 
4.Whenever the user starts the app, the app tries to check the validity of the subscription in my server;  a script in my server validates the subscription using the receipt and the userId (in RVSSandbox) and returns its validity

Now  I am going to cancel my subscription. I go to Amazon Test Client, go to Active Transactions, and cancel my subscription there. 

When my app contacts my server, the server still says the subscription is valid. 

This is what Amazon’s docs say 

Subscription Check (cancelled) ​ Make a successful purchase of a subscription SKU  Ensure the transaction is listed in the "Active Transactions" Page  Tap "Cancel" on the subscription transaction  Call initiatePurchaseUpdatesRequest, process in onPurchaseUpdatesResponse  From the returned receipts, Find the most recent receipt (by start date) for that SKU  Verify that the end date has a value other than null

So apparently once a subscription is cancelled, a new receipt is generated(correct me if I am wrong please). 

Will this receipt be received in the “revoked” phase in the store listener? I don’t think I am receiving one.
If yes, should I update the database in my server with this “new receipt” for future validations?
If not, how do I know that the subscription has been cancelled? Will the old receipt become invalid once the subscription’s time period expires, so that I don’t have to bother with this new receipt?

Would really appreciate some help here!

 

Hi,

This is my understanding:

Whenever you call restore() you will get receive receipts for all entitlements and subscriptions purchased by the logged in user previously. While a subscription is active, the end date of the subscription receipt will be null.
After the subscription expires, the next time the app opens and restore() is called, the receipt that comes through has a non-null end date, this is how you know the subscription is expired. I do not think an additional receipt is generated.

I’m not sure you can ever get a ‘revoked’ subscription, you would have to open a case with Amazon.

It gets more complicated if the user resubscribes. In this case, I believe you will have two receipts. The presence of any receipt for the subscription with a non-null end date means the user is currently subscribed.

Does this help?

@tamkinp 

Makes sense. 
 I am handling all my subscription-validations in my server, and according to you, I don’t have to worry about the receipt being changed in the normal-usecase scenario. Good! 

In the “user resubscribing” scenario, the resubscription will be considered a separate purchase right? I mean it will be sent to the store listener as a “purchased” event right? with the receipt, userId and what not…
If that is the case, I needn’t worry…

Hi,

This is my understanding:

Whenever you call restore() you will get receive receipts for all entitlements and subscriptions purchased by the logged in user previously. While a subscription is active, the end date of the subscription receipt will be null.
After the subscription expires, the next time the app opens and restore() is called, the receipt that comes through has a non-null end date, this is how you know the subscription is expired. I do not think an additional receipt is generated.

I’m not sure you can ever get a ‘revoked’ subscription, you would have to open a case with Amazon.

It gets more complicated if the user resubscribes. In this case, I believe you will have two receipts. The presence of any receipt for the subscription with a non-null end date means the user is currently subscribed.

Does this help?

@tamkinp 

Makes sense. 
 I am handling all my subscription-validations in my server, and according to you, I don’t have to worry about the receipt being changed in the normal-usecase scenario. Good! 

In the “user resubscribing” scenario, the resubscription will be considered a separate purchase right? I mean it will be sent to the store listener as a “purchased” event right? with the receipt, userId and what not…
If that is the case, I needn’t worry…

@tamkinp

A follow-up question for you on subcription. Reading through all the documentations, I understand that after calling restore() a valid subscription’s receipt will have a SubscriptionEndDate == nil. My question is what is in the SubscriptionStartDate? Assuming the subscription had been auto-renewed, would the SubscriptionStartDate be the original purchase date, or the date on which the subscription is renewed?

We basically would like to be able to calculate when the expected subscription end date is (assuming no renewal).

Thanks!

Andrew

Hi Andrew,

See this page: https://developer.amazon.com/public/apis/earn/in-app-purchasing/docs/purchasable-items

“SubsciptionPeriod.getStartDate() will always return the date the Subscription is purchased. SubscriptionPeriod.getEndDate() will return null if the Subscription is still active, or the date the Subscription ended if the period occurs in the past.”

It does not appear that the start date will change after an autorenew.

@tamkinp thank you for the really quick response!

We are running into another weird use case on subscription. We have a Parent SKU setup with 2 children SKUs for a monthly and an annual subscription. If the user were to purchase the monthly subscription, reinstall our app, then do a restore, the restore will return to us a transaction similar to the following:

I/Corona (27619): DEBUG: txn.state restored I/Corona (27619): DEBUG: txn.date nil I/Corona (27619): DEBUG: txn.identifier 4d265351-f078-4bc2-a196-ed33464a8004 I/Corona (27619): DEBUG: txn.productIdentifier com.sx.wonsterwords.subscription.parentSKU I/Corona (27619): DEBUG: txn.receipt eyJ0eXBlIjoiU1VCU0NSSVBUSU9OIiwic2t1IjoiY29tLnN4LndvbnN0ZXJ3b3Jkcy5zdWJzY3JpcHRpb24ucGFyZW50U0tVIiwic3RhcnREYXRlIjoxNDA2OTIwOTgxMTAzfQ I/Corona (27619): DEBUG: txn.originalDate: nil I/Corona (27619): DEBUG: txn.originalID nil I/Corona (27619): DEBUG: txn.originalReceipt nil I/Corona (27619): DEBUG: txn.errorType nil I/Corona (27619): DEBUG: txn.errorString nil I/Corona (27619): DEBUG: txn.userId DefaultTestUser I/Corona (27619): DEBUG: txn.subscriptionStartDate 1406920981000 I/Corona (27619): DEBUG: txn.subscriptionEndDate nil

While per-documentation, this tells me that my subscription is still valid, and the StartDate of the subscription, it doesn’t tell me which child SKU was purchased. Nor can I find anywhere in the Corona or Amazon documentation that indicates Amazon will return me the child SKU that was purchased. 

This creates a problem where I can’t calculate when the upcoming renewal date is. It forces me to check the subscription status upon every app launch by calling store.restore(). While I read in the Amazon documentation that this is the recommended approach, it really doesn’t work for us, since our app is often used off-line with no network connectivity. 

Would you have any suggestions for us in such situation? Seems like our use case would be a pretty common one for mobile devices. 

Thanks!

Andrew 

Hi Andrew,

Sorry for the delay.

Unfortunately I’m not sure there is a good solution for you. The Amazon IAP Plugin simply uses the Amazon IAP SDK under the hood so if that information is not available in the java side then we cannot expose it in the Corona side.

@tamkinp Thanks for the info. Yeah, we’ll look for ways to work around this. 

Thanks!
Andrew

@tamkinp

A follow-up question for you on subcription. Reading through all the documentations, I understand that after calling restore() a valid subscription’s receipt will have a SubscriptionEndDate == nil. My question is what is in the SubscriptionStartDate? Assuming the subscription had been auto-renewed, would the SubscriptionStartDate be the original purchase date, or the date on which the subscription is renewed?

We basically would like to be able to calculate when the expected subscription end date is (assuming no renewal).

Thanks!

Andrew

Hi Andrew,

See this page: https://developer.amazon.com/public/apis/earn/in-app-purchasing/docs/purchasable-items

“SubsciptionPeriod.getStartDate() will always return the date the Subscription is purchased. SubscriptionPeriod.getEndDate() will return null if the Subscription is still active, or the date the Subscription ended if the period occurs in the past.”

It does not appear that the start date will change after an autorenew.

@tamkinp thank you for the really quick response!

We are running into another weird use case on subscription. We have a Parent SKU setup with 2 children SKUs for a monthly and an annual subscription. If the user were to purchase the monthly subscription, reinstall our app, then do a restore, the restore will return to us a transaction similar to the following:

I/Corona (27619): DEBUG: txn.state restored I/Corona (27619): DEBUG: txn.date nil I/Corona (27619): DEBUG: txn.identifier 4d265351-f078-4bc2-a196-ed33464a8004 I/Corona (27619): DEBUG: txn.productIdentifier com.sx.wonsterwords.subscription.parentSKU I/Corona (27619): DEBUG: txn.receipt eyJ0eXBlIjoiU1VCU0NSSVBUSU9OIiwic2t1IjoiY29tLnN4LndvbnN0ZXJ3b3Jkcy5zdWJzY3JpcHRpb24ucGFyZW50U0tVIiwic3RhcnREYXRlIjoxNDA2OTIwOTgxMTAzfQ I/Corona (27619): DEBUG: txn.originalDate: nil I/Corona (27619): DEBUG: txn.originalID nil I/Corona (27619): DEBUG: txn.originalReceipt nil I/Corona (27619): DEBUG: txn.errorType nil I/Corona (27619): DEBUG: txn.errorString nil I/Corona (27619): DEBUG: txn.userId DefaultTestUser I/Corona (27619): DEBUG: txn.subscriptionStartDate 1406920981000 I/Corona (27619): DEBUG: txn.subscriptionEndDate nil

While per-documentation, this tells me that my subscription is still valid, and the StartDate of the subscription, it doesn’t tell me which child SKU was purchased. Nor can I find anywhere in the Corona or Amazon documentation that indicates Amazon will return me the child SKU that was purchased. 

This creates a problem where I can’t calculate when the upcoming renewal date is. It forces me to check the subscription status upon every app launch by calling store.restore(). While I read in the Amazon documentation that this is the recommended approach, it really doesn’t work for us, since our app is often used off-line with no network connectivity. 

Would you have any suggestions for us in such situation? Seems like our use case would be a pretty common one for mobile devices. 

Thanks!

Andrew 

Hi Andrew,

Sorry for the delay.

Unfortunately I’m not sure there is a good solution for you. The Amazon IAP Plugin simply uses the Amazon IAP SDK under the hood so if that information is not available in the java side then we cannot expose it in the Corona side.

@tamkinp Thanks for the info. Yeah, we’ll look for ways to work around this. 

Thanks!
Andrew