requestAutocomplete

Nehmen Sie mein Geld, aber nicht meine Zeit

Jake Archibald
Jake Archibald

Einführung

Ich mag das Web. Alles in allem finde ich das eine ziemlich gute Idee. Daher werde ich oft in Debatten über Web- und native Apps verwickelt. Es dauert nicht lange, bis die andere Person über die einfache Abwicklung von Zahlungen über native Systeme spricht. Meine übliche Reaktion ist, eine Rauchbombe zu zünden und lachhaft aus dem Raum zu rennen, weil ich dieses Argument nicht gewinnen kann. Der Anteil der Nutzer, die den Bezahlvorgang im mobilen Web abbrechen, kann bis zu 97%betragen. Stellen Sie sich das in der realen Welt vor. Stellen Sie sich vor, 97% der Menschen in einem Supermarkt würden ihren Einkaufswagen, der bis oben hin mit den gewünschten Artikeln gefüllt ist, umwerfen und den Laden verlassen. Einige dieser Personen geben einfach nur Preise an und hatten nie die Absicht zu kaufen, aber die schreckliche Nutzererfahrung beim Onlinekauf trägt dazu bei. Wir fordern von den Nutzern eine Steuer auf ihre geistige Gesundheit. Denken Sie an eine positive Zahlungserfahrung, die Sie im Web gemacht haben, insbesondere auf Mobilgeräten. Es ist ein App-Shop, richtig? Oder zumindest ein ähnliches geschlossenes System, das bereits Ihre Zahlungsinformationen enthält. Das ist ein Problem. Websites müssen sich dabei zu einem bestimmten Zahlungsanbieter verpflichten, bei dem der Nutzer bereits ein Konto hat und in dem er angemeldet ist, oder zu einer Plattform, bei der Nutzer bei einem bestimmten Zahlungsanbieter angemeldet sein müssen, z. B. App-Shops, bei denen Sie ausschließlich für diese Plattform programmieren müssen. Wenn Sie keines dieser Dinge tun, ist der Nutzer gezwungen, auf dem Display oder der Tastatur herumzutippen, bis die Haut seiner Finger abgetragen ist oder er aufgibt. Das müssen wir beheben.

requestAutocomplete

In einer Welt mit WebGL, WebRTC und anderen ausgefallenen Web-APIs, die mit „Web“ beginnen, ist requestAutocomplete eher unscheinbar. Es ist jedoch ein Superheld in beigefarbener Kleidung. Eine winzige, langweilige API, die dem Zeitvampir der Webzahlungen einen Pfahl durchs Herz rammen kann.

Anstatt sich auf einen bestimmten Zahlungsanbieter zu verlassen, fordert die Website Zahlungsdetails vom Browser an, der sie im Namen des Nutzers speichert. Die Chrome-Version von „requestAutocomplete()“ kann auch mit Google Wallet verknüpft werden, aber derzeit nur für Nutzer in den USA. Probieren Sie es auf unserer Testwebsite aus.

form.requestAutocomplete

Formularelemente haben eine neue Methode namens „requestAutocomplete“, mit der der Browser aufgefordert wird, das Formular auszufüllen. Der Browser zeigt dem Nutzer ein Dialogfeld an, in dem er um Erlaubnis gebeten wird und auswählen kann, welche Details er angeben möchte. Sie können diese Funktion nicht beliebig oft aufrufen. Sie muss während der Ausführung bestimmter Interaktionsereignisse wie Maus-nach-oben/nach-unten-, Klick-, Tasten- und Touch-Ereignisse aufgerufen werden. Dies ist eine beabsichtigte Sicherheitseinschränkung.

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

// TODO: listen for autocomplete events on the form

Bevor wir uns die Ereignisse ansehen, müssen wir dafür sorgen, dass der Browser Ihre Formularfelder versteht…

Anforderungen an Formulare

Damals, als das Internet noch schwarz-weiß war, führte Internet Explorer 5 das neue Attribut autocomplete für Formulareingabeelemente ein. Sie konnte auf „Aus“ gesetzt werden, damit der Browser keine Vorschläge mehr machte. Diese API wurde erweitert, sodass Sie den erwarteten Inhalt des Felds angeben können, ohne das Attribut „name“ zu ändern. So werden in requestAutocomplete Formularfelder mit Nutzerdaten verknüpft.

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

