No response from store.restore() on iOS while beta testing

Hi, all.  I’m having trouble with completing a restore IAP operation on iOS while beta testing my app.  I’m using the fantastic plugin IAP Badger to handle a lot of the nuts and bolts, but I’m pretty sure it isn’t the problem.  The call store.restore() doesn’t trigger a store transaction callback, but store.purchase() does.

Possibly relevant information:

1)  I’m testing on an iPad with my app installed through TestFlight.  The app is built with a Development Profile.

2)  I know my app is connecting to the App Store.  When I initialize IAP I get the correct localizedPrice, priceLocale, and productIdentifier returned from the App Store.

  1. I previously successfully purchased the IAP as a beta tester.

  2. If I call store.purchase() I’m shown a native dialog that says:  “You’ve already purchased this. Would you like to get it again for free? Cancel/OK”  If I click OK, the transaction completes.

  3. I’ve set up a sandbox user, but my understanding is that one isn’t needed anymore if using TestFlight.  Doing a purchase operation doesn’t seem to need it.

  4. The IAP Badger code I’m using is only slightly modified from the plugin examples:

    function MyApp.restore(iap_feature) native.setActivityIndicator(true) ------------------------------------------------------- local function lf_restoreListener(iap_feature, event) – If this is the first transaction… if (event.firstRestoreCallback) then native.setActivityIndicator(false) end if iap_feature == “unlock_all_levels” then MyApp.unlock_all_levels() native.showAlert("Restored " … iap_feature) end end ------------------------------------------------------- local function lf_restoreTimeout() native.showAlert("No response from App Store. Can’t restore " … iap_description) native.setActivityIndicator(false) end ------------------------------------------------------- local function lf_failedListener(iap_feature, transaction) local failed_message = “Restore of " … iap_description … " from App Store failed.” failed_message = failed_message … " App Store response: " … transaction.errorString native.showAlert(failed_message) native.setActivityIndicator(false) end ------------------------------------------------------- local function lf_cancelledListener(iap_feature, transaction) native.showAlert(“Restore of " … iap_description … " cancelled by App Store.”) native.setActivityIndicator(false) end ------------------------------------------------------- iap_badger.setFailedListener(lf_failedListener) iap_badger.setCancelledListener(lf_cancelledListener) iap_badger.restore(false, lf_restoreListener, lf_restoreTimeout)         – Ends up calling store.restore(). end

Is the problem that the IAP feature is already marked as purchased on my device?  I’ve found in the IAP Badger code this comment:

–store.restore does not provide a callback if there are no products to restore - the code

–is just left hanging. Call the userdefined timeoutFunction after the specified amount of

–time has elapsed if this happens.

I haven’t figured out how to un-purchase something so I can test this theory, and test restoring.  (I don’t think it’s even possible to un-purchase something.)  In any case if this is how store.restore() really works, it stinks.

Any suggestions?  Thanks!

  • Adam

The store.restore() API does not trigger a callback event. Instead, if you have made any managed purchases (items you can only buy once), you will get a “purchased” event to your transaction listener. For consumable items, you won’t get anything. And if there are no purchases you won’t get anything.

Rob 

Hi Adam,

As Rob said, if your test user has purchased a consumable, it won’t appear in the restore cycle.  Only non-consumbles get restored.

If you’ve got everything else working, and want to test your restore functions, initialise IAP Badger in debug mode.  When you call iap.restore(), IAP Badger will then fake restores for every non-consumable item in your catalogue.  It won’t actually do this by contacting the app store, but it will call the exact same functions that are triggered during a true restore with dummy data (you can specify values for the dummy data in your product catalogue).

If your callback functions get called in debug mode, and purchases are working on a true build on the App Store, you can be 99.99% sure they’ll work in the real world.

Just remember to turn off debug mode before you share your app with the world!

Simon :slight_smile:

The store.restore() API does not trigger a callback event. Instead, if you have made any managed purchases (items you can only buy once), you will get a “purchased” event to your transaction listener. For consumable items, you won’t get anything. And if there are no purchases you won’t get anything.

Rob 

Hi Adam,

As Rob said, if your test user has purchased a consumable, it won’t appear in the restore cycle.  Only non-consumbles get restored.

If you’ve got everything else working, and want to test your restore functions, initialise IAP Badger in debug mode.  When you call iap.restore(), IAP Badger will then fake restores for every non-consumable item in your catalogue.  It won’t actually do this by contacting the app store, but it will call the exact same functions that are triggered during a true restore with dummy data (you can specify values for the dummy data in your product catalogue).

If your callback functions get called in debug mode, and purchases are working on a true build on the App Store, you can be 99.99% sure they’ll work in the real world.

Just remember to turn off debug mode before you share your app with the world!

Simon :slight_smile: