j3k0 / cordova-plugin-purchase

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

How can I avoid product.type==="application" and product.id===applicationId events? #1316

Open eyedean opened 2 years ago

eyedean commented 2 years ago

Thanks for this fabulous plugin, @j3k0, and the team!

My app has 6 renewable subscription plans, all in one Subscription Group (e.g. 1 month, 3 months, etc.). I am registering all of them, and I am listening to all the events on all products (i.e., store.when("product")).

I have noticed that even if I change my sandbox user or clear the queue or do anything (including app restart or store.autoFinishTransactions = true), I still get almost one set of approved -> verified -> finished -> owned all having product.type === "application" and product.id === <com.company.app> (and owned === true and canPurchase === false) for every registered product! That is extremely confusing to us.

So, even if it's a new app user with a new sandbox user, when the app opens up and I register 6 plans, I immediately receive 24 events, including calls to the validator and all.

I have found that there is no notion of type === "application" in the API Doc. The closest thing I found was this comment on 1155.

So, I am wondering what are they? How can I avoid them? How should they be handled? What do they mean?

They are just there muddying everything and giving me a hard time figuring out what's happening.

Thanks!

eyedean commented 2 years ago

Update:

image

That transaction wasn't going away with .finish(). However, a complete uninstall and reinstallation of the app cleared that out.

I believe it was created in the middle of my implementation before I had a complete lifecycle in place (to call .finish() immediately after verification is done.)

eyedean commented 2 years ago

🤦‍♂️ I just made another full transaction with a sandbox tester. It all went great initially:

  1. I can see the subscription in the sandbox-account's App Store management.
  2. I am also able to validate the receipt via Apple's verifyReceipt HTTP call and get the full receipt and all.

However, the sticky transaction to the bundle_id is there and it's not going away! 😭😭😭 How can I clear that?

PS. Even after I cancel the subscription, that product and that transaction is still there. I am now looking at this commit, and having the exact same questions. Why?

It's not documented. I cannot clear it out. There could be much better ways to handle it (e.g. a separate queue/function/fallback) than making the products and all the events messy. Don't you agree?

image

It's just a single randomly-off item in that array, even after the user has canceled their subscription. Do you guys recommend that I ignore it?

image image
louisameline commented 2 years ago

From what I read, application is an implicit product that exists in iOS, so it's expected to have events about this product for some reasons, even if it's not documented.

store.when("product") listens to events on all products, including the application product. You can listen to your own events only if you want by not using the product reserved keyword, and use store.when("your.product.id") instead. However the author of the plugin recommended to verify() and finish() the application product too, so you're better off coping with it.

eqcb commented 1 year ago

Hello @eyedean , @louisameline. I'm having same issue but with consumables. Every time the app starts, refresh() is called and the previous purchase is set to approved but with 'application' as type and my app id as product id. When it tries to verify with my backend the transaction is sent to Apple's verify endpoint and the response comes with the whole information, that's how I know its the previous transaction.

I'm also using store.when("product"). If I change to the actual product names, can I ignore the application approval?

eqcb commented 1 year ago

No difference when I changed from store.when("product") to the products id's. I still get the "application" type purchase upon refresh. What I did notice is that when I try a new purchase it goes as expected but in the logs I get this as last entry(in bold):

