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

Add userHint to PaymentManager #206

Merged
merged 5 commits into from
Sep 5, 2017
Merged

Add userHint to PaymentManager #206

merged 5 commits into from
Sep 5, 2017

Conversation

ianbjacobs
Copy link
Contributor

Based on a discussion with @adamroach and @rsolomakhin, I have written this pull request
to address issue #173 .

The idea is that the payment handler provides a user hint (e.g., "**** 1234") that can complement
name and icon information associated with the payment handler. Although the user agent
could compute hint information like this (e.g., based on N payment instruments managed by the payment handler), this attribute gives more control to the payment handler.

I did not attempt to specify exactly how the string should be used, or combined with the name/logo of the payment handler.

This user hint string does not affect user interface behavior. Specifically, it does not mean that a particular payment instrument will be invoked automatically when the user selects the payment handler.

Ian

Copy link
Collaborator

@rsolomakhin rsolomakhin left a comment

Choose a reason for hiding this comment

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

Perfect!

@dlongley
Copy link
Contributor

I actually don't quite understand this addition.

I already consider the PaymentInstruments to really be "user hints", where their name would be something like ****1234. Maybe my confusion stems from adding it onto the PaymentManager interface? There's only one of these "user hints" for all "PaymentInstruments" that are set by the handler?

@rsolomakhin
Copy link
Collaborator

Chrome does not plan to display individual payment instruments. We plan to display only the payment app name, e.g.:

BobPay [PAY]

It would be useful for the user to see some kind of hint about the state of the payment app, which cannot be expressed in the payment app title, which is statically pulled from the web app manifest. For example, a browser may display this hint like so:

BobPay (Visa **** 1234) [PAY]

This hint does not have to be one of the instruments. It can be the logged in username, for example:

BobPay (user@example.com) [PAY]

@dlongley
Copy link
Contributor

@rsolomakhin,

Can you provide some of the rationale for not displaying individual payment instruments? They provide the actual mechanism for checking whether or not a payment handler matches anyway. Furthermore, passing along the payment instrument key selected (again, I think we should probably be calling these "user hints", not "payment instruments" but that's perhaps off topic) allows the payment handler to use that more granular choice to potentially save the user extra clicks.

I've already implemented this in a polyfill and it works well. I think deviating from it is an indication that perhaps we've got some redesign to do with what "payment instruments" actually mean in the API. We may need to revisit that anyway.

@rsolomakhin
Copy link
Collaborator

@dlongley

We are focusing on mobile UI with limited screen real estate. This is our current plan and we may in the future display the individual instruments.

I believe @adamroach has indicated that Mozilla will show the provided instruments, so there's no need to redesign the payment instrument concept, IMHO.

@dlongley
Copy link
Contributor

dlongley commented Aug 25, 2017

Managing "PaymentInstruments" is going to a somewhat complex matter for Payment Handler implementers if they really want a great experience for their users that have multiple devices. For example, whenever the user registers a new "payment instrument" on a payment handler's website, the website is going to do something like send a push notification to wake up service workers on other devices to do the same registration.

There's going to be significant thought and effort put into setting up icons, names, and doing maintenance on these things -- so if they aren't going to be used, we should really reconsider the approach entirely -- or at least understand a little bit more about what it takes to actually implement this stuff. I'm just saying I'm concerned with the direction.

Just imagine now that I'm setting a "userHint" of "***1234" that Chrome is showing ... and then Mozilla is showing the same user hint PLUS all of the instruments, some of which aren't "***1234". That will be quite confusing. How will Mozilla know whether or not they should show "userHint"? What if some people just want to do "user@example.com" for the userHint like you said?

@ianbjacobs
Copy link
Contributor Author

@dlongley asked:

"Can you provide some of the rationale for not displaying individual payment instruments?"

You might mean different things in that question:

a) Why wouldn't a browser display all the payment instruments managed by a payment handler? Google colleagues have said they do not plan do to that, and the reasons include (on mobile) screen real estate. Other browser might display all instruments, or might do so on desktop by not mobile.

b) Why not modify the "name" of one of the payment instruments as a user hint? That could work, but the question is "which one would be the best?" and this proposal suggests that the payment app may have information on what would be useful.

Having recently spoken with Mozilla and Google, here are the user experiences I expect when I click on a payment handler, either:

  1. Launch the payment handler and let the user choose 1 payment instrument from among multiple ones. The payment handler itself might support rapid selection of certain payment instruments.

  2. Show all the payment instruments and let the user select each one directly.

Both of those behaviors (and possibly others) are supported by the current specification.
The "userHint" proposal does not alter those possibilities. @rsolomakhin mentioned some
user experience with shipping addresses that suggested that a user hint could help
people select payment apps.

