requestAutocomplete

돈이 아니라 돈 가져가세요

제이크 아치볼드
제이크 아치볼드

소개

저는 웹을 좋아합니다. 대체로 좋은 생각이라고 생각합니다. 그래서 웹과 네이티브에 대한 논쟁을 많이 하고 있습니다. 상대방이 기본 시스템을 통한 지불의 용이성에 대해 이야기하는 데는 오래 걸리지 않습니다. 평소 내가 이길 수 있는 논쟁이 아니기 때문에 연막탄을 터뜨리고 미친 듯이 웃으면서 방 밖으로 나가는 거지. 모바일 웹에서의 장바구니 이탈은 최대 97%에 이를 수 있습니다. 현실 세계를 상상해 보세요. 슈퍼마켓에서 원하는 물건을 카트에 가득 채운 고객 중 97% 가 카트를 뒤집은 뒤 나가는 상황을 상상해 보세요. 일부 사용자는 단순히 물건을 구매할 의도가 없었지만, 웹에서 물건을 구매할 때 겪게 되는 끔찍한 경험은 중요한 요소입니다. Google은 사용자의 성향에 대한 세금을 부과하고 있습니다. 웹, 특히 모바일에서 즐거운 결제 경험을 했던 경험을 떠올려 보세요. 앱 스토어가 맞죠? 또는 이미 결제 정보가 있는 유사한 폐쇄형 시스템일 수도 있습니다. 이것은 문제입니다. 이 정책에 따라 사이트는 사용자가 이미 계정을 보유하고 있고 로그인되어 있어야 하는 특정 결제 시스템 공급자를 이용하겠다고 약속하거나, 특정 결제 시스템만을 위해 코딩해야 하는 앱 스토어처럼 사용자가 특정 결제 시스템 공급자로 로그인해야 하는 플랫폼을 약정해야 합니다. 개발자가 이러한 작업 중 하나를 수행하지 않으면, 사용자는 손가락 피부가 완전히 사라지거나 포기할 때까지 화면이나 키보드를 탭하여 벗어날 수밖에 없습니다. 이 문제를 해결해야 합니다.

requestAutocomplete

WebGL, WebRTC 및 '웹'으로 시작하는 기타 멋진 웹 API에서 requestAutocomplete는 과도하지 않습니다. 하지만 베이지색 옷을 입은 슈퍼히어로입니다. 이 작고 지루한 API로, 웹 결제 타임 뱀파이어의 핵심을 가르쳐 줄 수 있습니다.

사이트는 특정 결제 시스템 공급자에 의존하지 않고 브라우저에 결제 세부정보를 요청하며, 사용자 대신 정보를 저장합니다. Chrome 버전의 requestAutocomplete()는 미국 사용자만 (현재) Google 월렛과도 통합됩니다. 테스트 사이트에서 사용해 보세요.

form.requestAutocomplete

양식 요소는 브라우저에 양식을 채우도록 요청하는 단일 메서드인 requestAutocomplete를 전달합니다. 브라우저는 사용자에게 권한을 요청하고 사용자가 제공할 세부정보를 선택할 수 있는 대화상자를 표시합니다. 이 메서드는 원할 때마다 호출할 수 없으며, 마우스 위/아래, 클릭, 키, 터치 이벤트와 같은 특정 상호작용 이벤트가 실행되는 동안 호출되어야 합니다. 이는 의도적인 보안 제한입니다.

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

// TODO: listen for autocomplete events on the form

이벤트를 보기 전에 브라우저가 양식 필드를 이해하는지 확인해야 합니다.

양식 요구사항

인터넷이 흑백이었을 때 Internet Explorer 5는 양식 입력 요소에 새로운 속성인 autocomplete를 채택했습니다. '꺼짐'으로 설정하여 브라우저에서 제안을 제공하는 것을 중지할 수 있습니다. 'name' 속성을 수정하지 않고도 필드의 예상 콘텐츠를 지정할 수 있도록 이 API가 확장되었습니다. requestAutocomplete는 이 API를 사용하여 양식 필드를 사용자 데이터에 연결합니다.

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

