W3C home > Mailing lists > Public > public-payments-wg@w3.org > May 2016

Experiences with Native wallet Web shop integration

From: Anders Rundgren <anders.rundgren.net@gmail.com>
Date: Sun, 8 May 2016 10:33:41 +0200
To: Web Payments Working Group <public-payments-wg@w3.org>
Message-ID: <34083926-1531-cb0c-d3aa-15967aeb7c7b@gmail.com>
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 08:42:42 UTC

This archive was generated by hypermail 2.3.1 : Sunday, 8 May 2016 08:42:43 UTC