cordova-plugin-inapppurchase
cordova-plugin-inapppurchase copied to clipboard
Check if product was purchased (thin client/no server)
Hi! First of all..thanks SO much for this awesome plugin.
What is the best way to determine if a product was already purchased? This is a "thin" app, there is no back-end server. The only product is a simple "buy the dev a cold one" to get rid of ads. Is the best way to just store the purchase in localStorage() or should it call restorePurchases() every time the app starts? That seems a bit excessive though.
Thanks again!
@lifzgreat Use receipt validation to solve your issue.
there is no back-end server
@mitiaptest I was under the impression I needed a back-end server to do that. Is that incorrect?
@lifzgreat Not required.
Hmm, I guess I'm not following. Would we validate (this term is still a bit "fuzzy" to me) every time the user logs into the app?
Util now, i don't how to check user have purchased. Can anyone help me? Maybe, using localStorage save transaction id. Is that right?
@lifzgreat set interval and validate your users receipts.
@mitiaptest, could you explain detail for your said "Use receipt validation", pls? Thank you :)
server is necessary to do receipt validation
@mitiaptest, Thank for your reply. I don't use server. That is problem of this issue. Do you any suggesst?
@nhiendat I will try to help you since others are not very helpful at all. I had to make my way through it with no help too :) What I ended up doing was storing the purchase in localStorage. I then provided a button to restore purchases in case localStorage was somehow erased. That doesn't require a server and lets the user restore purchases if he needs to :)
@lifzgreat , "restore purchases in case localStorage was somehow erased." that mean end user must repurchase -> It will make uncomfortable to end user. This is final solution. Right?
@nhiendat If localStorage gets erased, the user will just click "restore purchases" which restores purchases without the user actually buying them again. There's no pain for the user :) And that is only necessary if the localStorage gets erased (manually by the user, or reinstall, things like that).
You right, i am clear. But how do you differentiate end user not buy yet and localStorage gets erased. Both cases localStorage is empty (eg: localstorage.getItem('receipt') == null) ?
The plugin handles that. When they click "restore purchases", you need to run the inAppPurchase.restorePurchases() function. Here is what I have:
restorePurchases = function() {
inAppPurchase
.restorePurchases()
.then(function(purchases) {
if (!purchases.length) {
alert("Sorry, there's nothing to restore. You haven't purchased anything using this account before!");
} else {
// Store the purchase in localStorage
}
})
.catch(function(err) {
alert("Error restoring purchase: " + err.message + " (Code " + err.code + ").");
});
};
Great, thank a lot @lifzgreat . I am clear now. I can explain i understand as bellow: If localStorage empty then run restorePurchases() function Continue, If response available then save transaction data into localStorage Else run buy() function and save transaction data into localStorage if buy successful
No problem!
Well, I don't automatically run the restorePurchases() function. I only run it when the user clicks the restore button (for example, he installs on a new device, he can transfer his purchase to that new device). But if they decided to NOT purchase in the first place, I don't run the buy() function for them without them running it themselves :)
I run automatically the restorePurchases() function to check purchased but unsuccessful (result is always show ads item after re-run application). I don't know reason. My code as bellow:
// Default show ads
$scope.isShowAds = true;
if(window.inAppPurchase){
inAppPurchase.getProducts(['product.ads']).then(function(products){
// Check product
if(products[0].productId == 'product.ads'){
// Check user purchased
inAppPurchase.restorePurchases().then(function(data){
if(data.productId == 'product.ads'){
$scope.isShowAds = false;
AdMob.removeBanner();
}else
{
$scope.isShowAds = true;
showAds();
}
}).catch(function(error){
console.log(error);
});
}
else{
$scope.isShowAds = true;
showAds();
}
}).catch(function(error){
console.log(error);
});
}
else{
console.log("NO PLUGIN IN-APP PURCHASE");
}
// Remove Ads click function
$scope.removeAds = function(){
inAppPurchase.buy('product.ads')
.then(function(data){
if(data.productId == 'product.ads'){
$scope.isShowAds = false;
AdMob.removeBanner();
}
else{
$scope.isShowAds = true;
showAds();
}
// This line required for Android purchases, does not affect iOS purchases
return inAppPurchase.consume(data.type, data.receipt, data.signature);
})
.catch(function(error){
console.log(error);
});
};
Do you know my mistake?
Hard to tell without having it in front of me but I'd start by checking all of your if() statements and making sure they're being hit like you think they should!
Thank for checking @lifzgreat , I think if i use restorePurchases() function then unnecessary using localStorage. Right?
Right, the only reason I use localStorage is so I don't have to run restorePurchases() every time the app runs :) If the purchase is in localStorage, there's no need to run it. If it's not, then the user can run it if he starts getting ads.
Yeah. I try to test my code above following:
- After click button 'Buy' to purchase then hide ads, hide button 'Buy'
- Close and open app again but show button 'Buy' again.
- Try click button 'Buy' again then result as step 1. This step It must show message: 'already purchased' (don't remember exactly content of message) Do you see that something unreasonable?
Hmm, nothing jumps out at me right away but I would go through each if() and do alert() something to make sure it's doing what you think it should. There's something about buying/restoring every time that might not work...might HAVE to use localStorage but I'm not sure...sorry I'm not more help!
Thank for your support. I will try debug with alert. So, i just used localStorage to avoid call restorePurchases() function when app start. Have a nice day :)
That's what I did too, seems to work great :)
And no problem!
@ lifzgreat
Hi, Where you able to resolve your issue?
Waiting for your reply.
Regards, Venkat
Hi @Venkat-TTapp, if you read over the thread, you will see that I did and gave code as well.
Yeah.. re-read whole thread again.. sorry about it...
I need help pertaining to restore purchase.
I did a test integration and the plugin works perfectly well, but I am getting struck at restore purchase.
When I do a restore purchase (Without doing a purchase), I am getting empty result "[]" in console.log. and no error because of which this restore purchase check turns out to be a sucess.
Below is the code what I have used:
function Restore_purchase(){
inAppPurchase
.restorePurchases()
.then(function (purchases) {
console.log(purchases);
console.log(JSON.stringify(purchases));
alert(JSON.stringify(purchases));
alert("restore purchase success");
})
.catch(function (err) {
console.log(err);
console.log(JSON.stringify(err));
alert(JSON.stringify(err));
alert("Restore purchase error");
});
Regards, Venkat
@Venkat-TTapp ok check up a few comments to where I posted the code I used to do this. You have to check purchases for length. If it's empty, they haven't purchased anything - simple as that :)
It is line 5 in this comment above: https://github.com/AlexDisler/cordova-plugin-inapppurchase/issues/44#issuecomment-251997440
@ lifzgreat, Thanks, #44 (comment) resolved this scenario.
I have 3 non consumable product in my app, I am not sure how restore purchase would behave where there is more than 1 purchase (Not sure how to pick and show which product to restore), I will do a test purchase and try to do a purchase restore. If I am struck, I will seek your help.
Thanks for your time,reply and support,
Regards, Venkat
@Venkat-TTapp well you just loop through all purchased products and modify your app depending on what was purchased. For example, let's say you have 2 products,: 1-kill ads, and 2-open levels. When you run restore purchases, anything that has been purchased before will be returned. Simply check the item and modify your app depending on which one(s) come(s) back. A very simple example:
for (i in purchases) {
if (purchases[i].productId == "killAds") {
killAds();
} else if (purchaes[i].productId == "unlockLevels") {
unlockLevels();
}
}
The productId is whatever you made it when you created it in the Google Dev console.