requestAutocomplete

Prendi i miei soldi, non il mio tempo

Jake Archibald
Jake Archibald

Introduzione

Mi piace il web. Tutto sommato, penso che sia una buona idea. Di conseguenza, mi capita spesso di partecipare a dibattiti sul web e sugli annunci nativi. Non ci vuole molto prima che l'altra persona inizi a parlare della semplicità dei pagamenti tramite i sistemi nativi. La mia risposta abituale è lanciare una bomba a fumo e correre fuori dalla stanza ridendo istericamente, perché non è un'argomentazione che posso vincere. L'abbandono del carrello degli acquisti sul web mobile può raggiungere il 97%. Immagina che cosa succederebbe nel mondo reale. Immagina che il 97% delle persone in un supermercato, con un carrello pieno di cose che vogliono, ribalti il carrello e se ne vada. Ora, alcune di queste persone si limitano a controllare i prezzi e non hanno mai avuto intenzione di acquistare, ma l'esperienza utente orribile dell'acquisto sul web è un fattore determinante. Stiamo imponendo agli utenti una tassa sulla loro sanità mentale. Pensa a un'esperienza di pagamento piacevole che hai avuto sul web, in particolare su dispositivo mobile. È uno store, giusto? O almeno un sistema chiuso simile che abbia già i tuoi dati di pagamento. Questo è un problema. I siti devono impegnarsi a utilizzare un determinato fornitore di servizi di pagamento per il quale l'utente deve già avere un account e aver eseguito l'accesso oppure a utilizzare una piattaforma che richiede agli utenti di accedere a un determinato fornitore di servizi di pagamento, ad esempio un app store che ti richiede di scrivere codice solo per quella piattaforma. Se non fai una di queste cose, l'utente è destinato a toccare lo schermo o la tastiera finché non si sarà consumata la pelle dei suoi polpastrelli o non avrà rinunciato. Dobbiamo risolvere il problema.

requestAutocomplete

In un mondo di WebGL, WebRTC e altre API web sofisticate che iniziano con "Web", requestAutocomplete è piuttosto poco appariscente. Tuttavia, è un supereroe con abbigliamento beige. Un'API piccola e noiosa che può piantare un paletto nel cuore del vampiro dei pagamenti web.

Anziché fare affidamento su un determinato fornitore di servizi di pagamento, il sito richiede i dettagli di pagamento al browser, che li memorizza per conto dell'utente. La versione di requestAutocomplete() di Chrome si integra anche con Google Wallet solo per gli utenti statunitensi (al momento). Prova sul nostro sito di test.

form.requestAutocomplete

Gli elementi del modulo contengono un unico nuovo metodo, requestAutocomplete, che chiede al browser di compilare il modulo. Il browser mostrerà all'utente una finestra di dialogo che richiede l'autorizzazione e gli consente di selezionare i dettagli che vuole fornire. Non puoi chiamarlo quando vuoi, ma deve essere chiamato durante l'esecuzione di determinati eventi di interazione, come mouse up/down, clic, tasti e tocco. Si tratta di una limitazione di sicurezza deliberata.

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

// TODO: listen for autocomplete events on the form

Prima di esaminare gli eventi, dobbiamo assicurarci che il browser comprenda i campi del modulo…

Requisiti del modulo

Quando internet era in bianco e nero, Internet Explorer 5 ha adottato un nuovo attributo, autocomplete, per gli elementi di immissione dei moduli. Potrebbe essere impostato su "off" per impedire al browser di offrire suggerimenti e basta. Questa API è stata estesa in modo da poter specificare i contenuti previsti del campo senza modificare l'attributo "name", che è ciò che requestAutocomplete utilizza per collegare i campi del modulo ai dati utente.

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

Come specifica, requestAutocomplete non è specifica per i pagamenti, ma l'attuale implementazione di Chrome lo è. In futuro, i browser dovrebbero essere in grado di gestire altri tipi di dati, ad esempio dati di accesso e generatori di password, dati del passaporto e persino il caricamento di un avatar.

Attualmente in Chrome, requestAutocomplete riconosce quanto segue:

Pagamento

  • email
  • cc-name - nome sulla carta
  • cc-number - numero carta
  • cc-exp-month - mese di scadenza della carta come due cifre
  • cc-exp-year: anno di scadenza della carta in formato a quattro cifre
  • cc-csc - codice di sicurezza della carta di 3-4 cifre
<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">

Gli attributi "name" che ho utilizzato sopra sono solo esempi. Non è necessario utilizzare valori specifici. Se vuoi riutilizzare questo modulo per gli utenti senza requestAutocomplete, che è l'ideale, ti consigliamo di aggiungere etichette, layout e convalida HTML5 di base.

Non sei limitato agli elementi di input, puoi utilizzare qualsiasi tipo di input del modulo. Ad esempio, puoi utilizzare <select> per i campi di scadenza della carta.

Messaggio dettagliato della console.
Messaggio dettagliato della console

Indirizzo

  • name: nome completo. Un nome completo come singolo campo è molto meglio di più campi. Più campi, come nome e cognome, mostrano un pregiudizio occidentale e potrebbero non avere senso per altre culture. Inoltre, è più facile digitare in un unico campo

  • tel - numero di telefono completo, incluso il codice paese, può essere suddiviso in

    • tel-country-code - ad es. +44
    • tel-national - the rest
  • street-address: indirizzo completo con componenti separati da virgole, può essere suddiviso in

    • address-line1
    • address-line2 - può essere vuoto
  • località - città

  • region: codice stato, contea o cantone

  • codice postale - Codice postale, CAP, codice postale

  • country

