cordova-plugin-inapppurchase
cordova-plugin-inapppurchase copied to clipboard
transactionId inconsistency - Android
Android transactionId is different between "buy" and "restorePurchases" for a consumable product.
Details are shown below, but basically (1) "buy" : transactionId == receipt.purchaseToken (2) "restorePurchase" : transactionId == receipt.orderId.
The "purchase data" should be the same (or at least consistent), no matter the function that returned it....
Why is this an issue, you ask?
On my sever, I save every purchase for every user, so I can make sure each purchase is applied to the user that purchased it, and that every purchase is not re-processed (for a game, to make sure they only receive their purchased coins once).
I use the restorePurchases.transactionId as the unique purchase identifies in my database (ex: "GPA.1395-0061-3237-38356").
This is used because the voltrue2/in-app-purchase NODEJS module returns this same value ("GPA.1395-0061-3237-38356") as "orderId", making things consistent, so I can correlate the verification request to the verification response.
- John
from inAppPurchase.buy
productId : "kf_coins_99" productType : "inapp" receipt : "{"orderId":"GPA.1395-0061-3237-38356","packageName":"com..app","productId":"kf_coins_99","purchaseTime":1484856489387,"purchaseState":0,"purchaseToken":"oknoanhaobleoniljhehhikb.AO-J1OzgFwHnaMcF6bB-iW6TQSLYRumjyCQVIYNCxzzb2L5Z6UUoLx_jCv9cEPjCgpnRGfr2Arf6Bq-8NQT3BoExmg0l29GWe75yma8hKeIANmObGNgh5k4uFOSszhO-s75Imzbe9Z63"}" signature : "" transactionId : "oknoanhaobleoniljhehhikb.AO-J1OzgFwHnaMcF6bB-iW6TQSLYRumjyCQVIYNCxzzb2L5Z6UUoLx_jCv9cEPjCgpnRGfr2Arf6Bq-8NQT3BoExmg0l29GWe75yma8hKeIANmObGNgh5k4uFOSszhO-s75Imzbe9Z63" type : "inapp"
from inAppPurchase.restorePurchases
date : undefined productId : "kf_coins_99" productType : "inapp" receipt : "{"orderId":"GPA.1395-0061-3237-38356","packageName":"com..app","productId":"kf_coins_99","purchaseTime":1484856489387,"purchaseState":0,"purchaseToken":"oknoanhaobleoniljhehhikb.AO-J1OzgFwHnaMcF6bB-iW6TQSLYRumjyCQVIYNCxzzb2L5Z6UUoLx_jCv9cEPjCgpnRGfr2Arf6Bq-8NQT3BoExmg0l29GWe75yma8hKeIANmObGNgh5k4uFOSszhO-s75Imzbe9Z63"}" signature : "" state : undefined transactionId : "GPA.1395-0061-3237-38356" type : "inapp"
Version of cordova
5.1.1
Version of iOS/Android
Android 6.0.1
@JohnScottMcNerney did you find a solution to this?
I'm curious about restorePurchases -> state: undefined
I'm seeing this on my subscription statuses along with date: undefined
, making it impossible for me to know if the user cancelled their subscription.
@skotturi Sorry, but I am only doing CONSUMABLE purchases, not SUBSCRIPTIONs. As such, I don't really look at the "state" or "date". If you get "state: undefined" for a product correctly configured as a SUBSCRIPTION, you have an issue different than what I have.
Guys if you can find any information about that, please write here. It can be helpful.
@centrual I believe its impossible to check android subscriptions with the receipt on the client. You will need to use Google Play Store API: https://github.com/voltrue2/in-app-purchase#google-play-store-api
I've setup most of it but haven't got it fully working yet.
@JohnScottMcNerney -- I know this is an old ticket, but did you ever solve this? I'm seeing the same thing, where the transactionId == purchaseToken after a call to buy(), but transactionId == orderId after a call to restorePurchases.
This still seems like a bug (maybe in the Android API), but I solved this by using the transactionId from the purchaseData. So,
const validatedData = await iap.validate(receipt);
const purchaseData = await iap.getPurchaseData(validatedData);
const transactionId = purchaseData.transactionId;
In this case, the transactionId is the same in both the buy
and restorePurchases
scenarios.
Note that validatedData also have the purchaseToken, but I don't know if that will always be the same as the transactionId, so I decided not to use it.
Actually, upon closer inspection, the issue is here:
https://github.com/AlexDisler/cordova-plugin-inapppurchase/blob/master/src/js/index-android.js#L70
and here:
https://github.com/AlexDisler/cordova-plugin-inapppurchase/blob/master/src/js/index-android.js#L114
Maybe this is just a workaround of some sort?
Sorry, one more thing I noticed. The purchaseToken is available from the native restorePurchases call on android:
https://github.com/AlexDisler/cordova-plugin-inapppurchase/blob/master/src/android/InAppBillingV3.java#L375
So it seems like the line transactionId: val.orderId,
in index-android.js is just a bug.