PeterStaev / nativescript-purchase

:moneybag: A NativeScript plugin for making in-app purchases!
Apache License 2.0
82 stars 28 forks source link

Consuming Old Items (Item already purchased promise error) #62

Closed cryptodude2000 closed 5 years ago

cryptodude2000 commented 5 years ago

I had an issue with consuming old purchases on my Android Device - i did not hook up the events to consume an android purchase before testing the actual purchase. I look through the issues and found several people with the same issue. Wanted to post this here, because it worked for me.

I have this rigged for development only, i doubt i will send it to production although I could: this is my buy code - still in dev:

if (purchase.canMakePayments()) {
  // NOTE: 'product' must be the same instance as the one returned from getProducts()
  (global as any).purchaseInitPromise.then(() => {
    purchase.buyProduct(productIn);                
  }
  ).catch(error => {        
    purchase.restorePurchases();
  });

}
else {
    alert("Sorry, your account is not eligible to make payments!!");
}

I edited the plugin restorePurchases function in purchase.android.js to this: function restorePurchases() {

Promise.all([
    futureToPromise(helper.getPurchases(null, "inapp")),
    futureToPromise(helper.getPurchases(null, "subs")),
]).then(function (result) {
    for (var type = 0; type <= 1; type++) {
        for (var _i = 0, _a = result[type]; _i < _a.length; _i++) {                
            var item = _a[_i];
             ////MY CONSUME CHANGE BEGIN
            var json = JSON.parse(item);
            if (json.purchaseToken)
            {
                consumePurchase(json.purchaseToken);
            }
             ////MY CONSUME CHANGE END
            var tran = new transaction_1.Transaction(null);

            tran.originalTransaction = new transaction_1.Transaction(item);
            tran.transactionState = transaction_1.TransactionState.Restored;
            //common._notify(common.transactionUpdatedEvent, tran);
        }
    }
});

}

Tested it many times and it always works.

Just an easy fix for folks before they release the app. We use travis to build so this code will never hit production in my world, but makes my dev testing a lot easier.

cryptodude2000 commented 5 years ago

@PeterStaev you could theoretically change the signature of restorepurchases() to restorePurchases(consume?:boolean) and check for consume variable and then if so consume like i did above to make life easier for folks.

PeterStaev commented 5 years ago

@cryptodude2000 , I prefer to leave the consuming to the end user by calling the already exposed consumePurchase() method. So instead of changing the method in the plugin you can simply call restorePurchases and then in the transaction update event to call consumePurchase()

cryptodude2000 commented 5 years ago

@PeterStaev makes sense to me. It was easier seeing how you processed restorepurchases to get the token and simply do it there.

Plugin works great. Do you have an ETH address?

PeterStaev commented 5 years ago

@cryptodude2000 , sure you can send any tips to: 0x0Ff105607a7Fec9fd033316Cd96A58D3aeEe1590 😄