requestAutocomplete

Ambil uang saya, bukan waktu saya

Jake Archibald
Jake Archibald

Pengantar

Saya suka web. Secara keseluruhan, saya rasa itu ide yang cukup bagus. Oleh karena itu, saya sering terlibat dalam perdebatan web vs native. Tidak butuh waktu lama bagi orang lain untuk mulai membahas kemudahan pembayaran melalui sistem native. Respons saya biasanya adalah melempar bom asap dan berlari keluar ruangan sambil tertawa gila-gilaan, karena ini bukan argumen yang bisa saya menangkan. Tingkat pengabaian keranjang belanja di web seluler dapat mencapai 97%. Bayangkan hal itu di dunia nyata. Bayangkan 97% dari orang di supermarket, dengan keranjang terisi penuh dengan barang-barang yang mereka inginkan, meninggalkan keranjang mereka kemudian berjalan keluar. Sekarang, beberapa orang tersebut hanya menaikkan harga barang dan tidak pernah berniat untuk membeli, tetapi pengalaman pengguna yang mengerikan saat membeli di web adalah kontributor yang signifikan. Kami membebani pengguna dengan pajak atas kewarasan mereka. Pikirkan pengalaman pembayaran yang menyenangkan yang Anda alami di web, terutama di perangkat seluler. Ini adalah app store, bukan? Atau setidaknya sistem tertutup serupa yang sudah memiliki informasi pembayaran Anda. Ini adalah masalah. Hal ini mengharuskan situs berkomitmen pada penyedia pembayaran tertentu yang harus sudah memiliki akun dan login pengguna, atau berkomitmen pada platform yang mengharuskan pengguna login ke penyedia pembayaran tertentu, seperti app store yang mengharuskan Anda membuat kode khusus untuk platform tersebut. Jika Anda tidak melakukan salah satu hal ini, pengguna akan terus mengetuk layar atau keyboard hingga kulit jari mereka habis, atau mereka menyerah. Kita harus memperbaikinya.

requestAutocomplete

Di dunia WebGL, WebRTC, dan API web menarik lainnya yang dimulai dengan “Web”, requestAutocomplete agak tidak menarik. Namun, ini adalah superhero yang mengenakan pakaian berwarna krem. API kecil dan membosankan yang dapat menusuk jantung vampir waktu pembayaran web.

Daripada mengandalkan penyedia pembayaran tertentu, situs meminta detail pembayaran dari browser, yang menyimpannya atas nama pengguna. Versi requestAutocomplete() Chrome juga terintegrasi dengan Google Wallet untuk pengguna Amerika Serikat saja (saat ini). Coba di situs pengujian kami.

form.requestAutocomplete

Elemen formulir membawa satu metode baru, requestAutocomplete, yang meminta browser untuk mengisi formulir. Browser akan menampilkan dialog kepada pengguna yang meminta izin dan memungkinkan pengguna memilih detail yang ingin diberikan. Anda tidak dapat memanggilnya kapan saja, tetapi harus dipanggil selama eksekusi peristiwa interaksi tertentu seperti peristiwa mouse atas/bawah, klik, tombol, dan sentuh. Ini adalah pembatasan keamanan yang disengaja.

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

// TODO: listen for autocomplete events on the form

Sebelum melihat peristiwa, kita perlu memastikan browser memahami kolom formulir Anda…

Persyaratan formulir

Saat internet masih hitam putih, Internet Explorer 5 mengadopsi atribut baru, autocomplete, pada elemen input formulir. Tombol ini dapat disetel ke “nonaktif” untuk menghentikan browser menawarkan saran, dan itu saja. API ini diperluas sehingga Anda dapat menentukan konten kolom yang diharapkan tanpa mengubah atribut "name", dan inilah yang digunakan requestAutocomplete untuk menautkan kolom formulir ke data pengguna.

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

