w3c / payment-request

Payment Request API
https://www.w3.org/TR/payment-request/
Other
489 stars 135 forks source link

Refactoring PaymentRequest #914

Closed cyberphone closed 4 years ago

cyberphone commented 4 years ago

PaymentRequest was primarily designed to offer:

In retrospect it has become evident that there are many "standards" in the payment world and there is rather little the W3C can do about that. In addition, most providers of mobile phone based payment solutions like the EMPSA members, are targeting quite different payment scenarios with the same native mode "wallet" making Web-only solutions somewhat less useful.

Rather than dumping all the good work that has gone into the PaymentRequest API, this issue outlines an update which permits the existing API to be "mapped" to a new API that universalizes the core functionality of PaymentRequest which simply is enabling Web applications to securely interact with installed applications which do not necessarily follow the general Web security model (SOP).

The proposed API would effectively create a bi-directional, asynchronous "channel" to installed applications (native or Web-based) which are specifically crafted to be "Web-callable". This API would inherit a bunch of things from PaymentRequest including:

Security Considerations

Wouldn't such an API introduce insurmountable security and privacy issues like the nowadays deprecated NPAPI and ActiveX solutions once did? No, the latter ran inside of browsers with full access to browser internals which created all sorts of problems. From what I can deduct the existing PaymentRequest API does not (in itself) stop potential misuses. In fact, native payment handlers in Android have access to everything offered by the operating system and granted by the user!

Obviously "Web-callable" applications must be designed with great care and ideally be subjected to a more thorough vetting process than "ordinary" applications.

See also Calling "Apps" from the Web.

Desktop Web to Mobile Wallet

A drawback with the current PaymentRequest API is that it doesn't address the quite popular scenario where a mobile phone "wallet" is used to together with a Web application running in a desktop computer. This scenario is fully supported by FIDO2 standards but can only be used for FIDO2. To cope with this the "channel" API (in similarity to FIDO2), should also be exposable via BLE and USB. For a calling Web application, this distinction should be close to transparent. It is worth noting that in the BLE and USB configurations, security measures (with gestures as the sole exception), are moved to the attached mobile devices which thus must be "intelligent".

The "channel" itself would be based on binary streams to cope with all formats in the wild, including those that are yet to be invented.

Mapping PaymentRequest

For "mapping" PaymentRequest into "channel" based payment handler applications, JSON would be the intermediary transport format since it readily translates back and forth into JavaScript. This change would be invisible on the Web but require revised payment handler code.

Further Enhancements Enabled by the Proposed API

In a proof-of-concept system called Saturn, the very same JSON message set are used both at the PoS terminal and on the Web. The only difference is the invocation which is based on QR holding an invocation URL respectively PaymentRequest (in "emulator" mode as shown in the next section), making the "wallet" comparatively simple as well as easier to integrate for Merchants and Payment Providers.

For Users this arrangement leads to a more uniform way of dealing with payments compared to systems like Apple Pay which at the PoS terminal is limited to EMV (card) level messaging.

The very same system is also used for enrollment of payment credentials which is performed via the 10-pass KeyGen2 protocol.

Emulating "Web-callable" APIs Using Android

JavaScript Invocation

const dummyDetails = {total:{label:'total',amount:{currency:'USD',value:'1.00'}}};
const methodData = [{
  supportedMethods: 'https://methodhost/proxy',
  data: ['customCodedUrl']
}];
const w3cPaymentRequest = new PaymentRequest(methodData, dummyDetails);

The customCodedUrl tells the receiving proxy code which particular sub API that is requested. The customCodedUrl also contains an encoded parameter holding a URL which is used to fetch the JSON request data. By relying on the skip-the-sheet mode, the browser PaymentRequest UI is never shown.

Using a URL may look a bit quirky; it was only used to maintain compatibility with the URL handler scheme.

AndroidManifest.xml

<activity
    android:name=".ProxyActivity"
    android:exported="true">
    <intent-filter>
       <action android:name="org.chromium.intent.action.PAY"/>
    </intent-filter>
    <meta-data android:name="org.chromium.default_payment_method_name"
       android:value="https://methodhost/proxy"/>
</activity>

Android Java Code

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_proxy);
    final Bundle extras = getIntent().getExtras();
    if (extras == null) {
        bad("Missing extras");
        return;
    }
    ArrayList<String> methodNames = extras.getStringArrayList("methodNames");
    if (methodNames == null || methodNames.size() != 1) {
        bad("Missing or too many methodNames");
        return;
    }
    Bundle methodData = extras.getBundle("methodData");
    if (methodData == null) {
        bad("Missing methodData");
        return;
    }
    String jsonString = methodData.getString(methodNames.get(0));
    if (jsonString == null) {
        bad("Missing 'data'");
        return;
    }
    // ["the url we are looking for"]
    final Uri proxyUrl = Uri.parse(jsonString.substring(2, jsonString.length() - 2));
    // Core decoding, now over to the parameters...
}

Enhancing PaymentHandler

It would be cool if the universalized API also could be applied to the W3C PaymentHandler but that is outside of my competence and interest.

ianbjacobs commented 4 years ago

This repo is for issues related to the Payment Request API. The proposal seems to address more general use cases that payments. For that reason, I am closing the issue in this repo.

I don't agree with this statement:

"A drawback with the current PaymentRequest API is that it doesn't address the quite popular scenario where a mobile phone "wallet" is used to together with a Web application running in a desktop computer. "

Nothing prevents a payment handler on a desktop from talking to a server that in turn interacts with a user's phone / mobile wallet. I don't believe it's a limitation of the API; it would just be one application leveraging the API.

cyberphone commented 4 years ago

Nothing prevents a payment handler on a desktop from talking to a server that in turn interacts with a user's phone / mobile wallet. I don't believe it's a limitation of the API; it would just be one application leveraging the API

We should (all) be happy that the FIDO folks came up with a more engineered concept which doesn't require custom installations and user-specific configurations.

By mirroring the (for practical purposes) not standardized PaymentRequest API into a neutral "channel" API you can leverage already working payment handlers.

I'm slightly puzzled by the fact that G-Pay doesn't even support QR invocation (the "workaround"), which practically all their competitors do. @marcoscaceres @adrianhopebailie @rsolomakhin @danyao