requestAutocomplete

Prends mon argent, pas mon temps

Jake Archibald
Jake Archibald

Introduction

J'aime le Web. Dans l'ensemble, je pense que c'est une assez bonne idée. À ce titre, je suis confronté à de nombreux débats sur le Web et les annonces natives. Il ne faut pas longtemps pour que l'autre personne commence à parler de la facilité des paiements via des systèmes natifs. J'ai l'habitude de faire tomber une bombe à fumée et de sortir de la pièce en riant de manière farfelue, car ce n'est pas un argument que je peux gagner. Le taux d'abandon du 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 rempli d'objets qu'ils recherchent, retournent leur chariot et en sortent. Aujourd'hui, certains d'entre eux ne font qu'augmenter les prix et n'ont jamais eu l'intention d'acheter, mais l'expérience utilisateur horrible liée aux achats sur le Web en est un facteur important. Les utilisateurs sont soumis à une taxe qui ne leur permet pas d'atteindre leurs objectifs. Pensez à une expérience de paiement agréable que vous avez eue sur le Web, en particulier sur mobile. C'est une plate-forme de téléchargement d'applications, n'est-ce pas ? Ou du moins un système fermé similaire qui dispose déjà de vos informations de paiement. C'est un problème. Les sites doivent s'engager auprès d'un fournisseur de services de paiement particulier auquel l'utilisateur doit déjà disposer d'un compte et auquel il doit être connecté, ou s'engager sur une plate-forme nécessitant que les utilisateurs soient connectés à un fournisseur de services de paiement particulier, comme une plate-forme de téléchargement d'applications qui vous oblige à coder uniquement pour cette plate-forme. Si vous n'effectuez pas l'une de ces actions, l'utilisateur est condamné à appuyer ailleurs sur son écran ou son clavier jusqu'à ce que toute sa peau ait disparu ou qu'il abandonne. Nous devons y remédier.

requestAutocomplete

Dans l'univers de WebGL, de WebRTC et d'autres API Web sophistiquées qui commencent par "Web", requestAutocomplete n'est pas très glamour. Il s'agit toutefois d'un super-héros vêtu d'un vêtement beige. Une API minuscule et ennuyeuse qui vous permet de gagner du temps.

Plutôt que de dépendre d'un fournisseur de services de paiement particulier, le site demande les détails du paiement au navigateur, qui les stocke pour le compte de l'utilisateur. La version de requestAutocomplete() de Chrome s'intègre également à Google Wallet pour les utilisateurs situés aux États-Unis uniquement (actuellement). Essayez sur notre site test.

form.requestAutocomplete

Les éléments du formulaire comportent une seule nouvelle méthode, requestAutocomplete, qui demande au navigateur de remplir le formulaire. Le navigateur affiche une boîte de dialogue demandant l'autorisation à l'utilisateur et lui permettant de sélectionner les informations qu'il souhaite fournir. Vous ne pouvez pas l'appeler quand vous le souhaitez. Elle doit être appelée lors de l'exécution d'événements d'interaction spécifiques tels que des événements de clic, de clic, de touche ou tactile, par exemple. 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 de passer en revue ces événements, nous devons nous assurer que le navigateur comprend les champs de votre formulaire...

Exigences concernant les formulaires

À l'époque où Internet était en noir et blanc, Internet Explorer 5 a adopté un nouvel attribut, autocomplete, pour les éléments de saisie de formulaire. Il pouvait être désactivé pour que le navigateur ne propose plus de 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". requestAutocomplete utilise cette méthode pour associer des champs de formulaire aux données utilisateur.

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

En tant que spécification, requestAutocomplete n'est pas spécifique aux paiements, contrairement à l'implémentation actuelle de Chrome. À l'avenir, attendez-vous à ce que les navigateurs soient capables de gérer d'autres types de données, comme les identifiants de connexion et le générateur de mots de passe, les informations de passeport et même le téléchargement d'un avatar.

Actuellement, dans Chrome, requestAutocomplete reconnaît les éléments suivants:

Paiement

  • e-mail
  • cc-name - nom 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é à 3 ou 4 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 obligatoire d'utiliser des valeurs particulières. Si vous comptez réutiliser ce formulaire pour les utilisateurs sans requestAutocomplete, ce qui est 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. Il est de loin préférable de prendre un nom complet comme un seul champ plutôt que de plusieurs champs. Plusieurs champs, comme le prénom et le nom, présentent un biais occidental et peuvent ne pas avoir de sens pour d'autres cultures. Il est également plus facile de saisir du texte dans un seul champ.

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

    • tel-country-code : par exemple, +44
    • tel-national - le reste
  • street-address - adresse complète avec des composants séparés par une virgule, peut être décomposée en

    • ligne-adresse1
    • address-line2 – peut être vide
  • Localité : ville

  • region : code de l'État, du comté ou du canton

  • postal-code : code postal

  • country

