How to test "revoked" transactions.

Is it possible to test a “revoked” response?

I tried tried to test this by cancelling the Active transaction in the Amazon SDK tester, but it doesn’t generate a “revoked” event.

Hi ingemar,

Sorry for the delay. Thank you for bringing this to our attention. A bug has been identified in the Amazon IAP plugin and a new build is now available. You should now receive ‘revoked’ purchases in the callback. Please try again and post here if you have any further issues.

-Preston

I can confirm that I now receive “revoked” callbacks for cancelled transactions.

I have a question though:

In a real-life situation, once a transaction for an item has been revoked. Its it possible for the user to re-purchase the same item?

If so, will the “revoked” status be removed?

I’m asking since when I tried to emulate this situation with the SDK tester I got multiple callbacks: first “restored” and then “revoked” every time I started the app. Clearing the data cache of the SDK Tester did reset all purchase data, but I’m wondering what happens in the Live environment.

Hi ingemar,

The live experience with the Appstore client will mirror the experience you are getting with the Amazon SDK Tester.

Yes, it is possible for a user to repurchase a revoked item.

Whenever you receive a ‘restored’ event for an entitlement, you should entitle the user to this sku.

If the user has had this item revoked and has not purcahsed, you will only  receive a ‘revoked’ event.

If the user then repurchases the item, you will get both a ‘revoked’ and ‘restored’ event.

This is due to the design of the Amazon In-App Purchasing API itself.

This means you should only revoke the SKU if you don’t also get a ‘restored’ receipt. If it is ‘revoked’ and not repurchased, you will only receive a ‘revoked’ event.

-Preston

Hi Preston, In that case I have a bit of a problem with the order of the callbacks. I would assume that the callbacks would be given in chronological order. Meaning that if a user has revoked a purchase and later re-purchased the same item, that the callbacks that are generated should be “revoked”->“restored”. However when I try this scenario in the SDK Tester I always get “restored”->“revoked”. Logically I would assume that the last callback received would be the definitive callback, right? But that’s not the case at least in the SDK Tester.

Hi ingemar,

The Amazon IAP plugin is wrapping the Amazon In-App Purchasing API call ‘initiatePurchaseUpdatesRequest’. The async response for this request contains a Set of valid receipts and a Set of revoked SKUs. The plugin translates these to Lua objects and initiates a callback to application code for them one at a time. As these are Sets, there is no way for the plugin to make these callbacks in chronological order as the order is not known(there is no date information). This is a limitation of the Amazon In-App Purchasing API.

There is a possible modification to the plugin that could be made: the plugin could send ‘revoked’ events before ‘restore’ events. This is further complicated because the Amazon In-App Purchasing API sends these in batches, so, for example, your app could receive a set of ‘revoked’ skus, a set of 'receipts, another set of 'revoked ’ skus, and then another set of receipts. I believe these batches themselves are in chronological order relative to each other even though the items within them are not ordered. This way I believe you would always receive the ‘revoked’ event before the subsequent ‘restore’ for the same item, but they may not be in the same batch. Would this be helpful to you?

-Preston

Hi Preston,

Your suggestion sounds good since the batches would be delivered in the same order as they occurred, right? 

Let’s take another scenario:

Is it possible for a user to purchase an item, have it revoked, purchase it again and yet again having it revoked? In that case I guess that your proposed solution would catch that since the batches would be delivered in order?

Sorry for being such pain :slight_smile: I know I’m nit-picking here especially since we’re talking about extreme edge cases, but I just want to be able to handle all situations if possible…

Yes, that is correct. The batches would be delivered in order.

Yes, I believe it is possible for a user to purchase an item, have it revoked, purchase it again, and have it revoked again. In this case you would only have one call of state ‘revoked’(because it has been revoked) and no calls with state ‘restored’(because it is currently revoked).
-Preston

Aha!  OK… In that case it’s unnecessary to complicate things.

That means that if I get a “restored” and soon after a “revoked” (as it works now) I can trust that the app is in fact still purchased, right?

Yes I believe so. If you receive a ‘restored’ event than the item is entitled.

