libgdx / gdx-pay

A libGDX cross-platform API for InApp purchasing.
Apache License 2.0
225 stars 83 forks source link

Restoring purchases #154

Closed amitkot closed 5 years ago

amitkot commented 6 years ago

I do not use a server, and I prefer not to keep the current purchases in any persistent manner on the device, for security reasons. What I do is every time I call PurchaseSystem.install() I also call the restore() method, and keep the results in memory.

And it's mostly working great. My app is currently only available for Android, and I have tested the InApp purchase with a test user - it works fine.

I have two questions:

  1. You write in the documentation:

    IMPORTANT: `PurchaseSystem.restore()' should not be called directly by your application. Restoring purchases shall only be called when a user explicitly requests it.

This is obviously exactly what I am doing, in spite of the warning, and it works - what am I missing? What is the problem with calling this automatically as part of PurchaseObserver.handleInstall()?

  1. I wanted to use the test user again, so I refunded their purchase on the Play Store Console, and it worked. For some reason, when I call PurhcaseSystem.restore() I am getting the refunded purchase show as an active purchase, with transaction.isPurchased() returning true. I tried calling AndroidGooglePlayPurchaseManager.cancelTestPurchases(), but it changed nothing.
keesvandieren commented 6 years ago

Answer to (1):

That is for the iOS platform. Apple rejects apps that call PurchaseSystem.restore() without user interaction.

Answer to (2):

When cancelling a 'real' purchase, it takes while (few hours) before the cancellation passes through to the device.

Another approach I use to test purchases on Android, is to use the Android test-purchases.

amitkot commented 6 years ago

So regarding (1) - does that mean my logic for not keeping the purchase in a persistent manner be a problem on iOS? What is the best practice on iOS in that case?

(2) - I followed pretty much the same process you describe, only I refunded the purchase on the Google Play Store Console. If I understand you correctly, what you are saying is that I should have not refunded it, but called AndroidGooglePlayPurchaseManager#cancelTestPurchases instead? I'll try purchasing the item again and calling that method.

keesvandieren commented 6 years ago

Regarding (1): you have to store the purchase state in the app in a way that it is obfuscated / hard to reverse engineer. For Android this is more important than it is for iOS; Apps will appear on APK download sites (making reverse engineering easy), not yet seen that for iOS apps.

Regarding (2): if a purchase appears in the Play Store Console, it is not a test-purchase. Test-purchases used to appear in the Play Console until June 2017. So there is something wrong in the Test Purchases setup

amitkot commented 6 years ago

Moving (1) into a new issue - #155 .

Regarding (2): I still see test purchases marked clearly in the Play Console as "Test Order", and can cancel them. It takes some time for the cancellation to be updated on Google's servers from what I see, but after enough time it no longer returns the purchase when I call restorePurchases().

MrStahlfelge commented 5 years ago

Closing this because it looks like both issues are resolved. If not, feel free to reopen this issue.