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

Just-in-time payment handler install #240

Closed
rsolomakhin opened this issue Nov 29, 2017 · 25 comments
Closed

Just-in-time payment handler install #240

rsolomakhin opened this issue Nov 29, 2017 · 25 comments

Comments

@rsolomakhin
Copy link
Collaborator

rsolomakhin commented Nov 29, 2017

To help bootstrapping new payment handlers into the ecosystem, we at Chrome would like to experiment with installation of the payment handler at the time of payment. The use case would work as follows for a user that does not have 'https://bobpay.xyz/pay' payment handler installed, for example.

  1. The merchant calls new PaymentRequest([{supportedMethods: 'https://bobpay.xyz/pay'}], shoppingCart).show();
  2. The browser checks the HTTP headers from http://bobpay.xyz/pay to verify that it supports just-in-time installation of a payment handler. This would be indicated by a header that we need to name something. If the header is absent, the merchant would receive NotSupportedError.
  3. Otherwise, if the header is present, the browser shows the payment sheet with a prompt Install a payment app from https://bobpay.xyz/pay? [ ALLOW ] [ DENY ].
  4. If the user taps [ DENY ], the merchant would receive NotSupportedError.
  5. Otherwise, if the user taps [ ALLOW ], the browser would open a popup window with a URL that instructs the payment app via a hash parameter (#) to install itself and prepare for payment. For example, https://bobpay.xyz/pay#install-payment-handler-and-prepare-for-payment-from-origin=merchant-shop.com. The payment handler should show an "Initializing..." screen on this page. The payment handler communicates its own readiness to process payments via the hash parameter as well.
  6. If the payment handler navigates to https://bobpay.xyz/pay#fail, then the installation failed. The browser should give the user the opportunity to install a different payment app, if possible.
  7. Otherwise, if the payment handler navigates to https://bobpay.xyz/pay#success, then the installation succeeded. At this point, the browser fires the 'paymentrequest' event in the newly installed service worker with scope https://bobpay.xyz/pay and payment proceeds as defined in the rest of the spec. The service worker should communicate with the existing popup window via the service worker clients API to smoothly transition into showing the normal payment flow.

Is this something that's interesting to other implementers as well? If so, we are wondering what, if anything, should be added to this specification. I suspect that the following items would need be defined somewhere.

  • An HTTP header for https://bobpay.xyz/pay to indicate that it supports just-in-time install.
  • #install-payment-handler-and-prepare-for-payment-from-origin=
  • #fail
  • #success

cc: @romandev @marcoscaceres @gogerald @anthonyvd

@rsolomakhin
Copy link
Collaborator Author

cc: @DurgaTheHutt

@jenan-stripe
Copy link

Hey @rsolomakhin! How would this work with canMakePayment?

@adrianhopebailie
Copy link
Contributor

I assume that the HEAD call would happen before calling .show() so that the potentially many supported payment methods can all be queried before the user is shown the sheet?

@rsolomakhin
Copy link
Collaborator Author

@jenan-stripe: I can see two approaches to paymentRequest.canMakePayment() with some benefits and drawbacks to both. We can figure this out together.

  • Option 1: If the app is not installed, paymentRequest.canMakePayment() returns false, even if the app supports just-in-time install.
  • Option 2: The HTTP header of the payment method may also specify what the browser should do for paymentRequest.canMakePayment(). The browser will read this information at the same time as checking whether the payment method supports a just-in-time install of a payment handler.

Does the group have any preference?

@adrianhopebailie: You're correct, the HEAD call would happen upon new PaymentRequest(methods, cart), which is before .show(). The merchant may call .show() at any moment, but the browser has control of UX. If .show() happens before all HTTP headers have been read, I expect the browser to show a "Loading..." spinner sheet until all queries complete.

@rsolomakhin
Copy link
Collaborator Author

@madmath suggested that we use the HTTP Link header to indicate both whether just-in-time install is supported and the URL of the page that can perform the install. For example:

Link: </payments/just-in-time-install.html>; rel="default-payment-handler-installer-page"

@jenan-stripe
Copy link

jenan-stripe commented Nov 30, 2017

Without splitting canMakePayment and having an explicit canMakePaymentWithActiveInstrument, I'd be in favor of Option 1.

@ianbjacobs
Copy link
Contributor

@rsolomakhin,

I would lean towards option 1.

Ian

@rsolomakhin
Copy link
Collaborator Author

Thank you for the feedabck, @jenan-stripe and @ianbjacobs.

@rsolomakhin
Copy link
Collaborator Author

FYI, @mhahmadi suggests to place the payment handler installer URL in the payment method manifest, which would reduce the number of Link headers we're adding to HTTP. This does indeed sound more elegant.

  • HTTP Link header already exists:
Link </payments/payment-method-manifest.json>; rel="payment-method-manifest"
  • Add "default_payment_handler_installer_page" field to the payment method manifest:
{
  "default_payment_handler_installer_page": "/payments/just-in-time-install.html",
  "default_applications": ["https://bobpay.xyz/pay/app1.json"],
  "supported_origins": ["https://partner1.com", "https://partner2.com"]
}

@romandev
Copy link
Member

romandev commented Dec 4, 2017

@rsolomakhin, I totally support your idea. I have some questions.

Otherwise, if the header is present, the browser shows the payment sheet with a prompt Install a payment app from https://bobpay.xyz/pay? [ ALLOW ] [ DENY ].

Does it provide only if there is only one item of supportedMethods array?
If two methods are not installed as follows, how it works?

new PaymentRequest([{
    supportedMethods: 'https://bobpay.xyz/pay'
  }, {
    supportedMethods: 'https://hellopay.xyz/pay'
  }], shoppingCart).show();

BTW, is there any reason to have to pop up window here?
You already said that you'd like to install SW and instruments data silently without any user consent(in #239 issue). And then the user will have the opportunity to allow or deny the payment handlers when PaymentRequest.show() is called.
Then, if merchant site writes code as follows, the SW and instruments data are registered silently and users can just decided whether allow the payment handler or not.

<!-- In merchant.com -->
<iframe src="https://hellopay.com/register" style="display: none"></iframe>

<!-- In hellopay.com -->
<script>
navigator.serviceWorker.register("payment-handler.js");
const reg = navigator.serviceWorker.ready;
reg.paymentManager.paymentInstruments.set(...);
</script>

WDYT?

@rsolomakhin
Copy link
Collaborator Author

@romandev, in case of multiple payment methods, each one can have an install prompt in the payment sheet. This would not be a popup, but would be in place of the payment app selection. Here's an ASCII mock up:

_________________________________________________________________________
| Total:                                                      USD $1.00 |
|_______________________________________________________________________|
| Payment method:                                                       |
| Install payment app from https://bobpay.xyz/pay?   [ ALLOW ] [ DENY ] |
| Install payment app from https://hellopay.xyz/pay? [ ALLOW ] [ DENY ] |
|_______________________________________________________________________|
|                                                    [ PAY ] [ CANCEL ] |
|_______________________________________________________________________|

@rsolomakhin
Copy link
Collaborator Author

TL;DR: No changes needed in this spec.

After discussion this morning, we have decided to not add anything to the payment handler spec. @marcoscaceres recommended to indicate success and failure by redirecting to a success or a failure page. The browser can detect HTTP status codes 2xx or 5xx to understand the status. Also, there's no need to pass in parameters into the install page, because the "PaymentRequestEvent" will contain all of the information necessary.

@rsolomakhin
Copy link
Collaborator Author

@domenic: Do you think it would be better to add "install_url" to webapp manifest instead of adding "default_payment_handler_installer_page" to the payment method manifest? It kind of makes sense for "install_url" to be a parallel to the "start_url" in the webapp manifest. Would be interesting to hear your thoughts.

@domenic
Copy link

domenic commented Jan 2, 2018

I think this comes down to the fact that one PMM can point to multiple WAMs. And you derive the payment apps from the WAM, not the PMM; the PMM just points you to one or more WAMs. So it makes more sense to associate the URL with the WAM.

I'd call it something slightly more specific like "payment_handler_install_url" or "payment_handler_url" probably, but yeah, that's the direction I would go.

@rsolomakhin
Copy link
Collaborator Author

Should I send a pull request to the WAM spec?

@domenic
Copy link

domenic commented Jan 2, 2018

Seems reasonable to me! @marcoscaceres can probably help with details, e.g. bikeshedding on the name.

@ianbjacobs
Copy link
Contributor

@rsolomakhin,

I am thinking about where to document this (eventually). My current best guess is the Payment Method Good Practice wiki [1]. Does that seem correct to you?

Ian

[1] https://github.com/w3c/payment-request-info/wiki/PaymentMethodPractice

@rsolomakhin
Copy link
Collaborator Author

That should work, @ianbjacobs.

The pull request: w3c/manifest#634

@gogerald
Copy link
Contributor

gogerald commented Jan 4, 2018

What about putting the payment handler installation url in related_applications in the web app manifest like below:
[{
"platform": "web",
"url": "https://bobpay.xyz/",
}]
This way we no need to introduce any specific field for payment handler.

@domenic
Copy link

domenic commented Jan 4, 2018

related_applications is specifically for non-web applications related to the web application that's already available at the main URL specified by the manifest.

@gogerald
Copy link
Contributor

gogerald commented Jan 4, 2018

what is the main URL here? the 'start_url' or the url to find the web app manifest in the payment method manifest?

@domenic
Copy link

domenic commented Jan 4, 2018

start_url, or the inferred default (see https://w3c.github.io/manifest/#dfn-processing-the-start_url-member), is indeed the URL of the web application.

@gogerald
Copy link
Contributor

gogerald commented Jan 4, 2018

Then do we need extra url for payment handler if we consider payment handler is the web app.

I was looking the example in this web page (https://developer.mozilla.org/en-US/docs/Web/Manifest), there is platform:”web” in the related application, but without url which might because that manifest is supposed to embedded in a web page instead of be fetched directly as we do here.

@domenic
Copy link

domenic commented Jan 4, 2018

Thanks, I've fixed that wiki page to no longer include that misleading entry.

@rsolomakhin
Copy link
Collaborator Author

Thank you, all, for your input. It appears that we do not need to make any changes to the spec, because this is an implementer (browser) optimization. With that, let's close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants