This repository has been archived by the owner on Mar 19, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathindex.html
1253 lines (1121 loc) · 40.5 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
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<title>Web Payments Browser API 1.0</title>
<meta http-equiv='Content-Type' content='text/html;charset=utf-8'/>
<!--
=== NOTA BENE ===
For the three scripts below, if your spec resides on dev.w3 you can check them
out in the same tree and use relative links so that they'll work offline,
-->
<link rel="stylesheet" href="spec.css">
<script src='//www.w3.org/Tools/respec/respec-w3c-common' async class='remove'></script>
<script src='utils.js' async class='remove'></script>
<script type="text/javascript" class="remove">
var respecConfig = {
// specification status (e.g. WD, LCWD, NOTE, etc.). If in doubt use ED.
specStatus: "CG-DRAFT",
// the specification's short name, as in http://www.w3.org/TR/short-name/
shortName: "web-payments-browser-api",
// if you wish the publication date to be other than today, set this
// publishDate: "2009-08-06",
// if there is a previously published draft, uncomment this and set its YYYY-MM-DD date
// and its maturity status
// previousPublishDate: "1977-03-15",
// previousMaturity: "WD",
// if there a publicly available Editor's Draft, this is the link
edDraftURI: "https://wicg.github.io/web-payments-browser-api/",
// if this is a LCWD, uncomment and set the end of its review period
// lcEnd: "2009-08-05",
// editors, add as many as you like
// only "name" is required
editors: [
{ name: "Manu Sporny", url: "https://manu.sporny.org/",
company: "Digital Bazaar, Inc.", companyURL: "http://digitalbazaar.com/" },
{ name: "Dave Longley", url: "https://github.com/dlongley",
company: "Digital Bazaar, Inc.", companyURL: "http://digitalbazaar.com/" },
],
// authors, add as many as you like.
// This is optional, uncomment if you have authors as well as editors.
// only "name" is required. Same format as editors.
authors: [
{ name: "Manu Sporny", url: "https://manu.sporny.org/",
company: "Digital Bazaar, Inc.", companyURL: "http://digitalbazaar.com/" },
{ name: "Dave Longley", url: "https://github.com/dlongley",
company: "Digital Bazaar, Inc.", companyURL: "http://digitalbazaar.com/" },
],
// extend the bibliography entries
//localBiblio: {},
// name of the WG
wg: "W3C Web Payments Community Group",
// URI of the public WG page
wgURI: "http://www.w3.org/community/webpayments/",
// name (with the @w3c.org) of the public mailing to which comments are due
wgPublicList: "public-webpayments",
// URI of the patent status for this WG, for Rec-track documents
// !!!! IMPORTANT !!!!
// This is important for Rec-track documents, do not copy a patent URI from a random
// document unless you know what you're doing. If in doubt ask your friendly neighbourhood
// Team Contact.
wgPatentURI: "",
maxTocLevel: 4,
preProcess: [ ] /*,
alternateFormats: [ {uri: "diff-20111214.html", label: "diff to previous version"} ],
*/
};
</script>
<style>
.sequence-diagram {
margin: auto;
}
</style>
</head>
<body>
<section id="abstract">
<p>
This document outlines a low-level API for registering <a>payment app</a>s,
requesting payments, and acknowledge payment requests using a polyfillable
browser API. There is also a higher-level ecommerce
<a href="https://github.com/w3c/webpayments/wiki/Checkout-API">Checkout API</a> that utilizes
this low-level API.
</p>
</section>
<section id="sotd">
<p>There are a number of ways that one may participate in the development of
this specification:</p>
<ul>
<li>Ad-hoc technical discussion primarily occurs on the public community mailing list:
<a href="http://lists.w3.org/Archives/Public/public-webpayments/">[email protected]</a></li>
<li><a href="http://payswarm/minutes/">Public Web Payments Community Group teleconferences</a>
are held on Wednesdays at 1600UTC every other week.</li>
<li>Specification bugs and issues should be reported in the
<a href="https://github.com/web-payments/web-payments.org/issues">issue tracker</a>
if you do not want to send an e-mail to the public-webpayments mailing
list.</li>
<li><a href="https://github.com/web-payments/web-payments.org/tree/master/">Source code</a>
for the specification can be found on Github.</li>
</ul>
</section>
<section class="informative">
<h1>Introduction</h1>
<p>
This API enables a web application to initiate payment for a product or
service by calling a <code>navigator.payment.request()</code> method. The
implementation of this feature is expected to be provided by a JavaScript
polyfill at first, and if deployment is successful, native browser
implementations will surface to enhance usability and transaction
security.
</p>
<section class="informative">
<h2>About this Document</h2>
<p>This document is a detailed specification for an application programming
interface (API) for initiating payments from within a browser
environment. The document is primarily intended for the following
audiences:</p>
<ul>
<li>Software developers who want to understand the design decisions and
algorithms behind the API.</li>
<li>Software developers who want to implement the API.</li>
</ul>
</section>
<section>
<h3>How this Document is Organized</h3>
<p>
This document is organized as follows:
</p>
<ul>
<li>
<a href="#terminology">Section 2: Terminology</a> defines basic terminology
used throughout this document.
</li>
<li>
<a href="#a-basic-purchase-flow">Section 3: A Basic Purchase Flow</a> describes
the basic payment flow at a high-level.
</li>
<li>
<a href="#detailed-flows">Section 4: Detailed Flows</a> describes each
flow provided by the browser API in detail.
</li>
<li>
<a href="#the-application-programming-interface">Section 5:
The Application Programming Interface</a> defines the browser API for
registering, initiating, and acknowledging payments.
</li>
</ul>
</section>
</section>
<section class="normative">
<h2>Terminology</h2>
<div data-include="//w3c.github.io/webpayments-ig/latest/common/terms.html"
data-oninclude="restrictReferences">
</div>
</section>
</section>
<section>
<h2>A Basic Purchase Flow</h2>
<p>
The diagram below outlines a basic payment flow with no errors. The basic
flow starts out with the <a>payee</a> offering the <a>payer</a> a
payment request. The <a>payer</a>'s user agent then helps them select a
<a>payment app</a> that is compatible with one of the <a>payment method</a>s
offered in the payment request. The <a>payment app</a> is responsible for
processing the request and returning a payment acknowledgement to the user
agent. How the <a>payment app</a> processes the request is an implementation
detail; it may be done locally or the request may be sent to a 3rd party for
processing. The flow ends with the user agent returning the payment
acknowledgement the payee for processing and, if no errors occurred, the
delivery of the good or service to the payer. There may be additional steps
following the receipt of a payment acknowledgement that the payee must perform
to execute the actual payment, such as communicating with their own
<a>payment service provider</a>, but these are specific to the
<a>payment method</a> used.
</p>
<script type='text/jumly+sequence'>
@found "Payee server (merchant)", ->
@message "display offer", "Payer browser (customer)", ->
@message "click 'Pay'", "Payee server (merchant)", ->
@reply "payment request", "Payer browser (customer)"
@message "select payment app", "Payment App", ->
@message "(optional) select payment instrument", "Payment App"
@alt
"3rd party NOT required": ->
@message "process request", "Payment App", ->
"3rd party required": ->
@message "payment request + (optional) payment instrument", "Payer payment processor (wallet)", ->
@message "process request", ->
@reply "payment response", "Payment App", ->
@reply "payment acknowledgement", "Payer browser (customer)", ->
@reply "payment acknowledgement", "Payee server (merchant)"
@message "process acknowledgement", ->
@message "deliver good/service", "Payer browser (customer)"
</script>
<ol class="algorithm">
<li>
The <a>payee</a>'s web page calls <code>navigator.payment.request(req)</code>.
</li>
<li>
The <a>payment mediator</a> scans the list of previously registered
<a>payment app</a>s and finds matches that support
<code>paymentMethod</code> in <code>acceptablePayment</code> in
<code>request</code>.
</li>
<li>
A <a>payment app</a> is selected by the payment mediator or the <a>payer</a>.
The process MAY consist of one or more of the following steps:
<ol class="algorithm">
<li>
If there is only one payment app that matches, that is automatically set
to the <em>selected <a>payment app</a></em>.
</li>
<li>
If there is a pre-existing preference set by the <a>payer</a> that narrows the
selection of the <a>payment app</a> to one match, the match is set to the
<em>selected <a>payment app</a></em>.
</li>
<li>
If there is more than one potential match, the <a>payer</a> is asked which
app they would like to use and the selection is set to the
<em>selected <a>payment app</a></em>.
</li>
<li>
If there are no matches, the <a>payer</a> is notified and may be taken to an
alternate flow where a matching <a>payment app</a> is acquired.
</li>
</ol>
</li>
<li>
If the <a>payment app</a> optionally requests the payer to select a
payment instrument.
</li>
<li>
If the <a>payment app</a> does not require the use of a
3rd party <a>payment service provider</a> or <a>payment processor</a>
(e.g. cryptocurrency), then the payment is processed locally.
</li>
<li>
If the <a>payment app</a> or <a>payment method</a> requires the use of a 3rd
party payer <a>payment service provider</a> or <a>payment processor</a> (e.g.
push-payment that uses a PayPal/Google Wallet-like instrument, ACH, ISO20022
style instrument):
<ol class="algorithm">
<li>
The <a>payment app</a> forwards the <code>request</code> and
<em>selected <a>payment instrument</a></em> (if previously
selected) to the 3rd party for approval.
</li>
<li>
The <a>payment processor</a>
</li>
</ol>
</li>
<li>
The <a>payment app</a> creates the payment acknowledgement, which includes any
potential errors that occurred, and passes it to the
<code>navigator.payment.acknowledge()</code> method. This
method sends the payment acknowledgement to the Web application that called
<code>navigator.payment.request()</code> by resolving the Promise returned
from that method.
</li>
<li>
If the <a>payment method</a> requires the payment flow to continue to a
3rd party payee <a>payment service provider</a> or <a>payment processor</a>
(e.g. pull-payment like non-EMV magstripe credit card with embossed PAN and
CVV2, or tokenized credit card):
<ol class="algorithm">
<li>
The payee's Web application forwards the appropriate information
(e.g. payment approval token) from the payment acknowledgement to their
<a>payment service provider</a> or <a>payment processor</a>, which executes
the payment.
</li>
</ol>
</li>
<li>
The payee delivers goods/services to the payer.
</li>
</ol>
</section>
<section>
<h2>Detailed Flows</h2>
<p class="issue">
Describe the payment flow in detail here using Adrian's flow diagram and Ian's
steps.
</p>
<section>
<h3>Payment App Registration</h3>
<ol>
<li>
The <a>payer</a> navigates to a <a>payment app</a> provider website
(like their bank) to sign up.</li>
</li>
<li>
During sign up, the <code>navigator.payment.registerApp()</code> call is made
to register a <a>payment app</a>:
<pre class="example highlight" title="Example of a payment app registration">
var app = {
id: 'https://bank.example.com/app/',
type: 'PaymentApp',
name: 'ExampleBank App',
image: 'https://bank.example.com/icons/app.png',
url: 'https://bank.example.com/app/',
supportedPaymentMethod: [
'https://w3id.org/payment-methods#Visa',
'https://w3id.org/payment-methods#MasterCard'
]
};
// register the <a>payment app</a> - at this point, the <a>payee interface</a>
// asks the person for approval to register the new <a>payment app</a>
var registration = navigator.payment.registerApp(app);
// called when the registration completes
registration.then(function(result) {
// app has been registered, do something
}).catch(function(err) {
// app has not been registered, do something
});
</pre>
</li>
</ol>
</section>
<section>
<h3>Processing a Payment Request</h3>
<p class="issue">
Additional parts of the Payment Request may be digitally signed (such as
payment method-specific data). For push-based payment methods, it is important
that the payer's payment service provider can verify that certain pieces of
information in the payment request have not been altered.
</p>
<p class="issue">
Can we make `type` a default attribute with a value of `PaymentRequest`? If
not, we may want to exclude it here and mention it in the extension section.
</p>
<ol>
<li>
The <a>payer</a> navigates to a <a>payee</a>'s website.</li>
<li>
The <a>payer</a> finds an item to buy and initiates the payment flow
(by clicking a button, swiping, speaking a voice command, etc.).
</li>
<li>
The <a>payee</a> application generates a signed payment request that
contains enough information to process the payment:
<pre class="example highlight" title="Example of a payment request">
var request = {
type: 'PaymentRequest',
description: 'Payment to ExampleMerch for widgets',
acceptablePayment: {
paymentMethod: 'https://w3id.org/payment-methods#Visa',
paymentAmount: {
amount: '4.35',
currency: 'USD'
}
}
};
// request payment and get a promise that will resolve to
// a payment acknowledgement
var payment = navigator.payment.request(request);
// called when the payment request has been processed
payment.then(function(acknowledgement) {
// payment request was at least partially processed, do something with the
// acknowledgement, such as check its approval code or forward an approval
// token to actually execute the payment
}).catch(function(err) {
// payment request failed
});
</pre>
</li>
</ol>
</section>
<section>
<h3>Generating a Payment Acknowledgement</h3>
<p class="issue">
Additional parts of the Payment Acknowledgment may be digitally signed (such as
payment method-specific data). For push-based payment methods, this is one
mechanism that a payee can use to verify that a payment was processed.
</p>
<p class="issue">
Can we make `type` a default attribute with a value of `PaymentAcknowledgement`?
If not, we may want to exclude it here and mention it in the extension section.
</p>
<ol>
<li>
The <a>payee</a>'s <a>payment app</a> receives a payment request (for a
Web-based payment app, this is done via
<code>navigator.payment.getPendingRequest</code>), obtains and authenticates
the payer's <a>payment instrument</a> information, and gets approval to proceed
with the payment from the <a>payer</a>.
</li>
<li>
Once approval has been provided by the <a>payer</a>, the payment
acknowledgement is transmitted to the <a>payee</a>'s web application.
</li>
<li>
The <a>payment app</a> or a <a>payment service processor</a> it works with
generates a payment acknowledgement message
that contains enough information to verify that the payment
request has completed successfully (or has failed). The <a>payment app</a>
resolves the Promise that the <a>payer</a>'s web application is waiting on
by calling <code>navigator.payment.acknowledge</code> and passing the
payment acknowledgement message.
<pre class="example highlight" title="Example of a payment acknowledgement">
// Web-based payment app gets request via `getPendingRequest`
navigator.payment.getPendingRequest().then(function(paymentRequest) {
// process payment request ...
// generate acknowledgement
var acknowledgement = {
type: 'PaymentAcknowledgement',
description: 'Payment to ExampleMerch for widgets',
payment: {
paymentMethod: 'https://w3id.org/payment-methods#Visa',
status: 'authorized',
approvalCode: '10025AB',
paymentAmount: {
amount: '4.35',
currency: 'USD'
}
}
};
// acknowledge that the payment was processed
navigator.payment.acknowledge(acknowledgement);
});
</pre>
</li>
</ol>
</section>
</section>
<section>
<h2>The Application Programming Interface</h2>
<p class="issue">
This browser-based API is provided for convenience purposes only. The
existence of the API is absolutely not a requirement for the basic operation
of the Web Payments protocol. No browser API is necessary in order for a
Web application to initiate payment and receive an acknowledgement of the
result of the payment.
</p>
<p>This API provides a clean mechanism that enables developers to
initiate payments in a user agent.
A conformant user agent MUST implement the entirety of the
following API.</p>
<section>
<h3>Object Interfaces</h3>
<section>
<h4>PaymentApplication</h4>
<pre class="idl">
interface PaymentApplication {
attribute DOMString id;
attribute (DOMString or Sequence <DOMString>) type;
attribute DOMString name;
attribute DOMString image;
attribute DOMString url;
attribute (DOMString or Sequence <DOMString>) supportedPaymentMethod;
};
</pre>
<p>
A <a><code>PaymentApplication</code></a> describes a <a>payment app</a>,
primarily for the purposes of registration.
</p>
<dl>
<dt><code>id</code></dt>
<dd>
A URL identifier for the <a>payment app</a> that will be used by the
implementation to differentiate one payment application from another. For
example: <code>"https://bank.example.com/generic-brand-rewards-app"</code>
</dd>
<dt><code>type</code></dt>
<dd>
A type identifier associated with the object, typically set to
<code>"PaymentApplication"</code>. The set of available types MAY be extended
in the future to add things like <code>"OfflineApplication"</code> to identify
payment applications that are capable of running in an offline mode.
</dd>
<dt><code>name</code></dt>
<dd>
Human readable text that will be used to identify the payment application.
This text MAY be displayed to the <a>payer</a> in a <a>payment app</a>
selection interface. For example, <code>"Red Bank Visa Card"</code>.
</dd>
<dt><code>image</code></dt>
<dd>
A URL to a brand image or logo associated of the payment application. This
image MAY be displayed to the <a>payer</a> in a <a>payment app</a> selection
interface. For example:
<code>"https://bank.example.com/generic-brand-rewards-app.png"</code>
</dd>
<dt><code>url</code></dt>
<dd>
The target URL for the <a>PaymentRequest</a>. This URL should be capable of
processing a pending payment request, generating a payment acknowledgement,
and responding with the final result. For example:
<code>"https://bank.example.com/web-payments"</code>
</dd>
<dt><code>supportedPaymentMethod</code></dt>
<dd>
One or more payment method identifiers, which may be simple strings or URLs.
For example, <code>"VisaLegacy"</code> or
<code>"https://newnetwork.example.com/methods/SuperCard"</code>
</dd>
</dl>
<pre class="example highlight">
var app = {
id: 'https://bank.example.com/generic-brand-rewards-app',
type: 'PaymentApplication',
name: 'ExampleBank App',
image: 'https://bank.example.com/icons/app.png',
url: 'https://bank.example.com/web-payments/',
supportedPaymentMethod: [
'VisaLegacy', 'VisaTokenized', 'https://newnetwork.example.com/methods/SuperCard'
]
};
</pre>
</section>
<section>
<h4>PaymentRequest</h4>
<pre class="idl">
interface PaymentRequest {
attribute (DOMString or Sequence <DOMString>) type;
attribute DOMString description;
attribute (AcceptablePayment or Sequence <AcceptablePayment>) acceptablePayment;
};
</pre>
<p>
A <a><code>PaymentRequest</code></a> expresses a payment that is requested
by a <a>payee</a>.
</p>
<dl>
<dt><code>type</code></dt>
<dd>
An type identifier associated with the object, typically set to
<code>"PaymentRequest"</code>. The set of available types MAY be extended
in the future to add things like <code>"SubscriptionRequest"</code> to identify
payment requests that may have some recurring quality to them.
</dd>
<dt><code>description</code></dt>
<dd>
A human-readable description of the reason the payment request was initiated.
This text MAY be displayed to the <a>payer</a> in a payment interface.
For example, <code>"Payment for widgets from Acme Anvil Emporium"</code>.
</dd>
<dt><code>acceptablePayment</code></dt>
<dd>
One or more ways that the <a>payee</a> can accept payment for the request.
</dd>
</dl>
<pre class="example highlight">
var request = {
type: 'PaymentRequest',
description: 'Payment to ExampleMerch for widgets',
acceptablePayment: {
paymentMethod: 'VisaTokenized',
paymentAmount: {
amount: '4.35',
currency: 'USD'
}
}
};
</pre>
<pre class="idl">
interface AcceptablePayment {
attribute (DOMString or Sequence <DOMString>) paymentMethod;
attribute FinancialAmount paymentAmount;
};
</pre>
<p>
An <a><code>AcceptablePayment</code></a> expresses the terms under which a
payment request may be fulfilled.
</p>
<dl>
<dt><code>paymentMethod</code></dt>
<dd>
One or more payment method identifiers, which may be simple strings or URLs.
For example, <code>"VisaLegacy"</code> or
<code>"https://newnetwork.example.com/methods/SuperCard"</code>
</dd>
<dt><code>paymentAmount</code></dt>
<dd>
The amount of financial value requested by the <a>payee</a>.
</dd>
</dl>
<pre class="idl">
interface FinancialAmount {
attribute DOMString amount;
attribute DOMString currency;
};
</pre>
<p>
A <a><code>FinancialAmount</code></a> interface is used to express a scalar
financial value.
</p>
<dl>
<dt><code><dfn>currency</dfn></code></dt>
<dd>
<code>currency</code> is a string containing a three-character alphaneumeric
code for the currency as defined by [[!ISO4217]] or a URL for a currency
identifier. For example, <code>"USD"</code> for US Dollars or
<code>"https://example.com/currencies/experimental-XYZ"</code> for a new
experimental currency.
</dd>
<dt><code><dfn>amount</dfn></code></dt>
<dd>
A string containing the decimal monetary value. The string MUST use a single
U+002E FULL STOP character as the decimal separator. The string MUST begin
with a single U+002D HYPHEN-MINUS character if the value is negative. All
other characters must be characters in the range U+0030 DIGIT ZERO (0) to
U+0039 DIGIT NINE (9).
<div class="note">
The string should match the regular expression
<code>^-?[0-9]+(\.[0-9]+)?$</code>.
</div>
</dd>
</dl>
<p>The following example shows how to represent $55.00 US Dollars.</p>
<pre class="example highlight">
{
amount: "55.00"
currency: "USD",
}
</pre>
</section>
<section>
<h4>PaymentAcknowledgement</h4>
<pre class="idl">
interface PaymentAcknowledgement {
attribute (DOMString or Sequence <DOMString>) type;
attribute DOMString description;
attribute Payment payment;
};
</pre>
<p>
A <a><code>PaymentAcknowledgement</code></a> expresses the result of processing
a payment request.
</p>
<dl>
<dt><code>type</code></dt>
<dd>
An type identifier associated with the object, typically set to
<code>"PaymentAcknowledgement"</code>. The set of available types MAY be
extended in the future to add things like <code>Receipt</code> to identify
acknowledgements that contain receipt information.
</dd>
<dt><code>description</code></dt>
<dd>
Human readable text that will be used to identify what the payment was for.
This text MAY be displayed to the <a>payer</a>. For example,
<code>"Payment to ExampleMerch for widgets"</code>.
</dd>
<dt><code>payment</code></dt>
<dd>
Information such as the payment method used and the payment amount. Payment
method specific information, such as the status of the payment, may also be
included. The presence and meaning of this extra information is dependent on
the payment method. The payment information may be used by the <a>payee</a> or
their associated <a>payment service provider</a> to, for example, finalize a
payment or display information to the <a>payer</a>.
</dd>
</dl>
<pre class="example highlight">
var acknowledgement = {
type: 'PaymentAcknowledgement',
description: 'Payment to ExampleMerch for widgets',
payment: {
paymentMethod: 'https://w3id.org/payment-methods#Visa',
status: 'authorized',
approvalCode: '10025AB',
paymentAmount: {
amount: '4.35',
currency: 'USD'
}
}
};
</pre>
</section>
<section>
<h4>Payment</h4>
<pre class="idl">
interface Payment {
attribute DOMString paymentMethod;
attribute FinancialAmount paymentAmount;
};
</pre>
<p>
A <a><code>Payment</code></a> expresses details of a payment such as the
payment method used and the payment amount.
</p>
<dl>
<dt><code>paymentMethod</code></dt>
<dd>
One or more payment method identifiers, which may be simple strings or URLs.
For example, <code>"VisaLegacy"</code> or
<code>"https://newnetwork.example.com/methods/SuperCard"</code>
</dd>
<dt><code>paymentAmount</code></dt>
<dd>
The <code>FinancialAmount</code> associated with the payment.
</dd>
</dl>
<pre class="example highlight">
var payment = {
paymentMethod: 'https://w3id.org/payment-methods#Visa',
paymentAmount: {
amount: '4.35',
currency: 'USD'
}
};
</pre>
</section>
</section>
<section>
<h3>NavigatorPayment</h3>
<p>Navigator Payment is the name of the high-level programming
interface that Web developers use to initiate payments. If MUST be
made available via the <code>navigator.payment</code> object.</p>
<dl title="interface NavigatorPayment" class="idl">
<dt>Promise registerApp()</dt>
<dd>
<p>
Typically called by a <a>payment service provider</a> to register a
<a>payment app</a> for later use during a payment request.
</p>
<dl class="parameters">
<dt>PaymentApplication app</dt>
<dd>
A description of the <a>payment app</a>.
</dd>
<dt>object options</dt>
<dd>
A set of options to use when registering the payment app.
</dd>
</dl>
</dd>
<dt>Promise request()</dt>
<dd>
<p>
Typically called by a <a>payee</a> to initiate a payment.
</p>
<dl class="parameters">
<dt>PaymentRequest request</dt>
<dd>
Typically called by a <a>payee</a> to request a payment.
</dd>
<dt>object options</dt>
<dd>
A set of options to use when requesting payment.
</dd>
</dl>
</dd>
<dt>Promise getPendingRequest()</dt>
<dd>
<p>
Called by a <a>payment app</a> to get the pending payment request. The returned
Promise resolves to the request.
</p>
</dd>
<dt>void acknowledge()</dt>
<dd>
<p>
Typically called by a <a>payment app</a> to acknowledge that a payment request
has been processed.
</p>
<dl class="parameters">
<dt>PaymentAcknowledgement acknowledgement</dt>
<dd>
Describes the result of a payment request.
</dd>
<dt>object options</dt>
<dd>
A set of options to use when processing the payment acknowledgement.
</dd>
</dl>
</dd>
</dl>
</section> <!-- end of NavigatorPayment -->
</section>
<section>
<h2>Extensibility</h2>
<p>
In general, the WebIDL descriptions provided in this specification outline
the specific interfaces, properties, and values that an implementation MAY
depend on. It is expected that other properties and values will be stored in
objects that implement the various interfaces in this specification (e.g.
<a>PaymentApplication</a>, <a>PaymentRequest</a>,
<a>PaymentAcknowledgement</a>, etc.). While this specification does
not suggest a single extension mechanism, it does anticipate
extensibility. To that end,
</p>
<ul>
<li>
Implementations MUST preserve unrecognized properties and their
associated values.
</li>
<li>
Another specification [LINK_TBD] explains how to extend the
parameters used with this API using JSON-LD.
</li>
</ul>
<p class="issue">
The Working Group seeks feedback from the Web community on that
specification and how well it furthers interoperability needs in the
payments ecosystem. To provide feedback, see the
<a href="#h-sotd">status section</a> above.
</p>
</section>
<!-- section>
<h3>Extending Messages Using JSON-LD</h3>
<p>
The interfaces in this specification (e.g.
<a>PaymentApplication</a>, <a>PaymentRequest</a>,
<a>PaymentAcknowledgement</a>, etc.)
are designed to optionally accept JSON-LD objects. In
order to ensure a JSON-LD object can be passed to the API properly, the
following transformation MUST be applied:
</p>
<ol>
<li>
If a <code>@context</code> property does not exist, add one and assign the
value <code>"https://w3id.org/payments/v1"</code> to it. If a
<code>@context</code> does exist, ensure its value is
<code>"https://w3id.org/payments/v1"</code>. If its value does not match,
perform JSON-LD compaction on the object using that context. This MUST be done
as there is no requirement for API implementations to perform any JSON-LD
processing.
</li>
<li>
Pass the resulting object to the API.
</li>
</ol>
<p>
Any application receiving an interface from the API can similarly interpret
it as a JSON-LD object. In this case, the application MUST ensure that if the
<code>@context</code> property exists and that the value associated is
<code>"https://w3id.org/payments/v1"</code>. If the <code>@context</code>
does not exist, it MUST be assumed that the object has a <code>@context</code>
property with the value of <code>"https://w3id.org/payments/v1"</code>.
</p>
<p class="issue">
Can we simplify the above `@context` check (when receiving an interface from
the API) so it's unnecessary by adding an optional `@context` property with
a required value of "https://w3id.org/payments/v1" to the appropriate
interfaces?
</p>
<section-->
<section>
<h2>Security Considerations</h2>
<section>
<h3>Message Integrity</h3>
<p class="issue">
This section has not been discussed by the WG and is kept here as
a placeholder for a larger discussion around ensuring
message integrity.
</p>
<p>
It is possible to sign any JSON-LD based message by using
Linked Data Signatures, like so:
</p>
<pre class="example highlight" title="Example of a signed payment acknowledgement">
// generate acknowledgement
var acknowledgement = {
type: 'PaymentAcknowledgement',
description: 'Payment to ExampleMerch for widgets',
payment: {
paymentMethod: 'https://w3id.org/payment-methods#Visa',
status: 'authorized',
approvalCode: '10025AB',
paymentAmount: {
amount: '4.35',
currency: 'USD'
}
},
signature: {
type: 'LinkedDataSignature2015',
creator: 'https://payment-service-provider.example.com/keys/12',
created: '2015-09-23T20:23:15Z',
nonce: '239807882930744352',
signatureValue: 'm4NTIyZTOGQzNGVkMzVkZ...OWM32NjIgoYzI43Q3ODIy='
}
};
</pre>
</section>
</section>
<section class="appendix informative">
<h2>Messages Addendum</h2>
<p>
Multiple types of <a>payment app</a>s, each supporting multiple types of
<a>payment method</a>s and <a>payment instrument</a>s may be supported using
this approach:
</p>
<pre class="example highlight" title="Example of Bitcoin App registration">
var app = {
id: 'https://bitcoin-wallet.example.com/app/',
type: 'PaymentApp',
name: 'Example Bitcoin App',
image: 'https://bitcoin-wallet.example.com/icons/app.png',
url: 'https://bitcoin-wallet.example.com/app/',
supportedPaymentMethod: [
'https://w3id.org/payment-methods#Bitcoin'
]
};
// register the <a>payment app</a> - at this point, the <a>payee interface</a>
// asks the person for approval to register the new <a>payment app</a>
var registration = navigator.payment.registerApp(app);
// called when the registration completes
registration.then(function(result) {
// app has been registered, do something
}).catch(function(err) {
// app has not been registered, do something
});