OK then. I’m a happy camper :slight_smile:

I’ll adjust my IAP logic to reflect this.

Thanks,

Ingemar

Hi ingemar,

Sorry for the delay. Thank you for bringing this to our attention. A bug has been identified in the Amazon IAP plugin and a new build is now available. You should now receive ‘revoked’ purchases in the callback. Please try again and post here if you have any further issues.

-Preston

I can confirm that I now receive “revoked” callbacks for cancelled transactions.

I have a question though:

In a real-life situation, once a transaction for an item has been revoked. Its it possible for the user to re-purchase the same item?

If so, will the “revoked” status be removed?

I’m asking since when I tried to emulate this situation with the SDK tester I got multiple callbacks: first “restored” and then “revoked” every time I started the app. Clearing the data cache of the SDK Tester did reset all purchase data, but I’m wondering what happens in the Live environment.

Hi ingemar,

The live experience with the Appstore client will mirror the experience you are getting with the Amazon SDK Tester.

Yes, it is possible for a user to repurchase a revoked item.

Whenever you receive a ‘restored’ event for an entitlement, you should entitle the user to this sku.

If the user has had this item revoked and has not purcahsed, you will only  receive a ‘revoked’ event.

If the user then repurchases the item, you will get both a ‘revoked’ and ‘restored’ event.

This is due to the design of the Amazon In-App Purchasing API itself.

This means you should only revoke the SKU if you don’t also get a ‘restored’ receipt. If it is ‘revoked’ and not repurchased, you will only receive a ‘revoked’ event.

-Preston

Hi Preston, In that case I have a bit of a problem with the order of the callbacks. I would assume that the callbacks would be given in chronological order. Meaning that if a user has revoked a purchase and later re-purchased the same item, that the callbacks that are generated should be “revoked”->“restored”. However when I try this scenario in the SDK Tester I always get “restored”->“revoked”. Logically I would assume that the last callback received would be the definitive callback, right? But that’s not the case at least in the SDK Tester.

Hi ingemar,

The Amazon IAP plugin is wrapping the Amazon In-App Purchasing API call ‘initiatePurchaseUpdatesRequest’. The async response for this request contains a Set of valid receipts and a Set of revoked SKUs. The plugin translates these to Lua objects and initiates a callback to application code for them one at a time. As these are Sets, there is no way for the plugin to make these callbacks in chronological order as the order is not known(there is no date information). This is a limitation of the Amazon In-App Purchasing API.

There is a possible modification to the plugin that could be made: the plugin could send ‘revoked’ events before ‘restore’ events. This is further complicated because the Amazon In-App Purchasing API sends these in batches, so, for example, your app could receive a set of ‘revoked’ skus, a set of 'receipts, another set of 'revoked ’ skus, and then another set of receipts. I believe these batches themselves are in chronological order relative to each other even though the items within them are not ordered. This way I believe you would always receive the ‘revoked’ event before the subsequent ‘restore’ for the same item, but they may not be in the same batch. Would this be helpful to you?

-Preston

Hi Preston,

Your suggestion sounds good since the batches would be delivered in the same order as they occurred, right? 

Let’s take another scenario:

Is it possible for a user to purchase an item, have it revoked, purchase it again and yet again having it revoked? In that case I guess that your proposed solution would catch that since the batches would be delivered in order?

Sorry for being such pain :slight_smile: I know I’m nit-picking here especially since we’re talking about extreme edge cases, but I just want to be able to handle all situations if possible…

Yes, that is correct. The batches would be delivered in order.

Yes, I believe it is possible for a user to purchase an item, have it revoked, purchase it again, and have it revoked again. In this case you would only have one call of state ‘revoked’(because it has been revoked) and no calls with state ‘restored’(because it is currently revoked).
-Preston

Aha!  OK… In that case it’s unnecessary to complicate things.

That means that if I get a “restored” and soon after a “revoked” (as it works now) I can trust that the app is in fact still purchased, right?

Yes I believe so. If you receive a ‘restored’ event than the item is entitled.