Skip to main content

When to use restoreCompletedTransactions for in-app purchases?



For a basic app with nonconsumable in-app purchases, has anyone figured out best practices for using SKPaymentQueue's restoreCompletedTransactions ?





Observations





I know it's recommended to always register a transaction observer to receive pending transactions that make their way back to the app, but this is a different question. It looks like restoreCompletedTransactions is something the app has to actively decide when to call to poll for all the purchases the customer has already made.





From what I can tell, the method is designed to retrieve purchases that may have been lost. For example a customer might install or move an app to a new device in such a way where the user defaults (where Apple recommends recording nonconsumable payments) are lost or reset.





Concerns





What's not clear to me is how to automatically detect this condition (i.e. how to decide when to poll for missing purchases) in a reliable way. I don't want to screw this up and risk denying a customer access to functionality they've already paid for.





At the same time, I don't want to call restoreCompletedTransactions every single time the app launches just to be safe and basically get back transactions I already know about 99.9% of the time. (Except for in-app purchasing, my app doesn't really require any network connectivity.)





Notes





Apple documentation clarifies that customers are not charged again for any nonconsumable purchases they have already made. If they try to re-purchase, a payment transaction is still supposedly sent to the app.





Worst-case, a customer could recover purchases this way but I'd still like to avoid walking them down a path that resembles re-purchasing something they've already paid for.


Comments

  1. After writing out the question and thinking about it, I came up with a couple solutions.

    Automatic (Not Recommended)

    One option is to record in user defaults whether restoreCompletedTransactions has been called (and successfully completed) yet in the app. If not, the app calls it once on start-up. Since this flag is stored in the same place as the nonconsumable payments, if user defaults get wiped later on then the restore method would get called again when the app starts.

    This way, if an existing costumer is somehow doing a fresh install of the app they still get their purchases restored automatically. If they are a new customer that has never launched the app before, then the restore operation returns nothing.

    In either case, restoreCompletedTransactions is only called once instead of at every launch.

    Manual (Recommended)

    Another option is to offer the customer a "Restore Purchases" button somewhere, hook it up to restoreCompletedTransactions and let them decide if and when it might be needed.

    (The comments below go into why a manual restore is probably better than attempting to do it automatically.)

    ReplyDelete
  2. Don't forget that one Apple ID can span multiple devices. So maintaining a flag on one one device (say, the user's iPhone) that tells you whether or not you've done a restore will not allow you to detect if the customer has made a purchase on another device (say his iPad) that needs to be restored onto the iPhone. So having a manual method of launching a restore is ALSO necessary, even if you have an automatic method.

    To make matters worse, I haven't figured out yet how you're notified when REFUNDS of IAPs are made. I suspect the restore process will simply return a list of the non-refunded transactions. So a) you need to DELETE your record of the user's IAP's when you do your restore in case refunded products are simply not reported during restore, and b) you need to periodically do a restore automatically in order to pick up refunds.

    This all highlights the problem with Apple's IAP -- it's poorly conceived and inadequately documented -- and now it's REQUIRED for content providers like ebook readers who already have perfectly functioning web-based stores already working in their apps (like Kindle).

    ReplyDelete

Post a Comment

Popular posts from this blog

[韓日関係] 首相含む大幅な内閣改造の可能性…早ければ来月10日ごろ=韓国

div not scrolling properly with slimScroll plugin

I am using the slimScroll plugin for jQuery by Piotr Rochala Which is a great plugin for nice scrollbars on most browsers but I am stuck because I am using it for a chat box and whenever the user appends new text to the boxit does scroll using the .scrollTop() method however the plugin's scrollbar doesnt scroll with it and when the user wants to look though the chat history it will start scrolling from near the top. I have made a quick demo of my situation http://jsfiddle.net/DY9CT/2/ Does anyone know how to solve this problem?

Why does this javascript based printing cause Safari to refresh the page?

The page I am working on has a javascript function executed to print parts of the page. For some reason, printing in Safari, causes the window to somehow update. I say somehow, because it does not really refresh as in reload the page, but rather it starts the "rendering" of the page from start, i.e. scroll to top, flash animations start from 0, and so forth. The effect is reproduced by this fiddle: http://jsfiddle.net/fYmnB/ Clicking the print button and finishing or cancelling a print in Safari causes the screen to "go white" for a sec, which in my real website manifests itself as something "like" a reload. While running print button with, let's say, Firefox, just opens and closes the print dialogue without affecting the fiddle page in any way. Is there something with my way of calling the browsers print method that causes this, or how can it be explained - and preferably, avoided? P.S.: On my real site the same occurs with Chrome. In the ex