requestAutocomplete

Je prends mon argent, pas mon temps

Jake Archibal
Jake Archibal

Introduction

J'aime le Web. Dans l'ensemble, je pense que c'est une très bonne idée. Je participe donc à de nombreux débats sur le Web et la langue native. Votre interlocuteur ne met pas beaucoup de temps à parler de la facilité des paiements via les systèmes natifs. J'ai l'habitude de lâcher une bombe à fumée et de sortir de la pièce en riant d'un air fou, car je ne peux pas gagner. Le taux d'abandon de panier d'achat sur le Web mobile peut atteindre 97%. Imaginez cela dans le monde réel. Imaginez que 97% des personnes dans un supermarché, avec un chariot débordant de choses qu'elles veulent, retourner et sortir. Certaines d'entre elles ne font qu'augmenter leurs prix et n'ont jamais eu l'intention d'en acheter. Cependant, l'horrible expérience utilisateur liée aux achats sur le Web contribue pour une grande part. Nous imposons aux utilisateurs une taxe sur leur intégrité. Pensez à une expérience de paiement agréable que vous avez vécue sur le Web, en particulier sur mobile. C'est une plate-forme de téléchargement d'applications, n'est-ce pas ? Ou au moins un système fermé similaire qui contient déjà vos informations de paiement. Cela pose problème. Les sites doivent s'engager auprès d'un fournisseur de services de paiement spécifique auprès duquel l'utilisateur doit déjà posséder un compte et y être connecté, ou utiliser une plate-forme qui oblige les utilisateurs à se connecter à un fournisseur de services de paiement particulier (par exemple, une plate-forme de téléchargement d'applications où vous devez coder uniquement pour cette plate-forme). Si vous n'effectuez aucune de ces actions, l'utilisateur est condamné à appuyer sur l'écran ou le clavier jusqu'à ce que la peau de son doigt ait disparu, ou jusqu'à ce qu'il abandonne. Nous devons résoudre ce problème.

requestAutocomplete

Avec WebGL, WebRTC et d'autres API Web sophistiquées qui commencent par "Web", requestAutocomplete est plutôt peu glamour. Cependant, il s'agit d'un super-héros vêtu d'une tenue beige. Une API minuscule et ennuyeuse capable de maintenir un intérêt au cœur des paiements Web : un vampire-t-il.

Au lieu de s'appuyer sur un fournisseur de services de paiement particulier, il demande des informations de paiement au navigateur, qui les stocke au nom de l'utilisateur. La version Chrome de requestAutocomplete() s'intègre également à Google Wallet pour les utilisateurs situés aux États-Unis uniquement (actuellement). Essayer cette fonctionnalité sur notre site de test

form.requestAutocomplete

Les éléments du formulaire disposent d'une nouvelle méthode unique, requestAutocomplete, qui demande au navigateur de remplir le formulaire. Le navigateur affiche une boîte de dialogue demandant à l'utilisateur une autorisation lui permettant de sélectionner les informations qu'il souhaite fournir. Vous ne pouvez pas l'appeler quand vous le souhaitez. Il doit être appelé lors de l'exécution d'événements d'interaction particuliers, tels que les événements de haut/bas de la souris, de clic, de touche et d'appui. Il s'agit d'une restriction de sécurité délibérée.

button.addEventListener('click', function(event) {
  form.requestAutocomplete();
  event.preventDefault();
});

// TODO: listen for autocomplete events on the form

Avant d'examiner les événements, nous devons nous assurer que le navigateur comprend vos champs de formulaire...

Exigences relatives aux formulaires

À l'époque où Internet était en noir et blanc, Internet Explorer 5 a adopté un nouvel attribut, autocomplete, sur les éléments de saisie de formulaire. Elle pourrait être désactivée pour empêcher le navigateur de proposer des suggestions, et c'est tout. Cette API a été étendue afin que vous puissiez spécifier le contenu attendu du champ sans modifier l'attribut "name". C'est ce que requestAutocomplete utilise pour associer les champs de formulaire aux données utilisateur.

<input name="fullname" autocomplete="name">

En guise de spécification, requestAutocomplete n'est pas spécifique au mode de paiement, mais l'implémentation actuelle de Chrome l'est plutôt. À l'avenir, attendez-vous à ce que les navigateurs soient capables de traiter d'autres types de données, comme les informations de connexion, le générateur de mots de passe, les informations de passeport et même l'importation d'un avatar.

Actuellement dans Chrome, requestAutocomplete reconnaît:

Paiement

  • adresse email
  • nom-Cc - nom figurant sur la carte
  • cc-number - numéro de carte
  • cc-exp-month - Mois d'expiration de la carte à deux chiffres
  • cc-exp-year - Année d'expiration de la carte à quatre chiffres
  • cc-csc : code de sécurité à trois ou quatre chiffres de la carte
<input type="email" autocomplete="email" name="email">
<input type="text" autocomplete="cc-name" name="card-name">
<input type="text" autocomplete="cc-number" name="card-num">
<input type="text" autocomplete="cc-exp-month" name="card-exp-month">
<input type="text" autocomplete="cc-exp-year" name="card-exp-year">
<input type="text" autocomplete="cc-csc" name="card-csc">

