requestAutocomplete

Lấy tiền chứ không phải thời gian của tôi

Jake Archibald
J Jake Archibald

Giới thiệu

Tôi thích trang web. Nhìn chung, tôi nghĩ đó là một ý tưởng khá hay. Vì vậy, tôi thường tham gia rất nhiều cuộc tranh luận trên web và tự nhiên. Không mất nhiều thời gian để đối phương bắt đầu nói về sự dễ dàng của việc thanh toán thông qua hệ thống gốc. Phản ứng thường lệ của tôi là thả một quả bom khói rồi chạy ra khỏi phòng và cười điên rồ, vì tôi không thể thắng. Tỷ lệ bỏ ngang giỏ hàng trên web dành cho thiết bị di động có thể cao tới 97%. Hãy tưởng tượng điều đó trong thế giới thực. Hãy tưởng tượng 97% số người trong một siêu thị có một giỏ hàng chứa đầy những thứ họ muốn, lật giỏ hàng và bước ra. Giờ đây, một số người đó chỉ định giá cao và không có ý định mua, nhưng trải nghiệm người dùng rất khủng khiếp khi mua trên web là một yếu tố quan trọng góp phần đáng kể. Chúng tôi sẽ đánh thuế người dùng dựa trên sự an toàn của họ. Hãy nghĩ đến trải nghiệm thanh toán thú vị của bạn trên web, đặc biệt là trên thiết bị di động. Đó là một cửa hàng ứng dụng, đúng không? Hoặc ít nhất là một hệ thống khép kín tương tự đã có thông tin thanh toán của bạn. Đây là một vấn đề. Chính sách này yêu cầu các trang web cam kết với một nhà cung cấp dịch vụ thanh toán cụ thể rằng người dùng phải có tài khoản và phải đăng nhập, hoặc cam kết với một nền tảng yêu cầu người dùng phải đăng nhập vào một nhà cung cấp dịch vụ thanh toán cụ thể, chẳng hạn như một cửa hàng ứng dụng yêu cầu bạn chỉ được viết mã cho nền tảng đó. Nếu bạn không thực hiện một trong những thao tác này, người dùng sẽ vô tình nhấn vào màn hình hoặc bàn phím của họ cho đến khi tất cả ngón tay của họ biến mất hoặc họ bỏ cuộc. Chúng tôi cần khắc phục vấn đề đó.

requestAutocomplete

Trong thế giới WebGL, WebRTC và các API web lạ mắt khác bắt đầu bằng "Web", requestAutocomplete thật là tục tĩu. Tuy nhiên, đó là một siêu anh hùng mặc trang phục màu be. Một API nhỏ, nhàm chán, có thể sử dụng cốt lõi của công nghệ thanh toán trên web.

Thay vì dựa vào một nhà cung cấp dịch vụ thanh toán cụ thể, trang web yêu cầu thông tin thanh toán từ trình duyệt để lưu trữ thông tin đó thay mặt người dùng. Phiên bản requestAutofill() của Chrome cũng tích hợp với Google Wallet chỉ dành cho người dùng ở Hoa Kỳ (hiện tại). Hãy dùng thử tính năng này trên trang web thử nghiệm của chúng tôi.

form.requestAutocomplete

Các thành phần biểu mẫu có một phương thức mới là yêu cầu Tự động hoàn thành. Phương thức này sẽ yêu cầu trình duyệt điền vào biểu mẫu. Trình duyệt sẽ hiển thị một hộp thoại để người dùng yêu cầu cấp quyền và cho phép người dùng chọn thông tin chi tiết họ muốn cung cấp. Bạn không thể gọi lệnh này bất cứ khi nào bạn muốn, nó cần được gọi trong quá trình thực thi các sự kiện tương tác cụ thể như các sự kiện di chuột lên/xuống, nhấp, nhấn và chạm. Đây là một quy định hạn chế có chủ ý về bảo mật.

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

// TODO: listen for autocomplete events on the form

Trước khi xem xét các sự kiện, chúng tôi cần đảm bảo trình duyệt hiểu các trường trong biểu mẫu của bạn...

Yêu cầu về biểu mẫu

Trước khi Internet ở chế độ đen trắng, Internet Explorer 5 đã sử dụng một thuộc tính mới là autocomplete trong các phần tử đầu vào của biểu mẫu. Tôi có thể đặt chính sách này thành “tắt” để dừng trình duyệt đưa ra đề xuất, và thế là xong. API này đã được mở rộng để bạn có thể chỉ định nội dung dự kiến của trường mà không cần sửa đổi thuộc tính "name" và đây là nội dung mà requestAutocomplete sử dụng để liên kết các trường trong biểu mẫu với dữ liệu người dùng.

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

