Closed marcoscaceres closed 7 years ago
Basically, the missing piece is being able to "hydrate" a form with a payment request (or more generally with form data).
Ideally:
// if paymentResponse is or inherits from FormData
paymentForm.fillWith(paymentResponse);
//Then we end up in form nirvana
if( form.checkValidity() ) {
form.submit();
} else {
// fix form issues....
}
Does it make sense to have a form that accepts Android Pay fields, for example?
On 24 Nov. 2016, at 10:17 pm, Rouslan Solomakhin notifications@github.com wrote:
Does it make sense to have a form that accepts Android Pay fields, for example?
Sure, I don't see any problem. Thats just a feature of the payment method. If you look at that example you can see the result just gets copied and POSTed for verification. It's consequential that it's JSON. But my argument stands: the payment response is just form data.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.
I think I'm a bit confused by what "form data" means in this context. Does anything that can go into a JSON object constitute "form data"?
I don't think it's valid to compare this with "UAs that don't support this API" and their need to fall back to forms. By falling back to forms, they're limiting the payment methods that are available. For example, native-only forms of payment (e.g. Android Pay, Samsung Pay, etc) wouldn't be available. Put another way, there is no "pure form" equivalent of these forms of payment. As we get into more complicated forms of payment, this will continue to hold true.
Doesn't this also require having a Form for every form of payment that you support? That seems quite unfortunate to me.
I am with @zkoch on this. I'm not sure I see the use case here beyond card payments.
I'd expect that for websites that are posting the PaymentResponse to a server they'll simply POST the JSON in the body of a new request. I think this issue is implying that POSTing application/json
is less desirable than POSTing application/x-www-form-urlencoded
data?
@zkoch, wrote:
I think I'm a bit confused by what "form data" means in this context. Does anything that can go into a JSON object constitute "form data"?
Sorry for not being clear, form data means this API: https://xhr.spec.whatwg.org/#formdata
I don't think it's valid to compare this with "UAs that don't support this API" and their need to fall back to forms.
Consider, Firefox will support this on Desktop, but we don't have any plans right now to support this on mobile... let's say, for arguments sake we don't ship on mobile until 2019 or later. I don't know what Chrome's plans are to support this on Desktop - but I imagine your desktop users will need a fallback too.
From that perspective, it's totally valid to say that a UA won't support this API, as I know for a fact that we don't plan to ship this on mobile.
By falling back to forms, they're limiting the payment methods that are available.
Yes, which is fine. It's what you want, really because at the very least one can support "basic card". Or just manual form input.
For example, native-only forms of payment (e.g. Android Pay, Samsung Pay, etc) wouldn't be available.
They won't be available on desktop anyway (at least, not yet). We will be lucky if we even get ApplePay on Mac in non-Apple browsers. Or we will be dependent on plugins.
There are millions of people who will still need to pay the old fashion way on Desktop - but they too should have a great experience.
Put another way, there is no "pure form" equivalent of these forms of payment. As we get into more complicated forms of payment, this will continue to hold true.
I haven't seen any evidence of this yet - because at the end of the day, the payment response is either a token+some name/value pairs or the details of a credit card (both of which require the web app to verify those by POSTing that form data somewhere).
I'm probably missing something tho. Can you help me understand where it gets more complicated than the above?
===
@adrianhopebailie, wrote:
I am with @zkoch on this. I'm not sure I see the use case here beyond card payments.
A lot of people will continue to pay with cards. Cards are not going away. Their usage may actually increase (specially with dynamically-generated, time-bombed, exact value cards). For example: https://twitter.com/producthunt/status/802897292390866945
I'd expect that for websites that are posting the PaymentResponse to a server they'll simply POST the JSON in the body of a new request. I think this issue is implying that POSTing application/json is less desirable than POSTing application/x-www-form-urlencoded data?
This has limited relationship to how it's actually POSTed - and it's not about giving preference to one format over another. FormData
is just a representation of the collection of the data as it relates to a form. That data can then be transformed to JSON or whatever.
Thus, FormData is a primitive to represent the data. However, we would need to find a way to transform FormData into JSON by working with @annevk and friends from HTML.
If I understand the argument for this correctly then I think it would be more appropriate for the payment method specific details
from the response to be FormData only if the payment method is basic card.
i.e. We can spec this in the Basic Card Payment Method Spec
if(paymentResponse.methodName == "basic-card"){
cardPaymentForm.fillWith(paymentResponse.details);
if( cardPaymentForm.checkValidity() ) {
cardPaymentForm.submit();
} else {
// fix form issues....
}
}
@adrianhopebailie, can you help me understand why it doesn't apply to all types? Basically, I'm wondering why ".details" can be collapsed into FormData
?
Look at the API:
interface PaymentResponse {
serializer = {attribute};
readonly attribute DOMString methodName;
readonly attribute object details;
readonly attribute PaymentAddress? shippingAddress;
readonly attribute DOMString? shippingOption;
readonly attribute DOMString? payerName;
readonly attribute DOMString? payerEmail;
readonly attribute DOMString? payerPhone;
Promise<void> complete(optional PaymentComplete result = "unknown");
};
All the attributes there can just be collapsed into FormData to the point where all you need is:
interface PaymentResponse : FormData {
Promise<void> complete(optional PaymentComplete result = "unknown");
};
@adrianhopebailie see also the long form proposal.
It's fairly easy for a developer to construct a FormData
object and fill it with whatever they want including taking data from a PaymentResponse
. I've not personally heard feedback before that this is needed and I'm reluctant to make this change at this stage for what might be a small convenience for a few developers that can be handled with a JavaScript function.
It's fairly easy for a developer to construct a FormData object and fill it with whatever they want including taking data from a PaymentResponse.
Absolutely, but that's kinda missing the point. We've spec'ed a crazy complex object hierarchy that could be collapsed down into a multi-map structure (FormData or the like). Additionally, the interface we've created has fairly limited serialization options (just JSON) and it's not very extensible.
I've not personally heard feedback before that this is needed and I'm reluctant to make this change at this stage for what might be a small convenience for a few developers that can be handled with a JavaScript function.
This is not really about a small convenience. Consider the three main things the current API doesn't address (or maybe you can tell me how it addresses the following):
form
s.form
validation - via form.checkValidity()). form
to be submit()
ted somewhere. Note again the the above applies in all cases where a browser does not support the API - where a form needs to always be used as a fallback (basically 99% of all websites rely on form
s to achieve this today). There's almost 2 decades of form validation machinery in browsers and in libraries which we are effectively not making use of: this strikes me as a bit of an oversight in the design of this API, particularly into how it integrates with the existing web.
If we do choose to keep the current complex object hierarchy, we should perhaps consider instead adding .json()
and .formData()
methods instead?
Marcos, it seems as if you're getting caught up on the idea of "web sites currently use forms to collect credit cards, so we should optimize for that." This is what requestAutocomplete was, and we decided that was insufficient for our needs. Chrome was also the only browser to implement, even after a number of years.
A few quick answers to your questions:
Existing web store fronts that are already using forms.
Yep, and they will continue to have to for the foreseeable future. At least, until we can rid the world of basic card payments. :) This itself is not a strong case for making forms the backbone of every payment response, the responses of which can be very varied and quite complex.
Validation of the Payment Response (where 1 already has form validation - via form.checkValidity())
I'm no expert here, but what does a validity check for a proprietary payment response look like? What about for a Stripe token? Or an Apple Pay response? Or a SEPA credit transfer?
It seems to me that validation checks for anything other than basic card are not feasible on the client. In addition to that, what happens if client-side validation fails? How does a user fix a network token?
The site expects the form to be submit()ted somewhere.
Perhaps. We can all agree the payment data ultimately needs to be sent somewhere, but that somewhere is quite varied. It could be Braintree's client-side JavaScript API, where you don't submit() you client.tokenizeCard(), for example.
But these issues aside for the moment, I think the larger point is that the time for such a large change has passed. If this is a path the WG wants to go down, we should consider how we can add this later in a backwards compatible way.
This does seem reasonable, though:
If we do choose to keep the current complex object hierarchy, we should perhaps consider instead adding .json() and .formData() methods instead?
Would this work by allowing a user to do something like, paymentResponse.toFormData()
or similar?
Marcos, it seems as if you're getting caught up on the idea of "web sites currently use forms to collect credit cards, so we should optimize for that."
That's possible, yes 😸 Apologies, I don't meant to derail this too much.
I'm no expert here, but what does a validity check for a proprietary payment response look like? What about for a Stripe token? Or an Apple Pay response? Or a SEPA credit transfer?
Right now, I'm only interested in the most simple validation of the values returned by PaymentResponse (i.e., shipping address, credit card number, email, etc.). There is enough complexity just in that to keep us happy for a little while.
The above proprietary payment methods and associated tokens + related data will require that information be POSTed to some server for validation. The client can't do much else with that stuff.
Perhaps. We can all agree the payment data ultimately needs to be sent somewhere, but that somewhere is quite varied. It could be Braintree's client-side JavaScript API, where you don't submit() you client.tokenizeCard(), for example.
But at the end of the day, everything that leaves the browser conforms to the Fetch spec. So, irrespective of what any library does, it basically has only a few choices:
But these issues aside for the moment, I think the larger point is that the time for such a large change has passed. If this is a path the WG wants to go down, we should consider how we can add this later in a backwards compatible way. Would this work by allowing a user to do something like, paymentResponse.toFormData() or similar?
Yes, it would. Alternatively:
var data = new FormData(paymentResponse);
Few ways to skin this cat. However, I'm pretty sure this will come up sooner or later as more sites try to integrate this API with their existing payment systems.
So, it would be good to just add .formData()
and .json()
the PaymentResponse interface (and ditch the serializer). That would allow us to keep the current design, while addressing my concerns about this not being form data.
The serializer is a .toJSON()
method, right? That's [automatically called](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior) when developer writes JSON.stringify(response)
. The .json()
method would not be automatically called by JSON.stringify(response)
. Can we stick with .toJSON()
because of this?
Talked to @zkoch about this proposal. In light of Edge's announcement, I'm postponing this to "V2" pending feedback from the developer community. If no one complains about lack of integration with HTML form validation in 1 year, then we can probably close this.
I'm closing and will reopen it if need be in the future (based on developer feedback). There is nothing actionable here.
This is a follow on from #326... the ability to use this API with HTML forms seems limited, which strikes me as quite odd given that this API just collects form data. In particular, web applications that are loaded on UAs that don't support this API will need to use HTML forms.
Additionally,
PaymentResponse
needs to be validated in the same way that one would validate a HTML Form. And, in most cases,PaymentResponse
, needs to be POSTed by the developer asFormData
to a server for verification.Thus, it feels deficient that I can't easily do the following (given we have extensive form validation and form-related primitives in the platform):
Going from a
PaymentResponse
to populating a form is not overly traumatic. But could be made much more coherent. Additionally, reusing more of the existing form infrastructure could significantly reduce the API surface.