Sebagai spesifikasi, requestAutocomplete tidak khusus pembayaran, tetapi penerapan Chrome saat ini hampir khusus pembayaran. Di masa mendatang, browser diharapkan dapat menangani jenis data lainnya, seperti detail login dan generator sandi, informasi paspor, dan bahkan mengupload avatar.

Saat ini di Chrome, requestAutocomplete mengenali hal berikut:

Pembayaran

  • email
  • cc-name - name on card
  • cc-number - nomor kartu
  • cc-exp-month - bulan habis masa berlaku kartu sebagai dua digit
  • cc-exp-year - tahun habis masa berlaku kartu sebagai empat digit
  • cc-csc - kode keamanan kartu 3-4 digit
<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">

Atribut “name” yang saya gunakan di atas hanyalah contoh, tidak ada persyaratan untuk menggunakan nilai tertentu. Jika Anda akan menggunakan kembali formulir ini untuk pengguna tanpa requestAutocomplete, yang ideal, Anda harus menambahkan label, tata letak, dan validasi HTML5 dasar.

Anda juga tidak dibatasi pada elemen input, Anda dapat menggunakan jenis input formulir apa pun. Misalnya, Anda dapat menggunakan <select> untuk kolom masa berlaku kartu.

Pesan konsol mendetail.
Pesan konsol terperinci

Alamat

  • name - full name. Menggunakan nama lengkap sebagai satu kolom jauh lebih baik daripada beberapa kolom. Beberapa kolom seperti nama depan dan nama belakang menunjukkan bias Barat dan mungkin tidak masuk akal bagi budaya lain, selain itu lebih mudah untuk mengetik ke dalam satu kolom

  • tel - nomor telepon lengkap termasuk kode negara, atau dapat dibagi menjadi

    • tel-country-code - misalnya +44
    • tel-national - the rest
  • street-address - alamat lengkap dengan komponen yang dipisahkan koma, dapat dibagi menjadi

    • address-line1
    • address-line2 - boleh kosong
  • lokalitas - kota/kota kecil

  • region - Kode negara bagian, county, atau kanton

  • postal-code - Kode pos, kode pos, kode ZIP

  • country

Hal di atas harus digunakan bersama dengan: - penagihan - pengiriman

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

Sekali lagi, atribut nama adalah contoh, Anda dapat menggunakan nama apa pun yang Anda inginkan. Tentu saja tidak semua formulir harus meminta alamat pengiriman, misalnya, jangan bertanya kepada saya tempat saya ingin kamar hotel saya dikirimkan, karena lokasi saat ini sering kali menjadi nilai jual. Baik, jadi kita sudah memiliki formulir, dan kita tahu cara meminta autocompletion. Namun…

Kapan requestAutocomplete harus dipanggil?

Idealnya, Anda ingin menampilkan dialog requestAutocomplete, bukan memuat halaman yang menampilkan formulir checkout. Jika semuanya berjalan dengan baik, pengguna tidak akan melihat formulir tersebut sama sekali.

Alur Pembayaran

Pola umum adalah memiliki halaman keranjang dengan tombol “checkout” yang mengarahkan Anda ke formulir detail pembayaran. Dalam situasi ini, Anda ingin memuat formulir penagihan di halaman keranjang, tetapi menyembunyikannya dari pengguna, dan memanggil requestAutocomplete saat pengguna menekan tombol “checkout”. Ingat, Anda harus menayangkan halaman keranjang melalui SSL untuk menghindari peringatan Skeletor. Untuk memulai, kita harus menyembunyikan tombol checkout agar pengguna tidak dapat mengkliknya hingga kita siap, tetapi kita hanya ingin melakukannya untuk pengguna dengan JavaScript. Jadi, di bagian head halaman Anda:

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

Dan di CSS Anda:

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

Kita perlu menyertakan formulir penagihan di halaman keranjang. Ini dapat ditempatkan di mana saja, CSS di atas memastikannya tidak terlihat oleh pengguna.

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

Sekarang JavaScript kita dapat mulai menyiapkan semuanya:

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
}

