cordova-plugin-purchase icon indicating copy to clipboard operation
cordova-plugin-purchase copied to clipboard

Already payed iOS non consumable LOST `owned= true` in new installations

Open losciur opened this issue 2 years ago • 7 comments
trafficstars

Observed behavior

When a user buy a non consumable product in iOS and Android all is ok, the state of the product change in owned= true. When I reopen the app the product mantains owned= true, both iOS and Android. BUT if I send a new version of the app, or if I uninstall and reinstall the same version of the app, appears the problem:

  • Android is ok, and the product correctly has owned= true.
  • iOS doesn't work and the product has owned= false.

Expected behavior

I expect that also in iOS the product already payed, in new version of the app or in case of uninstallation and re-installation of the same version, has owned= true.

System Info

I have a ionic angular capacitor app, here the ionic info output:

Ionic:

   Ionic CLI                     : 6.20.6 (/Users/losciur/.nvm/versions/node/v18.12.1/lib/node_modules/@ionic/cli)
   Ionic Framework               : @ionic/angular 6.4.1
   @angular-devkit/build-angular : 15.0.4
   @angular-devkit/schematics    : 15.0.4
   @angular/cli                  : 15.0.4
   @ionic/angular-toolkit        : 6.1.0

Capacitor:

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

Utility:

   cordova-res : not installed globally
   native-run  : 1.7.1

System:

   NodeJS : v18.12.1 (/Users/losciur/.nvm/versions/node/v18.12.1/bin/node)
   npm    : 8.19.2
   OS     : macOS

I have installed: [email protected]

Can you help me? Thanks

losciur avatar Jan 09 '23 13:01 losciur

Hello, what's the status of that issue?

j3k0 avatar May 30 '23 09:05 j3k0

Same problem here.. I checked my old Cordova-based app and I always got an "owned" property in the productUpdate event data. Now, with using the latest version with Capacitor, there isn't any "owned" information.

petrot avatar Jun 05 '23 07:06 petrot

I got similar problem in IOS7 with this plugin Version 13.9.0 and 13.10.0 for subscription packages:

  • buy subscription package can response with product updated with owned == true and canPurchase == false
  • but after re-open the app, all of the subscription products with owned == false and canPurchase == true

richso avatar Dec 06 '23 11:12 richso

@richso Can you share some logs and relevant source code, thanks.

j3k0 avatar Dec 06 '23 19:12 j3k0

product.owned is still always false for a subscription on iOS.

If I successfully buy a subscription, then close the app and reopen it. The store.when().productUpdated(...) event shows product.owned = false. Also no transactions from this subscription product are triggered in store.when().approved(...) after the start. I have no information at startup to see if the subscription is purchased.

I cannot get subscription to run on iOS with purchase 13.10.0. How can I know if the product is owned / purchased? Any ideas @j3k0?

PS.

  • The test purchase was transfered to iaptic and was / is valid.
  • It was working on purchase 11.x
  • It is a renewed purchase, as the test account already purchased it with before.
  • .receiptsReady(receipts) are null
  • .receiptsVerified(receipts) are null
  • those two functions result also in null:
var LastVerifiedReceipt = store.findInVerifiedReceipts(product);
console.log(LastVerifiedReceipt);
var LastLocalReceipt = store.findInLocalReceipts(product);
console.log(LastLocalReceipt);

MarcelSchuermann avatar Jan 05 '24 20:01 MarcelSchuermann

owned should be true after receipt validation (because subscriptions expiry date only provided by validation). If using iaptic, this is well tested, so I will assume something specific happens in your setup.

Can you share code and logs?

j3k0 avatar Jan 12 '24 09:01 j3k0

@j3k0 thanks for the input.

I use the official code from iaptic for cordova for v13: https://www.iaptic.com/documentation/setup/cordova official code:

store.when()
   .approved(transaction => transaction.verify())
   .verified(receipt => receipt.finish())
   .unverified(receipt => console.log('receipt cannot be verified'));

I changed following event, to exclude the default app product (which only occurs on apple). I only want the subscription product to be checked at startup - but the product is never returned in console:

.productUpdated(product => {
                   console.log(product.id); // this is never the subscription product id
                   console.log(product.owned) // product is therefore never owned for the real subscription product - only for the internal iOS app id
                   
                   if (product.id === 'id.of.subscription.product'){
                       renderIAP(product); // in this fuction product.owned would be checked and UI would be updated.
                   }
               })

Edit: Store initialization is like this - if I uncomment the options I do not get the right information (price etc.) from the subscription:

store.initialize([
                        {
                          platform: Platform.APPLE_APPSTORE
                        //   ,options: {
                        //     needAppReceipt: true,
                        //     discountEligibilityDeterminer: iaptic.appStoreDiscountEligibilityDeterminer,
                        //   }
                        }
                    ]); 

if I purchase the subscription (renew it), I get the corresponding event in Iaptic Event overview: [Notification received from Apple][DID_RENEW]

Repoen app But after reopening the app, I cannot find the subscription.

Trying to order again If I want to purchase the subscription again, it says "You are currently subscribed to this... (my subscription)". If I look in the "manage subscription" section, there is no subscription. But it is also a sandbox / virtual subscription. If I then click on "OK" - the subscription gets recognized but after I reopen the app it is gone again.

MarcelSchuermann avatar Jan 12 '24 10:01 MarcelSchuermann