j3k0 / cordova-plugin-purchase

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

[Android] working example please #1538

Closed kreso22 closed 2 months ago

kreso22 commented 2 months ago

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 🙏😌

kreso22 commented 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
kreso22 commented 2 months ago

Made the app debuggable in production mode (so I can inspect console.logs). That helped determine everything around billing is working in order.