j3k0 / cordova-plugin-purchase

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

[ANDROID] register fails and no error info? #889

Closed travisryan closed 4 years ago

travisryan commented 4 years ago

system info

I'm using this and can't figure out why I'm getting an error in calling the register. I'm using Ionic 3.x and have uninstalled and reinstall so many times. I've scoured Google, forums, this bug list, etc and can't find my answer. I have a try catch and the catch is fired but the error is empty. I have the BILLING KEY declared as all the info shows, etc. I have my app in as a closed Alpha, and a non developer user that is on my One Plus 6 phone, etc. I think I've followed everything I could find and still have this weird issue.

Expected behavior

I expect the .register command to run without issue.

Observed behavior

calling .register, it fires the catch but has NO error info, etc.

Steps to reproduce

Code that is relevant is as follows.....

import { InAppPurchase2, IAPProduct,  } from '@ionic-native/in-app-purchase-2/ngx';

export class OptionsPage {

constructor(public platform: Platform, private store: InAppPurchase2 ) {

          platform.ready().then(() => {
            this.configurePurchasing();
          });
  }

  configurePurchasing() {
    if (!this.platform.is('cordova')) { return; }
    console.log('Starting Configurations');
    let productId;

      if (this.platform.is('ios')) {

      } else if (this.platform.is('android')) {

        productId = 'credits10';
      }

      if(!this.store) {
        console.log('Store not available.');
        alert('Store not available.');
      }
      alert(JSON.stringify(this.store));
      // Register Product
      console.log('Registering Product ' + JSON.stringify(productId));
      alert('Registering Product ' + JSON.stringify(productId));
      try {
        this.store.verbosity = this.store.DEBUG;

        this.store.register({
          id: productId,
          //alias: productId,
          type: this.store.NON_CONSUMABLE,
        });
      }
      catch(err2)
      {
        alert("Product register error! " + JSON.stringify(err2));

      }

  }

}
Dexus commented 4 years ago

Ionic has the store reserved for other functions... as far as I know, you can search for it in previous issues from last year. So far I know you need to redirect the name to an other one. But I‘m not familiar with ionic.

Regards, Josef

Am 02.07.2019 um 19:27 schrieb travisryan notifications@github.com:

!!! PLEASE USE IN SUBJECT [IOS] OR [ANDROID] AS PREFIX FOR YOUR ISSUE !!!

system info

I'm using this and can't figure out why I'm getting an error in calling the register. I'm using Ionic 3.x and have uninstalled and reinstall so many times. I've scoured Google, forums, this bug list, etc and can't find my answer. I have a try catch and the catch is fired but the error is empty. I have the BILLING KEY declared as all the info shows, etc. I have my app in as a closed Alpha, and a non developer user that is on my One Plus 6 phone, etc. I think I've followed everything I could find and still have this weird issue.

Expected behavior

I expect the .register command to fun without issue.

Observed behavior

calling .register, it fires the catch but has NO error info, etc.

Steps to reproduce

Code that is relevant is as follows..... import { InAppPurchase2, IAPProduct, } from '@ionic-native/in-app-purchase-2/ngx';

export class OptionsPage {

constructor(public platform: Platform, private store: InAppPurchase2 ) {

  platform.ready().then(() => {
    this.configurePurchasing();
  });

}

configurePurchasing() { if (!this.platform.is('cordova')) { return; } console.log('Starting Configurations'); let productId;

if (this.platform.is('ios')) {

} else if (this.platform.is('android')) {

productId = 'credits10';

}

if(!this.store) { console.log('Store not available.'); alert('Store not available.'); } alert(JSON.stringify(this.store)); // Register Product console.log('Registering Product ' + JSON.stringify(productId)); alert('Registering Product ' + JSON.stringify(productId)); try { this.store.verbosity = this.store.DEBUG;

this.store.register({
  id: productId,
  //alias: productId,
  type: this.store.NON_CONSUMABLE,
});

} catch(err2) { alert("Product register error! " + JSON.stringify(err2));

} }

