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.
Uncaught DOMException: The payment method "https://play.google.com/billing" is not supported.
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();