Les attributs "name" que j'ai utilisés ci-dessus ne sont fournis qu'à titre d'exemple. Il n'est pas nécessaire d'utiliser des valeurs particulières. Si vous comptez réutiliser ce formulaire pour les utilisateurs sans requestAutocomplete (idéal), vous devrez ajouter des libellés, une mise en page et une validation HTML5 de base.

Vous n'êtes pas non plus limité aux éléments de saisie. Vous pouvez utiliser n'importe quel type de saisie de formulaire. Par exemple, vous pouvez utiliser <select> pour les champs d'expiration de la carte.

Message détaillé de la console.
Message détaillé de la console

Adresse

  • name : nom complet. Prendre un nom complet comme un seul champ est beaucoup mieux que plusieurs champs. Plusieurs champs, tels que le prénom et le nom, montrent un parti pris occidental et peuvent ne pas avoir de sens pour d'autres cultures. De plus, il est plus facile de saisir du texte dans un seul champ.

  • tél. : numéro de téléphone complet avec l'indicatif du pays, peut également être divisé en

    • Code de pays : +44, par exemple
    • tel-national - le reste
  • street-address - adresse complète avec les composants séparés par une virgule, pouvant être divisée en

    • ligne-adresse1
    • address-line2 - peut-être vide
  • localité - ville/commune

  • région (code d'état, comté ou canton)

  • postal-code : code postal, code postal

  • country (pays)

Les informations ci-dessus doivent être utilisées en combinaison avec : - facturation - livraison

<input type="text" autocomplete="billing name" required name="billing-name">
<input type="tel" autocomplete="billing tel" required name="billling-tel">
<input type="text" autocomplete="billing address-line1" required name="billing-address1">
<input type="text" autocomplete="billing address-line2" required name="billing-address2">
<input type="text" autocomplete="billing locality" required name="billing-locality">
<input type="text" autocomplete="billing region" required name="billing-region">
<input type="text" autocomplete="billing postal-code" required name="billing-postal-code">
<select autocomplete="billing country" required name="billing-country">
  <option value="US">United States</option>
  …
</select>

<input type="text" autocomplete="shipping name" name="shipping-name">
…

Pour rappel, les attributs "name" sont des exemples que vous pouvez utiliser comme bon vous semble. Il est évident que tous les formulaires ne doivent pas demander d'adresse de livraison. Par exemple, ne me demandez pas où je souhaite recevoir ma chambre d'hôtel, car son emplacement actuel est souvent l'argument de vente. Nous avons donc le formulaire et nous savons comment faire une demande de autocompletion. Mais…

À quel moment la requête requestAutocomplete doit-elle être appelée ?

Idéalement, vous souhaitez afficher la boîte de dialogue requestAutocomplete au lieu de charger la page qui affiche le formulaire de paiement. Si tout se passe bien, l'utilisateur ne doit pas voir le formulaire.

Flux de paiement

Généralement, la page du panier comporte un bouton de paiement qui vous redirige vers le formulaire des détails du paiement. Dans ce cas, vous souhaitez charger votre formulaire de facturation sur la page du panier, mais le masquer pour l'utilisateur et l'appeler requestAutocomplete lorsque l'utilisateur clique sur le bouton de paiement. N'oubliez pas que vous devrez diffuser votre page de panier via SSL pour éviter l'affichage de l'avertissement Skeletor. Pour commencer, nous devons masquer notre bouton de paiement afin que l'utilisateur ne puisse pas cliquer dessus tant que nous ne sommes pas prêts, mais nous ne voulons le faire que pour les utilisateurs avec JavaScript. Ainsi, dans l'en-tête de votre page:

<script>document.documentElement.className += ' js';</script>

Et dans votre CSS:

.js #checkout-button,
#checkout-form.for-autocomplete {
  display: none;
}

Nous devons inclure le formulaire de facturation sur la page du panier. Cela peut aller n'importe où. Le CSS ci-dessus s'assure qu'il n'est pas visible pour l'utilisateur.

<form id="checkout-form" class="for-autocomplete" action="/checkout" method="post">
  …fields for payment, billing address &amp; shipping if relevant…
</form>

JavaScript peut maintenant commencer à tout configurer:

function enhanceForm() {
  var button = document.getElementById('checkout-button');
  var form = document.getElementById('checkout-form');

  // show the checkout button
  button.style.display = 'block';

  // exit early if there's no requestAutocomplete support
  if (!form.requestAutocomplete) {
    // be sure to show the checkout button so users can
    // access the basic payment form!
    return;
  }

  button.addEventListener('click', function(event) {
    form.requestAutocomplete();
    event.preventDefault();
  });

  // TODO: listen for autocomplete events on the form
}