Về thông số kỹ thuật, requestAutocomplete không dành riêng cho việc thanh toán, nhưng cách triển khai hiện tại của Chrome lại quan trọng. Trong tương lai, hy vọng các trình duyệt sẽ có thể xử lý các loại dữ liệu khác, hy vọng là các thông tin như thông tin đăng nhập, trình tạo mật khẩu, thông tin hộ chiếu và thậm chí là tải hình đại diện lên.

Hiện có trong Chrome, requestAutocomplete nhận dạng những nội dung sau:

Thanh toán

  • email
  • cc-name – tên trên thẻ
  • số cc – số thẻ
  • cc-exp-month – tháng hết hạn thẻ dưới dạng hai chữ số
  • cc-exp-year – năm hết hạn thẻ dưới dạng bốn chữ số
  • cc-csc – Mã bảo mật thẻ gồm 3-4 chữ số
<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">

Các thuộc tính "tên" tôi đã sử dụng ở trên chỉ là ví dụ, không bắt buộc phải sử dụng các giá trị cụ thể. Nếu định sử dụng lại biểu mẫu này cho người dùng không có requestAutocomplete thì lý tưởng nhất là bạn nên thêm nhãn, bố cục và phương thức xác thực HTML5 cơ bản.

Bạn cũng không bị hạn chế nhập các phần tử và có thể sử dụng bất kỳ kiểu nhập biểu mẫu nào. Ví dụ: bạn có thể sử dụng <select> cho các trường ngày hết hạn của thẻ.

Thông báo chi tiết trên bảng điều khiển.
Thông báo chi tiết về bảng điều khiển

Address (Địa chỉ)

  • tên - tên đầy đủ. Việc lấy tên đầy đủ dưới dạng một trường duy nhất sẽ hiệu quả hơn nhiều so với nhiều trường. Nhiều trường như họ và tên cho thấy thiên kiến phương Tây và có thể không phù hợp với các nền văn hoá khác. Ngoài ra, việc nhập một trường sẽ dễ dàng hơn

  • tel – số điện thoại đầy đủ bao gồm mã quốc gia, ngoài ra có thể chia thành

    • tel-country-code – ví dụ: +44
    • công ty dịch vụ viễn thông – phần còn lại
  • địa chỉ đường phố - địa chỉ đầy đủ với các thành phần được phân tách bằng dấu phẩy, có thể được chia thành

    • dòng địa chỉ 1
    • address-line2 – có thể trống
  • địa phương - thành phố/thị trấn

  • vùng - Mã tiểu bang, hạt hoặc bang

  • mã bưu chính - Mã bưu chính, mã bưu điện, mã ZIP

  • country

Bạn nên sử dụng kết hợp những tính năng trên với: - thanh toán - thông tin vận chuyển

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

Một lần nữa, thuộc tính tên chỉ là ví dụ, bạn có thể sử dụng bất cứ điều gì bạn muốn. Rõ ràng là không phải biểu mẫu nào cũng cần yêu cầu địa chỉ giao hàng. Ví dụ: Đừng hỏi tôi nơi tôi muốn giao phòng khách sạn, vị trí hiện tại của địa điểm đó thường là điểm bán hàng. Đúng vậy, chúng tôi đã có biểu mẫu và biết cách yêu cầu autocompletion. Nhưng...

Khi nào nên gọi yêu cầu Tự động hoàn thành?

Lý tưởng nhất là bạn nên hiển thị hộp thoại requestAutocomplete thay vì tải trang hiển thị biểu mẫu thanh toán. Nếu mọi việc diễn ra suôn sẻ, người dùng sẽ hoàn toàn không thấy biểu mẫu đó.

Quy trình thanh toán

Một cách phổ biến là trang giỏ hàng có nút "thanh toán" đưa bạn đến biểu mẫu xem thông tin thanh toán. Trong trường hợp này, bạn muốn tải biểu mẫu thanh toán trên trang giỏ hàng, nhưng ẩn biểu mẫu thanh toán với người dùng và gọi requestAutocomplete trên biểu mẫu đó khi người dùng nhấp vào nút "thanh toán". Lưu ý rằng bạn cần phân phát trang giỏ hàng của mình qua SSL để tránh hiển thị cảnh báo Bộ xương. Để bắt đầu, chúng ta nên ẩn nút thanh toán để người dùng không nhấp vào được cho đến khi chúng ta sẵn sàng, nhưng chúng ta chỉ muốn làm điều này cho người dùng có JavaScript. Vì vậy, trong phần đầu trang:

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

Và trong CSS của bạn:

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

Chúng tôi cần đưa biểu mẫu thanh toán vào trang giỏ hàng. URL này có thể xuất hiện ở bất cứ đâu. CSS ở trên đảm bảo rằng người dùng không thấy được.

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