Ian

@rsolomakhin
Copy link
Collaborator

How will Mozilla know whether or not they should show "userHint"?

I'm sure they can create nifty heuristic, e.g., "if the hint looks like e-mail, show it." Regardless, the spec should not concern itself with UI details, correct?

@ianbjacobs
Copy link
Contributor Author

@dlongley,

When you refer to payment instrument names/icons and say "so if they aren't going to be used"
it makes me think that there is confusion about the proposal.

When the user agent provides access to a payment instrument, it will display that instrument using the name/icons provided by the payment handler.

The question is: when the instruments are NOT shown, and only the "top level" name and icon for the payment handler is shown, will that suffice to encourage the user to select that payment handler? @rsolomakhin's suggest is that a hint could raise the confidence of the user to choose that payment app.

@dlongley
Copy link
Contributor

dlongley commented Aug 25, 2017

@rsolomakhin,

Regardless, the spec should not concern itself with UI details, correct?

It shouldn't -- but I don't consider this a detail. I think it's a confusing semantic. We don't have to get into how it will be shown, but developers should know the semantics behind the thing. And right now, I think those are too ill-defined.

You've already got essentially a bunch of hints (+constraints) -- which we've called "Payment Instruments" ... and now we're adding another top-level "hint". If we're not clear to developers what should be put there and when it will be shown -- it's kind of a big deal. If payment handler developers put the same information into two different places and then we don't tell user agent devs what should trigger when it will be used, there's confusion -- and that will translate into user confusion and people thinking it's the payment handler's fault.

One way to remedy this is to say that the user agent should either use payment instruments as hints OR use userHint. That sends a clear message to the developer on what makes sense to put in userHint. Other similar choices could be made, but some kind of constraint should be put here if we're adding this thing, IMO.

@dlongley
Copy link
Contributor

@ianbjacobs,

The question is: when the instruments are NOT shown, and only the "top level" name and icon for the payment handler is shown, will that suffice to encourage the user to select that payment handler? @rsolomakhin's suggest is that a hint could raise the confidence of the user to choose that payment app.

Then include, in the semantics of userHint, that it will only be used if payment instrument names and icons are NOT shown (like you said). That tells the payment handler developer what kind of values should be used for "userHint" -- and gives them a guarantee that if they use those values their users won't get a bad experience.

@rsolomakhin
Copy link
Collaborator

I'm ok to add "user agent should use either PaymentInstruments or userHint" to the spec, as long as it's a "should", not a "must." Does that help?

@dlongley
Copy link
Contributor

@rsolomakhin,

I'm ok to add "user agent should use either PaymentInstruments or userHint" to the spec, as long as it's a "should", not a "must." Does that help?

Yes, that helps. I don't know if an explanation for the SHOULD should be in there as well -- essentially indicating that there's a developer expectation that it's an either-or.

@dlongley
Copy link
Contributor

dlongley commented Aug 25, 2017

Please consider this situation:

  1. User visits a site that does a payment request for bitcoin.
  2. User sees ("VISA ***1234" Ultimate Wallet) as a payment choice to pay with bitcoin.
  3. User thinks what?

So there's no easy way for "Ultimate Wallet" to participate in the ecosystem (and have decent hints) without splitting their wallet up.

@rsolomakhin
Copy link
Collaborator

If your payment app can handle bitcoin, arguably your hint should not exclude that possibility. I do not claim to know all the answers. A/B testing would be useful here. Here's a few ideas to test out:

Ultimate Wallet (VISA **** 1234 and 3 more methods) [PAY]

Ultimate Wallet (4 instruments) [PAY]

Ultimate Wallet (cards and bitcoin) [PAY]

Ultimate Wallet (user@example.com) [PAY]

@dlongley
Copy link
Contributor

@rsolomakhin, seems like you could just generate that information without "userHint" from the payment instruments if you want to save space on mobile.

@dlongley
Copy link
Contributor

dlongley commented Aug 25, 2017

The second you start defining an algorithm or "best practice" that developers should be using for "userHint" (based on payment instrument information) is the same second the user agent should just be doing it for them so they don't mess it up.

@rsolomakhin
Copy link
Collaborator

A user agent that does not show instruments would not know which payment instrument to use for generating a hint, because it knows neither which instrument was selected last time nor the ordering of the instruments in the payment handler. Would you be open to providing this information to the user agent?

@dlongley
Copy link
Contributor

@rsolomakhin,

A user agent that does not show instruments would not know which payment instrument to use for generating a hint, because it knows neither which instrument was selected last time nor the ordering of the instruments in the payment handler.