참고로 requestAutocomplete는 결제 전용이 아니지만 현재 Chrome에서는 거의 구현되어 있습니다. 앞으로 브라우저는 로그인 세부정보와 비밀번호 생성기, 여권 정보, 아바타 업로드와 같은 다른 종류의 데이터를 처리할 수 있을 것으로 예상됩니다.

현재 Chrome에서 requestAutocomplete는 다음을 인식합니다.

지급

  • 이메일
  • cc-name - 카드에 기재된 이름
  • cc-number - 카드 번호
  • cc-exp-month - 카드 만료 월(2자리)
  • cc-exp-year - 카드 만료 연도(4자리)
  • cc-csc - 3-4자리 카드 보안 코드
<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">

위에서 사용한 'name' 속성은 예시일 뿐이며 특정 값을 사용할 필요는 없습니다. requestAutocomplete가 없는 사용자를 위해 이 양식을 재사용하려면 라벨, 레이아웃, 기본 HTML5 확인을 추가하는 것이 좋습니다.

입력 요소로 제한되지 않으며 모든 양식 입력 유형을 사용할 수 있습니다. 예를 들어 카드 만료 필드에 <select>를 사용할 수 있습니다.

자세한 콘솔 메시지입니다.
자세한 콘솔 메시지

주소

  • name - 성명. 전체 이름을 단일 필드로 사용하는 것이 여러 필드보다 훨씬 낫습니다. 이름과 성 같은 입력란이 여러 개인 경우 서양의 편견이 드러나 다른 문화권에서는 이해되지 않을 수 있으며, 하나의 입력란에 입력하는 것이 더 쉽기 때문입니다.

  • tel - 국가 코드를 포함한 전체 전화번호이며

    • tel-country-code - 예: +44
    • tel-national - 나머지
  • Street-address - 구성요소가 쉼표로 구분된 전체 주소이며

    • 주소-행1
    • address-line2 - 비어 있을 수 있음
  • 지역 - 구/군/시

  • 지역 - 주 코드, 카운티 또는 주

  • 우편번호 - 우편번호

  • country

위의 내용은 다음 항목과 함께 사용해야 합니다. - 청구 - 배송

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

앞서 언급했듯이 이름 속성은 예시이므로 원하는 대로 사용할 수 있습니다. 모든 양식에서 배송지 주소를 요청해야 하는 것은 당연합니다.예를 들어 어느 호텔 객실을 배송받고 싶은지 묻지 마세요. 주로 현재 위치가 판매 포인트인 경우가 많습니다. 맞습니다. Google 양식과 autocompletion 요청 방법을 알 수 있습니다. 하지만...

requestAutocomplete를 언제 호출해야 하나요?

결제 양식을 표시하는 페이지를 로드하는 대신 requestAutocomplete 대화상자를 표시하는 것이 좋습니다. 순조롭게 진행되면 사용자에게 양식이 표시되지 않습니다.

결제 흐름

일반적인 패턴은 결제 세부정보 양식으로 이동하는 '결제' 버튼이 있는 장바구니 페이지를 만드는 것입니다. 장바구니 페이지에서 결제 양식을 로드하지만 사용자에게는 숨기고 사용자가 '결제' 버튼을 누를 때 결제 양식에서 requestAutocomplete를 호출하려고 합니다. Skeletor 경고를 피하려면 SSL을 통해 장바구니 페이지를 제공해야 합니다. 먼저 준비가 될 때까지 사용자가 결제 버튼을 클릭할 수 없도록 결제 버튼을 숨겨야 하지만, JavaScript를 사용하는 사용자에게만 이 작업을 하려고 합니다. 따라서 페이지 헤드에서

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

CSS에서 다음을 수행합니다.

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

장바구니 페이지에 결제 양식을 포함해야 합니다. 어느 곳에나 사용할 수 있으며 위의 CSS를 통해 사용자에게 표시되지 않도록 합니다.

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

