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

What is the extensibility mechanism for the payment request and response messages? #146

Closed
adrianhopebailie opened this issue Apr 20, 2016 · 9 comments

Comments

@adrianhopebailie
Copy link
Collaborator

Forked from #40

The concept of "messages" has been raised in numerous issues and PRs but not clearly defined.

There is a requirement for websites to be able to construct a payment request message (a JSON-serialized object) that is passed to the API and passed, unchanged by the browser, to the payment app that processes the payment request.

Likewise, there is a requirement for payment apps to be able to construct a payment response message (a JSON-serialized object) that is passed back unchanged to the website that made the original request.

The need for JSON serialization of these messages is driven by a requirement to pass them across process and network boundaries. Until such a mechanism exists there will be no standard for interfacing with payment apps which implies they will either be built into the browser or their integration will be entirely proprietary. Put differently, the current API spec has no conformance criteria imposed on browsers to support third-party payment apps.

It is unclear how the current API would cater for this requirement to pass an unaltered payment request message on to the payment app as the current design does not allow for a complete message to even be passed to the API.

There is a proposal to address this #133 BUT this issue assumes that this will be resolved (either through that or some other proposal) and that what is being discussed here is how this message can be extended.

In #40 @triblondon (in his review for the TAG) made the observation:

AFAICT, the merchant doesn't know about payment apps, only payment methods, so it's hard to see how custom data not tied to a payment method could be useful.

This suggest that it's not necessary (and would be very difficult) to facilitate extensibility of the whole payment request message.

However, there was also a previous resolution by the group at w3c/webpayments#83 to include the following text in the API spec once a companion document was available describing how the API parameters could be extended:

The JSON-LD Payment Extension specification (linked to the document) explains how to extend the parameters used with this API using JSON-LD.

This suggests that the requirement is to define a standardized format for the payment request message which maps directly to the WebIDL definition of one of the input parameters to the API and includes extension points for the custom payment method data.

@dlongley
Copy link

dlongley commented Apr 20, 2016

This suggest that it's not necessary (and would be very difficult) to facilitate extensibility of the whole payment request message.

Completely disagree. Not every payment app has to take advantage of extra features provided via extensibility in a payment request message. Merchants that know about extra features may use them -- and payment apps that also use them may take advantage of them, leading to differentiation and better experiences for users. Merchants needn't know which payment app, specifically, is being used -- the idea is to augment payment request messages with additional machine readable information that any payment app may utilize in creative ways to their and their users' benefit.

This suggests that the requirement is to define a standardized format for the payment request message which maps directly to the WebIDL definition of one of the input parameters to the API and includes extension points for the custom payment method data.

+1

@adrianhopebailie
Copy link
Collaborator Author

@dlongley my point, in agreeing with what was said by @triblondon, was that the parts that need to be extensible are the parts that contain custom data per payment method.

As this is a browser API we need to define the basic structure of the request in WebIDL which is not extensible so we will not have an easy way to allow extensions of that entire message.

Instead, we will define a message with some fixed aspects to it's schema but extension points, probably in the areas where custom payment method data is provided, where the WebIDL simply defines the schema as object or similar and this can take any form as defined by some external extensibility mechanism.

The expected behavior of the browser will be to simply pass this on to the payment app as provided.

Do we think there is a need for some other extension point, outside the custom payment method data? If so I'd be interested to hear the rationale and see a proposal for how this might be acheived.

@dlongley
Copy link

@adrianhopebailie,

I would prefer a design where the payment request message is passed, untouched, through the browser API. The payment request message is the set of information that encompasses all data required to initiate a payment via a payment app and any additional machine-readable information that could enhance the user's experience via a payment app, such as offers, links to product information, taxation rules, links to other offers should additional choices be made, options to add donations to third parties, rebates, whatever anyone could possibly conceive of.

The user agent needn't concern itself with just about all of that. All it needs to do is ensure that it helps the user select a payment app that can process that payment request message using the one of the acceptable methods listed within it.

Now, if we want to create a browser API that has to repeat that most basic information outside of the payment request so that we can meet some Web IDL restrictions, then so be it. However, this should not place an undue burden on the ability for people to innovate and extend the payment request message itself in any way. When I hear about people "adding extension points", what I hear is "let's restrict how you can extend these messages to whatever this small group of people can imagine." That's a mistake. I don't know what patterns people will come up with in the future or what cleverness will arise. I certainly don't want to place restrictions on the evolution of this ecosystem because of Web IDL.

Instead, define the parts of the message that we do know about and say what the conformance is. Everything else, leave untouched. We need to figure out the best way to accomplish this with the user agent API, given its restrictions, in consultation with user agent implementers. However, those implementers need to understand that the vision for this ecosystem is larger than a user agent UI that improves the checkout experience. Decisions regarding the shape of the browser API should not impede that vision nor, do I think, should they ignore the fact a design that put payments first allows us to have a more consistent model for how things like Payment Apps work -- regardless of the variety of APIs we provide to allow people to interface with them.