purchase() {

/this.loader = this.loadingCtrl.create({ content: 'Completing Transaction' }); this.loader.present(); / // Check For Review Status /if (!this.program.appleProductId || !this.program.googleProductId) { this.toastCtrl.create({ message: 'This product has not yet been approved for purchase. Please submit it for review.', duration: 2000 }).present(); this.loader.dismiss(); return; }/

this.configurePurchasing();

if (!this.platform.is('cordova')) { return };

let productId;

if (this.platform.is('ios')) { //productId = this.program.appleProductId; } else if (this.platform.is('android')) { //productId = this.program.googleProductId; productId = ""; }

try { let product = this.store.get(productId); console.log('Product Info: ' + JSON.stringify(product)); this.store.order(productId).then( () => { console.log('Purchase Succesfull'); //this.loader.dismiss(); }).catch( () => { console.log('Error Ordering From Store'); //this.loader.dismiss(); }); } catch (err) { console.log('Error Ordering ' + JSON.stringify(err)); //this.loader.dismiss(); } } }

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

travisryan commented 4 years ago

Do you mean that the word "store" is a reserved word for them? Could it be as simple as naming it something else? All examples I found used the code I put here.

travisryan commented 4 years ago

renamed it and still get same issue.

travisryan commented 4 years ago

How can I get some debug info so I can actually see the error? adb logcat didn't seem to get my anywhere and alerts with any data from the try catch didn't. I'll take ANY help as I'm totally stuck. Thanks!

travisryan commented 4 years ago

I've looked through all old patches, issues, etc and didn't find anything related to the reserved word issue @Dexus spoke of. :(

ittiwutw commented 4 years ago

@travisryan Hi, I face the same issue, have you fix this yet? :(

travisryan commented 4 years ago

@ittiwutw nope I moved on to other bugs in my app, while I wait. I really need this answer.

ittiwutw commented 4 years ago

@travisryan I found that may be it's error at "this.store.NON_CONSUMABLE" but still don't know hot to fix it

travisryan commented 4 years ago

REALLY need some help on this issue! I'd be very thankful for anyone that can help pinpoint this issue. THANKS! Travis

travisryan commented 4 years ago

It appears that the testing for the this.store or this.store2 which I also switched everything to, comes back as an empty object. This means the if(!this.store2) will still think it's valid, but it's not. Even something simple like setting the verbosity will cause a catch error. Hmmm...

travisryan commented 4 years ago

@Dexus I just looked through ALL the old open and closed tickets back to 2017 and don't see anything related to this. PLEASE HELP! :D

Dexus commented 4 years ago

Hello travisryan,

You use the ionic plugin that’s wrapped this plugin? I don’t know it’s name but I mean it sounds like something „purchase2“ or similar.

As already saying I don’t use Ionic and the universe of ionic. But why you try to make an app when you don’t know how to debug and use plugins correctly?

Please note if you like to get support you can get it - but as often it’s not free if you are not able to understand what you are doing... and the problem is not plugin related for what I can read.

Von meinem iPhone gesendet

Am 08.07.2019 um 22:02 schrieb travisryan notifications@github.com:

@Dexus I just looked through ALL the old open and closed tickets back to 2017 and don't see anything related to this. PLEASE HELP! :D

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

travisryan commented 4 years ago

yes I use the following line and project: import { InAppPurchase2, IAPProduct } from '@ionic-native/in-app-purchase-2/ngx';

I'm doing ok and have a full application with many api's integrated including Parse, and a telecom provider. If I'm using the typical plugin and wrapper, then it seems I should get some support? I understand right now it's free, and that's why I REALLY appreciate it!

My problem is I'm not getting a proper error message from the plugin, and all I'm getting is that my store is an empty object. So my debugging questions, really are to do with the plugin and wrapper more than ionic itself. :(

Dexus commented 4 years ago

Yah you please provide the installed plugins and share the version of ionic you using? Thanks

Von meinem iPhone gesendet

Am 08.07.2019 um 22:32 schrieb travisryan notifications@github.com:

yes I use the following line and project: import { InAppPurchase2, IAPProduct } from '@ionic-native/in-app-purchase-2/ngx';

I'm doing ok and have a full application with many api's integrated including Parse, and a telecom provider. If I'm using the typical plugin and wrapper, then it seems I should get some support? I understand right now it's free, and that's why I REALLY appreciate it!

My problem is I'm not getting a proper error message from the plugin, and all I'm getting is that my store is an empty object. So my debugging questions, really are to do with the plugin and wrapper more than ionic itself. :(

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

travisryan commented 4 years ago

Here is my package.json with private keys etc masked ......

{
  "name": "***",
  "version": "",
  "author": "",
  "homepage": "",
  "private": true,
  "scripts": {
    "clean": "ionic-app-scripts clean",
    "build": "ionic-app-scripts build",
    "lint": "ionic-app-scripts lint",
    "ionic:build": "ionic-app-scripts build",
    "ionic:serve": "ionic-app-scripts serve"
  },
  "dependencies": {
    "@angular/common": "^5.2.11",
    "@angular/compiler": "^5.2.11",
    "@angular/compiler-cli": "^5.2.11",
    "@angular/core": "^5.2.11",
    "@angular/forms": "^5.2.11",
    "@angular/http": "^5.2.11",
    "@angular/platform-browser": "^5.2.11",
    "@angular/platform-browser-dynamic": "^5.2.11",
    "@ionic-native/android-permissions": "^4.20.0",
    "@ionic-native/background-mode": "^4.20.0",
    "@ionic-native/call-number": "^4.20.0",
    "@ionic-native/camera": "^4.20.0",
    "@ionic-native/contacts": "^4.20.0",
    "@ionic-native/core": "^4.20.0",
    "@ionic-native/file": "^4.20.0",
    "@ionic-native/image-picker": "^4.20.0",
    "@ionic-native/in-app-purchase-2": "^5.8.0",
    "@ionic-native/splash-screen": "^4.20.0",
    "@ionic-native/status-bar": "^4.20.0",
    "@ionic/storage": "^2.2.0",
    "call-number": "1.0.1",
    "cc.fovea.cordova.purchase": "8.1.1",
    "com.synconset.imagepicker": "^2.1.10",
    "cordova-android": "7.1.4",
    "cordova-android-support-gradle-release": "3.0.0",
    "cordova-browser": "^4.1.0",
    "cordova-plugin-android-permissions": "1.0.0",
    "cordova-plugin-camera": "^2.4.1",
    "cordova-plugin-console": "^1.1.0",
    "cordova-plugin-contacts": "3.0.1",
    "cordova-plugin-device": "^1.1.7",
    "cordova-plugin-file": "^6.0.1",
    "cordova-plugin-inapppurchase": "1.2.0",
    "cordova-plugin-ionic-keyboard": "2.1.3",
    "cordova-plugin-splashscreen": "^4.1.0",
    "cordova-plugin-statusbar": "^2.4.2",
    "cordova-plugin-whitelist": "^1.3.3",
    "cordova-support-google-services": "1.3.1",
    "ionic-angular": "^3.9.6",
    "ionicons": "^3.0.0",
    "mx.ferreyra.callnumber": "~0.0.2",
    "parse": "^1.11.1",
    "parse-push-plugin": "git+https://github.com/bal200/parse-push-plugin.git",
    "parse-sdk": "^1.5.0",
    "rxjs": "^5.5.12",
    "rxjs-compat": "^6.5.2",
    "sw-toolbox": "3.6.0",
    "zone.js": "^0.8.29"
  },
  "devDependencies": {
    "@ionic/app-scripts": "^3.2.4",
    "typescript": "^2.9.2"
  },
  "description": "An Ionic project",
  "cordova": {
    "plugins": {
      "cordova-plugin-console": {},
      "cordova-plugin-device": {},
      "cordova-plugin-splashscreen": {},
      "cordova-plugin-statusbar": {},
      "cordova-plugin-whitelist": {},
      "cordova-plugin-contacts": {},
      "mx.ferreyra.callnumber": {},
      "cordova-plugin-ionic-keyboard": {},
      "cordova-plugin-inapppurchase": {},
      "cordova-plugin-android-permissions": {},
      "cordova-android-support-gradle-release": {
        "ANDROID_SUPPORT_VERSION": "27.+"
      },
      "parse-push-plugin": {},
      "cordova-support-google-services": {},
      "cc.fovea.cordova.purchase": {
        "BILLING_KEY": "MIIBIjANBgkqhkiG*******PIcNym3I3pW6xZzQIDAQAB"
      },
      "cordova-plugin-telerik-imagepicker": {}
    },
    "platforms": [
      "browser"
    ]
  },
  "cordovaPlugins": [],
  "cordovaPlatforms": [
    "android"
  ]
}
travisryan commented 4 years ago

I thought maybe having the old version still hanging around would be a problem... "cordova-plugin-inapppurchase": "1.2.0", so I removed it and then tried again. Still same issue. deleted all modules, npm install same. Removed android, added android platform back in, etc. still same. So frustrating...

travisryan commented 4 years ago

@ittiwutw are you by any chance using Parse with your app?

travisryan commented 4 years ago

So I created a new ionic app, and only thing I added was the this plugin. I put in the same billing info, etc, which probably should fail as it's a different app altogether. Without signing, etc what would be expected to happen? It just comes up an empty string/array just like my regular app that can be signed, etc. This makes no sense to me...

j3k0 commented 4 years ago

Hey, you're not supposed to install cordova-plugin-inapppurchase. This plugin is called cordova-plugin-purchase (cf README)

travisryan commented 4 years ago

on my main app I removed the cordova-plugin-inapppurchase as stated.

So now on my current and the new test, I did the following per the instructions, but added the billing_key variable as well ... ionic cordova plugin add cc.fovea.cordova.purchase npm install @ionic-native/in-app-purchase-2

Is this not right? The in-app-purchase-2 is the wrapper for this plugin right? Thanks!

travisryan commented 4 years ago

I uninstalled the cc.fovea.cordova.purchase plugin and installed cordova-plugin-purchase.

Now I get alot of the following when trying to open the store... 07-10 14:34:44.623 12044 12044 E libc : Access denied finding property "vendor.perf.iop_v3.enable" 07-10 14:34:44.623 12044 12044 E libc : Access denied finding property "vendor.perf.iop_v3.enable.debug" 07-10 14:34:44.625 12044 12044 E libc : Access denied finding property "vendor.perf.iop_v3.enable" 07-10 14:34:44.625 12044 12044 E libc : Access denied finding property "vendor.perf.iop_v3.enable.debug" 07-10 14:34:44.628 12044 12044 E libc : Access denied finding property "vendor.perf.iop_v3.enable" 07-10 14:34:44.628 12044 12044 E libc : Access denied finding property "vendor.perf.iop_v3.enable.debug"

travisryan commented 4 years ago

I don't have much money yet as I'm still trying to get this app up and working, but do I have to buy support? Honestly I'll donate some money if I can get some help that makes this work. PLEASE! :)

j3k0 commented 4 years ago

From my google research, Access denied finding property "vendor.perf.iop_v3.enable" doesn't seem to be linked to anything specific to in-app purchase.

travisryan commented 4 years ago

adb logcat won't show me anything related to an issue with this plugin. How can I get more debug information about what is happening when it's trying to load? It's obviously not normal for this.store to be equal to {}. I don't get any meaningful errors.

travisryan commented 4 years ago

What more information or money should I put forward? This is a major roadblock for me and I really need to get past it. Isn't there some REALLY low-level debugging I can turn on somewhere to get more insight into why it's not working?

Dexus commented 4 years ago

Hi travisryan,

Maybe you think you a contract with us, but it is open source and we have also a real life, so please learn to have time with issues or learn first how you have to code your application to get it working. I‘m sorry when i‘m to direct when I think it’s a Layer 8 problem...

You don‘t use this plugin directly and we (at last me) can not support the Ionic Plugin Wrapper. I don’t know why you have the problems and if you really already have done all the things that are need in the apple/google developer process that are required.

If you need the help, share your code base so other developer that maybe use also ionic can help you.

Good luck!

Am 14.07.2019 um 19:22 schrieb travisryan notifications@github.com:

What more information or money should I put forward? This is a major roadblock for me and I really need to get past it. Isn't there some REALLY low-level debugging I can turn on somewhere to get more insight into why it's not working?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

travisryan commented 4 years ago

I definitely know that we don't have a contract. I'm very close to others who have open source projects, and like anything in life, "you get what you pay for." I totally understand that. I just don't want this to be one of the many threads I've seen in support that end up getting closed for no activity. Seems alot of threads I've seen have been closed like that, and I want you guys to know I'm committed to solving this.

I believe there IS a company far down the line that is behind this and that's why I say I'm willing to get quotes from that company to figure this out. If I can't even get it working with a real basic ionic app with JUST this plugin, then either I'm doing something wrong, or something else is really wrong. From the plugin site for in-apps-purchases-2 it seem that @j3k0 and his employer/company are the ones that support it? My guess is that the more people that can use this plugin, the more chance they have for customers of their verification product. I hope to one day be one of them and make enough money to become one. :)

Again, I REALLY want to solve this. I'll make another comment with alot of relevant code, but I hadn't yet as I didn't want to spam this forum with a bunch of code. Should I use something like pastbin to post the code link here?

travisryan commented 4 years ago

Here is my relevant pieces of code. please let me know if I should post anything else... app.module.ts https://pastebin.com/6yq5pewL

package.json https://pastebin.com/jL9zhbbf

options.ts // the file that tries to load the store and product... https://pastebin.com/zcFz7LC9

Of course all this is signed with the same key that my approved upload to the store has, with the same version number, etc.

I'd hope that I could get more debugging info from the application on why it's not working. So far all I get is an empty this.store = {};

Please help! Thanks!

travisryan commented 4 years ago

So.... for anyone following... I think I've finally figured out where I was steered wrong. When declaring the object in the constructor and the page you use it....

import { Component } from '@angular/core';
import { App, NavController, LoadingController, Platform, ModalController } from 'ionic-angular';
import { InAppPurchase2, IAPProduct  } from '@ionic-native/in-app-purchase-2/ngx';
@Component({
  selector: 'page-options',
  templateUrl: 'options.html'
})
export class OptionsPage {

  constructor(public platform: Platform, public store: InAppPurchase2, private parseProvider: ParseProvider, public navCtrl: NavController,private auth: AuthProvider, private app: App, 
        public loadingCtrl: LoadingController, public modalController: ModalController ) {

You DON'T refer to the store as "this.store". Some documentation has stated that, and it's wrong in my case. AND if you use just "store", it works, but any IDE like Visual Studio Code will know that it's not the right way to work, so it just COMPLETELY throws off the programmer.

Image/Screenshot of this craziness here. https://imgur.com/y1D3GPC

I hope this helps someone else using Ionic.

travisryan commented 4 years ago

ok so I spoke too soon. Somehow this worked when doing live reloads, but when you go to compile, of course it doesn't like it not being this.store. I'm not sure exactly what's going on and why all this is happening.

travisryan commented 4 years ago

Ok so after more debugging.... It doesn't matter what I name the InAppPurchase2 object in my controller, I can still only get a valid object if it's only referred to as just "store". this.store will not work and if I name the object in the constructor store2, this.store2 and also just store2 is an empty or undefined object. BUT even if I call it store2 in the constructor, IT STILL HAS A VALUE and is stored in an undefined (in my code) variable called "store". How the heck to I get the compiler to let me use just store? Or how can I make sure this is defined properly so the typescript will not throw an error that "store is undefined, did you mean this.store?".

@j3k0 @Dexus Since I'm now finally getting some lower level information and explaining what works and what doesn't, can you guys help? Thanks!

travisryan commented 4 years ago

OK, @j3k0 PLEASE put this in the documentation, but I had to put the following in before the object, and below the import line.

declare var store: any;

This let me tell the debugger that there was a global variable somewhere that I needed to access and it keeps it happy when compiling. FYI

ittiwutw commented 4 years ago

@travisryan can you give me some example please?

travisryan commented 4 years ago

Sure. Just make sure you have the entries in your app.module... import { InAppPurchase2 } from '@ionic-native/in-app-purchase-2/ngx'; <-- at the top providers: [ StatusBar, SplashScreen, { provide: ErrorHandler, useClass: IonicErrorHandler }, InAppPurchase2 ] <-- and somewhere in your providers array in that same file

Then in your actual page, mine is a test in my options.ts... The key was to basically ignore whatever you name the variable in your constructor function, and make sure you just use "store." NOT this.store. BUT to keep the compiler happy, you need to have the "declare var store..." line. That tells your code, that SOMEWHERE there is a global variable named store that you want to reference. My guess is that the cordova plugin somewhere creates that, and we need to access it.

The Purchase function is what is called then the user clicks a button or whatever to start the purchase of an item. I'll be adding the product it to the arguments for that, but for now it's hardcoded as my credits10 product item.

import { Component } from '@angular/core';
import { App, NavController, LoadingController, Platform, ModalController } from 'ionic-angular';
import { InAppPurchase2, IAPProduct  } from '@ionic-native/in-app-purchase-2/ngx';

declare var store: any;

@Component({
  selector: 'page-options',
  templateUrl: 'options.html'
})
export class OptionsPage {

  vgNumber = "";
  vgName = "";

  constructor(public platform: Platform, private store2: InAppPurchase2, public navCtrl: NavController,private auth: AuthProvider, private app: App, 
        public modalController: ModalController ) {

          platform.ready().then(() => {
                this.configurePurchasing();
          });  
  }

configurePurchasing() {
    if (!this.platform.is('cordova')) { return; }
    console.log('Starting Configurations');
    let productId;

      if (this.platform.is('ios')) {
        //productId = this.program.appleProductId;
      } else if (this.platform.is('android')) {
        //productId = this.program.googleProductId;
        productId = 'credits10';
      }

      if(!store) {
        console.log('Store not available.');
        alert('Store not available.');
      }
      //alert(JSON.stringify(store));

      try {
        store.verbosity = store.DEBUG;

      }
      catch(err3)
      {
        alert("Store Debug error! " + JSON.stringify(err3));

      }
      //Register the store validator, IF you want to use it......
      store.validator = "https://validator.fovea.cc/v1/validate?appName=com.yourapp.app&apiKey=******";

      // Register Product
      console.log('Registering Product ' + JSON.stringify(productId));
      //alert('Registering Product ' + JSON.stringify(productId));
      try {
        //store.verbosity = store.DEBUG;

        store.register({
          id: productId,
          //alias: productId,
          type: store.CONSUMABLE,
        });
      }
      catch(err2)
      {
        alert("Product register error! " + JSON.stringify(err2));

      }
      try {

      // Handlers
      store.when(productId).approved( (product: IAPProduct) => {
        // Purchase was approved
        console.log("Purchase Approved: "+ JSON.stringify(product));
        product.verify();
        //
        // I think I need to update the user's purchase in VG and then call the product.finish()
        //product.finish();  //confirms delivery of the item and completes the purchase
        //this.loader.dismiss();
        //this.subscribe();
      });
      store.when(productId).verified((product: IAPProduct) => {
        product.finish();
      });

      store.when(productId).registered( (product: IAPProduct) => {
        console.log('Registered: ' + JSON.stringify(product));
      });

      store.when(productId).updated( (product: IAPProduct) => {
        console.log('Loaded' + JSON.stringify(product));
      });

      store.when(productId).cancelled( (product) => {

        console.error('Purchase was Cancelled');
      });

      store.error( (err) => {

        console.error('Store Error ' + JSON.stringify(err));
      });

      store.ready(() =>  {
       // alert('Store is ready');
        console.log('Store is ready');
        //alert('Products: ' + JSON.stringify(store.products));
        console.log('Products: ' + JSON.stringify(store.products));
        console.log(JSON.stringify(store.get(productId)));
      });

      // Errors
      store.when(productId).error( (error) => {

        alert('An Error Occured' + JSON.stringify(error));
      });
      // Refresh Always
      console.log('Refresh Store');
      //alert('Refreshing Store.');
      store.refresh();
    } catch (err) {
      console.log('Error On Store Issues' + JSON.stringify(err));
      alert('Error On Store Issues' + JSON.stringify(err));
    }

  }

purchase() {

     // Check For Review Status?
    this.configurePurchasing();

    if (!this.platform.is('cordova')) { return };

    let productId;

    if (this.platform.is('ios')) {
      //productId = this.program.appleProductId;
    } else if (this.platform.is('android')) {
      //productId = this.program.googleProductId;
      productId = "credits10";
    }

    try {
      let product = store.get(productId);
      console.log('Product Info: ' + JSON.stringify(product));
      store.order(productId).then( () => {
        console.log('Purchase Successful');
        //this.loader.dismiss();
      }).catch( () => {
        console.log('Error Ordering From Store');
        //this.loader.dismiss();
      });
    } catch (err) {
      console.log('Error Ordering ' + JSON.stringify(err));
      //this.loader.dismiss();
    }
  }
}
Dexus commented 4 years ago

Thank you @travisryan for sharing the code base and help so other users with the same problem.

:+1:

Von meinem iPhone gesendet

Am 16.07.2019 um 17:03 schrieb travisryan notifications@github.com:

Sure. Just make sure you have the entries in your app.module... import { InAppPurchase2 } from '@ionic-native/in-app-purchase-2/ngx'; <-- at the top providers: [ StatusBar, SplashScreen, { provide: ErrorHandler, useClass: IonicErrorHandler }, InAppPurchase2 ] <-- and somewhere in your providers array in that same file

Then in your actual page, mine is a test in my options.ts... The key was to basically ignore whatever you name the variable in your constructor function, and make sure you just use "store." NOT this.store. BUT to keep the compiler happy, you need to have the "declare var store..." line. That tells your code, that SOMEWHERE there is a global variable named store that you want to reference. My guess is that the cordova plugin somewhere creates that, and we need to access it.

The Purchase function is what is called then the user clicks a button or whatever to start the purchase of an item. I'll be adding the product it to the arguments for that, but for now it's hardcoded as my credits10 product item.

import { Component } from '@angular/core'; import { App, NavController, LoadingController, Platform, ModalController } from 'ionic-angular'; import { InAppPurchase2, IAPProduct } from '@ionic-native/in-app-purchase-2/ngx';

declare var store: any;

@Component({ selector: 'page-options', templateUrl: 'options.html' }) export class OptionsPage {

vgNumber = ""; vgName = "";

constructor(public platform: Platform, private store2: InAppPurchase2, public navCtrl: NavController,private auth: AuthProvider, private app: App, public modalController: ModalController ) {

      platform.ready().then(() => {
            this.configurePurchasing();
      });  

}

configurePurchasing() { if (!this.platform.is('cordova')) { return; } console.log('Starting Configurations'); let productId;

  if (this.platform.is('ios')) {
    //productId = this.program.appleProductId;
  } else if (this.platform.is('android')) {
    //productId = this.program.googleProductId;
    productId = 'credits10';
  }

  if(!store) {
    console.log('Store not available.');
    alert('Store not available.');
  }
  //alert(JSON.stringify(store));

  try {
    store.verbosity = store.DEBUG;

  }
  catch(err3)
  {
    alert("Store Debug error! " + JSON.stringify(err3));

  }
  //Register the store validator, IF you want to use it......
  store.validator = "https://validator.fovea.cc/v1/validate?appName=com.yourapp.app&apiKey=******";

  // Register Product
  console.log('Registering Product ' + JSON.stringify(productId));
  //alert('Registering Product ' + JSON.stringify(productId));
  try {
    //store.verbosity = store.DEBUG;

    store.register({
      id: productId,
      //alias: productId,
      type: store.CONSUMABLE,
    });
  }
  catch(err2)
  {
    alert("Product register error! " + JSON.stringify(err2));

  }
  try {

  // Handlers
  store.when(productId).approved( (product: IAPProduct) => {
    // Purchase was approved
    console.log("Purchase Approved: "+ JSON.stringify(product));
    product.verify();
    //
    // I think I need to update the user's purchase in VG and then call the product.finish()
    //product.finish();  //confirms delivery of the item and completes the purchase
    //this.loader.dismiss();
    //this.subscribe();
  });
  store.when(productId).verified((product: IAPProduct) => {
    product.finish();
  });

  store.when(productId).registered( (product: IAPProduct) => {
    console.log('Registered: ' + JSON.stringify(product));
  });

  store.when(productId).updated( (product: IAPProduct) => {
    console.log('Loaded' + JSON.stringify(product));
  });

  store.when(productId).cancelled( (product) => {

    console.error('Purchase was Cancelled');
  });

  store.error( (err) => {

    console.error('Store Error ' + JSON.stringify(err));
  });

  store.ready(() =>  {
   // alert('Store is ready');
    console.log('Store is ready');
    //alert('Products: ' + JSON.stringify(store.products));
    console.log('Products: ' + JSON.stringify(store.products));
    console.log(JSON.stringify(store.get(productId)));
  });

  // Errors
  store.when(productId).error( (error) => {

    alert('An Error Occured' + JSON.stringify(error));
  });
  // Refresh Always
  console.log('Refresh Store');
  //alert('Refreshing Store.');
  store.refresh();
} catch (err) {
  console.log('Error On Store Issues' + JSON.stringify(err));
  alert('Error On Store Issues' + JSON.stringify(err));
}

}

purchase() {

 // Check For Review Status?
this.configurePurchasing();

if (!this.platform.is('cordova')) { return };

let productId;

if (this.platform.is('ios')) {
  //productId = this.program.appleProductId;
} else if (this.platform.is('android')) {
  //productId = this.program.googleProductId;
  productId = "credits10";
}

try {
  let product = store.get(productId);
  console.log('Product Info: ' + JSON.stringify(product));
  store.order(productId).then( () => {
    console.log('Purchase Successful');
    //this.loader.dismiss();
  }).catch( () => {
    console.log('Error Ordering From Store');
    //this.loader.dismiss();
  });
} catch (err) {
  console.log('Error Ordering ' + JSON.stringify(err));
  //this.loader.dismiss();
}

} }

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

ittiwutw commented 4 years ago

@travisryan Thank you, do I have to test after publish to PLayStore (Android case)?

Now, I test on Simulator the product details return null

Dexus commented 4 years ago

Ittiwut yes, you need first add the app to play store as alpha or beta. And test on phone ore simulator.

Please make sure you already done all developer console tasks that need to test your purchases! Like bank details and contracts.(like apple)

Regards Josef

Von meinem iPhone gesendet

Am 16.07.2019 um 17:43 schrieb Ittiwut Wongsawat notifications@github.com:

@travisryan Thank you, do I have to test after publish to PLayStore (Android case)?

Now, I test on Simulator the product details return null

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

materazu commented 4 years ago

@travisryan You save me! thx a lot for this post!