Als Spezifikation ist requestAutocomplete nicht zahlungsspezifisch, aber die aktuelle Implementierung in Chrome ist es ziemlich. In Zukunft werden Browser voraussichtlich auch andere Arten von Daten verarbeiten können, z. B. Anmeldedaten und Passwortgenerator, Passinformationen und sogar das Hochladen eines Avatars.

Derzeit wird in Chrome Folgendes durch requestAutocomplete erkannt:

Zahlung

  • E-Mail
  • cc-name – Name auf der Karte
  • cc-number - Kartennummer
  • cc-exp-month – Monat des Ablaufdatums der Karte als zweistellige Zahl
  • cc-exp-year – Jahr des Ablaufdatums der Karte als vierstellige Zahl
  • cc-csc – drei- bis vierstelliger Kartensicherheitscode
<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">

Die oben verwendeten „name“-Attribute sind nur Beispiele. Es ist nicht erforderlich, bestimmte Werte zu verwenden. Wenn Sie dieses Formular für Nutzer ohne requestAutocomplete wiederverwenden möchten, was ideal ist, sollten Sie Labels, ein Layout und eine grundlegende HTML5-Validierung hinzufügen.

Sie sind auch nicht auf Eingabeelemente beschränkt, sondern können jeden Formulareingabetyp verwenden. Sie können beispielsweise <select> für die Gültigkeitsfelder der Karte verwenden.

Detaillierte Konsolenmeldung
Detaillierte Konsolenmeldung

Adresse

  • name – vollständiger Name. Ein vollständiger Name in einem einzelnen Feld ist viel besser als mehrere Felder. Mehrere Felder wie „Vorname“ und „Nachname“ sind westliche Voreingenommenheiten und haben für andere Kulturen möglicherweise keinen Sinn. Außerdem ist es einfacher, in ein einzelnes Feld zu tippen.

  • tel – vollständige Telefonnummer einschließlich Ländervorwahl, kann alternativ in folgende Bestandteile unterteilt werden:

    • tel-country-code – z.B. +44
    • tel-national – Rest
  • street-address: Vollständige Adresse mit durch Kommas getrennten Komponenten, kann in folgende Bestandteile unterteilt werden:

    • address-line1
    • address-line2 – kann leer sein
  • Ort – Stadt

  • region – Bundesland, Landkreis oder Kanton

  • postal-code – Postleitzahl

  • country

Die oben genannten Informationen sollten in Kombination mit folgenden Angaben verwendet werden: - Abrechnung - Versand

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

Die Namensattribute sind wieder nur Beispiele. Sie können beliebige Namen verwenden. Natürlich sollte nicht in jedem Formular eine Lieferadresse abgefragt werden. Fragen Sie mich beispielsweise nicht, wo ich mein Hotelzimmer geliefert haben möchte, da der aktuelle Standort oft das Verkaufsargument ist. Alles klar. Wir haben unser Formular und wissen, wie wir autocompletion anfordern. Aber…

Wann sollte „requestAutocomplete“ aufgerufen werden?

Idealerweise sollte das Dialogfeld requestAutocomplete angezeigt werden, anstatt die Seite mit dem Zahlungsformular zu laden. Wenn alles richtig funktioniert, sollte der Nutzer das Formular gar nicht sehen.

Zahlungsablauf

Ein gängiges Muster ist eine Warenkorbseite mit einer Schaltfläche „Zur Kasse“, über die Sie zum Formular für Zahlungsdetails gelangen. In diesem Fall möchten Sie Ihr Zahlungsformular auf der Einkaufswagenseite laden, es aber für den Nutzer ausblenden und requestAutocomplete aufrufen, wenn der Nutzer auf die Schaltfläche „Kasse“ klickt. Denken Sie daran, dass Sie Ihre Warenkorbseite über SSL bereitstellen müssen, um die Skeletor-Warnung zu vermeiden. Zuerst sollten wir die Schaltfläche „Kasse“ ausblenden, damit Nutzer sie erst anklicken können, wenn wir bereit sind. Das soll aber nur für Nutzer mit JavaScript gelten. Fügen Sie im Head-Bereich Ihrer Seite Folgendes hinzu:

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

Und in Ihrem Preisvergleichsportal:

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

