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

Getting empty ([]) products #1539

Closed ivaniclixx closed 2 months ago

ivaniclixx commented 2 months ago

Observed behavior

No matter how and what I do, I can't get any product. It was working perfectly a few months ago with the ionic awesome plugin. Now I get an empty array [] with either Android or iOs. Published Apps. Registering the product returns nothing, trying to get() the product returns undefined. Tried everything I have been reading for a week with 0 results. The only thing that I get is previous receipts from Apple Store.

IONIC, capacitor, Angular based project.

Relevant code:

import 'cordova-plugin-purchase';

export class TabStorePage {

    constructor(public platform: Platform, /* private store: InAppPurchase2*/
        private ref: ChangeDetectorRef) {

    this.platform.ready().then(() => {

            console.info("Platform is ready.");
            CdvPurchase.store.verbosity = CdvPurchase.LogLevel.DEBUG;

           this.setupCourses();

           this.setupListeners();

            console.info("Store initialization");
            CdvPurchase.store.initialize([CdvPurchase.Platform.APPLE_APPSTORE, CdvPurchase.Platform.GOOGLE_PLAY,
            {
              platform: CdvPurchase.Platform.APPLE_APPSTORE,
              options: {
                needAppReceipt: true,
              }
            }
            ]).then((value: CdvPurchase.IError[]): void => {
              console.info("CdvPurchase.IError[]");
              console.info(value);
            });

            CdvPurchase.store.ready(() => {
              console.info("Store is ready.");
              this.products = CdvPurchase.store.products;
              this.ref.detectChanges();
            });
    });

    public setupCourses() {

            console.info("setupCourses();");
            const url = "https://*************";

            // I get {"courses": ["43", "72", "78"]}
            this.http.get(url).subscribe((data: any) => {
                    this.setupStoreItems(data["courses"]);
            }
            );

    }

    private setupListeners() {

        console.info("setupListeners()");

        CdvPurchase.store.when().productUpdated((product) => {

          this.getCourse(product.id);

        })
          .approved((p: any) => {

            this.ref.detectChanges();
            return p.verify();

          })

          .verified((receipt) => {

            console.info("Verified and calling finish();");
            receipt.finish();

            try {

              const source_receipt = receipt.sourceReceipt;
              const body = (source_receipt as any).nativeData.appStoreReceipt;

              console.info("receipt is:");
              console.info(body);
              console.info("Sending receipt to confirm_appstore_receipt...");
              this.http.post("https://*********", body).subscribe((data) => {

                console.info("Data from confirm_appstore_receipt");
                console.info(data);

              });

            } catch (e) {
              console.error("JSON parse or appStoreReceipt key error", e);
            }

          });

      }

  private setupStoreItems( ids: string[] ) {

    console.info("Registering store items: " + ids);
    let items = [];

    for ( let id of ids )
      items.push({
          type: CdvPurchase.ProductType.NON_CONSUMABLE,
          id: id,
          platform: this.platform.is("ios") ? CdvPurchase.Platform.APPLE_APPSTORE : CdvPurchase.Platform.GOOGLE_PLAY
        }
      );

      CdvPurchase.store.register(items);

  }

}

LOG (manually typed, sorry)

Platform is ready. setupCouses(); setupListeners(); [CdvPurchase] initialize(["ios-appstore", "android-playstore",{"platform": "ios-appstore", "options": {"needAppReceipt":true}}] v13.10.1 [CdvPurchase.Adapters] Adding platforms: [{"platform::"ios-appstore"}, {"platform": "android-playstore"}, {"platform": "ios-appstore"},"options":{"needAppReceipt":true}}] [CdvPurchase.Adapters] AppStore initializing... [CdvPurchase.Adapters] AppStore is not supported. [CdvPurchase.Adapters] GooglePlay initializing... [CdvPurchase.GooglePlay] Initialize [CdvPurchase.GooglePlay.Bridge] setup ok [CdvPurchase.Adapters] AppStore initializing... [CdvPurchase.Adapters] AppStore is not supported [CdvPurchase.GooglePlay.Bridge] listener: {"type":"ready","data":{}} [CdvPurchase.GooglePlay] Ready [CdvPurchase.Adapters] GooglePlay initialized. [CdvPurchase.Adapters] GooglePlay products: [] [CdvPurchase.AdapterListener] setSupportedPlatforms: android-playstore (0 have their receipts ready) [CdvPurchase] Calling callback: type=ready() name=#ab7c9f178e68c4a6b49698def59bbdf9 reason=initialize_promise_resolved Store is ready. Registering store items: 43,72,78

The same occurs with iOs. It's an IONIC App. I use CdvPurchase.store for everything. No syntax error anywhere, etc.

Expected behavior

I have 3 products in iOs, 1 product in Android. Should appear and get registered.

System Info

Ionic:

Ionic CLI : 7.1.1 (/usr/lib/node_modules/@ionic/cli) Ionic Framework : @ionic/angular 7.2.2 @angular-devkit/build-angular : 16.1.8 @angular-devkit/schematics : 16.1.8 @angular/cli : 16.1.8 @ionic/angular-toolkit : 9.0.0

Capacitor:

Capacitor CLI : 5.2.2 @capacitor/android : 5.2.2 @capacitor/core : 5.2.2 @capacitor/ios : 5.2.2

Utility:

cordova-res : not installed globally native-run (update available: 2.0.1) : 1.7.2

System:

NodeJS : v21.2.0 (/usr/bin/node) npm : 10.2.4 OS : Linux 6.5

ivaniclixx commented 2 months ago

Other DEBUG things:

CdvPurchase.store.registeredProducts is: {list: [{type: "non consumable", id: "43", platform: "ios-appstore"},{type: "non consumable", id: "72", platform: "ios-appstore"},{type: "non consumable", id: "78", platform: "ios-appstore"}]

CdvPurchase.store.products is: []

ivaniclixx commented 2 months ago

Screenshot_20240228_161630

selcukbeyhan commented 2 months ago

your code seems to have some async order issue. your setupCourses calls the setupStoreItems but the code doesnt wait to end and moves to initialize.

ivaniclixx commented 2 months ago

setupStoreItems

Huge thanks to you ! You were 100% right. I called the functions inside the subscribe() after getting the products array and calling setupListeners().

Again, I really appreciate it. Have a nice day.

public setupCourses() {

console.info("setupCourses();");
const url = "https://www.********";

this.http.get(url).subscribe((data: any) => {

  this.setupStoreItems(data["courses"]);
  this.setupListeners();
  this.initializeStore();
  this.storeReady();

}
);

}