Closed kreso22 closed 2 months ago
After a good night sleep I found a bug in my code. I was setting up the product as CONSUMABLE but in fact it was NON_CONSUMABLE. This is my mistake completely. I love when main differentiation for such a big deal is a simple negative. Should've been called PERMANENT or some other. And I think it's quite strange that Google would allow charging again for a product that is defined as non-consumable on their platform.
Anyways, another problem still persists. After purchase, I get charged, but the IAP is never processed inside the app (my app doesn't know it ever happened). I guess I am missing a special super secret listener... The good thing is when the game is restarted - IAP is loaded correctly.
Here is some code (that doesn't work):
/** initialize store on start up */
initializeStore() {
// Register the product
CdvPurchase.store.register([{
id: myproductID,
platform: platform,
type: CdvPurchase.ProductType.NON_CONSUMABLE
}]);
CdvPurchase.store.when()
.productUpdated(product => {
console.log("Product updated:", product);
ProcessPurchase(product.owned);
})
.receiptUpdated(localReceipt => {
console.log("Listing local receipt ...", localReceipt);
if (CdvPurchase.store.owned(CdvPurchase.store.get(MyBuyNoAds.PRODUCT_NAME_NO_ADS))) {
console.log("Product is owned");
ProcessPurchase(true);
}
})
.approved(transaction => {
MyDebug.log("Verifying transaction...", transaction);
ProcessPurchase(true);
transaction.finish();
});
// Initialize the store
CdvPurchase.store.initialize([
{
platform: platform,
options: { needAppReceipt: false }
}
]);
}
/** Callback when product updated in the store
* @param {boolean} success
*/
static ProcessPurchase(success) {
// Get the product from the pool.
console.log("Processing ownership. Owned: ", success);
}
And here is some shortened & redacted log (that doesn't let my app know the purchase was a success) when in fact it was:
CdvPurchase: buy()
CdvPurchase: buy() -> setProductDetailsParamsList
CdvPurchase: initiatePurchaseFlow()
CdvPurchase: executeServiceRequest() -> OK
CdvPurchase: initiatePurchaseFlow() -> launchBillingFlow.
PluginManager: THREAD WARNING: exec() call to InAppBillingPlugin.buy blocked the main thread for 54ms. Plugin should use CordovaInterface.getThreadPool().
CordovaActivity: Paused the activity.
CdvPurchase: onPurchasesUpdated() -> Success
CdvPurchase: sendToListener() -> purchasesUpdated
CdvPurchase: data -> {"purchases":[{"productId":"my.product.id","purchaseTime":170950003,"purchaseState":0,"quantity":1,"acknowledged":false...}]}
CdvPurchase: acknowledgePurchase([PURCHASE_TOKEN])
CdvPurchase: executeServiceRequest() -> OK
CdvPurchase: onAcknowledgePurchaseResponse() -> Success
Made the app debuggable in production mode (so I can inspect console.logs). That helped determine everything around billing is working in order.
Observed behavior
The client makes a purchase. On next start there is no clue that the purchase happened - and the client can purchase again. I observe emails from a many unsatisfied clients.
Can someone who has this plugin working comment? I don't see how it can work. After trying for weeks now. I had previous version work a while back without any problems. But this one (13) is not working for me no matter what I try.
I tried the minimal version, and the other one. Nothing works. Well, running as an internal test via Google Play it works. Not the production one.
Expected behavior
A working example. Ideally one without receipt validation since I don't use/need it.
I wish I had created a more concrete ticket. But this being the single most popular Cordova iAP plugin, and I'm not able to make it run is frustrating. I'm not looking to fly a rocket. 🚀 Not sure sure where to look for answers so maybe some kind soul will grant me a glimpse at a tested & working example 🙏😌