quanto sopra deve essere utilizzato in combinazione con: - fatturazione - spedizione

<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">
…

Ancora una volta, gli attributi name sono esempi, puoi utilizzare qualsiasi nome. Ovviamente non tutti i moduli devono richiedere un indirizzo di spedizione, ad esempio non chiedermi dove vorrei che venisse consegnata la mia camera d'albergo, la sua posizione attuale è spesso il punto di forza. Bene, abbiamo il modulo e sappiamo come richiedere autocompletion. Ma…

Quando deve essere chiamata requestAutocomplete?

Idealmente, dovresti mostrare la finestra di dialogo requestAutocomplete anziché caricare la pagina che mostra il modulo di pagamento. Se tutto va bene, l'utente non dovrebbe vedere il modulo.

Flusso dei pagamenti

Un pattern comune è avere una pagina del carrello con un pulsante "Pagamento" che rimanda al modulo dei dati di pagamento. In questa situazione, vuoi caricare il modulo di fatturazione nella pagina del carrello, ma nasconderlo all'utente e chiamare requestAutocomplete quando l'utente fa clic sul pulsante "Pagamento". Ricorda che devi pubblicare la pagina del carrello tramite SSL per evitare l'avviso Skeletor. Per iniziare, dobbiamo nascondere il pulsante di pagamento in modo che l'utente non possa fare clic finché non è tutto pronto, ma vogliamo farlo solo per gli utenti con JavaScript. Quindi, nell'intestazione della pagina:

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

E nel CSS:

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

Dobbiamo includere il modulo di fatturazione nella pagina del carrello. Può essere inserito ovunque, il CSS riportato sopra garantisce che non sia visibile all'utente.

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

Ora il nostro codice JavaScript può iniziare a configurare tutto:

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
}

Dovresti chiamare enhanceForm nella pagina del carrello, dopo il modulo e il pulsante di pagamento. I browser che supportano requestAutocomplete avranno la nuova esperienza rapida, mentre gli altri torneranno alla normale forma di pagamento. Per ottenere punti extra, ti consigliamo di caricare il codice HTML del modulo tramite XHR nell'ambito di enhanceForm. Ciò significa che puoi caricare il modulo solo nei browser che supportano requestAutocomplete e non devi ricordarti di aggiungerlo a ogni pagina da cui potresti chiamare enhanceForm. Ecco come funziona il sito demo.

Hai chiamato requestAutocomplete, cosa succede ora?

Il processo di completamento automatico è asincrono, requestAutocomplete viene restituito immediatamente. Per scoprire come è andata, ascoltiamo un paio di nuovi eventi:

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
  }
});

Se tutto ha funzionato, puoi fare ciò che vuoi con i dati. La cosa più semplice da fare è inviare il modulo. Il server può quindi convalidare i dati e mostrare all'utente una pagina di conferma che include il costo di consegna. Se i dati non sono validi, puoi mostrare il modulo e evidenziare i campi che l'utente deve modificare. In alternativa, puoi semplicemente inviare il modulo e lasciare che la normale convalida lato server prenda il sopravvento. Se l'utente ha annullato la procedura, non devi fare nulla. Se la funzionalità è disattivata, indirizza l'utente al modulo normale. Quindi, nella maggior parte dei casi, i tuoi ascoltatori saranno molto simili a…

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/';
  }
});

Dove vengono archiviati i miei dati dal browser?

La specifica non indica dove vengono archiviati i dati, consentendo ai browser di fare innovazione. Se hai eseguito l'accesso a Chrome, hai la possibilità di memorizzare i dettagli in Google Wallet, rendendoli accessibili su altri dispositivi su cui hai eseguito l'accesso. Se memorizzi i tuoi dati in Wallet, il numero reale della tua carta non verrà gestito da requestAutocomplete, aumentando la sicurezza. Se non hai eseguito l'accesso a Chrome o scegli di non utilizzare Google Wallet, i tuoi dati possono essere archiviati facoltativamente in locale nel browser per il riutilizzo. Questo è lo stato attuale delle cose, ma in futuro Chrome e altri browser potrebbero adottare altri fornitori di servizi di pagamento.

Semplificare i pagamenti

È un po' ridicolo che gli utenti debbano inserire i propri dati di pagamento ogni volta che vogliono effettuare un acquisto. Le cose si semplificano quando un sito memorizza i tuoi dati di pagamento, ma mi preoccupa il numero di siti che memorizzano i dati della mia carta. Si tratta di un problema perfetto per gli standard web. requestAutocomplete può portare i pagamenti con un solo clic su tutto il web, senza vincoli di servizio o piattaforma, ed è anche ora di farlo.

Tappa bonus: gestione dei moduli di più pagine

È molto meglio chiamare requestAutocomplete una volta e raccogliere tutti i dati di cui hai bisogno. Se non puoi modificare il server in modo che riceva tutti questi dati contemporaneamente, non preoccuparti: recupera i dati dal modulo compilato e inviali nel modo che preferisci. Puoi utilizzare questa utile funzione per acquisire tutti i dati attualmente supportati come un semplice oggetto, senza dover creare un modulo. Una volta ottenuti i dati, puoi trasformarli nel formato necessario per il tuo server e pubblicarli in più passaggi.

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
    });
  });
});