WICG / digital-goods

Other
50 stars 28 forks source link

Persistent "Payment method https://play.google.com/billing is not supported" #53

Open monstermac77 opened 1 year ago

monstermac77 commented 1 year ago

We've been stuck for days trying to implement Google Play Billing in our TWA. We have experience with Billing, having implemented it on our native Android app, but we just can't seem to get past this error.

We've been following this guide to a T, but upon trying to make a new PaymentRequest, we receive the the following error:

Uncaught DOMException: The payment method "https://play.google.com/billing" is not supported.

We've ensured ensured "playBilling": {"enabled": true} is in our manifest.json, which would be the most likely culprit. We've cleared Chrome's cache/storage, etc. And in general, it seems like our TWA is configured correctly, as everything else seems to work and there is no URL bar displayed at any point in the app's lifecycle.

What could be the problem here? One of the only people we've seen run into this issue was here, but they had the URL bar showing which led them to discover their assetlinks.json was incorrect, whereas there's no indication that our assetlinks.json is wrong. Code is below.

//Billing
window.billingService

var googleBilling = async function(){
    if ('getDigitalGoodsService' in window) {
        // Digital Goods API is supported!
        try {
            window.billingService = await window.getDigitalGoodsService('https://play.google.com/billing');

            console.log("getDigitalGoodsService is here")
            // Check and redeem purchases
            const existingPurchases = await window.billingService["listPurchases"];

            if (existingPurchases.length == 0){
                console.log("No Purchases")
            } else {
                for (const p in existingPurchases) {
                    // Update the UI with items the user is already entitled to.
                    console.log(`Users has entitlement for ${p.itemId}`);
                }
            }

            var skuDetailFun = async function(){
                var semester = $('#semesterSelect').val();
                var hostSite = window.location.host.split(".")[0];
                var prodToShow = ""

                if (hostSite == "coursicle"){
                    prodToShow = "com.coursicle.coursicle."+semester+"premium"
                } else {
                    prodToShow = "dev.coursicle.coursicle."+semester+"premium"
                }           

                var skuDetails = await window.billingService.getDetails([prodToShow]);

                console.log("sku details", skuDetails);

                for (var index in skuDetails) {
                    var item = skuDetails[index]
                    // Format the price according to the user locale.
                    const localizedPrice = new Intl.NumberFormat(
                        navigator.language,
                        {style: 'currency', currency: item.price.currency}
                    ).format(item.price.value);

                    // Render the price to the UI.
                    //renderProductDetails(
                    //item.itemId, item.title, localizedPrice, item.description);
                }   
            }

            skuDetailFun();

        } catch (error) {
            console.log("Google Play Billing is not available. Use another payment flow.", error);
            return;
        }
    }

}

async function makePurchase(service, sku) {
   // Define the preferred payment method and item ID
   const paymentMethods = [{
       supportedMethods: ["https://play.google.com/billing"],
       data: {
           sku: sku,
       },
   }];

    const paymentDetails = {
        total: {
            label: `Total`,
            amount: {currency: `USD`, value: `0`}
        }
    };

    var request = new PaymentRequest(paymentMethods, paymentDetails);

    try {   
        const paymentResponse = await request.show();
        const {purchaseToken} = paymentResponse.details;

        // Call backend to validate and acknowledge the purchase.
        if (await acknowledgePurchaseOnBackend(purchaseToken, sku)) {
            // Optional: tell the PaymentRequest API the validation was
            // successful. The user-agent may show a "payment successful"
            // message to the user.
            const paymentComplete = await paymentResponse.complete('success');
        } else {
            // Optional: tell the PaymentRequest API the validation failed. The
            // user agent may show a message to the user.
            const paymentComplete = await paymentResponse.complete('fail');
        }
    } catch (error) {
        if (error.message.includes('was cancelled')) {
            // User dismissed native dialog
            logWarning('User chose not to subscribe:', error);
        } else {
            // Report unexpected error
            reportError(error, 'PaymentRequest.show() failed');
        }
        return;
    }
}   

$(document).on('click', '#premiumSetting', function(){
    console.log("do I exist")

    var semester = $('#semesterSelect').val();
    var hostSite = window.location.host.split(".")[0];
    var prodToShow = ""

    if (hostSite == "coursicle"){
        prodToShow = "com.coursicle.coursicle."+semester+"premium"
    } else {
        prodToShow = "dev.coursicle.coursicle."+semester+"premium"
    }

    //const service = await window.getDigitalGoodsService('https://play.google.com/billing');
    console.log(prodToShow)
    makePurchase(window.billingService,prodToShow)

})

googleBilling();
monstermac77 commented 1 year ago

Turns out we had missed one part of the documentation: we had to #enable-debug-for-store-billing on our Android device. Probably would be better if the error message in this case were more specific than The payment method "https://play.google.com/billing" is not supported..

phoglenix commented 1 year ago

@rsolomakhin would it be simple enough to add an extra message to the error response in findAppStoreBillingApp() if it fails to find a valid app and WEB_PAYMENTS_APP_STORE_BILLING_DEBUG is disabled? There is already an error message response in AreRequestedMethodsSupportedCallback() but it's a bit hard to follow due to the callback spaghetti.