j3k0 / cordova-plugin-purchase

In-App Purchase for Cordova on iOS, Android and Windows
https://purchase.cordova.fovea.cc
1.3k stars 535 forks source link

refresh do not restore previous transaction #453

Closed kappuccino closed 8 years ago

kappuccino commented 8 years ago

Hello,

I try to figure out why i can't restore previous purchase for NON_RENEWING_SUBSCRIPTION When I click a button to make an order, i got

2016-05-25 14:48:52.254 Epiz[1175:498045] [store.js] INFO: ios -> transaction 1000000213544948 purchased (1 in the queue for oneMonth_ns)

When I call store.get('oneMonth_ns') just after that, i can see a very detailed object with a transaction id.

But, when I rebuild the app, or just relaunch it, store.get('oneMonth_ns') give me the same detailed object without the transaction id.

How can i get back this transaction id ?

By the way, maybe i got it wrong, but i have 2 subscriptions products (1 month & 1 year) for a large number of content. When a purchase is made, i save it on my server... and later i want to be able to get the items saved on the server based on the transaction id. Because the subscription product id could be used for a lot of product, i can not used to to identify multiple purchases...

j3k0 commented 8 years ago

Hello,

How can i get back this transaction id ?

You can't.

Non-renewing subscriptions transactions aren't persisted in the AppStore Receipt, so you can't rely on that. Once you processed the non-renewing subscription, you should finish it, then assume you'll never be able to hear about that transaction ever again. It's been consumed for good, your server should associate a user with a "subscription expiry date". It can remember in DB all transactions that have already processed (to prevent malicious "replaying" of valid receipts, a common hack).

Make sure you use the latest version of the plugin (6.0.0) in which a few things got fixed related to non-renewing subscriptions.

Also feel free to check this out: https://github.com/j3k0/cordova-non-renewing-subscription

kappuccino commented 8 years ago

Thank you so much for thoses enlightenment. My app was rejected by apple because a user have to be connected before doing an inapp purchase. Apple do nos allow that. (this was a pretty simple way to remember on my server what IAP was purchased)

So i try to find a way to:

any tips ?

i will test your cordova-non-renewing-subscription plugin extension, but i think my problem will be the same...

j3k0 commented 8 years ago

If you don't want to force a user to be logged-in, you can store the subscription status on localStorage in case they aren't.

If transactions are properly finished, you can repurchase. Again, you can refer to how the lib mentioned above is implemented.

kappuccino commented 8 years ago

yep, but how to perform a "restore purchase" from another device in this case ? Apple documentation is pretty clear in this case : an inapp purchase have to be available on all the user devices...

I have no issue to repurchase, your doc is pretty clear on that subject.

No way to get a uniq id of the user ? like a itunes use hash or something ?

j3k0 commented 8 years ago

Since localStorage is (unless specified otherwise) backed up on iCloud, I think it's fine. User can change device and keep their data. Better than storing the expiry date on localStorage, you can store a randomly generated user-id (very large string), if it's not already present in localStorage.

j3k0 commented 8 years ago

On native app dev, some people use KeyChain key-value store.

https://gist.githubusercontent.com/miguelcma/e8f291e54b025815ca46/raw/17018c4a93a330a44528c99d6df1c819b0e4cd33/DeviceUID.m

I think managing this kind of global user ID goes beyond the scope of the plugin. It's something that could be used for many other things... So it should probably be handled by another plugin (maybe it already exists, I don't know)

j3k0 commented 8 years ago

As such, this thing may be better than localStorage:

https://github.com/Crypho/cordova-plugin-secure-storage

kappuccino commented 8 years ago

you may be right. i do know the local storage was synced with iCloud. i plan to use local storage to save only an ID, and request the full data from the server . cordova-plugin-secure-storage sounds great, i will have a look.

thank you again for your help & your advices