이제 JavaScript에서 모든 설정을 시작할 수 있습니다.

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
}

결제 양식 및 버튼이 표시된 후 장바구니 페이지에서 enhanceForm를 호출합니다. requestAutocomplete을(를) 지원하는 브라우저에서는 새롭고 멋지고 빠른 환경을 이용할 수 있으며, 다른 브라우저는 일반 결제 양식으로 돌아갑니다. 보너스 포인트를 받으려면 enhanceForm의 일부로 XHR을 통해 양식 HTML을 로드하는 것이 좋습니다. 즉, requestAutocomplete를 지원하는 브라우저에서만 양식을 로드할 수 있으며 enhanceForm를 호출하는 각 페이지에 양식을 추가할 필요가 없습니다. 데모 사이트의 작동 방식은 다음과 같습니다.

requestAutocomplete를 호출했는데 이제 어떻게 해야 할까요?

자동 완성 프로세스는 비동기적이며 requestAutocomplete는 즉시 반환됩니다. 어떻게 진행되었는지 알아보기 위해 몇 가지 새로운 이벤트를 수신합니다.

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

모든 것이 효과가 있다면 데이터로 원하는 작업을 할 수 있으며, 가장 간단한 방법은 양식을 제출하는 것입니다. 그런 다음 서버는 데이터를 확인하고 사용자에게 배송비가 포함된 확인 페이지를 제공할 수 있습니다. 데이터가 잘못된 경우 양식을 표시하고 사용자가 수정해야 하는 입력란을 강조 표시할 수 있습니다. 또는 양식을 제출하기만 하면 일반 서버 측 유효성 검사가 인계됩니다. 사용자가 프로세스를 취소한 경우에는 아무것도 할 필요가 없습니다. 이 기능이 사용 중지되면 사용자를 일반 양식으로 안내합니다. 대부분의 경우 리스너는 다음과 매우 유사합니다.

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

브라우저는 내 데이터를 어디에 저장하나요?

이 사양은 데이터 저장 위치를 지정하지 않으므로 브라우저가 혁신할 수 있습니다. Chrome에 로그인하면 Google 월렛에 세부정보를 저장할 수 있으므로 로그인한 다른 기기에서 세부정보를 확인할 수 있습니다. 월렛에 세부정보를 저장하면 requestAutocomplete에서 실제 카드 번호가 거래되지 않으므로 보안이 강화됩니다. Chrome에 로그인하지 않았거나 Google 월렛을 사용하지 않기로 선택한 경우 사용자의 세부정보는 선택적으로 다시 사용할 수 있도록 브라우저에 로컬로 저장됩니다. 지금은 현재 상태이지만 향후 Chrome 및 기타 브라우저에서 추가 결제 시스템 공급자를 채택할 수 있습니다.

간편 결제

사용자가 구매를 할 때마다 결제 정보를 반복해서 입력해야 한다는 것은 이상한 일입니다. 결제 세부정보가 사이트에 저장되면 상황이 좀 더 쉬워지는데, 제 카드 세부정보를 저장하는 사이트가 얼마나 되는지는 불안합니다. 이는 웹 표준으로 해결하기에 완벽한 문제입니다. requestAutocomplete을(를) 사용하면 서비스나 플랫폼에 구애받지 않고 웹 전체에서 원클릭 결제를 사용할 수 있습니다.

보너스 라운드: 다중 페이지 양식 처리

requestAutocomplete를 한 번 호출하고 필요한 모든 데이터를 수집하는 것이 훨씬 좋습니다. 이 모든 데이터를 한 번에 수신하도록 서버를 수정할 수 없더라도 괜찮습니다. 완성된 양식에서 데이터를 가져와 가장 효과적인 방법으로 제출하세요. 이 깔끔한 함수를 사용하면 양식을 직접 만들지 않고도 현재 지원되는 모든 데이터를 간단한 객체로 캡처할 수 있습니다. 데이터가 확보되면 서버에 필요한 형식으로 변환하고 여러 단계로 게시할 수 있습니다.

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