Anda akan memanggil enhanceForm di halaman keranjang, beberapa saat setelah formulir dan tombol checkout. Browser yang mendukung requestAutocomplete akan mendapatkan pengalaman cepat baru yang menarik, sedangkan browser lain akan kembali ke formulir pembayaran normal Anda. Untuk mendapatkan poin bonus, Anda dapat memuat HTML formulir melalui XHR sebagai bagian dari enhanceForm. Artinya, Anda hanya dapat memuat formulir di browser yang mendukung requestAutocomplete, dan Anda tidak perlu mengingat untuk menambahkan formulir ke setiap halaman tempat Anda dapat memanggil enhanceForm. Beginilah cara kerja situs demo.

Anda telah memanggil requestAutocomplete, apa yang harus dilakukan selanjutnya?

Proses pelengkapan otomatis bersifat asinkron, requestAutocomplete akan langsung ditampilkan. Untuk mengetahui hasilnya, kita memproses beberapa peristiwa baru:

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

Jika semuanya berfungsi, Anda dapat melakukan apa pun yang Anda inginkan dengan data tersebut. Hal paling sederhana yang dapat dilakukan adalah mengirimkan formulir. Server kemudian dapat memvalidasi data dan memberi pengguna halaman konfirmasi yang menyertakan biaya pengiriman. Jika data tidak valid, Anda dapat menampilkan formulir dan menandai kolom yang perlu diubah oleh pengguna. Atau, Anda dapat mengirimkan formulir dan membiarkan validasi sisi server reguler Anda mengambil alih. Jika pengguna membatalkan proses, Anda tidak perlu melakukan apa pun. Jika fitur dinonaktifkan, arahkan pengguna ke formulir reguler. Jadi, dalam sebagian besar kasus, pemroses Anda akan terlihat seperti…

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

Di mana browser menyimpan data saya?

Spesifikasi ini tidak menentukan tempat data disimpan, sehingga browser dapat berinovasi. Jika Anda login ke Chrome, Anda akan mendapatkan opsi untuk menyimpan detail di Google Wallet, sehingga detail tersebut dapat diakses di perangkat lain yang Anda gunakan untuk login. Jika Anda menyimpan detail di Wallet, nomor kartu Anda yang sebenarnya tidak akan diberikan oleh requestAutocomplete, sehingga meningkatkan keamanan. Jika Anda tidak login ke Chrome, atau memilih untuk tidak menggunakan Google Wallet, detail Anda dapat disimpan secara lokal di browser untuk digunakan kembali. Inilah kondisinya saat ini, tetapi pada masa mendatang, Chrome dan browser lainnya dapat menggunakan penyedia pembayaran tambahan.

Mempermudah pembayaran

Agak konyol jika pengguna harus memasukkan informasi pembayaran mereka berulang kali setiap kali mereka ingin melakukan pembelian. Prosesnya menjadi lebih mudah jika situs menyimpan detail pembayaran Anda, tetapi saya sedikit tidak nyaman dengan banyaknya situs yang menyimpan detail kartu saya. Ini adalah masalah yang tepat untuk dipecahkan oleh standar web. requestAutocomplete dapat menghadirkan pembayaran sekali klik ke seluruh web, tanpa layanan atau platform lock-in, dan sudah waktunya juga.

Babak bonus: Menangani formulir multi-halaman

Sebaiknya panggil requestAutocomplete sekali dan kumpulkan semua data yang Anda perlukan. Jika Anda tidak dapat mengubah server untuk menerima semua data ini sekaligus, tidak apa-apa. Ambil data dari formulir yang telah diisi dan kirimkan dengan cara yang paling sesuai untuk Anda. Anda dapat menggunakan fungsi kecil yang praktis ini untuk mengambil semua data yang saat ini didukung sebagai objek sederhana, tanpa harus membuat formulir sendiri. Setelah memiliki data, Anda dapat mengubahnya ke format apa pun yang diperlukan server, dan mempostingnya dalam beberapa langkah.

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