Vous pouvez appeler enhanceForm sur la page du panier, quelque temps après le formulaire et le bouton de paiement. Les navigateurs compatibles avec requestAutocomplete bénéficient d'une nouvelle expérience rapide et sophistiquée, tandis que les autres navigateurs utilisent votre mode de paiement habituel. Pour obtenir des points bonus, vous pouvez charger le code HTML du formulaire via XHR dans enhanceForm. Autrement dit, vous ne pouvez charger le formulaire que dans les navigateurs compatibles avec requestAutocomplete, et vous n'avez pas besoin de l'ajouter à chaque page à partir de laquelle vous pouvez appeler enhanceForm. Voici comment fonctionne le site de démonstration.

Vous avez appelé requestAutocomplete. Que faire maintenant ?

Le processus de saisie semi-automatique étant asynchrone, requestAutocomplete est renvoyé immédiatement. Pour savoir comment cela s'est passé, nous écoutons quelques nouveaux événements:

form.addEventListener('autocomplete', function() {
  // hurrah! You got all the data you needed
});

form.addEventListener('autocompleteerror', function(event) {
  if (event.reason == 'invalid') {
    // the form was populated, but it failed html5 validation
    // eg, the data didn't match one of your pattern attributes
  }
  else if (event.reason == 'cancel') {
    // the user aborted the process
  }
  else if (event.reason == 'disabled') {
    // the browser supports requestAutocomplete, but it's not
    // available at this time. Eg, it wasn't called from an
    // interaction event or the page is insecure
  }
});

Si tout s'est déroulé comme prévu, vous pouvez utiliser les données comme bon vous semble. Le plus simple est d'envoyer le formulaire. Le serveur peut ensuite valider les données et proposer à l'utilisateur une page de confirmation incluant les frais de port. Si les données ne sont pas valides, vous pouvez afficher le formulaire et mettre en surbrillance les champs que l'utilisateur doit modifier. Vous avez aussi la possibilité d'envoyer le formulaire et de laisser votre validation habituelle côté serveur prendre le relais. Si l'utilisateur a annulé le processus, vous n'avez rien à faire. Si elle est désactivée, redirigez l'utilisateur vers le formulaire standard. Donc, dans la plupart des cas, vos auditeurs ressemblent beaucoup...

form.addEventListener('autocomplete', function() {
  form.submit();
});

form.addEventListener('autocompleteerror', function(event) {
  if (event.reason == 'invalid') {
    form.submit();
  }
  else if (event.reason != 'cancel') {
    window.location = '/checkout-page/';
  }
});

Où le navigateur stocke-t-il mes données ?

La spécification n'impose pas d'emplacement de stockage des données, ce qui permet aux navigateurs d'innover. Si vous êtes connecté à Chrome, vous avez la possibilité de stocker des informations dans Google Wallet afin de les rendre accessibles sur d'autres appareils sur lesquels vous êtes connecté. Si vous stockez vos informations dans Wallet, requestAutocomplete ne communiquera pas votre vrai numéro de carte, ce qui renforce la sécurité. Si vous n'êtes pas connecté à Chrome ou si vous choisissez de ne pas utiliser Google Wallet, vos informations sont éventuellement stockées localement dans le navigateur pour être réutilisées. C'est le cas aujourd'hui, mais à l'avenir, Chrome et d'autres navigateurs pourront adopter d'autres fournisseurs de services de paiement.

Faciliter les paiements

Il est assez ridicule que les utilisateurs aient à saisir leurs informations de paiement encore et encore chaque fois qu'ils veulent effectuer un achat. Les choses se compliquent quand un site stocke vos informations de paiement, mais le nombre de sites qui stockent les informations relatives à ma carte de paiement n'est pas une bonne chose. C'est un problème que les normes du Web doivent résoudre. Avec requestAutocomplete, vous pouvez effectuer des paiements en un clic sur l'ensemble du Web, sans dépendance vis-à-vis d'un service ou d'une plate-forme, et dans un délai très court.

Bonus: Gérer des formulaires de plusieurs pages

Il est préférable d'appeler requestAutocomplete une seule fois et de collecter toutes les données dont vous avez besoin. Si vous ne pouvez pas modifier votre serveur pour recevoir toutes ces données en même temps, ce n'est pas un problème. Vous pouvez les récupérer dans le formulaire rempli et l'envoyer de la manière qui vous convient le mieux. Vous pouvez utiliser cette fonction très pratique pour capturer toutes les données actuellement compatibles en tant qu'objet simple, sans avoir à créer de formulaire vous-même. Une fois que vous disposez des données, vous pouvez les convertir dans le format nécessaire à votre serveur et les publier en plusieurs étapes.

checkoutButton.addEventListener('click', function() {
  requestUserData({
    billing: true,
    shipping: true
  }, function(response) {
    if (response.err == 'cancel') {
      // exit silently
      return;
    }
    if (response.err) {
      // fall back to normal form
      window.location.href = '/normal-checkout-form/';
      return;
    }

    // the rest is just made-up pseudo code as an example
    postToServer(data.shipping).then(function() {
      return postToServer(data.billing);
    }).then(function() {
      return postToServer(data.cc);
    }).catch(function() {
      // handle error
    });
  });
});