[log] - [store.js] DEBUG: state: vcpk500 -> requested To Native Cordova -> InAppPurchase purchase InAppPurchase755483847 ["options": [vcpk500, 1, 9e7ee220aced5367585f2b048f97b33a, { }]] 2022-11-07 21:58:30.290279-0300 App[10921:685992] InAppPurchase[objc]: purchase: About to do IAP 2022-11-07 21:58:30.290363-0300 App[10921:685992] InAppPurchase[objc]: purchase applicationUsername (9e7ee220aced5367585f2b048f97b33a). 2022-11-07 21:58:30.290980-0300 App[10921:685992] InAppPurchase[objc]: paymentQueue:updatedTransactions: vcpk500 2022-11-07 21:58:30.291002-0300 App[10921:685992] InAppPurchase[objc]: paymentQueue:updatedTransactions: Purchasing... 2022-11-07 21:58:30.291014-0300 App[10921:685992] InAppPurchase[objc]: paymentQueue:updatedTransactions: State: PaymentTransactionStatePurchasing 2022-11-07 21:58:30.291027-0300 App[10921:685992] InAppPurchase[objc]: processTransactionUpdate:withArgs: transactionIdentifier= ⚡️ [log] - [store.js] DEBUG: ios -> is purchasing vcpk500 ⚡️ [log] - [store.js] DEBUG: state: vcpk500 -> initiated 2022-11-07 21:59:10.742619-0300 App[10921:685992] InAppPurchase[objc]: paymentQueue:updatedTransactions: vcpk500 2022-11-07 21:59:10.742729-0300 App[10921:685992] InAppPurchase[objc]: paymentQueue:updatedTransactions: State: PaymentTransactionStatePurchased 2022-11-07 21:59:10.742771-0300 App[10921:685992] InAppPurchase[objc]: processTransactionUpdate:withArgs: transactionIdentifier=2000000195971239 ⚡️ [log] - InAppPurchase[js]: product vcpk500 has a transaction in progress: 2000000195971239 ⚡️ [log] - InAppPurchase[js]: loading appStoreReceipt To Native Cordova -> InAppPurchase appStoreReceipt InAppPurchase755483848 ["options": []] 2022-11-07 21:59:10.746281-0300 App[10921:685992] InAppPurchase[objc]: appStoreReceipt: ⚡️ [log] - InAppPurchase[js]: infoPlist: XXXXXXX,1.4.6,16809984,null ⚡️ [log] - [store.js] INFO: ios -> transaction 2000000195971239 purchased (1 in the queue for vcpk500) ⚡️ [log] - [store.js] DEBUG: state: vcpk500 -> approved To Native Cordova -> InAppPurchase appStoreReceipt InAppPurchase755483849 ["options": []] ⚡️ [log] - InAppPurchase[js]: loading appStoreReceipt 2022-11-07 21:59:11.756720-0300 App[10921:685992] InAppPurchase[objc]: appStoreReceipt: ⚡️ [log] - InAppPurchase[js]: infoPlist: XXXXXXXX,1.4.6,16809984,null ⚡️ [log] - [store.js] DEBUG: scheduleValidation() ⚡️ [log] - [store.js] DEBUG: runValidation() ⚡️ [log] - [store.js] DEBUG: ajax -> send request to http://192.168.15.49:5621/api/payments/verifyiap ⚡️ [log] - [store.js] DEBUG: validator success, response: {"ok":true,"data":{"transaction":null,"code":0}} ⚡️ [log] - [store.js] DEBUG: verify -> {"success":true,"data":{"transaction":null,"code":0}} ⚡️ [log] - [store.js] DEBUG: verify -> success: {"transaction":null,"code":0} ⚡️ [log] - [store.js] DEBUG: product -> defer finishing vcpk500 ⚡️ [log] - [store.js] DEBUG: product -> finishing vcpk500 ⚡️ [log] - [store.js] DEBUG: state: vcpk500 -> finished ⚡️ [log] - [store.js] DEBUG: ios -> finishing vcpk500 (a consumable) To Native Cordova -> InAppPurchase finishTransaction InAppPurchase755483850 ["options": [2000000195971239]] 2022-11-07 22:02:20.861291-0300 App[10921:685992] InAppPurchase[objc]: finishTransaction: 2000000195971239 2022-11-07 22:02:20.861439-0300 App[10921:685992] InAppPurchase[objc]: finishTransaction: Transaction 2000000195971239 finished. 2022-11-07 22:02:20.861678-0300 App[10921:685992] InAppPurchase[objc]: transactionFinished: 2000000195971239 ⚡️ [log] - [store.js] DEBUG: state: vcpk500 -> valid ⚡️ [log] - [store.js] DEBUG: ios -> product vcpk500 owned=false ⚡️ [log] - InAppPurchase[js]: product vcpk500 has a transaction in progress: 2000000195971239

As if it was left in an ongoing transaction state. And now the previous purchase is no longer back upon refresh but this new one gives coming on every refresh.

Any ideas? I haven't submitted to Apple yet because of this. But about to do so, anyway.

bierzorutas commented 11 months ago

Same problem here, did you find any solution ?