It would know how to do "4 instruments" based on the fact that only 4 of the 16 that Ultimate Wallet provides match the payment method.

Would you be open to providing this information to the user agent?

I'm fine with providing some kind of order of preference in the PaymentInstrument data. The whole point of that data, in my view, is to expose valid choices to the user in the order they would prefer.

@rsolomakhin
Copy link
Collaborator

Something like this?

dictionary KeyPaymentInstrument : PaymentInstrument {
    required DOMString             key;
};
interface PaymentInstruments {
    Promise<boolean>             delete(DOMString instrumentKey);
    Promise<PaymentInstrument>   get(DOMString instrumentKey);
    Promise<sequence<DOMString>> keys();
    Promise<boolean>             has(DOMString instrumentKey);
    Promise<void>                update(DOMString instrumentKey,
                                        PaymentInstrument details);
    Promise<void>                set(sequence<KeyPaymentInstrument> details);
    Promise<void>                clear();
};

@dlongley
Copy link
Contributor

@rsolomakhin,

That's one way to do it, though set seems like it may be confusing or frustrating to use. For example, what happens here:

  1. I call set with three KeyPaymentInstruments [A, B, C].
  2. I call set with KeyPaymentInstruments [D].

What order is D in? First or last (or something else)? I assume we'd define it to be first or last -- but then if I want to do something else I have to fetch A, B, and C and insert them all at once along with D which is a bit messy, nevermind the potential race conditions.

An insert API could be used instead:

interface PaymentInstruments {
  ...
  Promise<void>  insert(KeyPaymentInstrument details,
                        DOMString? instrumentKeyBefore);
};

@rsolomakhin
Copy link
Collaborator

That seems even more confusing. How about using the insertion order?

A Map object iterates its elements in insertion order.

@dlongley
Copy link
Contributor

dlongley commented Aug 25, 2017

@rsolomakhin,

That seems even more confusing.

Why?

How about using the insertion order?

That's what the above insert proposal does, with the option to be more specific with a key to insert after. We could make that an "index" instead of a key if that's better.

@rsolomakhin
Copy link
Collaborator

Why?

I'm not sure how familiar the folks are with the "insert before" paradigm. If do go with it, I'd prefer to augment the current set() method instead:

interface PaymentInstruments {
  ...
  Promise<void> set(DOMString instrumentKey,
                    PaymentInstrument details,
                    DOMString? instrumentKeyBefore);
};

If the instrumentKeyBefore is not provided, then details is inserted at the end of the ordered map.

@dlongley
Copy link
Contributor

dlongley commented Aug 25, 2017

@rsolomakhin,

I think the approach of adding an insertKeyBefore parameter is potentially ok, though talking about the PaymentInstruments interface this like its an ordered Map is a bit strange to me. I can see now how it nearly maps to one, but I didn't implement this that way in the polyfill, I used a row for each PaymentInstrument handlerUrl + key + details in IndexedDB. I'm thinking about this being edited both in service workers (via push notifications) and in front of the user on a website (maybe on more than 1 tab), potentially concurrently. I'm seeing it as a database.

If I strip all of that away and think of it as a single Map sitting in one browser context ...that results in a totally different perspective. I can see now how you can think of this as a single Map instance that is built up all at once or cleared and rebuilt entirely at once. I wasn't thinking of it happening like that at all -- but much more piecemeal. The flows for making changes to this container are potentially very different in my mind.

@ianbjacobs
Copy link
Contributor Author

We discussed this at the 29 August Payment Apps task force call [1], and there was support for userHint as specified (rather than an ordering solution). Some considerations:

  • An important goal was that the payment handler, not the user agent, determine the exact string.
  • Ordering imposed additional complexity beyond what the problem statement demanded

Rouslan is going to experiment with userHint so we will not merge before then.

Ian

[1] https://www.w3.org/2017/08/29-apps-minutes.html#item05

index.html Outdated
@@ -529,6 +529,7 @@
interface PaymentManager {
[SameObject] readonly attribute PaymentInstruments instruments;
[Exposed=Window] static Promise&lt;PermissionState&gt; requestPermission();
DOMString userHint;
Copy link
Member

Choose a reason for hiding this comment

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

I think this should be attribute because this is not dictionary type.
attribute DOMString userHint

Also, if you don't mind, isn't it better to move this attribute to PaymentInstruments?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @romandev,

Thank you for help with the WebIDL. The reason I did not move it to payment instruments is that it did not seem to be part of the "standard" map-like interface (get, set, keys, etc.).

I will at least fix the "attribute" part and we can continue to discuss whether it belongs on a different interface.

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

Successfully merging this pull request may close these issues.

4 participants