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

How can a Web Based Payment App cancel the payment flow? #128

Closed
tommythorsen opened this issue Apr 26, 2016 · 14 comments
Closed

How can a Web Based Payment App cancel the payment flow? #128

tommythorsen opened this issue Apr 26, 2016 · 14 comments

Comments

@tommythorsen
Copy link
Member

I've experimented a bit with implementing a web based payment app, by making a simple web app that encapsulates a Visa Checkout flow (as described here). The Visa Checkout flow consists of a series of pages, which all have an X in the upper right corner for canceling out of the flow. See screenshot:

visacheckout

If the user presses that X, I need to send a "cancel" message back to the user agent, so that it can close the browser window and return to a suitable step in the web payments flow.

What would be the best way of doing this? A separate javascript api? Or calling submitPaymentResponse with a response that indicates an error/cancellation? Or Ballista IPC as mentioned in the issue box under payment-apps:6.3.1.1.1?

@dlongley
Copy link
Contributor

@tommythorsen,

Or calling submitPaymentResponse with a response that indicates an error/cancellation?

My view is that this is what you should do. Payment Apps are defined as receiving payment requests and sending payment responses in the proposed architecture document -- which keeps their API very simple. So, in this case, you would send a payment response that indicates the error/cancellation. Others may have different opinions.

@dlongley
Copy link
Contributor

To add -- I'd like to see an API where Web-based Payment Apps receive a payment request and Promise that they need to resolve to a payment response. So resolving that Promise is what I'd expect to be the way you send your result rather than an explicit call like submitPaymentResponse.

@tommythorsen
Copy link
Member Author

Or calling submitPaymentResponse with a response that indicates an error/cancellation?

My view is that this is what you should do.

Yeah, I like that approach too. Right now, there is no mention of error/cancellation status in the PaymentResponse interface, though. What would be the preferred way to signal this? An additional status field?

@dlongley
Copy link
Contributor

So, looking at this more closely ...

When a payment request occurs, I would expect the user agent to instantiate the Web-based payment app of the user's choice, and then that payment app would make a call to get an interface to the payment request data. To my knowledge, this hasn't yet been specified, but we called this navigator.payments.getPendingRequest in the WPCG spec proposal. We could also potentially use an event/message channel API for communication with the payment app, but messages could be sent prior to setting up a listener in the payment app and therefore missed (unless there's a clever way around that).

In any case, the payment app would be given an interface that has access to the payment request data and a Promise that should be resolved by the app to the payment response data. I think what we'd want to do in the case of cancellation, where the payment method wasn't actually used at all, is reject that Promise with an error, rather than resolving to payment response data with payment-method specific information in it. So this is a slight modification of what I said earlier.

This rejection would pass through the user agent and cause the merchant site code to receive an error and fall into the "Uh oh, something bad happened" catch in Example 1 in the spec. We may want to come up with a more specific error that indicates cancellation and that may allow user agents to recover and offer another option -- but I don't know how others feel about that level of complexity.

If we don't do it this way, then we would end up encoding the error in the payment response data itself (details in the PaymentResponse in the spec) -- and it would be up to payment methods to specify this information. They could, for example, encode this as a "refusal to consent". However, I can see how this kind of cancellation could fall outside of the domain of any particular payment method -- in which case the rejection of the Promise with an error that indicates cancellation seems like a valid approach.

Again, others will want to weigh in on this design.

@tommythorsen
Copy link
Member Author

When a payment request occurs, I would expect the user agent to instantiate the Web-based payment app of the user's choice, and then that payment app would make a call to get an interface to the payment request data. To my knowledge, this hasn't yet been specified (...)

The Payment Apps spec seems to specify the passing of the payment request to the payment app by converting the request to JSON, and POST'ing it to the url of the web based payment app (here). This approach would make it difficult to pass a promise to the app. A getPendingRequest call would work better for that. The advantage of the POST, on the other hand, is that it's a very intuitive way to pass something to a web page.

If we don't do it this way, then we would end up encoding the error in the payment response data itself (details in the PaymentResponse in the spec)

Yes, this would actually work perfectly well. As long as the user agent gets any response, it can close down the web context for the payment app and pass the response back to the merchant. It doesn't actually need to see any status information.

If I implement it this way, I don't strictly need any changes to the spec, but it would be nice if the cancel/error scenario was mentioned in the spec anyway, for clarity.

@dlongley
Copy link
Contributor

@tommythorsen,

Ah, I haven't fully reviewed Adrian's Payment App proposal yet. Reading over it, I have a slightly different view of how I would expect this to work with Payment Apps installed in browsers. Non-interactive HTTP-based payment apps would almost certainly receive payment request messages via POST -- but I'm not yet convinced we want those apps that also provide a Web-based UI to work that way. It may be more natural for them to interface with the user agent using JavaScript and Promises. Maintaining state may also be easier this way. We're kind of right in the middle of trying to figure out the best way to design this part of the API :).

