Skip to content

Commit 3597013

Browse files
Merge pull request #3313 from runyuany/main
Article "Provide in-app purchases with the Digital Goods API"
2 parents 4fbe3e0 + 785d4fc commit 3597013

2 files changed

Lines changed: 234 additions & 6 deletions

File tree

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
---
2+
title: Provide in-app purchases with the Digital Goods API
3+
description: How to provide in-app purchases in a Progressive Web App by using the Digital Goods API and the Payment Request API.
4+
author: MSEdgeTeam
5+
ms.author: msedgedevrel
6+
ms.topic: conceptual
7+
ms.service: microsoft-edge
8+
ms.subservice: pwa
9+
ms.date: 11/25/2024
10+
---
11+
# Provide in-app purchases with the Digital Goods API
12+
13+
If your Progressive Web App (PWA) is listed in the Microsoft Store, you can provide in-app products and subscriptions by using the Digital Goods API and the Payment Request API.
14+
15+
16+
<!-- ====================================================================== -->
17+
## Digital Goods API
18+
19+
The Digital Goods API is an interface between your PWA app and the Microsoft Store. The Digital Goods API supports:
20+
* Querying the details of a digital item from the Microsoft Store backend, such as the item's name, description, and regional price.
21+
* Consuming or acknowledging purchases.
22+
* Checking the digital items that are currently owned by the user.
23+
* Checking the purchase history of the user.
24+
25+
See:
26+
* [Digital Goods API For Microsoft Store PWA Explainer](https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/PwaDigitalGoods/explainer.md)
27+
* [Digital Goods API: Draft Community Group Report](https://wicg.github.io/digital-goods/)
28+
29+
30+
<!-- ====================================================================== -->
31+
## Payment Request API
32+
33+
The Payment Request API⁠⁠ handles the actual payment transaction when a purchase is made by a user. The Payment Request API uses the item details that the Digital Goods API provides, to make the in-app purchase by using whichever billing payment method the user has set up at the Microsoft Store.
34+
35+
See [Payment Request API](https://developer.mozilla.org/docs/Web/API/Payment_Request_API) at MDN.
36+
37+
38+
<!-- ====================================================================== -->
39+
## Checking whether the Digital Goods API is available
40+
41+
To detect whether you've correctly enabled the API on your website, check for the `getDigitalGoodsService` method in the window object:
42+
43+
```javascript
44+
if ('getDigitalGoodsService' in window) {
45+
// Digital Goods API is supported!
46+
} else {
47+
console.log('DigitalGoodsService is not available.');
48+
// Use other payment method
49+
}
50+
```
51+
52+
53+
<!-- ====================================================================== -->
54+
## Connecting to the Microsoft Store Billing service (`getDigitalGoodsService` method)
55+
56+
Use the `getDigitalGoodsService` method to connect to the Microsoft Store Billing service.
57+
58+
The Digital Goods API was designed to be compatible with various browsers and digital stores, similar to how the Payment Request API is browser-agnostic and can be used with different payment providers. To retrieve an instance of the service for Microsoft Store Billing, pass the string `"https://store.microsoft.com/billing"` as the payment method to the `getDigitalGoodsService` method.
59+
60+
If the method throws an error, the Microsoft Store Billing payment method is not available (such as when the user is accessing your PWA through the browser). Alternatively, consider providing a different payment method for transactions.
61+
62+
```javascript
63+
if (window.getDigitalGoodsService === undefined) {
64+
// Digital Goods API is not supported in this context.
65+
return;
66+
}
67+
try {
68+
const digitalGoodsService = await window.getDigitalGoodsService("https://store.microsoft.com/billing");
69+
// Use the service here.
70+
...
71+
} catch (error) {
72+
// Our preferred service provider is not available.
73+
// Use a web-based payment flow instead.
74+
return;
75+
}
76+
```
77+
78+
79+
<!-- ====================================================================== -->
80+
## Querying item details (`getDetails` method)
81+
82+
Use the `getDetails` method to query item details.
83+
84+
After connecting the Digital Goods service to Microsoft Store, you can use the API to access product and purchase information. The `getDetails` method lets you get information about the items you’ve set up in the Partner Center. Display information such as the product title, description, and price in your app UI, so the user knows what's available for purchase.
85+
86+
The `getDetails` method takes a list of item IDs, which correspond to the product IDs of the in-app products and subscriptions you created in the Partner Center.
87+
88+
```javascript
89+
const itemDetails = await digitalGoodsService.getDetails(['shiny_sword', 'gem', 'monthly_subscription']);
90+
91+
for (item of itemDetails) {
92+
const priceStr = new Intl.NumberFormat(
93+
locale,
94+
{style: 'currency', currency: item.price.currency}
95+
).format(item.price.value);
96+
97+
// Do something with the item's data, such as displaying it in the PWA's UI.
98+
displayProductItem(item.itemId, item.title, priceStr, item.description);
99+
}
100+
```
101+
102+
The returned `itemDetails` sequence may be in any order, and might not include an item if the item doesn't exist on the server (that is, if there's not a 1:1 correspondence between the input list and output list).
103+
104+
The item ID is a string that represents the primary key of the items. In the Microsoft Store, the item ID is `InAppOfferToken`. There is no function to get a list of item IDs; item IDs should be hardcoded in the client code or fetched from your own server (the developer's server).
105+
106+
The item's `price` is a `PaymentCurrencyAmount` that contains the current price of the item in the user's current region and currency. The `price` is designed to be formatted for the user's current locale by using `Intl.NumberFormat`, as shown above.
107+
108+
See also:
109+
* [StoreProduct.InAppOfferToken Property](/uwp/api/windows.services.store.storeproduct.inappoffertoken)
110+
* [PaymentCurrencyAmount dictionary](https://www.w3.org/TR/payment-request/#dom-paymentcurrencyamount) in _Payment Request API_ at W3C.
111+
* [Intl.NumberFormat](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) at MDN.
112+
113+
114+
<!-- ====================================================================== -->
115+
## Purchasing an item (`show` method)
116+
117+
Use the `show` method to purchase an item, after you construct a request that contains the item details.
118+
119+
Once your products and details are displayed to the user, you can implement the purchase flow by using the Payment Request API. When combined with the Digital Goods API, the only required input parameter is `methodData`.
120+
121+
Use the `supportedMethods` member of the `methodData`⁠⁠ parameter in the `PaymentRequest` to identify Microsoft Store Billing as the payment method with the string `"https://store.microsoft.com/billing"`. Then in the `data` member, pass along the item ID as the `sku`.
122+
123+
```javascript
124+
const details = await digitalGoodsService.getDetails(['monthly_subscription']);
125+
const item = details[0];
126+
127+
const request = new PaymentRequest([
128+
{
129+
supportedMethods: 'https://store.microsoft.com/billing',
130+
data: { sku: item.itemId }
131+
}
132+
]);
133+
```
134+
135+
Then call the `show` method to start the payment flow:
136+
137+
```javascript
138+
const response = await request.show();
139+
```
140+
141+
This will display the Store purchase UI to the user, where the user can view details about the product that they're trying to purchase. During this process, the current browser session is temporarily disabled until the purchase flow is complete. The user can either cancel the transaction, or proceed with the payment:
142+
143+
* If the user cancels the payment, the Promise that's returned by the `show` method will be rejected with an error.
144+
145+
* If the user successfully pays and completes the purchase, the Promise will resolve with a `PaymentResponse`.
146+
147+
In the `details` property of the payment response, a purchase token is returned.
148+
149+
150+
<!-- ====================================================================== -->
151+
## Acknowledging a purchase
152+
153+
The payment response returns a _purchase token_ string, which can be used for direct communication between your server and the service provider beyond the Digital Goods API. Such communication can allow you to independently verify information about the purchase before granting entitlements.
154+
155+
Some stores might require that you (the developer) acknowledge a purchase after the purchase has succeeded, to confirm that the purchase has been recorded.
156+
157+
158+
<!-- ====================================================================== -->
159+
## Consuming a purchase (`consume` method)
160+
161+
Use the `consume` method to consume a purchase.
162+
163+
A _consumable purchase_ is a purchase that's designed to be purchased multiple times. A consumable purchase usually needs to be marked as "consumed" before the purchase can be purchased again by the user. An example of a consumable purchase is an in-game powerup that makes the player stronger for a short period of time.
164+
165+
To mark a purchase as "consumed", use the `consume` method:
166+
167+
```javascript
168+
digitalGoodsService.consume(purchaseToken);
169+
```
170+
171+
172+
<!-- ====================================================================== -->
173+
## Checking existing purchases (`listPurchases` method)
174+
175+
Use the `listPurchases` method to check existing purchases. This method returns information about the user's existing purchases. This method allows a client to get a list of items that are currently owned or purchased by the user. This may be necessary, to do either of the following:
176+
177+
* Check for entitlements, such as whether a subscription, promotional code, or permanent upgrade is active.
178+
179+
* Recover from network interruptions during a purchase, such as when the item is purchased but not yet acknowledged.
180+
181+
The `listPurchases` method returns item IDs and purchase tokens. Before you grant an entitlement, you should verify the returned item ID or the returned purchase token, by using a direct developer-to-provider API, as shown below:
182+
183+
```javascript
184+
const purchaseList = await digitalGoodsService.listPurchases();
185+
186+
for (const purchase of purchaseList) {
187+
// Handle the purchase data in your PWA.
188+
verifyAndGrantEntitlement(purchase.itemId, purchase.purchaseToken);
189+
}
190+
```
191+
192+
The `listPurchases` method doesn't return consumed products or expired subscriptions.
193+
194+
195+
<!-- ====================================================================== -->
196+
## Getting the purchase history (`listPurchaseHistory` method)
197+
198+
Use the `listPurchaseHistory` method to get the purchase history. This method returns a list that shows the most recent purchase made by the user for each item, regardless of whether the purchase is expired, canceled, or consumed. This method returns a list of `PurchaseDetails` containing the `itemId` and `purchaseToken` for each purchase.
199+
200+
```javascript
201+
const purchaseList = await digitalGoodsService.listPurchaseHistory();
202+
203+
for (const purchase of purchaseList) {
204+
// Handle the expired purchase data in your PWA.
205+
verifyAndCheckExpiredEntitlement(purchase.itemId, purchase.purchaseToken);
206+
}
207+
```
208+
209+
210+
<!-- ====================================================================== -->
211+
## See also
212+
213+
* [Digital Goods API For Microsoft Store PWA Explainer](https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/PwaDigitalGoods/explainer.md)
214+
* [StoreProduct.InAppOfferToken Property](/uwp/api/windows.services.store.storeproduct.inappoffertoken)
215+
216+
W3C:
217+
* [Digital Goods API: Draft Community Group Report](https://wicg.github.io/digital-goods/)
218+
* [Payment Request API](https://www.w3.org/TR/payment-request/)
219+
* [PaymentCurrencyAmount dictionary](https://www.w3.org/TR/payment-request/#dom-paymentcurrencyamount) in _Payment Request API_.
220+
221+
MDN:
222+
* [Intl.NumberFormat](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat)

microsoft-edge/toc.yml

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
- name: Develop for the web with Microsoft Edge
66
href: develop-web-microsoft-edge.md
77

8+
# =============================================================================
9+
# DevTools
810
- name: Microsoft Edge DevTools
911
items:
10-
# Card-based landing page -----------------------------------------------------
12+
# Lannding page -----------------------------------------------------
1113
- name: Microsoft Edge DevTools documentation
1214
href: devtools-guide-chromium/landing/index.yml
1315
displayName: DevTools
@@ -903,6 +905,7 @@
903905
displayName: feedback, log issues, enter issues, report issues, reporting issues, support
904906

905907
# =============================================================================
908+
# DevTools for VS Code
906909
- name: DevTools for Visual Studio Code
907910
items:
908911

@@ -1169,9 +1172,8 @@
11691172

11701173
- name: How to
11711174
items:
1172-
- name: Publish a PWA to the Microsoft Store
1175+
- name: Publish a Progressive Web App to the Microsoft Store
11731176
href: progressive-web-apps-chromium/how-to/microsoft-store.md
1174-
displayName: Publish a Progressive Web App to the Microsoft Store # top-of-page title
11751177

11761178
- name: Experimental features and origin trials for PWAs
11771179
href: progressive-web-apps-chromium/how-to/origin-trials.md
@@ -1230,6 +1232,9 @@
12301232
- name: Build PWAs for the sidebar in Microsoft Edge
12311233
href: progressive-web-apps-chromium/how-to/sidebar.md
12321234

1235+
- name: Provide in-app purchases with the Digital Goods API
1236+
href: progressive-web-apps-chromium/how-to/digital-goods-api.md
1237+
12331238
- name: What's New in Progressive Web Apps
12341239
href: progressive-web-apps-chromium/whats-new/pwa.md
12351240
displayName: release notes, announcements
@@ -1649,7 +1654,7 @@
16491654
- name: Contact the WebView2 team
16501655
href: ./webview2/contact.md
16511656
displayName: feedback, log issues, enter issues, report issues, reporting issues, support
1652-
# / WebView2
1657+
# /WebView2
16531658

16541659
# =============================================================================
16551660
# Test and automation
@@ -1680,6 +1685,7 @@
16801685

16811686
- name: Capabilities and EdgeOptions
16821687
href: webdriver-chromium/capabilities-edge-options.md
1688+
16831689
- name: Contact the Microsoft Edge WebDriver team
16841690
href: webdriver-chromium/contact.md
16851691

@@ -1688,7 +1694,7 @@
16881694
# /Test and automation
16891695

16901696
# =============================================================================
1691-
# Development tips (Web platform)
1697+
# Development tips [Web platform]
16921698
- name: Development tips for Microsoft Edge
16931699
items:
16941700
- name: Development tips for Microsoft Edge
@@ -1726,7 +1732,7 @@
17261732

17271733
- name: Sign up for the Ad Selection API
17281734
href: ./web-platform/ad-selection-api.md
1729-
# /Development tips (Web platform)
1735+
# /Development tips [Web platform]
17301736

17311737
# =============================================================================
17321738
# Microsoft Edge IDE integration

0 commit comments

Comments
 (0)