Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] showPaymentUI() method #325

Open
wants to merge 1 commit into
base: gh-pages
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,7 @@ <h2>
readonly attribute DOMString instrumentKey;
readonly attribute boolean requestBillingAddress;
Promise&lt;WindowClient?&gt; openWindow(USVString url);
Promise&lt;PaymentHandlerResponse?&gt; showPaymentUI(USVString url, optional object? data = null);

This comment was marked as spam.

This comment was marked as spam.

Promise&lt;PaymentMethodChangeResponse?&gt; changePaymentMethod(DOMString methodName, optional object? methodDetails = null);
void respondWith(Promise&lt;PaymentHandlerResponse&gt;handlerResponsePromise);
};
Expand Down Expand Up @@ -1301,6 +1302,16 @@ <h2>
user. When called, it runs the <a>open window algorithm</a>.
</p>
</section>
<section>
<h2>
<dfn>showPaymentUI()</dfn> method
</h2>
<p>
This method is used by the payment handler to show a custom UI to
the user. When called, it runs the <a>show payment UI
algorithm</a>.
</p>
</section>
<section>
<h2>
<dfn data-lt=
Expand Down Expand Up @@ -1643,6 +1654,44 @@ <h2>
<a>PaymentRequest</a>. A single <a>payment handler</a> SHOULD NOT be
allowed to open more than one client window using this method.
</p>
<section data-dfn-for="PaymentHandlerContainer" data-link-for=
"PaymentHandlerContainer">
<h2>
<dfn>PaymentHandlerContainer</dfn> interface
</h2>
<pre class="idl">
[SecureContxt, Exposed=Window]
interface PaymentHandlerContainer {
readonly attribute object? data;
void respondWith(PaymentHandlerResponse response);
};

partial interface Navigator {
[SecureContext, SameObject] readonly attribute PaymentHandlerContainer paymentHandler;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If both navigator.paymentHandler and navigator.paymentHandler.data are not promises, then the browser has to initialize these objects very early in page load, which can affect page loading performance. Can we make at least one of these into a promise, so that the browser can lazy-instantiate them after the page has loaded?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

paymentHandler.data should be a Promise, IMO. This seemed to work well with the Web Payment CG's original API design where the "payment request" could be retrieved via getPendingRequest:

const paymentRequest = await navigator.payment.getPendingRequest();
// ... handle payment request, generate acknowledgement

// acknowledge payment request handled
navigator.payment.acknowledge(acknowledgement);

https://github.com/Spec-Ops/payment-polyfill#getting-a-pending-payment-request

Here it would be:

const data = await navigator.paymentHandler.data;
// ... handle payment request, generate response

// respond to payment request
navigator.paymentHandler.respondWith(response);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I agree with this. I'll update this soon.

};
</pre>
<section>
<h2>
<dfn>data</dfn> attribute
</h2>
<p>
The <a>data</a> attribute returns
<a>[[\paymentHandlerRequestData]]</a>.
</p>
</section>
<section>
<h2>
<dfn>respondWith()</dfn> method
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does navigator.paymentHandler.respondWith(response) need its own algorithm?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method simply passes the response data to SW thread. So, I thought that the method's explanation is enough.

</h2>
<p>
This method is used by the associated payment handler window to
provide a <a>PaymentHandlerResponse</a> to the associated payment
handler. When called, this method sets the <a>user agent</a>'s
<a>payment handler response data</a> to the <var>response</var>
argument.
</p>
</section>
</section>
<section>
<h2>
<dfn>Open Window Algorithm</dfn>
Expand Down Expand Up @@ -1731,6 +1780,79 @@ <h2>
</li>
</ol>
</section>
<section>
<h2>
<dfn>Show Payment UI Algorithm</dfn>
</h2>
<ol class="algorithm">
<li>Let <var>url</var> be the result of <a data-cite=
"!URL#concept-url-parser">parsing</a> the <var>url</var> argument.
</li>
<li>If the url parsing throws an exception, return a <a>Promise</a>
rejected with that exception.
</li>
<li>If <var>url</var> is <code>about:blank</code>, return a
<a>Promise</a> rejected with a <a>TypeError</a>.
</li>
<li>If <var>url</var>'s origin is not the same as the <a>service
worker</a>'s origin associated with the payment handler, return a <a>
Promise</a> rejected with a "<a>NotAllowedError</a>"
<a>DOMException</a>.
</li>
<li>If this algorithm is not <a data-cite=
"!HTML#triggered-by-user-activation">triggered by user
activation</a>, return a <a>Promise</a> rejected with a
"<a>NotAllowedError</a>" <a>DOMException</a>.
</li>
<li>If the <a>user agent</a>'s <a>payment handler's UI is showing</a>
boolean is true, return a <a>Promise</a> with an
"<a>InvalidStateError</a>" <a>DOMException</a> and abort these steps.
</li>
<li>Set the <a>user agent</a>'s <dfn>payment handler's UI is
showing</dfn> boolean to true.
</li>
<li>Set the <a>user agent</a>'s <dfn>payment handler response
data</dfn> object to <code>undefined</code>.
</li>
<li>Let <var>promise</var> be a new <a>Promise</a>.
</li>
<li>Return <var>promise</var> and perform the remaining steps in
parallel:
</li>
<ol>
<li>Let <var>newContext</var> be a new <a data-cite=
"!HTML#top-level-browsing-context">top-level browsing context</a>.
</li>
<li>
<a data-cite="!HTML#navigate">Navigate</a> <var>newContext</var>
to <var>url</var>, with exceptions enabled and replacement
enabled.
</li>
<li>If the navigation throws an exception, reject
<var>promise</var> with that exception and abort these steps.
</li>
<li>If the origin of <var>newContext</var> is not the same as the
<a>service worker</a> origin associated with the payment handler,
return a <var>promise</var> with a "<a>NotAllowedError</a>"
<a>DOMException</a> and abort these steps.
</li>
<li>Let <var>window</var> be a new <var>newContext</var>'s
<a data-cite="!HTML#active-document">active document</a>'s
<a data-cite="!HTML#relevant-settings-object">relevant global
object</a>.
</li>
<li>Set <var>window</var>.<dfn>[[\paymentHandlerRequestData]]</dfn>
to the <var>data</var> argument.
</li>
<li>Wait until <var>window</var>.<a data-cite=
"!HTML#dom-window-closed">closed</a> is true.
</li>
<li>Resolve <var>promise</var> with the <a>user agent</a>'s
<a>payment handler response data</a> object.
</li>
</ol>
</ol>
</section>
<section id="post-example" class="informative">
<h2>
Example of handling the <a>PaymentRequestEvent</a>
Expand Down