Giờ đây, JavaScript của chúng tôi có thể bắt đầu thiết lập mọi thứ:

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
}

Bạn sẽ gọi enhanceForm trên trang giỏ hàng, vào một lúc nào đó sau nút và biểu mẫu thanh toán. Các trình duyệt hỗ trợ requestAutocomplete sẽ có trải nghiệm nhanh chóng mới ưa thích, các trình duyệt khác sẽ quay lại hình thức thanh toán thông thường của bạn. Để nhận thêm điểm thưởng, bạn nên tải HTML của biểu mẫu qua XHR trong enhanceForm. Điều này có nghĩa là bạn chỉ có thể tải biểu mẫu trong các trình duyệt hỗ trợ requestAutocomplete và bạn không cần nhớ thêm biểu mẫu vào mỗi trang mà bạn có thể gọi enhanceForm. Đây là cách hoạt động của trang web minh hoạ.

Bạn đã gọi yêu cầu Tự động hoàn thành. Vậy bây giờ bạn nên làm gì?

Quá trình tự động hoàn thành không đồng bộ, requestAutocomplete sẽ trả về ngay lập tức. Để tìm hiểu điều đó diễn ra như thế nào, chúng ta hãy lắng nghe một số sự kiện mới:

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

Nếu mọi thứ hiệu quả, bạn có thể làm bất cứ điều gì mình muốn với dữ liệu này, nhưng đơn giản nhất cần làm là gửi biểu mẫu. Sau đó, máy chủ có thể xác thực dữ liệu và cung cấp cho người dùng trang xác nhận, bao gồm cả phí phân phối. Nếu dữ liệu không hợp lệ, bạn có thể hiển thị biểu mẫu và đánh dấu các trường mà người dùng cần sửa. Hoặc bạn chỉ cần gửi biểu mẫu và để quy trình xác thực phía máy chủ thông thường tiếp quản. Nếu người dùng đã huỷ quá trình, bạn thực sự không cần làm gì cả. Nếu tính năng này bị tắt, hãy chuyển người dùng tới biểu mẫu thông thường. Vì vậy, trong hầu hết các trường hợp, người nghe sẽ rất giống...

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

Trình duyệt lưu trữ dữ liệu của tôi ở đâu?

Quy cách không chỉ ra nơi lưu trữ dữ liệu, mà cho phép trình duyệt đổi mới. Nếu đã đăng nhập vào Chrome, bạn có thể lưu trữ thông tin chi tiết trong Google Wallet. Nhờ đó, bạn có thể truy cập vào những thông tin này trên các thiết bị khác mà bạn đã đăng nhập. Nếu bạn lưu trữ thông tin chi tiết trong Wallet, thì requestAutocomplete sẽ không xử lý số thẻ thực của bạn, nhờ đó tăng tính bảo mật. Nếu bạn chưa đăng nhập vào Chrome hoặc chọn không sử dụng Google Wallet, thông tin chi tiết của bạn sẽ được tuỳ chọn lưu trữ trên trình duyệt để sử dụng lại. Đây là tình trạng của mọi thứ hiện tại, nhưng trong tương lai, Chrome và các trình duyệt khác có thể áp dụng nhà cung cấp dịch vụ thanh toán khác.

Thanh toán dễ dàng

Một điều vô lý là người dùng phải nhập lại thông tin thanh toán của mình nhiều lần mỗi khi muốn mua hàng. Mọi thứ trở nên dễ dàng hơn khi một trang web lưu trữ thông tin thanh toán của bạn, tôi hơi không yên tâm về số lượng trang web lưu trữ thông tin thẻ của mình. Đây là một vấn đề hoàn hảo mà các tiêu chuẩn web cần giải quyết. requestAutocomplete có thể hỗ trợ thanh toán chỉ bằng một lần nhấp cho mọi trang web mà không bị bó buộc với dịch vụ hoặc nền tảng và cũng mất nhiều thời gian!

Vòng thêm: Xử lý các biểu mẫu nhiều trang

Bạn nên gọi cho requestAutocomplete một lần và thu thập tất cả dữ liệu bạn cần. Nếu bạn không thể sửa đổi máy chủ của mình để nhận tất cả dữ liệu này cùng một lúc, cũng không sao, hãy lấy dữ liệu từ biểu mẫu đã hoàn tất và gửi dữ liệu đó theo cách tốt nhất cho bạn. Bạn có thể sử dụng hàm nhỏ tiện lợi này để thu thập tất cả dữ liệu hiện được hỗ trợ dưới dạng một đối tượng đơn giản mà không cần phải tự tạo biểu mẫu. Sau khi có dữ liệu, bạn có thể chuyển đổi thành bất kỳ định dạng nào mà máy chủ của bạn cần và đăng dữ liệu đó trong nhiều bước.

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