Skip to content

Digital Goods API (Play Billing in TWAs)

Published Updated

The Digital Goods API lets a web app query SKU details and check purchases or entitlements from a store, working alongside the Payment Request API. Per Chrome for Developers, window.getDigitalGoodsService is currently only supported by Chrome when the PWA is executing inside a Trusted Web Activity (TWA).

Per the Chrome guide, the API is available when a PWA runs inside a TWA on Chrome, backed by the Google Play Billing provider. The explainer frames the method as a general, provider-agnostic proposal — getDigitalGoodsService() takes any service-provider URL — and this page documents the Chrome-in-TWA-with-Play-Billing integration covered by the Chrome guide.

const service = await window.getDigitalGoodsService('https://play.google.com/billing');
const itemDetails = await service.getDetails(['premium_upgrade']);
const purchases = await service.listPurchases();

Per the explainer, listPurchases() “allows a client to get a list of items that are currently owned or purchased by the user.” The item IDs and purchase tokens it returns “should be verified using a direct developer-to-provider API before granting entitlements.”

Feature-detect getDigitalGoodsService before calling it, and fall back to a web checkout when it isn’t available or the requested provider can’t be reached:

async function getStoreService() {
if (!('getDigitalGoodsService' in window)) {
// Not running in a TWA with Play Billing support — offer web checkout instead.
return null;
}
try {
return await window.getDigitalGoodsService('https://play.google.com/billing');
} catch {
// Per the explainer, the promise rejects when the requested service
// provider is unavailable — fall back to web checkout.
return null;
}
}
  • Per the Chrome guide, window.getDigitalGoodsService is currently only supported when the PWA runs inside a TWA — feature-detect with 'getDigitalGoodsService' in window before calling it.
  • Per the explainer, the promise rejects “if there is no Digital Goods Service associated with the given service provider” — per the Chrome guide, that includes Google Play Billing itself being unavailable, not only running outside a TWA — so treat a rejection as a signal to fall back rather than proof of why.
  • Per the Chrome guide, a working Digital Asset Links configuration is required as part of the Bubblewrap project foundation, and Play Billing itself is enabled separately by turning on Bubblewrap’s playBilling and alphaDependencies settings in twa-manifest.json.
  • Per the explainer and the Chrome guide, verify purchase tokens returned by listPurchases() through a direct developer-to-provider API and acknowledge the purchase on your backend — per the Chrome guide, if the purchase isn’t acknowledged, “after three days, the user will receive a refund and Google Play will revoke the purchase.”