The approach that the WPCG API took was to do just that -- and to let the user agent just read particular parts of the payment request message. Instead, we've opted to pull those parts that the user agent needs out of the message and pass them, on their own, into the API. I understand that these are the only parts that are important to the user agent, and that user agents may want to receive them in a particular way.

However, the user agent is just playing one role here -- there is much more going on than just making a request through the browser, there is everything that happens at the endpoints and in between as well. I don't want any restrictions placed on the data that is passed to Payment Apps other than what is minimally required for interoperability. I also would like us to recognize that we can have a much more powerful, interoperable design if we ensure that the messages that Payment Apps receive always follow the same format, regardless of how they get there. Sure, a user agent may be responsible for getting a message to a Payment App, when someone is using a browser on the Web. But the message could also get there another way! (e.g. HTTP).

Let's design Payment Apps so that they receive payment request messages and then return payment response messages. Then we can say how a user agent will hand one over. If we want to make it such that user agents don't read those messages at all to find totals, acceptable payment methods, or other information -- but rather we want to pull that information out and repeat it in the browser API, so be it. I don't think that's the best way to do it, but I'll accept it. But let's make sure we pass the payment request message, untouched, along side that information. And let's define what that message is in another spec -- that all APIs can depend on.

I do not agree with:

  • Chopping the message up into pieces because that's preferable (and is it really?) for one particular API
  • Making it hard to bundle everything together and digitally-sign it for integrity/non-repudiation
  • Completely punting on finding a unified vision and integration of messages with multiple APIs
  • Starting from a point of divergence with the various APIs instead of convergence and only diverting when necessary

@msporny
Copy link
Member

msporny commented Apr 20, 2016

@adrianhopebailie wrote:

As this is a browser API we need to define the basic structure of the request in WebIDL which is not extensible so we will not have an easy way to allow extensions of that entire message.

That's not accurate at all. We have a proposal that demonstrates that not only is it easy to define a basic message format and express it in WebIDL, but it's also easy to enable extensions of entire payments messages while also providing strict validation and conformance rules (if we want to do that):

http://manu.sporny.org/tmp/wpwg/webpayments/proposals/core-messages/

and a pending pull request for this mechanism:

w3c/webpayments#119

@adrianhopebailie
Copy link
Collaborator Author

@msporny, I think you misinterpreted my comment or perhaps I misunderstand your intent.

As someone that is not intimately familiar with how a browser processes input I have some questions. Assuming a browser API is defined that accepts the following message (described using WebIDL):

interface HelloApi {
  void sayHello(HelloWorld message);
};

dictionary HelloWorld {
  required DOMString title;
  required DOMString message;
};

And a website calls that API with the following code:

//Assume hello is an instance of HelloApi...
hello.sayHello({
  title: "Hello",
  message: "World",
  otherThing: "!"
});

I would expect the browser to throw an error, no? If so, how do we define a fully extensible message in WebIDL when its not possible to allow for extra top-level members?

Do we simply accept a parameter of type object and describe the data model loosely in the messages spec? I think that the browser vendors have already said that's not a workable solution.

@dlongley
Copy link

@adrianhopebailie,

I would expect the browser to throw an error, no?

I don't think it does. I think it accepts the data, however, it makes a copy of it using the Web IDL defined fields, which will cause otherThing to be dropped.

If so, how do we define a fully extensible message in WebIDL when its not possible to allow for extra top-level members?

You could use interfaces instead of dictionaries, but that seems like a hack to me. I think Web IDL may need an extension to cover this in a clean way. If the browser API needs Web IDL here, let's not muck up the rest of the ecosystem system because it has this bad restriction. When we have to use Web IDL, fine, but let's make sure we limit the damage.

Here's what we can do:

var paymentRequestMessage = {
  acceptablePaymentMethods: [...],
  otherThing: ...
};

var pr = new PaymentRequest(
  paymentRequestMessage.acceptablePaymentMethods,
  {items: ...}, // user-agent only "details"
  {...}, // user-agent only "options"
  paymentRequestMessage);

This way you construct the payment request message according to the messages spec, then you feed the bits that the browser API needs broken out per Web IDL into its PaymentRequest constructor, and then pass the whole message into the data parameter (which should just become the main message parameter). This seems like it would deal with the Web IDL issue and allow the API to consume the same messages that other APIs would consume -- and pass them straight through to the Payment App.

@halindrome
Copy link
Contributor

Fascinating. Are you saying that there are (some) user agents / processors that actually use WebIDL as a way of creating their implementation? That shocks me.

Regardless, we REALLY should have a way to say "and anything else" or "and anything else that matches a pattern".

I note that WebIDL 1 is in CR review right now. Good time to propose a change.

@AxelNennker
Copy link
Contributor

Yes. (Some) user agents (can) use WebIDL to create utility methods and stubs for implementations.
The major reason is security because it is non trivial to securely pass non-simple types to privileged code or to receive them from privileged code like the payment mediator.

@adrianhopebailie
Copy link
Collaborator Author

In the context of the PaymentRequest API this is being addressed in the payment method specific data.

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

No branches or pull requests

5 participants