Skip to content

Commit dc96d19

Browse files
author
Marcos Cáceres
authored
Editorial: move+rework examples (w3c#553)
1 parent e9990ec commit dc96d19

File tree

1 file changed

+249
-87
lines changed

1 file changed

+249
-87
lines changed

index.html

Lines changed: 249 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,255 @@ <h2>
182182
</section>
183183
</section>
184184
</section>
185+
<section class="informative">
186+
<h2>
187+
Examples of usage
188+
</h2>
189+
<p>
190+
In order to use the API, the developer needs to provide and keep track
191+
of a number of key pieces of information. These bits of
192+
information are passed to the <a>PaymentRequest</a> constructor as
193+
arguments, and subsequently used to update the payment request being
194+
displayed to the user. Namely, these bits of information are:
195+
</p>
196+
<ul>
197+
<li>The <var>methodData</var>: A sequence of <a>PaymentMethodData</a>s
198+
that represents the <a>payment methods</a> that the site supports
199+
(e.g., "we support card-based payments, but only Visa and MasterCard
200+
credit cards.").
201+
</li>
202+
<li>The <var>details</var>: The details of the transaction, as a
203+
<a>PaymentDetailsInit</a> dictionary. This includes total cost, and
204+
optionally a list of goods or services being purchased, for physical
205+
goods, and shipping options. Additionally, it can optionally include
206+
"modifiers" to how payments are made. For example, "if you pay with a
207+
credit card of type X, it incurs a US$3.00 processing fee".
208+
</li>
209+
<li>The <var>options</var>: Optionally, a list of things as
210+
<a>PaymentOptions</a> that the site needs to deliver the good or
211+
service (e.g., for physical goods, the merchant will typically need an
212+
physical address to ship to. For digital goods, an email will usually
213+
suffice).
214+
</li>
215+
</ul>
216+
<p data-link-for="PaymentRequest">
217+
Once a <a>PaymentRequest</a> is constructed, it's presented to the end
218+
user via the <a>show()</a> method. The <a>show()</a> returns a promise
219+
that, once the user confirms request for payment, results in a
220+
<a>PaymentResponse</a>.
221+
</p>
222+
<section>
223+
<h3>
224+
The <code>methodData</code> argument
225+
</h3>
226+
<p>
227+
The <var>methodData</var> sequence contains <a>PaymentMethodData</a>
228+
dictionaries containing the <a>payment method identifiers</a> for the
229+
<a>payment methods</a> that the web site accepts and any associated
230+
<a>payment method</a> specific data.
231+
</p>
232+
<pre class="example js" title="The `methodData` argument">
233+
const methodData = [
234+
{
235+
supportedMethods: "basic-card",
236+
data: {
237+
supportedNetworks: ["visa", "mastercard"],
238+
supportedTypes: ["debit", "credit"],
239+
},
240+
},
241+
{
242+
supportedMethods: "https://example.com/bobpay",
243+
data: {
244+
merchantIdentifier: "XXXX",
245+
bobPaySpecificField: true,
246+
},
247+
},
248+
];
249+
</pre>
250+
</section>
251+
<section>
252+
<h3>
253+
The <code>details</code> argument
254+
</h3>
255+
<p>
256+
The <var>details</var> contains information about the transaction
257+
that the user is being asked to complete, such as the line items in
258+
an order.
259+
</p>
260+
<pre class="example js" title="The `details` argument">
261+
const details = {
262+
id: "super-store-order-123-12312",
263+
displayItems: [
264+
{
265+
label: "Sub-total",
266+
amount: { currency: "USD", value: "55.00" },
267+
},
268+
{
269+
label: "Sales Tax",
270+
amount: { currency: "USD", value: "5.00" },
271+
},
272+
],
273+
total: {
274+
label: "Total due",
275+
amount: { currency: "USD", value: "65.00" },
276+
},
277+
};
278+
</pre>
279+
<section>
280+
<h4>
281+
Shipping options
282+
</h4>
283+
<p>
284+
Here we see an example of how to add two shipping options to the
285+
<var>details</var>.
286+
</p>
287+
<pre class="example js" title="Adding shipping options">
288+
const shippingOptions = [
289+
{
290+
id: "standard",
291+
label: "🚛 Ground Shipping (2 days)",
292+
amount: { currency: "USD", value: "5.00" },
293+
selected: true,
294+
},
295+
{
296+
id: "drone",
297+
label: "🚀 Drone Express (2 hours)",
298+
amount: { currency: "USD", value: "25.00" }
299+
},
300+
];
301+
Object.assign(details, { shippingOptions });
302+
</pre>
303+
</section>
304+
<section>
305+
<h4>
306+
Conditional modifications to payment request
307+
</h4>
308+
<p>
309+
Here we see how to add a processing fee for using a credit card.
310+
Notice that it requires recalculating the total.
311+
</p>
312+
<pre class="example js" title=
313+
"Modifying payment request based on card type">
314+
// Credit card incurs a $3.00 processing fee.
315+
const creditCardFee = {
316+
label: "Credit card processing fee",
317+
amount: { currency: "USD", value: "3.00" },
318+
};
319+
320+
// Modifiers apply when the user chooses to pay with
321+
// a credit card.
322+
const modifiers = [
323+
{
324+
additionalDisplayItems: [creditCardFee],
325+
supportedMethods: "basic-card",
326+
total: {
327+
label: "Total due",
328+
amount: { currency: "USD", value: "68.00" },
329+
},
330+
data: {
331+
supportedTypes: "credit",
332+
},
333+
},
334+
];
335+
Object.assign(details, { modifiers });
336+
</pre>
337+
</section>
338+
</section>
339+
<section>
340+
<h3>
341+
The <code>options</code> argument
342+
</h3>
343+
<p>
344+
The <var>options</var> dictionary contains information the developer
345+
needs from the user to perform the payment (e.g., the payer's name
346+
and shipping address).
347+
</p>
348+
<pre class="example" title="The `options` argument">
349+
const options = {
350+
requestPayerEmail: false,
351+
requestPayerName: true,
352+
requestPayerPhone: false,
353+
requestShipping: true,
354+
}
355+
</pre>
356+
</section>
357+
<section>
358+
<h3>
359+
Constructing a <code>PaymentRequest</code>
360+
</h3>
361+
<p>
362+
Having gathered all the prerequisite bits of information, we can now
363+
construct a <a>PaymentRequest</a> and request that the browser
364+
present it to the user:
365+
</p>
366+
<pre class="example" title="Constructing a `PaymentRequest`">
367+
async function doPaymentRequest() {
368+
try {
369+
const request = new PaymentRequest(methodData, details, options);
370+
// See below for a detailed example of handling these events
371+
request.onshippingaddresschange = ev =&gt; ev.updateWith(details);
372+
request.onshippingoptionchange = ev =&gt; ev.updateWith(details);
373+
const response = await request.show();
374+
await validateResponse(response);
375+
} catch (err) {
376+
// AbortError, SecurityError
377+
console.error(err);
378+
}
379+
}
380+
async function validateResponse(response) {
381+
try {
382+
if (await checkAllValuesAreGood(response)) {
383+
await response.complete("success");
384+
} else {
385+
await response.complete("fail");
386+
}
387+
} catch (err) {
388+
// Something went wrong...
389+
response.complete("unknown");
390+
}
391+
}
392+
doPaymentRequest();
393+
</pre>
394+
</section>
395+
<section>
396+
<h3>
397+
Handling events and updating the payment request
398+
</h3>
399+
<p>
400+
Prior to the user accepting to make payment, the site is given an
401+
opportunity to update the payment request in response to user input.
402+
This can include, for example, providing additional shipping options
403+
(or modifying their cost), removing items that cannot ship to a
404+
particular address, etc.
405+
</p>
406+
<pre class="example">
407+
const request = new PaymentRequest(methodData, details, options);
408+
request.onshippingaddresschange = async ev =&gt; {
409+
// Can we ship here?
410+
try {
411+
const json = request.shippingAddress.toJSON();
412+
const { shippingOptions, total } = await calculateShipping(json);
413+
const newDetails = {...details, ...{ shippingOptions, total }};
414+
ev.updateWith(newDetails);
415+
} catch (err) {
416+
ev.updateWith({ error: `Sorry! we can't ship to your address.` });
417+
}
418+
};
419+
// update the total
420+
request.onshippingoptionchange = ev =&gt; {
421+
const shippingOption = shippingOptions.find(
422+
option =&gt; option.id === request.id
423+
);
424+
const newTotal = {
425+
currency: "USD",
426+
value: calculateNewTotal(shippingOption),
427+
label: "Total due",
428+
};
429+
ev.udpateWith({ ...details, total: newTotal });
430+
};
431+
</pre>
432+
</section>
433+
</section>
185434
<section>
186435
<h2>
187436
Definitions
@@ -255,35 +504,6 @@ <h2>
255504
<a data-lt="PaymentOptions.requestShipping">requestShipping</a> flag is
256505
set.
257506
</p>
258-
<p>
259-
The following example shows how to construct a <a>PaymentRequest</a>
260-
and begin the user interaction:
261-
</p>
262-
<pre class="example" title="Constructing a PaymentRequest object">
263-
function validateResponse(response) {
264-
// check that the response is ok... throw if bad, for example.
265-
}
266-
267-
async function doPaymentRequest() {
268-
const payment = new PaymentRequest(methodData, details, options);
269-
payment.addEventListener("shippingaddresschange", event =&gt; {
270-
// Process shipping address change
271-
});
272-
let paymentResponse;
273-
try {
274-
paymentResponse = await payment.show();
275-
// paymentResponse.methodName contains the selected payment method.
276-
// paymentResponse.details contains a payment method specific
277-
// response.
278-
validateResponse(paymentResponse);
279-
paymentResponse.complete("success");
280-
} catch (err) {
281-
console.error("Uh oh, bad payment response!", err.message);
282-
paymentResponse.complete("fail");
283-
}
284-
}
285-
doPaymentRequest();
286-
</pre>
287507
<section>
288508
<h2>
289509
Constructor
@@ -294,64 +514,6 @@ <h2>
294514
specific <a data-lt="PaymentMethodData.data">data</a>, the payment
295515
<var>details</var>, and the payment <var>options</var>.
296516
</p>
297-
<div class="note">
298-
<p>
299-
The <var>methodData</var> sequence contains
300-
<a>PaymentMethodData</a> dictionaries containing the <a>payment
301-
method identifiers</a> for the <a>payment methods</a> that the web
302-
site accepts and any associated <a>payment method</a> specific
303-
data.
304-
</p>
305-
<pre class="example" title="The 'methodData' argument">
306-
const methodData = [{
307-
supportedMethods: "basic-card",
308-
data: {
309-
supportedNetworks: ['visa', 'mastercard'],
310-
supportedTypes: ['debit']
311-
}
312-
}, {
313-
supportedMethods: "https://example.com/bobpay",
314-
data: {
315-
merchantIdentifier: "XXXX",
316-
bobPaySpecificField: true
317-
}
318-
}];
319-
const request = new PaymentRequest(methodData, details, options);
320-
</pre>
321-
<p>
322-
The <var>details</var> object contains information about the
323-
transaction that the user is being asked to complete such as the
324-
line items in an order.
325-
</p>
326-
<pre class="example" title="The 'details' argument">
327-
const details = {
328-
id: "super-store-order-123-12312",
329-
displayItems: [{
330-
label: "Sub-total",
331-
amount: { currency: "USD", value: "55.00" }, // US$55.00
332-
}, {
333-
label: "Sales Tax",
334-
amount: { currency: "USD", value: "5.00" }, // US$5.00
335-
}],
336-
total: {
337-
label: "Total due",
338-
amount: { currency: "USD", value: "60.00" }, // US$60.00
339-
}
340-
}
341-
const request = new PaymentRequest(methodData, details, options);
342-
</pre>
343-
<p>
344-
The <var>options</var> object contains information the developer
345-
needs from the user to perform the payment (e.g., the payer's name
346-
and shipping address).
347-
</p>
348-
<pre class="example" title="The 'options' argument">
349-
const options = {
350-
requestShipping: true
351-
}
352-
const request = new PaymentRequest(methodData, details, options);
353-
</pre>
354-
</div>
355517
<p>
356518
The <a>PaymentRequest(methodData, details, options)</a> constructor
357519
MUST act as follows:

0 commit comments

Comments
 (0)