Ce qui précède doit être utilisé 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">
…

Encore une fois, les attributs de nom sont des exemples. Vous pouvez utiliser ce que vous voulez. Évidemment, tous les formulaires ne doivent pas demander une adresse de livraison (par exemple, ne me demandez pas où je souhaiterais vous faire livrer ma chambre d'hôtel, c'est souvent son emplacement actuel qui constitue l'argument de vente. Voilà, nous avons un formulaire et nous savons comment demander autocompletion. Mais…

Quand la requête requestAutocomplete doit-elle être appelée ?

Idéalement, vous préférez afficher la boîte de dialogue requestAutocomplete au lieu de charger la page qui affiche le formulaire de paiement. Si tout se passe comme prévu, l'utilisateur ne devrait pas du tout voir le formulaire.

Flux de paiements

Une pratique courante consiste à avoir une page de panier avec un bouton « 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 appeler requestAutocomplete sur celui-ci lorsque l'utilisateur clique sur le bouton de paiement. N'oubliez pas que vous devez diffuser votre page de panier via SSL pour éviter l'avertissement Skeletor. Pour commencer, nous devons masquer notre bouton de paiement afin que l'utilisateur ne puisse pas cliquer dessus avant d'être prêt, 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. Il peut aller n'importe où. Le CSS ci-dessus s'assure qu'il n'est pas visible par l'utilisateur.

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

Notre code 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 devez appeler enhanceForm sur la page du panier, quelque temps après l'affichage du formulaire et du bouton de paiement. Les navigateurs compatibles avec requestAutocomplete bénéficieront d'une nouvelle expérience rapide. Les autres navigateurs utiliseront le mode de paiement standard. Pour obtenir des points bonus, vous pouvez charger le formulaire HTML via XHR dans enhanceForm. Cela signifie que vous ne pouvez charger le formulaire que dans les navigateurs compatibles avec requestAutocomplete. Vous n'avez pas besoin de penser à l'ajouter à chaque page à partir de laquelle vous pouvez appeler enhanceForm. Voici comment fonctionne le site de démonstration.

Vous appelez la fonction requestAutocomplete. Que dois-je faire maintenant ?

Le processus de saisie semi-automatique est asynchrone. requestAutocomplete est immédiatement renvoyé. Pour savoir comment cela s'est passé, nous avons écouté 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é correctement, vous pouvez faire ce que vous voulez avec les données. Le plus simple est d'envoyer le formulaire. Le serveur peut ensuite valider les données et fournir à l'utilisateur une page de confirmation incluant les frais de livraison. Si les données ne sont pas valides, vous pouvez afficher le formulaire et mettre en surbrillance les champs que l'utilisateur doit modifier. Sinon, vous pouvez simplement envoyer le formulaire et 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 ressembleront 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 l'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 les autres appareils auxquels vous êtes connecté. Si vous stockez vos informations dans Wallet, votre vrai numéro de carte ne sera pas distribué par requestAutocomplete, 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 actuellement, mais Chrome et d'autres navigateurs pourraient adopter d'autres fournisseurs de services de paiement à l'avenir.

Faciliter les paiements

Il est plutôt ridicule que les utilisateurs doivent saisir leurs informations de paiement à chaque fois qu'ils veulent effectuer un achat. Tout devient plus facile lorsqu'un site stocke vos informations de paiement. Je ne suis pas très à l'aise avec le nombre de sites qui stockent les informations de ma carte. C'est le problème idéal pour les normes Web. Avec requestAutocomplete, vous pouvez effectuer des paiements en un clic sur l'ensemble du Web, sans être dépendant d'un service ou d'une plate-forme, et pour ne pas perdre de temps !

Bonus: Gérer les formulaires de plusieurs pages

Il est préférable d'appeler requestAutocomplete une fois pour recueillir 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, ne vous inquiétez pas : vous pouvez extraire les données du formulaire rempli et les envoyer de la manière qui vous convient le mieux. Vous pouvez utiliser cette petite fonction astucieuse pour capturer toutes les données actuellement prises en charge 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 dont votre serveur a besoin 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
    });
  });
});