Skip to content

Commit 6f2565b

Browse files
danyaomarcoscaceres
authored andcommitted
Add PaymentRequest.prototype.hasEnrolledInstrument() (#833)
1 parent 72de3ba commit 6f2565b

File tree

1 file changed

+124
-60
lines changed

1 file changed

+124
-60
lines changed

index.html

Lines changed: 124 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,8 @@ <h2>
616616
Promise&lt;void&gt; abort();
617617
[NewObject]
618618
Promise&lt;boolean&gt; canMakePayment();
619+
[NewObject]
620+
Promise&lt;boolean&gt; hasEnrolledInstrument();
619621

620622
readonly attribute DOMString id;
621623
readonly attribute PaymentAddress? shippingAddress;
@@ -1312,56 +1314,39 @@ <h2>
13121314
<h2>
13131315
<dfn>canMakePayment()</dfn> method
13141316
</h2>
1317+
<div class="note" title="canMakePayment() vs hasEnrolledInstrument()">
1318+
<p>
1319+
The <a>canMakePayment()</a> method can be used by the developer to
1320+
determine if the <a>user agent</a> has support for one of the
1321+
desired <a>payment methods</a>. See <a href="#canMakePayment-privacy">
1322+
privacy considerations</a>.
1323+
</p>
1324+
<p>
1325+
A true result from <a>canMakePayment()</a> does not imply that the
1326+
user has a provisioned instrument ready for payment. For that, use
1327+
<a>hasEnrolledInstrument()</a> instead.
1328+
</p>
1329+
</div>
1330+
<p data-tests="payment-request-canmakepayment-method.https.html">
1331+
The <a>canMakePayment()</a> method MUST run the <a>can make payment
1332+
algorithm</a> with |checkForInstruments| set to false.
1333+
</p>
1334+
</section>
1335+
<section data-dfn-for="PaymentRequest" data-link-for="PaymentRequest">
1336+
<h2>
1337+
<dfn>hasEnrolledInstrument()</dfn> method
1338+
</h2>
13151339
<p class="note">
1316-
The <a>canMakePayment()</a> method can be used by the developer to
1317-
determine if the <a>PaymentRequest</a> object can be used to make a
1318-
payment, before they call <a>show()</a>. It returns a <a>Promise</a>
1319-
that will be fulfilled with true if the <a>user agent</a> supports
1320-
any of the desired <a>payment methods</a> supplied to the
1321-
<a>PaymentRequest</a> constructor, and false if none are supported.
1322-
If the method is called too often, the user agent might instead
1323-
return <a>a promise rejected with</a> a "<a>NotAllowedError</a>"
1324-
<a>DOMException</a>, at its discretion.
1340+
The <a>hasEnrolledInstrument()</a> method can be used by the developer
1341+
to determine if the <a>user agent</a> has support for one of the
1342+
desired <a>payment methods</a> and if a <a>payment handler</a> has an
1343+
instrument ready for payment. See
1344+
<a href="#canmakepayment-protections"></a>.
13251345
</p>
1326-
<p data-tests="payment-request-canmakepayment-method.https.html">
1327-
The <a>canMakePayment()</a> method MUST act as follows:
1346+
<p data-tests="payment-request-hasenrolledinstrument-method.https.html">
1347+
The <a>hasEnrolledInstrument()</a> method MUST run the <a>can make
1348+
payment algorithm</a> with |checkForInstruments| set to true.
13281349
</p>
1329-
<ol class="algorithm">
1330-
<li>Let |request| be the <a>PaymentRequest</a> object on which the
1331-
method was called.
1332-
</li>
1333-
<li>If |request|.<a>[[\state]]</a> is not "<a>created</a>", then
1334-
return <a>a promise rejected with</a> an "<a>InvalidStateError</a>"
1335-
<a>DOMException</a>.
1336-
</li>
1337-
<li data-tests=
1338-
"payment-request/payment-request-canmakepayment-method-protection.https.html">
1339-
Optionally, at the <a>top-level browsing context</a>'s discretion,
1340-
return <a>a promise rejected with</a> a "<a>NotAllowedError</a>" <a>
1341-
DOMException</a>. As described in section <a href=
1342-
"#canmakepayment-protections"></a>, the user agent may limit the
1343-
rate at which a page can call <a>canMakePayment()</a>.
1344-
</li>
1345-
<li>Let |hasHandlerPromise| be <a>a new promise</a>.
1346-
</li>
1347-
<li>Return |hasHandlerPromise|, and perform the remaining steps <a>in
1348-
parallel</a>.
1349-
</li>
1350-
<li>For each |paymentMethod| tuple in
1351-
|request|.<a>[[\serializedMethodData]]</a>:
1352-
<ol>
1353-
<li>Let |identifier| be the first element in the |paymentMethod|
1354-
tuple.
1355-
</li>
1356-
<li>If the user agent has a <a>payment handler</a> that supports
1357-
handling payment requests for |identifier|, resolve
1358-
|hasHandlerPromise| with true and terminate this algorithm.
1359-
</li>
1360-
</ol>
1361-
</li>
1362-
<li>Resolve |hasHandlerPromise| with false.
1363-
</li>
1364-
</ol>
13651350
</section>
13661351
<section data-dfn-for="PaymentRequest" data-link-for="PaymentRequest">
13671352
<h2>
@@ -4216,6 +4201,90 @@ <h2>
42164201
</li>
42174202
</ol>
42184203
</section>
4204+
<section>
4205+
<h2>
4206+
Can make payment algorithm
4207+
</h2>
4208+
<p>
4209+
The <dfn>can make payment algorithm</dfn> checks if the <a>user
4210+
agent</a> supports making payment with the <a>payment methods</a> with
4211+
which the <a>PaymentRequest</a> was constructed. It takes a boolean
4212+
argument, |checkForInstruments|, that specifies whether the
4213+
algorithm checks for existence of enrolled instruments in addition to
4214+
supporting a <a>payment method</a>.
4215+
</p>
4216+
<ol class="algorithm">
4217+
<li>Let |request| be the <a>PaymentRequest</a> object on
4218+
which the method was called.
4219+
</li>
4220+
<li>If |request|.<a>[[\state]]</a> is not "<a>created</a>",
4221+
then return <a>a promise rejected with</a> an
4222+
"<a>InvalidStateError</a>" <a>DOMException</a>.
4223+
</li>
4224+
<li data-tests=
4225+
"payment-request-hasenrolledinstrument-method-protection.https.html, payment-request-canmakepayment-method-protection.https.html">
4226+
Optionally, at the <a>top-level browsing context</a>'s discretion,
4227+
return <a>a promise rejected with</a> a "<a>NotAllowedError</a>"
4228+
<a>DOMException</a>.
4229+
<p class="note" data-link-for="PaymentRequest">
4230+
This allows user agents to apply heuristics to detect and prevent
4231+
abuse of the calling method for fingerprinting purposes, such as
4232+
creating <a>PaymentRequest</a> objects with a variety of supported
4233+
<a>payment methods</a> and triggering the <a>can make payment
4234+
algorithm</a> on them one after the other. For example, a user
4235+
agent may restrict the number of successful calls that can be made
4236+
based on the <a>top-level browsing context</a> or the time period
4237+
in which those calls were made.
4238+
</p>
4239+
</li>
4240+
<li>Let |hasHandlerPromise| be <a>a new promise</a>.
4241+
</li>
4242+
<li>Return |hasHandlerPromise|, and perform the remaining steps
4243+
<a>in parallel</a>.
4244+
</li>
4245+
<li>For each |paymentMethod| tuple in |request|.
4246+
<a>[[\serializedMethodData]]</a>:
4247+
<ol>
4248+
<li>Let |identifier| be the first element in the |paymentMethod|
4249+
tuple.
4250+
</li>
4251+
<li>If |checkForInstruments| is false, and the user agent has a
4252+
<a>payment handler</a> that supports handling payment requests for
4253+
|identifier|, resolve |hasHandlerPromise| with true and terminate
4254+
this algorithm.
4255+
</li>
4256+
<li>If |checkForInstruments| is true:
4257+
<ol>
4258+
<li>Let |data| be the result of <a data-cite=
4259+
"ECMASCRIPT#sec-json.parse">JSON-parsing</a> the second
4260+
element in the |paymentMethod| tuple.
4261+
</li>
4262+
<li>If required by the specification that defines the
4263+
|identifier|, then <a>convert</a> |data| to an IDL value.
4264+
Otherwise, <a>convert</a> to <a>object</a>.
4265+
</li>
4266+
<li>Let |handlers| be a <a>list</a> of registered
4267+
<a>payment handlers</a> that are authorized and can handle
4268+
payment request for |identifier|.
4269+
</li>
4270+
<li>For each |handler| in |handlers|:
4271+
<ol>
4272+
<li>Let |hasEnrolledInstrument| be the result of running
4273+
|handler|'s <a>steps to check if a payment can be made</a>
4274+
with |data|.
4275+
</li>
4276+
<li>If |hasEnrolledInstrument| is true, resolve
4277+
|hasHandlerPromise| with true and terminate this algorithm.
4278+
</li>
4279+
</ol>
4280+
</li>
4281+
</ol>
4282+
</ol>
4283+
</li>
4284+
<li>Resolve |hasHandlerPromise| with false.
4285+
</li>
4286+
</ol>
4287+
</section>
42194288
<section>
42204289
<h2>
42214290
Shipping address changed algorithm
@@ -5206,24 +5275,19 @@ <h2 id="canmakepayment-protections">
52065275
<code>canMakePayment()</code> protections
52075276
</h2>
52085277
<p data-link-for="PaymentRequest">
5209-
The <a>canMakePayment()</a> method enables the payee to determine —
5210-
before calling <a>show()</a> — whether the user agent knows of any
5211-
<a>payment handlers</a> available to the user that support the
5212-
<a>payment methods</a> provided to the <a>PaymentRequest</a>
5213-
<a data-lt="PaymentRequest.PaymentRequest()">constructor</a>. If no
5214-
<a>payment handlers</a> support the <a>payment methods</a>, this
5215-
enables the payee to fall back to a legacy checkout experience. Because
5216-
this method shares some potentially unique information with the payee,
5217-
user agents are expected to protect the user from abuse of the method.
5218-
For example, user agents can reduce user fingerprinting by:
5278+
The <a>canMakePayment()</a> and <a>hasEnrolledInstrument()</a> methods
5279+
have the potential to expose user information that could be abused for
5280+
fingerprinting purposes. User agents are expected to protect the user
5281+
from abuse of the method. For example, user agents can reduce user
5282+
fingerprinting by:
52195283
</p>
52205284
<ul data-link-for="PaymentRequest">
52215285
<li>Allowing the user to configure the user agent to turn off
5222-
<a>canMakePayment()</a>, which would return <a>a promise rejected
5286+
<a>canMakePayment()</a> and <a>hasEnrolledInstrument()</a>, which would
5287+
return <a>a promise rejected
52235288
with</a> a "<a>NotAllowedError</a>" <a>DOMException</a>.
52245289
</li>
5225-
<li>Rate-limiting the frequency of calls to <a>canMakePayment()</a>
5226-
with different parameters.
5290+
<li>Rate-limiting the frequency of calls with different parameters.
52275291
</li>
52285292
</ul>
52295293
<p>

0 commit comments

Comments
 (0)