Skip to content

Commit 27486b4

Browse files
authored
Update payments articles (GoogleChrome#9407)
* Use bobbucks.dev instead of bobpay.xyz. * Add shipping information back to 'life of a transaction'. Note that show() requires user gesture now. * Remove identifying parameters from the IS_READY_TO_PAY intent. * Add back shipping address delegation for Android payment apps * Remove note about Mozilla implementing PH API, because they have put that work on hold. * Remove mentions of setting payment instruments. Remove mention of 'coming soon' articles that are not actually in the pipeline. * Resolve reviewer comments * Address reviewer comments part 2
1 parent d894217 commit 27486b4

File tree

9 files changed

+404
-142
lines changed
  • src/site/content
    • en/payments
      • android-payment-apps-delegation
      • android-payment-apps-developers-guide
      • handling-optional-payment-information
      • how-payment-request-api-works
      • life-of-a-payment-transaction
      • registering-a-web-based-payment-app
      • setting-up-a-payment-method
      • web-based-payment-apps-overview
    • es/payments/setting-up-a-payment-method

9 files changed

+404
-142
lines changed

src/site/content/en/payments/android-payment-apps-delegation/index.md

+295-15
Large diffs are not rendered by default.

src/site/content/en/payments/android-payment-apps-developers-guide/index.md

+2-80
Original file line numberDiff line numberDiff line change
@@ -147,84 +147,6 @@ class SampleIsReadyToPayService : Service() {
147147
}
148148
```
149149

150-
### Parameters
151-
152-
Pass the following parameters to `onBind` as Intent extras:
153-
154-
* `methodNames`
155-
* `methodData`
156-
* `topLevelOrigin`
157-
* `topLevelCertificateChain`
158-
* `topLevelCertificateChain`
159-
* `paymentRequestOrigin`
160-
161-
```kotlin
162-
override fun onBind(intent: Intent?): IBinder? {
163-
val extras: Bundle? = intent?.extras
164-
//
165-
}
166-
```
167-
168-
#### `methodNames`
169-
170-
The names of the methods being queried. The elements are the keys in the
171-
`methodData` dictionary, and indicate the methods that the payment app supports.
172-
173-
```kotlin
174-
val methodNames: List<String>? = extras.getStringArrayList("methodNames")
175-
```
176-
177-
#### `methodData`
178-
179-
A mapping from each entry of `methodNames` to the
180-
[`methodData`](https://w3c.github.io/payment-request/#declaring-multiple-ways-of-paying).
181-
182-
```kotlin
183-
val methodData: Bundle? = extras.getBundle("methodData")
184-
```
185-
186-
#### `topLevelOrigin`
187-
188-
The merchant's origin without the scheme (the scheme-less origin of the
189-
top-level browsing context). For example, `https://mystore.com/checkout` will be
190-
passed as `mystore.com`.
191-
192-
```kotlin
193-
val topLevelOrigin: String? = extras.getString("topLevelOrigin")
194-
```
195-
196-
#### `topLevelCertificateChain`
197-
198-
The merchant's certificate chain (the certificate chain of the top-level
199-
browsing context). Null for localhost and file on disk, which are both secure
200-
contexts without SSL certificates. The certificate chain is necessary because a
201-
payment app might have different trust requirements for websites.
202-
203-
```kotlin
204-
val topLevelCertificateChain: Array<Parcelable>? =
205-
extras.getParcelableArray("topLevelCertificateChain")
206-
```
207-
208-
Each `Parcelable` is a `Bundle` with a `"certificate"` key and a byte array
209-
value.
210-
211-
```kotlin
212-
val list: List<ByteArray>? = topLevelCertificateChain?.mapNotNull { p ->
213-
(p as Bundle).getByteArray("certificate")
214-
}
215-
```
216-
217-
#### `paymentRequestOrigin`
218-
219-
The schemeless origin of the iframe browsing context that invoked the `new
220-
PaymentRequest(methodData, details, options)` constructor in JavaScript. If the
221-
constructor was invoked from the top-level context, then the value of this
222-
parameter equals the value of `topLevelOrigin` parameter.
223-
224-
```kotlin
225-
val paymentRequestOrigin: String? = extras.getString("paymentRequestOrigin")
226-
```
227-
228150
### Response
229151

230152
The service can send its response via `handleIsReadyToPay(Boolean)` method.
@@ -280,7 +202,7 @@ To support multiple payment methods, add a `<meta-data>` tag with a
280202

