Closed jmdjr closed 1 year ago
The list of products is empty because the App Store adapter didn't reach the "ready" state. I wonder if it will work with the integration of a receipt validation service? The use case is more broadly tested. You can try this quickly with a free account on https://www.iaptic.com/
smooth method to "recommend" your company's services... but honestly was hoping not to need any more accounts to use iap. going to test with the free account but really sad that I have to use a service to get a free component to function.
how do we integrate the receipt validation service? the documentation links: https://www.iaptic.com/documentation/setup/ios is out of date (the images are of older ui and step 5/6 no longer exist on those pages) and https://www.iaptic.com/documentation/validator-url/ is straight up 404.
smooth method to "recommend" your company's services... but honestly was hoping not to need any more accounts to use iap. going to test with the free account but really sad that I have to use a service to get a free component to function.
You don't have to. I'm trying to understand what doesn't work in your case. As far as I know you're the only user with this issue, so I'm trying to eliminate possible reasons.
The broken link and outdated screenshots are fixed.
That was rude of me. I am sorry. It was uncalled for. I am going to review the updates and post the updates.
[Log] onscript loading complete (user-script:11, line 1456)
[Log] -IAP-: CdvPurchase IS defined (main.js, line 1)
[Log] -IAP-: installing iaptic receipt validator... (main.js, line 1)
[Log] -IAP-: registering products... (main.js, line 1)
[Log] -IAP-: setting up listeners... (main.js, line 1)
[Log] -IAP-: Store initializing... (main.js, line 1)
[Log] [CdvPurchase] INFO: initialize() (user-script:13, line 321)
[Log] [CdvPurchase.Adapters] INFO: Adding platforms: [{"platform":"ios-appstore"}] (user-script:13, line 321)
[Log] [CdvPurchase.Adapters] INFO: (user-script:13, line 321)
[Log] [CdvPurchase.Adapters] INFO: AppStore initializing... (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore] INFO: bridge.init (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore.Bridge] DEBUG: setup ok (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore] INFO: ready (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore] INFO: bridge.init done (user-script:13, line 321)
[Log] [CdvPurchase.Adapters] INFO: AppStore initialized. (user-script:13, line 321)
[Log] [CdvPurchase.Adapters] INFO: AppStore products: [{"id":"app.sgl.linker.iap.test.1","platform":"ios-appstore","type":"consumable"}] (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore] INFO: bridge.load (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore.Bridge] DEBUG: load ["app.sgl.linker.iap.test.1"] (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore.Bridge] DEBUG: load ok: { valid:[{"id":"app.sgl.linker.iap.test.1","description":"test purchasing something","introPrice":null,"introPricePaymentMode":null,"billingPeriodUnit":"Day","countryCode":"US","introPricePeriodUnit":null,"discounts":[],"title":"SGL: Test purchase 1","price":"$0.99","billingPeriod":0,"group":null,"priceMicros":990000,"currency":"USD","introPricePeriod":null,"introPriceMicros":null}] invalid:[] } (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore] INFO: bridge.loaded: {"validProducts":[{"id":"app.sgl.linker.iap.test.1","description":"test purchasing something","introPrice":null,"introPricePaymentMode":null,"billingPeriodUnit":"Day","countryCode":"US","introPricePeriodUnit":null,"discounts":[],"title":"SGL: Test purchase 1","price":"$0.99","billingPeriod":0,"group":null,"priceMicros":990000,"currency":"USD","introPricePeriod":null,"introPriceMicros":null}],"invalidProducts":[]} (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore] INFO: eligibilities ready. (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore] DEBUG: app.sgl.linker.iap.test.1 is valid: {"id":"app.sgl.linker.iap.test.1","description":"test purchasing something","introPrice":null,"introPricePaymentMode":null,"billingPeriodUnit":"Day","countryCode":"US","introPricePeriodUnit":null,"discounts":[],"title":"SGL: Test purchase 1","price":"$0.99","billingPeriod":0,"group":null,"priceMicros":990000,"currency":"USD","introPricePeriod":null,"introPriceMicros":null} (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore] DEBUG: registering existing product (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore] DEBUG: Products loaded: [{"className":"Product","title":"SGL: Test purchase 1","description":"test purchasing something","platform":"ios-appstore","type":"consumable","id":"app.sgl.linker.iap.test.1","offers":[{"className":"Offer","id":"$","pricingPhases":[{"price":"$0.99","priceMicros":990000,"currency":"USD","paymentMode":"UpFront","recurrenceMode":"NON_RECURRING"}],"productId":"app.sgl.linker.iap.test.1","productType":"consumable","platform":"ios-appstore","offerType":"Default"}],"raw":{"id":"app.sgl.linker.iap.test.1","description":"test purchasing something","introPrice":null,"introPricePaymentMode":null,"billingPeriodUnit":"Day","countryCode":"US","introPricePeriodUnit":null,"discounts":[],"title":"SGL: Test purchase 1","price":"$0.99","billingPeriod":0,"group":null,"priceMicros":990000,"currency":"USD","introPricePeriod":null,"introPriceMicros":null},"countryCode":"US"}] (user-script:13, line 321)
[Log] [CdvPurchase.Adapters] INFO: AppStore loaded: [{"className":"Product","title":"SGL: Test purchase 1","description":"test purchasing something","platform":"ios-appstore","type":"consumable","id":"app.sgl.linker.iap.test.1","offers":[{"className":"Offer","id":"$","pricingPhases":[{"price":"$0.99","priceMicros":990000,"currency":"USD","paymentMode":"UpFront","recurrenceMode":"NON_RECURRING"}],"productId":"app.sgl.linker.iap.test.1","productType":"consumable","platform":"ios-appstore","offerType":"Default"}],"raw":{"id":"app.sgl.linker.iap.test.1","description":"test purchasing something","introPrice":null,"introPricePaymentMode":null,"billingPeriodUnit":"Day","countryCode":"US","introPricePeriodUnit":null,"discounts":[],"title":"SGL: Test purchase 1","price":"$0.99","billingPeriod":0,"group":null,"priceMicros":990000,"currency":"USD","introPricePeriod":null,"introPriceMicros":null},"countryCode":"US"}] (user-script:13, line 321)
[Log] -IAP-: AppStore users can make payments (main.js, line 1)
[Log] -IAP-: checking app store redemption sheet... (main.js, line 1)
[Log] -IAP-: Store initialize done... (main.js, line 1)
[Log] [CdvPurchase.AppleAppStore.Bridge] DEBUG: processing pending transactions (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore] DEBUG: loading appstore receipt... (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore.Bridge] DEBUG: loading appStoreReceipt (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore.Bridge] DEBUG: infoPlist: app.lostseraph.linker,1.0,16809984,null (user-script:13, line 321)
[Log] [CdvPurchase.AppleAppStore] DEBUG: appstore receipt loaded (user-script:13, line 321)
[Warning] [CdvPurchase.AppleAppStore] WARNING: no appStoreReceipt (user-script:13, line 321)
[Log] -IAP-: running update purchases... (main.js, line 1)
...
< redacted PI related logs >
...
[Log] -IAP-: (main.js, line 1)
TESTS:
____________________________
list: false
actual product: undefined
test product: undefined
should I attach my iap connection logic?
it ends up allowing the appstore to initialize and the appstore is available, but the list is still empty and trying to get a product is undefined. later test show that while the appstore adapter is defined now, it is not "ready" after initializing the store.
I have a MVP of the project (takes out all the wrapping stuff and just the iap, which still doesn't connect. if that would be helpful? LinkerMVP_Purchasing.zip
It looks like the CdvPurchase plugin is loaded twice.
I added this in the service constructor (right after "CdvPurchase is defined")
(CdvPurchase as any).createdAt = new Date();
And this:
(CdvPurchase as any).debuggedAt = new Date();
In the debug_Purchases() function.
Just after startup, when I've seen the "CdvPurchase is defined" log message, I open Safari's developer tools, but createdAt
is undefined.
... clicking the debug button I get debuggedAt
defined, createdAt
still undefined.
Somehow the CdvPurchase object used by the service is different from the global object, or this global object has been overiden.
Quick test: adding window._CdvPurchase = CdvPurchase
in the service constructor. And see if window.CdvPurchase === CdvPurchase
.
In the constructor: window.CdvPurchase === CdvPurchase
is true, however from debug_Purchases, window._CdvPurchase !== CdvPurchase
.... So the global object was overridden, as if the plugin was loaded twice?
Also notice, in debug_Purchases
, _CdvPurchase.store.products
contains the non-empty list of products...
This is the root of the issue.
I have no idea what triggers this "double loading" of the plugin, working on a workaround...
NOTE:
Sometime at startup I get this logs:
⚡️ [log] - [LostSeraph] [-IAP-]: CdvPurchase IS defined!!
⚡️ [error] - ERROR Error: Uncaught (in promise): TypeError: undefined is not an object (evaluating 'CdvPurchase.LogLevel.DEBUG')
From this code:
this.logger.log("CdvPurchase IS defined!!");
const store = CdvPurchase.store;
store.verbosity = CdvPurchase.LogLevel.DEBUG;
It means there's really something fishy with the way the plugin's JavaScript is being loaded by the bundler.
thank you for continuing to work on this, I saw you push a couple of other changes, but are they not enough to solve the issue?
No, it didn't solve the issue, I tried a few quick fix that I thought would be simple... but eventually it's not that simple, as it either broke access to CdvPurchase's enums or the CdvPurchase.store object. I have to step through what your app is doing to figure out how is this happening in the first place and get a better understanding.
I see that the code of the plugin is present in the main.js
(bundled js file) but also in plugins/cordova/etc/...
, possible that there are 2 separate instances of the javascript code loaded...?
hrm... that is odd. it would explain why my particular project isn't working while others are just fine, if that is the case. I take it the mvp project helps?
MVP helps, because it allows to reproduce the issue.
Look, the 2 "CdvPurchase.store" instance have different types:
One is "Store" the other is "F", I guess the second one is from a minified version of the same code while the first is the non-minified version. So the problem definitely isn't with the plugin, just that you somehow bundle and load the code twice.
I see how that can be troublesome... odd. I don't know why I am loading the unminified version and the minified version at the same time...
I believe capacitor is probably already loading the plugin's js and angular's build chain also do.
On Mar 20, 2023 at 18:53:50, John M Davis Jr @.***> wrote:
I see how that can be troublesome... odd. I don't know why I am loading the unminified version and the minified version at the same time...
— Reply to this email directly, view it on GitHub https://github.com/j3k0/cordova-plugin-purchase/issues/1394#issuecomment-1476597550, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABO3CNT767OK6KHZY47COTW5CDR5ANCNFSM6AAAAAAVYPUDEI . You are receiving this because you modified the open/close state.Message ID: @.***>
ah. ok. armed with that I can look to see how to break the double loading. thank you for your hard work!
Maybe there's something I could do in the plugin to distribute it in a way that better suits your case. Let me know. I keep digging a little on your issue.
On Mar 20, 2023 at 18:59:14, John M Davis Jr @.***> wrote:
ah. ok. armed with that I can look to see how to break the double loading. thank you for your hard work!
Message ID: @.*** com>
will do. I don't know how I double loaded the code, will try some unloading/reloading methods to see. seems like an edge case but if it helps make your codebase more resilient, maybe some minor reworking would be good.
I found a fix that works here at least:
In your code, replace:
import "cordova-plugin-purchase";
with:
import 'cordova-plugin-purchase/www/store.d';
This way, angular only includes the typings, not the actual code of the plugin.
⚡️ [log] - [LostSeraph] [-IAP-]: CdvPurchase IS defined
⚡️ [log] - [LostSeraph] [-IAP-]: installing iaptic receipt validator...
⚡️ [error] - ERROR Error: Uncaught (in promise): TypeError: undefined is not an object (evaluating 'this.store.log')
Iaptic@user-script:13:104:34
@capacitor://www.lostseraph.com/main.js:1:646682
onInvoke@capacitor://www.lostseraph.com/main.js:1:87039
run@capacitor://www.lostseraph.com/polyfills.js:1:1920
@capacitor://www.lostseraph.com/polyfills.js:1:16761
onInvokeTask@capacitor://www.lostseraph.com/main.js:1:86859
runTask@capacitor://www.lostseraph.com/polyfills.js:1:2541
_@capacitor://www.lostseraph.com/polyfills.js:1:9190
trying the updated input and pushed to device, this is the result.
Oh yeah, maybe because I made this change to your code's checkReady as well:
async checkReady() {
return new Promise
Added this to the if condition: || !window.CdvPurchase.store
And make sure to remove the cordova-pluing-purchase import from iapCatalog as well
did that. added your extra check... still the same exception...
with the setup you provided
> window.CdvPurchase.store
< Store {0: "QUIET", 1: "ERROR", 2: "WARNING", 3: "INFO", 4: "DEBUG", 6777001: "SETUP", 6777002: "LOAD", 6777003: "PURCHASE", 6777004: "LOAD_RECEIPTS", 6777005: "CLIENT_INVALID", …}
> window._CdvPurchase.store
< TypeError: undefined is not an object (evaluating 'window._CdvPurchase.store')
My edited project, works fine here (notice I changed app ID in XCode project, might have to be reverted to your own). LinkerMVP_Purchasing_Edited.zip
window._CdvPurchase.store
will be undefined unless you stored window._CdvPurchase
somewhere in your code.
will try it :D... and ha. ok.
OK! whatever you did it works on your version. so now I get to find the differences between that edited and my local one. yay! thank you.
is the purchase supposed to show a confirmation before popping up the customary apple purchase dialog? I am only seeing the "type Y for purchase" and not the actual in-app purchase view.
Observed behavior
and on the app none of the products are visible? after all this, everything looks great, but inspecting the appstore adapter
is undefined. I have In-App Purchases enabled in the XCode, and my implementation follows all the tutorials (for the most part) yet this is happening...
Expected behavior
The CdvPurchase.store.products list has the loaded products, or at least the appstore adapter reporting itself as undefined.
System Info
XCode v 14.2 iMac MacOS Ventura 13.2.1 Capacitor v. 4.6.0 (capacitor apps are based off cordova, don't see how this would make a difference here)