Cordova-plugin-purchase on iOS: order() does not work without uninstalling the app first

Details

We are developing an application that uses Ionic (Angular) and Capacitor together with cordova-plugin-purchase to offer subscriptions (monthly and yearly). Purchases work perfectly on Android. However, on iOS, while the first purchase works fine, after that purchase expires (via cancelling the subscription, since it is actually automatically renewing) and the user purchases any product again (now on valid status since it expired already), calling the order() function does not do anything. The product status remains valid, no logs are written in the JavaScript console, nor Xcode. No errors, too. We have verified that our verification servers are returning correct responses. However, when we uninstall the app and install it from Xcode again, purchases start working again, and calling the order() function does show the purchase dialog again, and things work as expected. Until the subscription expires and they try to purchase again.

However, if the product is not yet expired, and the user tries to change subscription by subscribing to another subscription type, calling the order() function works as expected. It is only when a subscription expires, and then it starts to not work until the application is deleted/uninstalled and then installed again.

We implement the purchase using pretty standard code–we tried as minimal as possible to make it simple.

Code

Initialization:

    this.store.validator = 'https://xxxxxxx/api/app/purchased';

    this.store.register([
      {
        type: this.store.PAID_SUBSCRIPTION,
        id: this.YEARLY_SUBSCRIPTION
      },
      {
        type: this.store.PAID_SUBSCRIPTION,
        id: this.MONTHLY_SUBSCRIPTION
      }
    ]);

    this.subscriptions.add(
      this.status.userData.subscribe(ud => {
        this.user = ud;
        this.store.applicationUsername = ud.id.toString(10);
      })
    );

    this.store.when(this.YEARLY_SUBSCRIPTION)
      .cancelled(this.purchaseCancelled)
      .updated(this.purchaseYearlyUpdated)
      .approved(this.purchaseApproved)
      .verified(this.purchaseVerified)
      .owned(this.purchaseOwned);

    this.store.when(this.MONTHLY_SUBSCRIPTION)
      .cancelled(this.purchaseCancelled)
      .updated(this.purchaseMonthlyUpdated)
      .approved(this.purchaseApproved)
      .verified(this.purchaseVerified)
      .owned(this.purchaseOwned);

    this.store.error(this.handleError);

    this.store.autoFinishTransactions = true;

    this.store.refresh();

Other functions:

  purchaseCancelled = (p: IAPProduct) => {
    console.log(`${ p.id } cancelled`);
  }

  purchaseYearlyUpdated = (p: IAPProduct) => {
    console.log(`${ p.id } updated`);
    this.yearlyProduct = p;
    this.changeDetectorRef.detectChanges();
  }

  purchaseMonthlyUpdated = (p: IAPProduct) => {
    console.log(`${ p.id } updated`);
    this.monthlyProduct = p;
    this.changeDetectorRef.detectChanges();
  }

  purchaseApproved = (p: IAPProduct) => {
    console.log(`${ p.id } approved`);
    p.verify();
  }

  purchaseVerified = (p: IAPProduct) => {
    console.log(`${ p.id } verified`);
    p.finish();
  }

  purchaseOwned = (p: IAPProduct) => {
    console.log(`${ p.id } owned`);
  }

  handleError = (error) => {
    console.log('Error event:', error);
  }

  purchase(id: string) {
    this.store.order(id);
  }

  ngOnDestroy() {
    this.subscriptions.unsubscribe();
    this.store.off(this.purchaseCancelled);
    this.store.off(this.purchaseYearlyUpdated);
    this.store.off(this.purchaseMonthlyUpdated);
    this.store.off(this.purchaseApproved);
    this.store.off(this.purchaseVerified);
    this.store.off(this.purchaseOwned);
    this.store.off(this.handleError);
  }

Steps to reproduce

  1. Install the app from Xcode.
  2. Purchase a product (user clicks the purchase button, that button triggers store.order(...)
  3. Exit app
  4. Cancel subscription so it expires
  5. Subscription expires
  6. Open app, and confirm that subscription is indeed expired (status goes from approvedto valid)
  7. Try to purchase subscription again by clicking the purchase button (any subscription)
  8. Nothing happens. No logs. No errors. Product status remains valid.
  9. Closing the app and then running again does not help.
  10. Uninstall app
  11. Install app again from Xcode
  12. Purchase works again

Remarks

I can’t see anything wrong with the code, and since it’s working perfectly fine on Android, we’re guessing that it might be something wrong with the phone or maybe the cordova-plugin-purchase plugin.

I would really appreciate any suggestions, ideas, opinions, anything. Thank you very much in advance. I’m getting quite desperate.