If I implement it this way, I don't strictly need any changes to the spec, but it would be nice if the cancel/error scenario was mentioned in the spec anyway, for clarity.

Sure. It's worth trying it out that way -- experiments here are definitely welcome. And, yes, we'll want to indicate an example of how "cancel" (or refusal to consent) can be done.

@ianbjacobs
Copy link
Contributor

@tommythorsen,

Thanks for raising this issue. I don't have an answer to your question but agree the group needs to consider it.

Rather, I am curious how you wrote your payment app, and which of the following things you are experimenting with:

  • How a payment app declares what payment methods it supports
  • How you register a payment app with a browser
  • How the browser communicates with the payment app.

Thanks for any help on this.

You may wish to send a response elsewhere than on this issue thread. For example, if you write up a summary somewhere, you could send us the URL on the group's list (public-payments-wg at w3.org).

Thanks again!

Ian

@tommythorsen
Copy link
Member Author

@ianbjacobs

I'll just answer your questions with a short comment here, as this payment app is not nearly as impressive as you might think. The answer to the first two points is that it's all hard-coded into the browser at the moment. I'm planning to start experimenting with app registration soon, but I haven't gotten there quite yet.

The browser communicates with the payment app pretty much exactly as specified in the Payment Apps spec proposal, section 6, that is to say, I convert the whole payment request to JSON and POST it to the web app. The result is delivered back in the form of JSON passed through a javascript api, as in the spec proposal.

The payment app itself can be seen here: https://people.opera.com/tommyt/pay.php. Just view the page source to see how simple it is. There is some server-side PHP that handles the POST data, but this code will insert test data if nothing was POST'ed. If you want to look at the whole flow of the payment app, you can create a test account at https://sandbox.secure.checkout.visa.com.

@adrianhopebailie
Copy link
Collaborator

@dlongley said:

I'm not yet convinced we want those apps that also provide a Web-based UI to work that way. It may be more natural for them to interface with the user agent using JavaScript and Promises. Maintaining state may also be easier this way.

Can you elaborate?

The motivation for the HTTP POST is that there is no session yet between the browser and the app and the very first interaction contains the whole payment request.

The advantage is that the payment app can tailor it's response entirely using content-type negotiation and/or redirects.

In one instance it may possibly not even render UI. If the user has setup rules in the payment app to automatically authorize certain payments (eg: from certain merchants below certain values etc) the payment app could simply respond with a JSON-encoded payment response and the browser would never need to render any payment app UI.

In addition it supports the case where the payment app wants to redirect the request to native app. This can easily be supported by doing a redirect to a URL with a custom URL protocol like mypaymentapp://.

If we force the browser to first render the web-based payment app before the app even sees the content of the request then we can't support either of these uses cases without a nasty user experience of UI that may appear and then vanish or need to be loaded in the backgorund.

@dlongley
Copy link
Contributor

@adrianhopebailie,

I'm not opposed to your proposal and I understand the additional use cases it supports. I'm fine with going forward with it as the WG proposal for how to communicate with Payment Apps. I do like that it fits nicely with how you'd communicate with a Payment App in the HTTP spec as well.

@tommythorsen
Copy link
Member Author

@dlongley and @adrianhopebailie

I do like that it fits nicely with how you'd communicate with a Payment App in the HTTP spec as well.

Me too. In fact, I think it would be great if a web-based payment app and an HTTP payment app were exactly the same thing. The only thing that should differ between the two scenarios, from the payment app's point of view, should be whether the request had json and html in the accept header, or only json.

This would make it much more likely that PSP's would actually develop payment apps for both web- and http-based user-agents.

@msporny
Copy link
Member

msporny commented Apr 29, 2016

@tommythorsen wrote:

I think it would be great if a web-based payment app and an HTTP payment app were exactly the same thing.

I've heard a number of people say this. Unfortunately, at this point in time, we don't have an HTTP API spec in the group. We're going to be discussing whether or not to pull in the Web Payments Community Group HTTP API spec next week. If you (and others) could show your support, that would help us start discussing what you have said you want:

https://lists.w3.org/Archives/Public/public-payments-wg/2016Apr/0213.html

@jnormore
Copy link
Member

I agree that it should be handled in the submitPaymentResponse request. I also think it would be better to leave this up to the payment app to decide and encode it into the payment response data. The merchant should already know how to handle a payment response for any payment method it supports so the same expectation is there for any error/cancel response. Error or cancel response can also be very specific to a given payment method, so trying to encapsulate this into a new concept in the spec will only restrict their capabilities.

@ianbjacobs
Copy link
Contributor

Migrating to the payment apps issues list:
w3c/payment-handler#37

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

6 participants