forked from w3c/payment-handler
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
966 lines (933 loc) · 54.4 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
<!DOCTYPE html>
<html>
<head>
<title>Payment App API</title>
<meta charset='utf-8'>
<script src='https://www.w3.org/Tools/respec/respec-w3c-common' class='remove'></script>
<script src='utils.js' class='remove'></script>
<script class='remove'>
var respecConfig = {
shortName: "payment-apps",
edDraftURI: "https://w3c.github.io/webpayments-payment-apps-api/",
specStatus: "ED",
editors: [
{ name: "Adrian Hope-Bailie",
url: "https://github.com/adrianhopebailie",
company: "Ripple",
companyURL: "https://ripple.com"
},
{ name: "Tommy Thorsen",
url: "https://github.com/tommythorsen",
company: "Opera",
companyURL: "https://opera.com"
},
{ name: "Adam Roach",
url: "https://github.com/adamroach",
company: "Mozilla",
companyURL: "https://mozilla.org"
},
{ name: "Jason Normore",
url: "https://github.com/jnormore",
company: "Shopify",
companyURL: "https://shopify.com"
},
],
useExperimentalStyles: true,
license: "w3c-software-doc",
wg: "Web Payments Working Group",
wgURI: "https://www.w3.org/Payments/WG/",
wgPublicList: "public-payments-wg",
wgPatentURI: "https://www.w3.org/2004/01/pp-impl/83744/status",
issueBase: "https://github.com/w3c/webpayments-payment-apps-api/issues/",
localBiblio: {
"PAYMENT-REQUEST-API": {
title: "Payment Request API",
href: "http://www.w3.org/TR/payment-request/",
authors: [
"Adrian Bateman",
"Zach Koch",
"Roy McElmurray"
],
status: "FPWD"
},
"METHOD-IDENTIFIERS": {
title: "Payment Method Identifiers",
href: "https://www.w3.org/TR/payment-method-id/",
authors: [
"Adrian Bateman",
"Zach Koch",
"Roy McElmurry"
],
status: "FPWD"
}
}
};
</script>
<style>
dt { margin-top: 0.75em; }
table { margin-top: 0.75em; border-collapse:collapse; border-style:hidden hidden none hidden }
table thead { border-bottom:solid }
table tbody th:first-child { border-left:solid }
table td, table th { border-left:solid; border-right:solid; border-bottom:solid thin; vertical-align:top; padding:0.2em }
li { margin-top: 0.5em; margin-bottom: 0.5em;}
</style>
</head>
<body>
<section id='abstract'>
<p>The Payment Request API [[!PAYMENT-REQUEST-API]] provides
a standard way to initiate payment requests from Web pages and
applications. User agents implementing that API prompt the user
to select a way to handle the payment request, after which
the user agent returns a payment response to the originating site.
This specification adds <strong>payment apps</strong>
to that user experience. It defines how users
register payment apps with user agents, how user agents support the display of
information about payment options the user can select to handle the
payment request, how the user selects a payment app, and how communication takes
place between user agents and payment apps to fulfill the requirements of the
underlying Payment Request API.</p>
</section>
<section id='sotd'>
<p>The Web Payments Working Group maintains <a href="https://github.com/w3c/webpayments-payment-apps-api/issues">
a list of all bug reports that the group has not yet addressed</a>.
This draft highlights some of the pending issues that are still to
be discussed in the working group. No decision has been taken on
the outcome of these issues including whether they are valid. Pull
requests with proposed specification text for outstanding issues
are strongly encouraged.</p>
</section>
<section class='informative'>
<h2>Introduction</h2>
<p>The Web Payments Working Group seeks to streamline payments on the Web to
help reduce payment "abandonment" and make it easier to use
new payment methods on the Web. It has published the Payment Request
API [[!PAYMENT-REQUEST-API]] as a standard way to initiate payment
requests from Web pages and applications. This specification adds
payment apps to that user experience. A payment app is software that
enables the user to fulfill a payment request using the user's
preferred payment method.</p>
<p>This specification defines:</p>
<ul>
<li>How users register and unregister payment apps with the user agent.</li>
<li>How the user agent matches payment methods supported by the payee with those enabled in registered payment apps.</li>
<li>How the user agent displays information about payment options to the user for selection.</li>
<li>How the user agent invokes a payment app, communicates input/response data with it, and returns the response data to the underlying Payment Request API.</li>
</ul>
<p>Payment apps may be implemented in a variety of ways: as Web applications, native operating system applications,
browser extensions, built-in user agent components, interface-less Web services, or a combination.
This specification does not cover every aspect of communication on every platform.</p>
<p class="note" title="User agent as payment request mediator">The Web Payments Working Group has used the term
"mediator" to refer to the software (here, the user agent) that carries out the activities defined in this
specification (matching, information display, etc.).</p>
</section>
<section id='conformance'>
<p>
This specification defines one class of products:
</p>
<dl>
<dt><dfn>Conforming user agent</dfn></dt>
<dd>
<p>
A <a>user agent</a> MUST behave as described in this specification
in order to be considered conformant. In this specification, <a>user agent</a> means a <em>Web
browser or other interactive user agent</em> as defined in [[!HTML5]].
</p>
<p>
User agents MAY implement algorithms given in this
specification in any way desired, so long as the end result is
indistinguishable from the result that would be obtained by the
specification's algorithms.
</p>
<p>
A conforming Payment App API user agent MUST also be a
<em>conforming implementation</em> of the IDL fragments
of this specification, as described in the
“Web IDL” specification. [[!WEBIDL]]
</p>
<aside class="note">
This specification uses both the terms "conforming user agent(s)"
and "user agent(s)" to refer to this product class.
</aside>
</dd>
</dl>
</section>
<section id="dependencies">
<h3>Dependencies</h3>
<p>This specification relies on several other underlying specifications.</p>
<dl>
<!--
<dt>Payment Request Architecture</dt>
<dd>The term <dfn data-lt="payment method|payment methods">Payment Method</dfn>
is defined by the Payment Request Architecture document
[[PAYMENT-ARCH]].</dd>
-->
<!--
<dt>Payment Request API</dt>
<dd>The terms <dfn>Payment Request API</dfn>,
<dfn>PaymentRequest</dfn> and <dfn>PaymentResponse</dfn> are defined by the
Payment Request API specification [[!PAYMENT-REQUEST-API]].</dd>
-->
<!--
<dt>Payment Method Identifiers</dt>
<dd>The terms <dfn data-lt="payment method|payment methods">payment method</dfn> and
<dfn data-lt="payment method identifier|payment method identifiers">payment
method identifier</dfn> are defined by the Payment Method
Identifiers specification [[!METHOD-IDENTIFIERS]].</dd>
-->
<dt>HTML5</dt>
<dd>The terms <dfn>global object</dfn>,<dfn>origin</dfn>, <dfn>queue a task</dfn>,
<dfn>browsing context</dfn>, and <dfn>top-level browsing
context</dfn> are defined by [[!HTML5]].</dd>
<!--
<dt>ECMA-262 6th Edition, The ECMAScript 2015 Language
Specification</dt>
<dd>The terms <dfn>Promise</dfn>, <dfn>internal slot</dfn>,
<dfn><code>TypeError</code></dfn>, <dfn>JSON.stringify</dfn>,
<dfn>JSON.parse</dfn>, <dfn><code>Array</code></dfn>,
<dfn><code>type</code></dfn> and the <dfn>[[\GetOwnProperty]]</dfn>
operation are defined by [[!ECMA-262-2015]].
<p>This document uses the format <em>object</em>@[[\slotname]] to
mean the internal slot [[\slotname]] of the object
<em>object</em>.</p>
<p>The term <dfn>JSON-serializable object</dfn> used in this
specification means an object that can be serialized to a string
using <a>JSON.stringify</a> and later deserialized back to an
object using <a>JSON.parse</a> with no loss of data.</p>
<p>When instructed to <dfn>Trim</dfn>(<var>x</var>), a user agent
MUST behave as if [[!ECMA-262-2015]]'s
<code>String.prototype.trim()</code> function had been called on
the string <var>x</var>.</p>
</dd>
<dt>DOM4</dt>
<dd>The <code><dfn>Event</dfn></code> type and the terms <dfn>fire
an event</dfn>, <dfn>dispatch flag</dfn>, <dfn>stop propagation
flag</dfn>, and <dfn>stop immediate propagation flag</dfn> are
defined by [[!DOM4]].
<p><dfn>DOMException</dfn> and the following DOMException types
from [[!DOM4]] are used:</p>
<table>
<tr>
<th>Type</th>
<th>Message (optional)</th>
</tr>
<tr>
<td><code><dfn>InvalidStateError</dfn></code></td>
<td>The object is in an invalid state</td>
</tr>
<tr>
<td><code><dfn>NotSupportedError</dfn></code></td>
<td>The payment method was not supported</td>
</tr>
<tr>
<td><code><dfn>SecurityError</dfn></code></td>
<td>The operation is only supported in a secure context</td>
</tr>
</table>
</dd>
<dt>WebIDL</dt>
<dd>When this specification says to <dfn>throw</dfn> an error, the
<a>user agent</a> must throw an error as described in [[!WEBIDL]].
When this occurs in a sub-algorithm, this results in termination of
execution of the sub-algorithm and all ancestor algorithms until
one is reached that explicitly describes procedures for catching
exceptions.</dd>
-->
<dt>Secure Contexts</dt>
<dd>The term <dfn>secure context</dfn> is defined by the Secure
Contexts specification [[!POWERFUL-FEATURES]].</dd>
<dt>URL</dt>
<dd>The <dfn>URL</dfn> concept and <dfn>URL parser</dfn> are
defined in [[!WHATWG-URL]].</dd>
<dt>Fetch</dt>
<dd>The terms <dfn>Fetch</dfn>, <dfn>Request</dfn>, <dfn data-lt="body">Request Body</dfn>, <dfn data-lt="method">Request
Method</dfn>, <dfn>Header List</dfn>, <dfn>Response</dfn>,
<dfn>Context</dfn> and <dfn>Network Error</dfn> are defined in
[[!FETCH]].</dd>
<dt>Service Workers</dt>
<dd>The term <dfn data-lt="service worker|service workers">service worker</dfn> is defined in
[[SERVICE-WORKERS]].</dd>
</dl>
</section>
<section id="model">
<h2>Payment App Model and Design Considerations</h2>
<p>This section (which may be temporary) intends to help build shared understanding of the capabilities and limitations of the specified model.</p>
<section>
<h3>General Considerations</h3>
<ul>
<li>This specification builds on PaymentRequest API.</li>
<li>It defines mechanisms that may be used to support both Web-based and <a>native payment apps</a>. However, we anticipate
that the ecosystem will also include proprietary approaches to some of the functionality defined here
(e.g., for payment app registration or invocation).</li>
</ul>
</section>
<section>
<h3>Decoupling and Trust</h3>
<ul>
<li> A goal of this system is to decouple the payment methods used to pay from the software (payment apps) that implement those payment methods. By decoupling, merchants (and their payment service providers) can lower the cost of creating a checkout experience, users can have more choice in the software they use to pay, and payment app providers can innovate without imposing an integration burden on merchants.</li>
<li> Users may choose to use "open" or "proprietary" payment methods, so the payment app ecosystem must support both. Users must be able to register payment apps of their choosing. We expect the user to have greater choice of third party payment apps for open payment methods than for proprietary payment methods. Examples of open payment methods include card payment and SEPA credit transfer.</li>
<li> For privacy, the design should limit information about the user's environment available to merchant without user consent. That includes which payment apps the user has registered. For open payment methods, the merchant should not receive information about which payment app the user selected to pay unless the user consents to share that information. See <a href="https://github.com/w3c/browser-payment-api/issues/224">issue 224</a> for discussion about how merchant may track progress of a push payment.</li>
<li> Although decoupling relieves merchants of implementing some aspects of the checkout experience, one consequence is that they give up some degree of control. This was already the case for proprietary payment methods, but for open payment methods such as cards, merchants (or their PSPs) will be entrusting some portion of data collection to third party payment apps, without knowing which app the user will select.</li>
<li> We recognize, therefore, a tension between user preferences (e.g., registered payment apps, ordering of display of payment apps, etc.) and merchant preferences (e.g., control of the user experience previously implemented in a Web page, ordering of payment apps, presence of merchant's own payment app, etc.).</li>
<li> The design should address this tension by enabling the merchant to express preferences for both payment methods and payment apps. The design should not constrain how browsers make use of these preferences, only provide guidance to browser vendors about taking into account both merchant and user preferences.</li>
<li> Here are preferences the system might support:
<ul>
<li> Accepted payment methods (payment methods the merchant accepts, and no others may be used; part of payment request API)</li>
<li> Preferred payment methods (merchant-specified order part of payment request API)</li>
<li> Recommended payment apps (payment apps the merchant prefers, but others may be used)</li>
<li> Accepted payment apps (payment apps the merchant accepts, and no others may be used). Note that this is the status quo since merchants either accept card information through UI that they control, or they redirect users to payment service providers with whom they have existing relationships. Note that if we allow merchants to restrict payment apps that might end up requiring the customer to register multiple payment apps for the same payment method, which would complicate the user experience for the same payment method.</li>
</ul>
</li>
<li> The browser uses this information in conjunction with user preferences to:
<ul>
<li> Filter payment apps (to matching payment methods and accepted payment apps)</li>
<li> Order payment apps (according to merchant specified order)</li>
<li> Display recommended payment apps (according to merchant recommended payment app order)</li>
</ul>
</li>
</ul>
</section>
<section>
<h3>Registration and Unregistration</h3>
<ul>
<li>
We expect registrations will happen at various times (e.g., outside and inside of checkout): Here are some examples:
<ul>
<li> When the merchant recommends a payment app and the user selects it, registration can happen in that moment without additional user action.</li>
<li> When the browser recommends a payment app and the user selects it, registration can happen in that moment without additional user action. (There is an expectation that the display of browser-recommended apps will differ from the display of merchant-recommended apps).</li>
<li> When the user installs native payment app, registration can happen as part of the app installation process.</li>
<li> Users visiting a Web site (e.g., merchant or bank) may be invited to register a payment app outside of the context of checkout.</li>
</ul>
</li>
<li>
At the same time, the system should not modify the user's environment or share user data without the user's consent. Consent may be provided in a number of ways that can be streamlined (e.g., registration of a native payment app can happen when the native app is installed; when only one payment app matches merchant-accepted data, the browser can launch the app directly instead of requiring additional user selection; etc.)
</li>
<li>During registration, information about enabled payment methods and available payment options is provided to the user agent.
The user agent stores this information for subsequent actions (e.g., when matching merchant-accepted payment methods). In this
proposal, there are no requirements for a payment app to be able to respond to user agent queries for updated
registration information. In this proposal, payment apps update the information that a user agent has stored about them
by re-calling the registration API.</li>
</ul>
</section>
<section>
<h3>Payment App Identification</h3>
<ul>
<li> For both "recommended" and "accepted" payment apps, we will need payment app identifiers (PAIs).</li>
<li> A PAI should include origin information. This origin information may be used in a variety of ways:
<ul>
<li> The origin information could enable browsers to provide the user with useful services when the user is browsing a site with the same origin (e.g., putting that payment app at the top of a list or otherwise highlighted).</li>
<li> For a "proprietary" payment method with an associated origin, the browser can do some (security) checks by comparing the origin of the payment method and the payment app.</li>
</ul>
<li> A PAI should allow for granularity (e.g., payment app versioning); we should consider URLs.</li>
</ul>
</section>
<section>
<h3>Payment App Matching</h3>
<ul>
<li>When the user invokes the Payment Request API (e.g., by "pushing the Buy button"), the user agent
computes the intersection between merchant-accepted payment methods and user-registered payment methods. It
does this by comparing Payment Request API data (from the payee) and data provided during registration,
invoking the comparison algorithm defined in the Payment Method Identifier specification. The result is a list of
matching payment options and recommended payment apps.</li>
<li>Using information provided during registration (e.g., an app name or icon),the user agent displays matching
payment options for selection by the user. The user agent may also display merchant-specified or user agent-specified recommended payment apps, which are
displayed distinctly for the user. This mechanism is intended to support use cases such as a merchant
recommending their own payment app to the user, or the user agent helping the user find payment apps that are
relevant for a transaction but that the user has not yet registered or enabled.
<p class="note" title="Browser selection features not in scope">The user agent may offer features to facilitate selection (e.g., launch a chosen payment app or option every time the
user wants to pay at a given Web site); those features lie outside the scope of this specification.</p></li>
<li>The user selects a payment option to make a payment. The user may also select a recommended payment app.</li>
</ul>
</section>
<section>
<h3>User Experience</h3>
<ul>
<li>The system should minimize user interaction for payment app registration, payment app selection, and payment credentials selection. Ideas include:
<ul>
<li>When only one payment app matches, the browser does not require user selection to launch it.</li>
<li>The browser displays payment options for direct selection by the user, avoiding the need for the user to make a second selection within the payment app context. The payment app provides the browser with sufficient information to display payment options. It is still possible to launch the payment app upon selection of a payment option, and in some cases the payment app may return a response without further user interaction, depending on the nature of the payment method.</li>
</ul>
</li>
<li>It is likely that this specification will include <em>guidance</em> rather than requirements about specific user experience optimizations.</li>
</ul>
</section>
<section>
<h3>Payment App Invocation and Response</h3>
<ul>
<li>Based on information provided at registration, the user agent "launches" the payment app and provides it with
input data drawn from the Payment Request API.</li>
<li>The user may interact with the payment app in a variety of ways to authorize payment, cancel the transaction,
or carry out other activities supported by the payment app. This specification does not address payment app
behavior other than accepting requests and returning responses to the user agent.</li>
<li>This specification defines a means for the user agent to receive a response asynchronously once the user has
authorized payment. The response becomes the response of the Payment Request API.</li>
</ul>
</section>
<section>
<h3>Network Considerations</h3>
<ul>
<li>This specification only describes communication between the
user agent and the payment app. This includes an
asynchronous mechanism for a payment app to return a payment
response to the user agent. This specification does not
(yet) address scenarios where the user agent does not
receive the response (e.g., due to a crash or network
outage). Network failure may be especially problematic in the
case of a push payment; see <a href="https://github.com/w3c/browser-payment-api/issues/224">issue 224</a>, and so the Working Group is considering whether the specification should include a standard way to learn how to query a component for payment state information. For example, many systems use backchannel communications, so one idea is for the payee to provide a callback URL. This would allow (but not require) the payment app to communicate with the payee server until such time as all parties are satisfied they share the same view of the payment response. An alternative would be to provide the payment app and the user agent a channel so that communication continues until all aprties are satisfied they share the same view of the payment response. This might involve caching payment responses.</li>
</ul>
</li>
<li>This specification does not address communication between the payee server and the payee Web app, or between
the payment app and other parties (e.g., the payment app distibutor, or directly to the merchant).</li>
</ul>
</section>
</section>
<section id="definitions">
<h2>Definitions</h2>
<div data-include="https://w3c.github.io/webpayments-ig/latest/common/terms.html"
data-oninclude="restrictReferences">
</div>
<p class="issue">Updates needed for payment method option definition.</p>
<h3>Payment App Implementation Technology</h3>
<dl>
<dt><dfn id="dfn-browser-based-payment-app">browser-based payment app</dfn></dt>
<dd>a <a>payment app</a> that runs in a <a>browser</a>.</dd>
<dt><dfn id="dfn-headless-payment-app">headless Web payment app</dfn></dt>
<dd>a payment app that has no user interface.</dd>
<dt><dfn id="dfn-native-payment-app">native payment app</dfn></dt>
<dd>a payment app built with the operating system default technology stack that uses non-Web technologies.</dd>
</dl>
<p class="note" title="Payment Apps in scope">
The Web Payments Working Group intends for this specification to apply to any payment app that the may be invoked by the user agent, whatever technologies have been used to implement the payment app.</p>
<h3>Payment App Registration States</h3>
<dl>
<dt><dfn id="dfn-registered-payment-app">registered payment app</dfn></dt>
<dd>a payment app that is "known" to the user agent for the purposes of the interactions described in this document.
<div class="note" title="Platform-specific registration">
This specification defines a registration mechanism. Other registration mechanisms might co-exist with this one
(e.g., on some platforms there may be a way to register a payment app directly with the operating system).</div>
</dd>
<dt><dfn id="dfn-unregistered-payment-app">unregistered payment app</dfn></dt>
<dd>a payment app that is not known to the user agent, either because it has never been registered, or because it has been unregistered.</dd>
<dt><dfn id="dfn-enabled-payment-app">enabled payment app</dfn></dt>
<dd>A <a>registered payment app</a> with at least one <a>enabled
payment method</a>.</dd>
</dl>
<h3>Payment App Selection States</h3>
<dl>
<dt><dfn id="dfn-matching-payment-app">matching payment app</dfn></dt>
<dd>An <a>enabled payment app</a> that:
<ul>
<li>has at least one <a>enabled payment method</a> that the
<a>payee</a> accepts.</li>
<li>is not an <a>ignored payment app</a>.</li>
</ul>
</dd>
<dt><dfn id="dfn-recommended-payment-app">recommended payment app</dfn></dt>
<dd>a payment app suggested by the payee or user agent to be registered and used to handle a specific payment request.
<p class="issue" data-number="112" title="Recommended Payment Apps is still under discussion">
The Working Group has not yet agreed that the system should support recommended payment apps.
Inclusion might involve small changes to payment request API.</p>
</dd>
<dt><dfn id="dfn-accepted-payment-app">accepted payment app</dfn></dt>
<dd>a payment app accepted by the payee. When the payee specifies one or more accepted payment apps, this is a signal that the payee <em>only</em> accepts these payment apps, and thus any matching is limited to these payment apps.
<p class="issue" title="Accepted Payment Apps is still under discussion">
The Working Group has not yet agreed that the system should support accepted payment apps.
Inclusion might involve small changes to payment request API.</p>
</dd>
<dt><dfn id="dfn-displayed-payment-app">displayed payment app</dfn></dt>
<dd>A <a>matching payment app</a> or <a>recommended payment app</a> with at least one selectable payment option (i.e. presented by the browser for user selection).</dd>
<dt><dfn id="dfn-selected-payment-app">selected payment app</dfn></dt>
<dd>the payment app whose option has been selected by the user to make a payment, but not yet invoked.</dd>
<dt><dfn id="dfn-invoked-payment-app">invoked payment app</dfn></dt>
<dd>the selected payment app that the user agent has invoked (executed) and passed payment app input data.</dd>
</dl>
<h3>Payment Options</h3>
<p class="note">We need a clearer introduction to the concept of a payment option, and how it relates to payment apps.</p>
<dl>
<dt><dfn id="dfn-available-payment-app">available payment option</dfn></dt>
<dd>a payment option from a registered payment app available for selection, corresponding to at least one enabled payment method.</dd>
<dt><dfn id="dfn-matching-payment-option">matching payment option</dfn></dt>
<dd>an available payment option that has at least one enabled payment method accepted by the payee, or a recommended
payment app with at least one supported payment method accepted by the payee.</dd>
<dt><dfn id="dfn-selectable-payment-option">selectable payment option</dfn></dt>
<dd>a matching payment option for which information has been displayed by the user agent to facilitate user selection,
but that has not yet been selected. <strong>Note:</strong> Information about selectable payment apps may be
displayed in a variety of modalities, including visual and aural.</dd>
<dt><dfn id="dfn-selected-payment-option">selected payment option</dfn></dt>
<dd>the payment option selected by the user to handle the payment request.</dd>
</dl>
<h3>Payment Method Support</h3>
<dl>
<dt><dfn id="dfn-supported-payment-method">supported payment method</dfn></dt>
<dd>a payment method that a payment app has been designed to support however, this payment method may or may
not currently be enabled. A payment app may support more than one payment method.</dd>
<dt><dfn id="dfn-unsupported-method">unsupported payment method</dfn></dt>
<dd>a payment method that cannot be enabled by a payment app. Updates to a payment app may cause an
unsupported payment method to become supported, or vice-versa.</dd>
<dt><dfn id="dfn-enabled-method">enabled payment method</dfn></dt>
<dd>a supported payment method that a registered payment app is able to handle. The payment app must have at least
one available payment option with the corresponding enabled payment method.
<p class="note" title="Supported vs enabled Payment Methods">
The difference between <strong>supported</strong> and <strong>enabled</strong> payment methods is one of design-time vs runtime consideration.
A payment app supports all the payment methods it was designed to support however at runtime only a subset
may be enabled due to configuration or other runtime requirements that may not have been met for all
supported payment methods.
</p>
</dd>
</dl>
<h3>Payment App Invocation and Response Data</h3>
<dl>
<dt><dfn id="dfn-app-request-data">payment app request data</dfn></dt>
<dd>data provided to the <a>invoked payment app</a> by the user agent to initiate a payment request. This data is a subset
of data input to the Payment Request API.
<p class="note" title="JSON serialization">
The data passed between the user agent and the payment app will be serialized as JSON data.
</p>
</dd>
<dt><dfn id="dfn-app-response-data">payment app response data</dfn></dt>
<dd>data returned by an <a>invoked payment app</a> to the user agent, typically after payment authorization or other action
taken through the payment app. This data, which will vary according to payment method, is then passed through
the Payment Request API as the payment response.</dd>
</dl>
</section>
<section id="registration">
<h2>Payment App Registration, Updates and Unregistration</h2>
<p>To support registration and unregistration, the user agent provides primitives that may be called from within a Web
page.</p>
<p>Payment apps are registered with the user agent through a call to the <code>register()</code> method of the API.
The input to the registration process consists of:</p>
<ol>
<li>a <code>payment_app_id</code>, a URL that identifies the app.</li>
<li>a <code>request_url</code> which identifies the
endpoint where the user agent submits payment requests.</li>
<li>a sequence of <code>PaymentOption</code>
dictionaries to provide information displayed to the user to facilitate payment app selection.</li>
</ol>
<section>
<h3>The PaymentOption dictionary</h3>
<pre class="idl">
dictionary PaymentOption {
DOMString label;
DOMString icon;
sequence<DOMString> enabled_methods;
};
</pre>
<dl>
<dt><code>label</code> member</dt>
<dd>
The <dfn id="payment-app-option-label"><code>label</code> member</dfn> is a
string that represents the lable for this option as it is usually displayed to the user when
selecting a payment app.
</dd>
<dt><code>icon</code> member</dt>
<dd class="issue">
Need to define how an icon would be represented in this data. Url? Data URL? Size options?
</dd>
<dt><code>enabled_methods</code> member</dt>
<dd>
The <dfn id="payment-app-option-enabled-methods"><code>enabled_methods</code></dfn> member
lists the <a>payment method identifiers</a> of the payment methods enabled by this option.
</dd>
</dl>
</section>
<section>
<h3>PaymentApp.register()</h3>
<p>
The <code><dfn>register</dfn></code> method is used to register, update, or unregister a payment app with a <a>user agent</a>.
</p>
<p>
Payment apps are uniquely identifed by their <code>payment_app_id</code>. To update the payment options
offered by a registered payment app, a website calls <code>register()</code> using the same
<code>payment_app_id</code> as was used when registering the app and pass in the new sequence of options. To
unregister a payment app the website calls <code>register()</code> with an empty sequence of options.
</p>
<pre class="idl">
partial interface PaymentApp {
static Promise<void> register (URLString payment_app_id, URLString request_url, sequence<PaymentOption> payment_options);
};
</pre>
<dl>
<dt><code>payment_app_id</code> parameter</dt>
<dd>An identifier for the payment app. If a payment app is already installed with the same <code><a>request_url</a></code>
the registered payment options will be replaced with the new sequence of options provided.</dd>
<dt><code>request_url</code> parameter</dt>
<dd>
<p>
The <dfn id="payment-app-request-url"><code>request_url</code></dfn> is a string that
represents the <dfn>request URL</dfn>, which is the <a>URL</a> that accepts
payment request messages via HTTP POST.
</p>
<p>
The <code><a>request_url</a></code> is the API entry point for the payment
app and MUST have the same <a>origin</a> as the web application that attempts
to register the payment app.
</p>
<p class="note" title="Origin for native apps">Native apps could be registered from Web pages, thus allowing the association of an origin to a native app.</p>
</dd>
<dt><code>payment_options</code> parameter</dt>
<dd>
<p>
The <dfn id="payment-app-options"><code>payment_options</code></dfn> is a sequence of one or more
options that can be presented to the user for selection when the [[!PAYMENT-REQUEST-API]] is invoked.
</p>
</dd>
</dl>
<p>The <a><code>register</code></a> method MUST act as follows:</p>
<ol>
<li>Let <em>promise</em> be a new <a>Promise</a>.</li>
<li>Return <em>promise</em> and asynchronously perform the remaining steps.</li>
<li>If the <a>origin</a> of <em>request_url</em> does not match the <a>origin</a> of the current document
reject <em>promise</em> with a <a><code>SecurityError</code></a>.</li>
<li>Let <em>registered_app</em> be the registered payment app where
<em>registered_app</em>@[[\request_url]] is equal to <em>request_url</em>.</li>
<li>If <em>registered_app</em> is null, let <em>new_app</em> be a new registered payment app and:
<ol>
<li>Set <em>new_app</em>@[[\\request_url]] to <em>request_url</em>.</li>
<li>Set <em>new_app</em>@[[\\payment_options]] to <em>payment_options</em>.</li>
<li>Store <em>new_app</em> as a registered payment app.</li>
</ol>
</li>
<li>Else
<ol>
<li>If <em>payment_options</em> is an empty sequences, unregister <em>registered_app</em>.</li>
<li>Else, set <em>registered_app</em>@[[\\payment_options]] to <em>payment_options</em>.</li>
</ol>
</li>
<li>Resolve <em>promise</em> with <code>undefined</code>.</li>
</ol>
<p>The following example shows how to register a payment app:</p>
<pre class="example highlight">
PaymentApp.register(
"https://example.com/paymentapp/v1",
[
{
label: "Visa ending ****4756",
icon: "...",
enabled_methods: ["https://webpayments.org/payment-methods/card/visa"]
},
{
label: "My Bob Pay Account",
icon: "...",
enabled_methods: ["https://bobpay.com/"]
},
{
label: "Add new credit/debit card to ExampleApp",
icon: "...",
enabled_methods: [
"https://webpayments.org/payment-methods/card/visa",
"https://webpayments.org/payment-methods/card/mastercard",
"https://webpayments.org/payment-methods/card/amex" ]
}
]
).then(function(value) {
console.log("Installed https://example.com/paymentapp/v1 payment app"); // Success!
}, function(reason) {
console.log(reason); // Error!
});
</pre>
</section>
<p class="issue" title="Registration of native payment apps?">
What, if anything, should we say about registering native payment apps?
</p>
</section>
<section id="matching">
<h2>Payment App Matching</h2>
<div class="issue" title="Dependency on Payment Method Identifiers spec">
<p>
We anticipate that the Payment Method Identifier specification will define the PMI matching algorithm. This
specification will explain how to invoke that algorithm using data available from the Payment Request API input
and payment method information aggregated from:
</p>
<ul>
<li>enabled payment methods across all payment options of registered payment apps.</li>
<li>supported payment methods of recommended but unregistered payment apps.</li>
</ul>
</div>
</section>
<section id="selection">
<h2>Payment App Selection</h2>
<section>
<h3>Selectable App Information Display</h3>
<p class="issue" title="Need to define display algorithm">
After matching the user agent will have a list of payment options that the user can select to handle the
payment request. How will these be ordered when they are displayed to the user, where do recommended apps
fit in to the order and how do we treat apps that are both registered and recommended?
</p>
<p class="issue" title="Should payment instrument details be included?" data-number="142">
What information is needed by the user agent to display selectable apps/options? This needs to be captured
during registration.
</p>
<p>
The output of the payment method matching algorithm will be a list of matching payment options from registered
payment apps and a list of recommended payment apps. The user agent will present this list of options to the user
so they can select how they want to handle the payment request.
</p>
<ul>
<li>The user agent <span class='rfc2119'>MUST</span> display all matching payment options.</li>
<li>The user agent <span class='rfc2119'>MAY</span> display recommended payment apps.</li>
<li>In its display, the user agent <span class='rfc2119'>MUST</span> distinguish recommended payment apps from
payment options from registered payment apps.</li>
<li>The user agent <span class='rfc2119'>MAY</span> allow the user to configure the display of matching payment
options to control the ordering and define preselected defaults.</li>
<li>The user agent <span class='rfc2119'>MUST</span> display matching payment options in an order that corresponds
to the order of supported payment methods supplied by the payee, except where the user agent enables the user
to override this order.</li>
<li>The user agent <span class='rfc2119'>SHOULD</span> display any payee-recommended apps in the order specified
by the payee.</li>
</ul>
<div class="issue" title="Payment app selection user experience consistency">
<p>
Which of these scenarios do we expect to support through the set of technologies, and should we seek to harmonize
the user experience across them?
</p>
<ol>
<li>User has no registered payment apps.</li>
<li>User has apps with supported but no enabled payment methods.</li>
<li>User has apps with supported and enabled payment methods.</li>
<li>Merchant wishes to recommend a payment app to the user.</li>
<li>user agent wishes to recommend a payment app that supports a payment method for which the user does not
currently have a supporting payment app.</li>
</ol>
<p>
Current ideas for supporting 4 and 5 include (1) using the "recommended payment apps" approach of this
spec (2) using payment method identifiers to designated recommended payment apps.
</p>
</div>
<section class="informative">
<h4>Examples of Ordering of Selectable Payment Apps</h4>
<p>The following are examples of user agent display behavior.</p>
<ul>
<li>Display a user-configured preferred payment app at the top of a list of matching payment apps.</li>
<li>Enable the user to set a default payment app for a Web site, and display that payment at the top of a list
of matching payment apps for transactions with that site.</li>
<li>Enable the user to set a default payment app for a Web site (e.g., the payment app distributed by that
retailer), and display that payment at the top of a list of matching payment apps for transactions with that
site.</li>
</ul>
</section>
</section>
<section>
<h3>Selection by the User</h3>
<ul>
<li>The user agent <span class='rfc2119'>MUST</span> enable the user to select any <a>displayed payment option</a>.</li>
<li>If the user selects an unregistered recommended payment app, the user agent <span class='rfc2119'>SHOULD</span>
offer the user an opportunity to register it.</li>
</ul>
</section>
</section>
<section id="invocation">
<h2>Payment App Invocation, Display and Response</h2>
<p>
Once the user has selected a payment option, the user agent is responsible for preparing payment app request data,
invoking the payment app, providing the request data to the payment app, and returning the payment app response
through the Payment Request API.
</p>
<p>
This specification defines an HTTP-based mechanism to provide data to the payment app. Payment apps may use
a variety of mechanisms to handle the incoming data, including server-side processing, or client-side interception
of the HTTP message by a <a>ServiceWorker</a>.
</p>
<p class="note" title="Developing payment apps">The Working Group should discuss how to capture good practice for payment app development, with examples that illustrate common payment flows, different platforms, etc.. A public resource (e.g., on github) could foster contributions of good practice information from the developer community.</p>
<section>
<h3>Payment App Request Data</h3>
<p class="issue" title="Need to define the shape of the payment app request data">
Let P be the intersection of payment methods supported by the payee and enabled by the selected payment option.
Send the data corresponding to P, as well as any global transaction data (total, etc.) to the payment app.
The details depend on discussions about the shape of the Payment Request API.
</p>
<p class="issue" title="Need to define an algorithm for serializing the payment app request data to JSON">
Once we have finalized the shape of the data that is returned from the matching process we must define a
deterministic algorithm for serializing this as JSON for transmission over the wire.
</p>
</section>
<section>
<h3>Payment App Invocation</h3>
<p class="issue" title="Invocation" data-number="130">
The Working Group is still discussing how to invoke payment apps (e.g., via an HTTP POST to
<code>request_url</code> or by executing a piece of JS provided at registration). The following
algorithm assumes an HTTP POST approach.
</p>
<p>
The payment app is invoked by the user agent making an HTTP request to the app's <code>request_url</code>
acording to the following algorithm:
</p>
<ol>
<li>Let <var>payment request</var> be the string that is the
outcome of the steps to prepare the payment app request data.
</li>
<li>Let <var>app_url</var> be the <code>request_url</code> member of the selected payment app.</li>
<li>Let <var>request</var> be a new [[!FETCH]] <a>Request</a>, whose members are set to the following values:
<table>
<tr>
<th>Member</th>
<th>Value</th>
</tr>
<tr>
<td><code><a>URL</a></code></td>
<td>The value of <var>app_url</var></td>
</tr>
<tr>
<td><code><a>method</a></code></td>
<td>The value "<code>POST</code>"</td>
</tr>
<tr>
<td><code><a>header list</a></code></td>
<td>
<table>
<tr>
<td><code>Accept</code></td>
<td>text/html;application/json</td>
</tr>
</table>
</td>
</tr>
<tr>
<td><code><a>body</a></code></td>
<td>The value of <var>payment request</var></td>
</tr>
</table>
</li>
<li>Await the result of performing a <a>fetch</a> with
<var>request</var>, letting <var>response</var> be the result.</li>
<li>If <var>response</var> is a <a>network error</a>, terminate this algorithm.</li>
<li>Switch on <var>response</var>'s <var>MIME type</var>:
<ul>
<li>if <code>text/html</code> go to the section below on Payment App Display</li>
<li>else if <code>application/json</code> then go to the section below on Payment App Response</li>
<li>otherwise reject the <a>Promise</a> created during <a>PaymentRequest.show</a> with an error.</li>
</ul>
</li>
</ol>
<p class="issue" data-number="" title="What are the appriate fetch parameters for this request?">
We should get input form Web Platform and WebAppSec on how to best construct this request.
</p>
<p class="issue" data-number="" title="How do we support long-running payment apps?">
A remote payment app may be getting payment authorization from the user via different channel (such as a
mobile app) so we need the app to be able to send keep-alive messages back to the browser while this is in
progress.
</p>
<p class="issue" data-number="128" title="Cancelation is treated as an ordinary response">
If the user cancels the handling of the payment request then the app should return a response
with an appropriate error/response code. Will this be done through the HTTP status code or defined as a value
that is set in the response.
</p>
<div class="issue" data-number="141" title="Handling network and other failures">
<p>Communication mail fail at various points in the flow; see design considerations for some ideas for managing this.</p>
</div>
</section>
<section>
<h3>Payment App Display</h3>
<p class="issue" title="Payment app instantiation" data-number="143">
The Working Group is still discussing how payment apps are displayed for user interaction.
</p>
<p>
Payment apps are invoked via an HTTP request. If the resulting HTTP response body is text/html then the user agent
MUST render this content for the user.
</p>
<ol>
<li>The user agent MUST render the <a>Response</a> in a new secure context.</li>
<li>The user agent MUST make the <code>PaymentApp.respond()</code> method available to the page that is
rendered.</li>
</ol>
<p>
This specification does not otherwise prescribe how user agents render the payment app. This may be in a new tab/window, in
a special modal dialogue specifically for this purpose, in an iframe embedded in the web page of the payee
website or any other mechanism the user agent defines.
</p>
<section>
<h4>The PaymentAppResponse dictionary</h4>
<p>
A payment app that runs in the user agent responds to a payment request by returning a new
<code>PaymentAppResponse</code> via the <code>PaymentApp.respond()</code> method.
</p>
<pre class="idl">
dictionary PaymentAppResponse {
DOMString method;
object details;
};
</pre>
<dl>
<dt><code>method</code> member</dt>
<dd>
The <dfn id="payment-app-response-method"><code>method</code> member</dfn> is the payment method
identifer of the payment method used to handle the payment request.
</dd>
<dt><code>details</code> member</dt>
<dd>
The <dfn id="payment-app-response-details"><code>details</code></dfn> member contains the payment method
specific data that is expected in a payment response.
</dd>
</dl>
</section>
<section>
<h4>PaymentApp.respond()</h4>
<p>
The payment app submits the <code>PaymentAppResponse</code> by calling the <code>respond()</code> method and
passing this in as a parameter.
</p>
<pre class="idl">
partial interface PaymentApp {
static void respond (PaymentAppResponse response);
};
</pre>
<p>The <a><code>respond</code></a> method MUST act as follows:</p>
<p class="issue" title="Define algorithm for passing response back to calling context">
This should be a light algorithm that simply hands off to the steps defined in Payment Request
</p>
<p>The following example shows how to respond to a payment request:</p>
<pre class="example highlight">
PaymentApp.respond(
"https://webpayments.org/payment-methods/card/visa",
{
card_number : "1232343451234",
expiry_month : "12",
expiry_year : "2020",
cvv : "123"
});
</pre>
</section>
</section>
<section>
<h3>Payment App Response</h3>
<p>
The user agent receives a response from the payment app in one of two forms:</p>
<ol>
<li>a JSON serialized
<code>PaymentAppResponse</code> sent as a response to the HTTP request that invoked the app</li>
<li>a
<code>PaymentAppResponse</code> dictionary instance submitted via the <code>PaymentApp.respond()</code> method</li>
</ol>
<p>
The user agent MUST use this <code>PaymentAppResponse</code> to resolve the promise that was created
by <a>PaymentRequest.show</a> when the user agent executed the <a>user accepts the payment request algorithm</a>
as defined in [[!PAYMENT-REQUEST-API]].
</p>
<p class="issue" title="Generic callback back-channel for the payment response transmission">
Some payment methods might require a back channel to guarantee payment response delivery (especially push payment methods).
Should it be part of the generic portion of paymentRequest and paymentResponse?
</p>
</section>
</section>
<section id="security">
<h2>Security and Privacy Considerations</h2>
<section>
<h3>Design Considerations</h3>
<ul>
<li>The API does not share information about the user's registered payment methods or payment apps with the payee. The only information that is shared is the result of user selection.</li>
</ul>
</section>
<section>
<h3>Secure Communications</h3>
<ul>
<li>See <a href="https://www.w3.org/TR/service-workers/#security-considerations">Service Worker security considerations</a></li>
<li>Payment method security is outside the scope of this specification and is addressed by payment apps that support those payment methods.</li>
</ul>
</section>
<section>
<h3>Data Validation</h3>
<ul>
<li>Payees should validate that the data they have received through the paymentRequest API is what they expect (e.g., the total that was paid, etc.).</li>
</ul>
</section>
</section>
</body>
</html>