Wir müssen das Zahlungsformular auf unserer Einkaufswagenseite einfügen. Dieser kann überall platziert werden. Das CSS oben sorgt dafür, dass er für den Nutzer nicht sichtbar ist.

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

Jetzt kann unser JavaScript alles einrichten:

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
}

Sie rufen enhanceForm auf der Seite mit dem Einkaufswagen auf, kurz nach dem Zahlungsformular und der Schaltfläche. In Browsern, die requestAutocomplete unterstützen, wird die neue, schnelle Zahlungsfunktion angezeigt. In anderen Browsern wird das normale Zahlungsformular verwendet. Für Bonuspunkte können Sie das Formular-HTML als Teil von enhanceForm über XHR laden. Das Formular kann also nur in Browsern geladen werden, die requestAutocomplete unterstützen. Außerdem müssen Sie nicht daran denken, das Formular auf jeder Seite einzufügen, von der aus Sie requestAutocomplete aufrufen können.enhanceForm So funktioniert die Demowebsite.

Sie haben „requestAutocomplete“ aufgerufen. Was passiert jetzt?

Der Autocomplete-Vorgang ist asynchron. requestAutocomplete wird sofort zurückgegeben. Um herauszufinden, wie das funktioniert hat, hören wir uns ein paar neue Ereignisse an:

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

Wenn alles funktioniert hat, können Sie mit den Daten machen, was Sie möchten. Am einfachsten ist es, das Formular einzureichen. Der Server kann dann die Daten validieren und dem Nutzer eine Bestätigungsseite mit den Versandkosten anzeigen. Wenn die Daten ungültig sind, können Sie das Formular anzeigen und die Felder hervorheben, die der Nutzer ändern muss. Alternativ können Sie das Formular einfach einreichen und die reguläre serverseitige Validierung übernehmen lassen. Wenn der Nutzer den Vorgang abgebrochen hat, müssen Sie nichts weiter tun. Wenn die Funktion deaktiviert ist, leite den Nutzer an das normale Formular weiter. In den meisten Fällen sehen deine Zuhörer also so aus:

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

Wo speichert der Browser meine Daten?

Die Spezifikation legt nicht fest, wo Daten gespeichert werden, sodass Browser innovativ sein können. Wenn Sie in Chrome angemeldet sind, können Sie Details in Google Wallet speichern und so auf anderen Geräten darauf zugreifen, auf denen Sie angemeldet sind. Wenn Sie Ihre Daten in Wallet speichern, wird Ihre echte Kartennummer nicht von requestAutocomplete weitergegeben. So wird die Sicherheit erhöht. Wenn Sie nicht in Chrome angemeldet sind oder Google Wallet nicht verwenden, werden Ihre Daten optional lokal im Browser zur Wiederverwendung gespeichert. Das ist der aktuelle Stand. In Zukunft werden in Chrome und anderen Browsern möglicherweise weitere Zahlungsanbieter unterstützt.

Einfache Zahlungen

Es ist ziemlich lächerlich, dass Nutzer jedes Mal ihre Zahlungsinformationen eingeben müssen, wenn sie etwas kaufen möchten. Es ist einfacher, wenn eine Website Ihre Zahlungsdetails speichert. Ich bin jedoch etwas beunruhigt darüber, wie viele Websites meine Kartendetails speichern. Das ist ein perfektes Problem für Webstandards. requestAutocomplete kann Zahlungen per Klick im gesamten Web ermöglichen, ohne dass Nutzer an einen Dienst oder eine Plattform gebunden sind. Es ist an der Zeit!

Bonusrunde: Mehrseitige Formulare

Es ist viel besser, requestAutocomplete einmal aufzurufen und alle benötigten Daten zu erheben. Wenn Sie Ihren Server nicht so ändern können, dass alle diese Daten gleichzeitig empfangen werden, ist das in Ordnung. Sie können die Daten aus dem ausgefüllten Formular kopieren und auf die für Sie am besten geeignete Weise einreichen. Mit dieser nützlichen Funktion können Sie alle derzeit unterstützten Daten als einfaches Objekt erfassen, ohne selbst ein Formular erstellen zu müssen. Sobald Sie die Daten haben, können Sie sie in das Format umwandeln, das Ihr Server benötigt, und sie in mehreren Schritten posten.

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