requestAutocomplete

קחו את הכסף שלי, לא את הזמן שלי

Jake Archibald
Jake Archibald

מבוא

אני אוהב את האינטרנט. בסך הכול, לדעתי זה רעיון טוב. לכן, אני נכנס לדיונים רבים בנושא מודעות אינטרנט לעומת מודעות מותאמות. לא ייקח הרבה זמן עד שהאדם השני יתחיל לדבר על הקלות של תשלומים דרך מערכות מקומיות. התגובה הרגילה שלי היא לזרוק פצצת עשן ולברוח מהחדר תוך כדי צחוק מטורף, כי זו לא וויכוח שאני יכולה לנצח בו. שיעור הנטישה של עגלות קניות באינטרנט לנייד יכול להגיע ל-97%. דמיינו את זה בעולם האמיתי. נסו לדמיין 97% מהאנשים בסופרמרקט, עם עגלה מלאה בדברים שהם רוצים, שמפנים את העגלה וממשיכים הלאה. חלק מהאנשים האלה רק בודקים מחירים ומעולם לא התכוונו לקנות, אבל חוויית המשתמש האיומה של רכישה באינטרנט תורמת לכך באופן משמעותי. אנחנו מחייבים את המשתמשים בתשלום על שפיותם. נסו לחשוב על חוויית תשלום מהנה שהייתה לכם באינטרנט, במיוחד בנייד. זו חנות אפליקציות, נכון? או לפחות מערכת סגורה דומה שכבר מכילה את פרטי התשלום שלכם. זו בעיה. המדיניות מחייבת אתרים להתחייב לספק תשלומים מסוים, שכבר צריך להיות למשתמש חשבון אצלו והוא צריך להיות מחובר אליו, או להתחייב לפלטפורמה שמחייבת את המשתמשים להתחבר לספק תשלומים מסוים, כמו חנויות אפליקציות שמחייבות לכתוב קוד רק לפלטפורמה הזו. אם לא תעשו אחת מהפעולות האלה, המשתמש יאלץ להקיש על המסך או על המקלדת עד שכל העור באצבעות שלו יירד, או עד שהוא יתייאש. אנחנו צריכים לתקן את זה.

requestAutocomplete

בעולם של WebGL, ‏ WebRTC ו-Web APIs אחרים ומפונפנים שמתחילים ב-'Web', requestAutocomplete הוא קצת פחות זוהר. עם זאת, זהו גיבור-על בבגדים בצבע בז'. ממשק API קטן ומשעמם שיכול להחדיר יתד ללב של ערפד הזמן של תשלומי האינטרנט.

במקום שהאתר יסמוך על ספק תשלומים מסוים, הוא מבקש את פרטי התשלום מהדפדפן, שמאחסן אותם בשם המשתמש. הגרסה של requestAutocomplete() ב-Chrome משולבת גם ב-Google Wallet עבור משתמשים בארה"ב בלבד (כרגע). כדאי לנסות את התכונה באתר הבדיקה שלנו.

form.requestAutocomplete

רכיבי הטפסים כוללים שיטה חדשה אחת, requestAutocomplete, שמבקשת מהדפדפן לאכלס את הטופס. הדפדפן יציג למשתמש תיבת דו-שיח עם בקשה להרשאה, שתאפשר לו לבחור אילו פרטים הוא רוצה לספק. אי אפשר להפעיל את הפונקציה הזו מתי שרוצים, אלא רק במהלך ביצוע של אירועי אינטראקציה ספציפיים, כמו אירועי העכבר למעלה/למטה, אירועי לחיצה, אירועי מקש ואירועי מגע. זוהי הגבלת אבטחה מכוונת.

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

// TODO: listen for autocomplete events on the form

לפני שנבדוק את האירועים, אנחנו צריכים לוודא שהדפדפן מבין את שדות הטופס…

הדרישות לגבי טפסים

בימים שבהם האינטרנט היה בשחור-לבן, גרסה 5 של Internet Explorer אימצה מאפיין חדש, autocomplete, לאלמנטי קלט בטופס. אפשר להגדיר את האפשרות הזו ל'מושבתת' כדי שהדפדפן יפסיק להציע הצעות, וזה הכל. ה-API הזה הורחב כדי שתוכלו לציין את התוכן הצפוי של השדה בלי לשנות את המאפיין 'name'. זהו התוכן ש-requestAutocomplete משתמש בו כדי לקשר בין שדות הטופס לנתוני המשתמשים.

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

כמפרט, requestAutocomplete לא ספציפי לתשלומים, אבל ההטמעה הנוכחית ב-Chrome היא כמעט ספציפית לתשלומים. בעתיד, הדפדפנים יוכלו לטפל בסוגי נתונים אחרים, כמו פרטי התחברות ויצירת סיסמאות, פרטי דרכון ואפילו העלאת תמונת פרופיל.

נכון לעכשיו, ב-Chrome, requestAutocomplete מזהה את האפשרויות הבאות:

תשלום

  • אימייל
  • cc-name - name on card
  • cc-number - מספר כרטיס
  • cc-exp-month – חודש התפוגה של הכרטיס בשתי ספרות
  • cc-exp-year – שנת התפוגה של הכרטיס בארבע ספרות
  • 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 – שם מלא. עדיף להשתמש בשם מלא כשדה יחיד מאשר בשדות מרובים. שדות מרובים כמו first-name ו-last-name משקפים הטיה מערבית, ויכול להיות שהם לא יתאימו לתרבויות אחרות. בנוסף, קל יותר להקליד בשדה אחד.

  • tel – מספר טלפון מלא, כולל קידומת המדינה. אפשר גם לפרק אותו ל-

    • tel-country-code – לדוגמה, ‎+44
    • tel-national - the rest
  • street-address – כתובת מלאה עם רכיבים מופרדים בפסיקים, שניתן לפרק אותה ל-

    • address-line1
    • address-line2 – יכול להיות ריק
  • רשות מוניציפאלית – עיר/יישוב

  • אזור – קוד מדינה, מחוז או קנטון

  • postal-code – מיקוד

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

שוב, מאפייני השם הם דוגמאות, אפשר להשתמש בכל שם שרוצים. ברור שלא צריך לבקש כתובת למשלוח בכל הטפסים. לדוגמה, אין צורך לשאול אותי לאן אני רוצה שהחדר במלון יישלח, כי המיקום הנוכחי שלו הוא לרוב נקודת המכירה. בסדר, יש לנו את הטופס ואנחנו יודעים איך לבקש את 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 תהיה חוויה מהירה ומודרנית, ובדפדפנים אחרים תופיע שוב טופס התשלום הרגיל. כדי לקבל נקודות בונוס, מומלץ לטעון את ה-HTML של הטופס דרך XHR כחלק מ-enhanceForm. המשמעות היא שאפשר לטעון את הטופס רק בדפדפנים שתומכים ב-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 Wallet כדי שתוכלו לגשת אליהם במכשירים אחרים שבהם אתם מחוברים. אם תשמרו את הפרטים ב-Wallet, מספר הכרטיס האמיתי שלכם לא יועבר על ידי requestAutocomplete, וכך האבטחה תשתפר. אם לא נכנסתם לחשבון ב-Chrome או אם בחרתם לא להשתמש ב-Google Wallet, הפרטים שלכם יישמרו באופן מקומי בדפדפן לשימוש חוזר, אם תבחרו בכך. זה המצב כרגע, אבל בעתיד יכול להיות ש-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
    });
  });
});