Experiences with Native wallet Web shop integration

I'm currently working with three variants of a native wallet implementation.

- W2NB (Web2Native Bridge) using Chrome desktop on Windows, Linux and OS/X
- On Android using the intent system
- A QR code version also running on Android

A thing I care about is how such systems are integrated in a Web shop.

The W2NB-powered Wallet integration code is a fairly clean JS-only [1] scheme while the Android counterpart is a pretty disgusting hack.
AFAICT, Android's intent system is not suitable for "real" Web payment applications (it was designed for invoking media applications).

That the QR version needs some specials is less surprising since it is a remote Wallet.

Observation: Properly implemented native mode Wallets (unlike CNP payments) can without drawbacks run in the merchant's domain rather than at a PSP.

Anders

1]

"use strict";

var invocationData = {
    "@context": "http://xmlns.webpki.org/webpay/v2",
    "@qualifier": "WalletRequest",
    acceptedAccountTypes: ["https://supercard.com","https://bankdirect.net","https://nosuchcard.com"],
    paymentRequest: {
      payee: {
        commonName: "Demo Merchant",
        id: "86344"
      },
      amount: "94599.00",
      currency: "USD",
      referenceId: "#1000001",
      timeStamp: "2016-05-08T08:07:38Z",
      expires: "2016-05-08T08:38:00Z",
      software: {
        name: "WebPKI.org - Merchant",
        version: "1.00"
      },
      signature: {
        algorithm: "ES256",
        publicKey: {
          type: "EC",
          curve: "P-256",
          x: "rZ344aiTaOATmLBOdfYThvnQu_zyB1aJZrbbbks2P9I",
          y: "lKOvfJdgN8WqEbXMDYPRSMsPicm0Tk10pmer9LxvxLg"
        },
        value: "Z28NslphBqgGjFEHPJ_wvolDYmXCEnYxs6VL3ZvS2yEjA2MkMNI5VGm8X719jh6-zd0eJXE8jMtGbl4GeUFXxA"
      }
    }
};

var nativePort = null;

function closeWallet() {
    if (nativePort) {
      nativePort.disconnect();
      nativePort = null;
    }
}

function setFail(message) {
    closeWallet();
    alert(message);
}

function activateWallet() {
    var initMode = true;
    if (!navigator.nativeConnect) {
      setFail('"navigator.nativeConnect" not found, \ncheck Chrome extension settings');
      return;
    }
    navigator.nativeConnect('org.webpki.webpay.wallet3',
                            setExtensionPosition('Center', 'Center', 'wallet')).then(function(port) {
      nativePort = port;
      port.addMessageListener(function(message) {
        if (message['@context'] != 'http://xmlns.webpki.org/webpay/v2') {
          setFail('Wrong or missing "@context"');
          return;
        }
        var qualifier = message['@qualifier'];
        if ((initMode && qualifier != 'WalletIsReady')  ||
            (!initMode && qualifier != 'PayerAuthorization')) {
          setFail('Wrong or missing "@qualifier"');
          return;
        }
        if (initMode) {
          document.getElementById('wallet').style.height = message.window.height + 'px';
          initMode = false;
          nativePort.postMessage(invocationData);
        } else {
// This is it...transfer the Wallet authorization data back to the Merchant server
          fetch('transact', {
             headers: {
               'Content-Type': 'application/json'
             },
             method: 'POST',
             credentials: 'same-origin',
             body: JSON.stringify(message)
          }).then(function (response) {
            return response.json();
          }).then(function (resultData) {
            if (typeof resultData == 'object' && !Array.isArray(resultData)) {
              if (Object.keys(resultData).length == 0) {
// "Normal" return
                document.location.href='result';
              } else {
// "Exceptional" return with error or RBA
                nativePort.postMessage(resultData);
              }
            } else {
              setFail('Unexpected wallet return data');
            }
          }).catch (function (error) {
            console.log('Request failed', error);
          });
        }
      });
      port.addDisconnectListener(function() {
        if (initMode) alert('Wallet application "org.webpki.webpay.wallet3.jar" appears to be missing!');
        nativePort = null;
// User cancel
        document.forms.restore.submit();
      });
    }, function(err) {
      console.debug(err);
    });
}

function setExtensionPosition(hAlign, vAlign, optionalId) {
    var result = {horizontalAlignment:hAlign, verticalAlignment:vAlign}
    if (optionalId) {
      var input = document.getElementById(optionalId).getBoundingClientRect();
      var rectangle = {};
      rectangle.left = input.left;
      rectangle.top = input.top;
      rectangle.width = input.width;
      rectangle.height = input.height;
      result.targetRectangle = rectangle;
    }
    return result;
}

window.addEventListener('beforeunload', function(event) {
    closeWallet();
});

Received on Sunday, 8 May 2016 10:20:27 UTC