281203
<meta-data
282204
android:name="org.chromium.default_payment_method_name"
283-
android:value="https://bobpay.xyz/pay" />
205+
android:value="https://bobbucks.dev/pay" />
284206
<meta-data
285207
android:name="org.chromium.payment_method_names"
286208
android:resource="@array/method_names" />
@@ -415,7 +337,7 @@ The activity can send its response back through `setResult` with `RESULT_OK`.
415337
416338
```kotlin
417339
setResult(Activity.RESULT_OK, Intent().apply {
418-
putExtra("methodName", "https://bobpay.xyz/pay")
340+
putExtra("methodName", "https://bobbucks.dev/pay")
419341
putExtra("details", "{\"token\": \"put-some-data-here\"}")
420342
})
421343
finish()

src/site/content/en/payments/handling-optional-payment-information/index.md

+1-9
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ propagated to the payment app's service worker as a property of
349349
350350
```js
351351
const request = new PaymentRequest([{
352-
supportedMethods: 'https://bobpay.xyz/pay',
352+
supportedMethods: 'https://bobbucks.dev/pay',
353353
data: { transactionId: '****' }
354354
}], {
355355
displayItems: [{
@@ -532,11 +532,3 @@ To try it out:
532532
3. Press **Add a payment button**.
533533
4. Enter `https://paymenthandler-demo.glitch.me` to the **Payment Method Identifier** field.
534534
5. Press **Pay** button next to the field.
535-
536-
## Next steps
537-
538-
In this article, we learned how to handle optional information on the service
539-
worker. The final step for building a web-based payment app is to learn how to
540-
build the frontend.
541-
542-
* Handling payments on the payment frontend (coming soon)

src/site/content/en/payments/how-payment-request-api-works/index.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,15 @@ an array variable. Each element in the array comprises two components,
4242

4343
For `supportedMethods`, the merchant needs to specify a [Payment Method
4444
Identifier](/setting-up-a-payment-method/#step-1-provide-the-payment-method-identifier)
45-
such as `https://bobpay.xyz/pay`. The existence and content of `data` depends on
45+
such as `https://bobbucks.dev/pay`. The existence and content of `data` depends on
4646
the content of `supportedMethods` and payment app provider's design.
4747

4848
Both pieces of information should be provided by the payment app provider.
4949

5050
```javascript
5151
// Supported payment methods
5252
const paymentMethods = [{
53-
supportedMethods: 'https://bobpay.xyz/pay',
53+
supportedMethods: 'https://bobbucks.dev/pay',
5454
data: {
5555
... // Optional parameters defined by the payment app provider.
5656
}
@@ -114,8 +114,8 @@ interface.
114114
To call the `show()` method, you must add a [user
115115
activation](https://developer.chrome.com/blog/user-activation/).
116116
This means the call must be inside an event listener, such as
117-
`click`. Note that Chrome currently bypasses this constraint, but plans to enforce
118-
it sometime in the future.
117+
`click`. Note that Chrome [enforces this constraint from version
118+
102](https://chromestatus.com/feature/5948593429020672).
119119

120120
{% endAside %}
121121

src/site/content/en/payments/life-of-a-payment-transaction/index.md

+83-13
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,6 @@ tags:
1616
- payments
1717
---
1818

19-
{% Aside 'warning' %}
20-
21-
Shipping and address support in [the Payment Request API is removed from the
22-
specification](https://github.com/w3c/payment-request/pull/955) and is no longer
23-
functional.
24-
25-
{% endAside %}
26-
2719
Web Payments APIs are dedicated payment features built into the browser
2820
for the first time. With Web Payments, merchant integration with payment apps
2921
becomes simpler while the customer experience gets streamlined and more secure.
@@ -46,8 +38,10 @@ The process involves 6 steps:
4638

4739
{% Img src="image/tcFciHGuF3MxnTr1y5ue01OGLBn2/IHztIcfJKeWDUIkugTkb.svg", alt="A diagram of the cheese shop website with BobPay app launched in a modal. The modal shows shipping options and total cost.", width="671", height="366" %}
4840

49-
5. If the customer changes payment method, the merchant updates the transaction
50-
details reflecting the change.
41+
5. If the customer changes any details (such as shipping options or their
42+
address), the merchant updates the transaction details reflecting the change.
43+
44+
{% Img src="image/tcFciHGuF3MxnTr1y5ue01OGLBn2/BR9Od63aOdG9CaaD1z7K.svg", alt="A diagram showing the customer choosing a different shipping option in BobPay app modal. A second diagram showing the merchant updating the total cost displayed in BobPay.", width="777", height="702" %}
5145

5246
6. After the customer confirms the purchase, the merchant validates the payment
5347
and completes the transaction.
@@ -63,6 +57,14 @@ object. This object includes important information about the transaction:
6357

6458
* Acceptable payment methods and their data to process the transaction.
6559
* Details, such as the total price (required) and information about the items.
60+
* Options in which merchants can request shipping information such as a shipping
61+
address and a shipping option.
62+
* Merchants can also request the billing address, the payer's name, email, and
63+
phone number.
64+
* Merchants can also include optional [shipping
65+
type](https://developers.google.com/web/fundamentals/payments/merchant-guide/deep-dive-into-payment-request#changing_the_shipping_type)
66+
(`shipping`, `delivery`, or `pickup`) in the `PaymentRequest`. The payment app
67+
can use that as a hint to display the correct labels in its UI.
6668

6769
```js
6870
const request = new PaymentRequest([{
@@ -79,6 +81,13 @@ const request = new PaymentRequest([{
7981
label: 'Total due',
8082
amount: { currency: 'USD', value : '22.15' }
8183
}
84+
}, {
85+
requestShipping: true,
86+
requestBillingAddress: true,
87+
requestPayerEmail: true,
88+
requestPayerPhone: true,
89+
requestPayerName: true,
90+
shippingType: 'delivery'
8291
});
8392
```
8493

@@ -194,18 +203,21 @@ passed to the `PaymentRequest` object in Step 1, which includes the following:
194203

195204
* Payment method data
196205
* Total price
206+
* Payment options
197207

198208
The payment app uses the transaction information to label its UI.
199209

200210
## Step 5: How a merchant can update the transaction details depending on customer's actions
201211

202212
Customers have an option to change the transaction details such as payment
203-
method in the payment app. While the customer makes changes, the merchant
204-
receives the change events and updates the transaction details.
213+
method and shipping option in the payment app. While the customer makes changes,
214+
the merchant receives the change events and updates the transaction details.
205215

206216
There are four types of events a merchant can receive:
207217

208218
* Payment method change event
219+
* Shipping address change event
220+
* Shipping option change event
209221
* Merchant validation event
210222

211223
### Payment method change event
@@ -224,6 +236,61 @@ request.addEventListener('paymentmethodchange', e => {
224236
});
225237
```
226238

239+
### Shipping address change event
240+
241+
A payment app can optionally provide the customer's shipping address. This is
242+
convenient for customers because they don't have to manually enter any details
243+
into a form and they can store their shipping address in their preferred payment
244+
apps, rather than on multiple different merchant websites.
245+
246+
If a customer updates their shipping address in a payment app after the
247+
transaction has been initiated, a `'shippingaddresschange'` event will be sent
248+
to the merchant. This event helps the merchant determine the shipping cost based
249+
on the new address, update the total price, and return it to the payment app.
250+
251+
```js
252+
request.addEventListener('shippingaddresschange', e => {
253+
e.updateWith({
254+
// Update the details
255+
});
256+
});
257+
```
258+
259+
If the merchant can't ship to the updated address, they can provide an error
260+
message by adding an error parameter to the transaction details returned to the
261+
payment app.
262+
263+
{% Aside %}
264+
Merchants don't receive customers' full shipping address until they've
265+
authorized the payment.
266+
{% endAside %}
267+
268+
### Shipping option change event
269+
270+
A merchant can offer multiple shipping options to the customer and can delegate
271+
that choice to the payment app. The shipping options are displayed as a list of
272+
prices and service names the customer can select from. For example:
273+
274+
* Standard shipping - Free
275+
* Express shipping - 5 USD
276+
277+
When a customer updates the shipping option in a payment app, a
278+
`'shippingoptionchange'` event will be sent to the merchant. The merchant can
279+
then determine the shipping cost, update the total price, and return it to the
280+
payment app.
281+
282+
```js
283+
request.addEventListener('shippingoptionchange', e => {
284+
e.updateWith({
285+
// Update the details
286+
});
287+
});
288+
```
289+
290+
The merchant can dynamically modify the shipping options based on the customer's
291+
shipping address as well. This is useful when a merchant wants to offer
292+
different sets of shipping options for domestic and international customers.
293+
227294
### Merchant validation event
228295

229296
For additional security, a payment app can perform a merchant validation before
@@ -252,6 +319,9 @@ returns a promise that resolves to a
252319
The `PaymentResponse` object includes the following information:
253320

254321
* Payment result details
322+
* Shipping address
323+
* Shipping option
324+
* Contact information
255325

256326
At this point, the browser UI may still show a loading indicator meaning that
257327
the transaction is not completed yet.
@@ -278,7 +348,7 @@ they can either:
278348
```js
279349
async function doPaymentRequest() {
280350
try {
281-
const request = new PaymentRequest(methodData, details);
351+
const request = new PaymentRequest(methodData, details, options);
282352
const response = await request.show();
283353
await validateResponse(response);
284354
} catch (err) {

src/site/content/en/payments/registering-a-web-based-payment-app/index.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,8 @@ to the service worker that handles payments.
136136

137137
## Next steps
138138

139-
You learned how to register a service worker, set payment instruments for a
140-
web-based payment app. The next step is to learn how the service worker can
141-
orchestrate a payment transaction at runtime.
139+
The next step is to learn how the service worker can orchestrate a payment
140+
transaction at runtime.
142141

143142
* [Orchestrating payment transactions with a service
144143
worker](/orchestrating-payment-transactions)

src/site/content/en/payments/setting-up-a-payment-method/index.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ is a URL-based string. For example, Google Pay's identifier is
6969
`https://google.com/pay`. Payment app developers can pick any URL as a payment
7070
method identifier as long as they have control over it and can serve arbitrary
7171
content. In this article, we'll use
72-
[`https://bobpay.xyz/pay`](https://bobpay.xyz/pay) as the payment method
72+
[`https://bobbucks.dev/pay`](https://bobbucks.dev/pay) as the payment method
7373
identifier.
7474

7575
{% Aside %}
@@ -87,7 +87,7 @@ for the `supportedMethods` property. For example:
8787

8888
```js
8989
const request = new PaymentRequest([{
90-
supportedMethods: 'https://bobpay.xyz/pay'
90+
supportedMethods: 'https://bobbucks.dev/pay'
9191
}], {
9292
total: {
9393
label: 'total',
@@ -151,7 +151,7 @@ A payment method manifest file should look like this:
151151

152152
```json
153153
{
154-
"default_applications": ["https://bobpay.xyz/manifest.json"],
154+
"default_applications": ["https://bobbucks.dev/manifest.json"],
155155
"supported_origins": [
156156
"https://alicepay.friendsofalice.example"
157157
]
@@ -178,19 +178,19 @@ Configure the payment method server to respond with a HTTP `Link` header with
178178
the `rel="payment-method-manifest"` attribute and the [payment method
179179
manifest](https://w3c.github.io/payment-method-manifest/) URL.
180180

181-
For example, if the manifest is at `https://bobpay.xyz/payment-manifest.json`,
181+
For example, if the manifest is at `https://bobbucks.dev/payment-manifest.json`,
182182
the response header would include:
183183

184184
```http
185-
Link: <https://bobpay.xyz/payment-manifest.json>; rel="payment-method-manifest"
185+
Link: <https://bobbucks.dev/payment-manifest.json>; rel="payment-method-manifest"
186186
```
187187

188188
The URL can be a fully-qualified domain name or a relative path. Inspect
189-
`https://bobpay.xyz/pay/` for network traffic to see an example. You may use a
189+
`https://bobbucks.dev/pay/` for network traffic to see an example. You may use a
190190
`curl` command as well:
191191

192192
```shell
193-
curl --include https://bobpay.xyz/pay
193+
curl --include https://bobbucks.dev/pay
194194
```
195195

196196
{% Aside %}

src/site/content/en/payments/web-based-payment-apps-overview/index.md

+3-4
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,9 @@ if used in a top-level document, with only a few exceptions:
9292
* `window.open()` is disabled.
9393

9494
{% Aside 'caution' %}
95-
Payment Handler API is only supported in Chrome as of July 2020. However, since
96-
Chromium based browsers already have the implementation, some of them may expose
97-
the API in the future. Also, [Mozilla recently announced it's implementing the
98-
API](https://groups.google.com/g/mozilla.dev.platform/c/gBQp1URD1lE/m/Fswh-5-ZBgAJ).
95+
Payment Handler API is only supported in Chrome as of January 2023. However,
96+
since Chromium based browsers already have the implementation, some of them may
97+
expose the API in the future.
9998
{% endAside %}
10099

101100
### WebAuthn support

0 commit comments

Comments
 (0)