# Digital Goods API (Play Billing in TWAs)

> The Digital Goods API lets a PWA running in a Trusted Web Activity query SKUs and purchases through Google Play Billing, alongside the Payment Request API.

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).

## Where it's supported

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.

## How to use it

```js
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."

## How to detect it at runtime

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:

```js
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;
  }
}
```

## Practical checklist

- 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."

## Where to go next

- [Payment Request API](/reference/capabilities/payment-request/) — the
  browser-mediated checkout flow the Digital Goods API complements.
- [Web Share API](/reference/capabilities/web-share/)