requestAutocomplete

मेरे पैसे लो, मेरा समय नहीं

जेक आर्चिबाल्ड
जेक आर्चिबाल्ड

शुरुआती जानकारी

मुझे वेब पसंद है. कुल मिलाकर, मुझे लगता है कि यह बहुत अच्छा आइडिया है. इसलिए, मैं बहुत सी वेब के मुकाबले स्थानीय बहस में शामिल हो जाती हूं. नेटिव सिस्टम से पेमेंट पाना आसान होने के बारे में बात करने में, दूसरे व्यक्ति को ज़्यादा समय नहीं लगता. मेरा आम जवाब यह है कि मैं स्मोक बम गिराऊं और पागलों की तरह हंसते हुए कमरे से भागूं, क्योंकि इसमें कोई ऐसा तर्क नहीं है जिसे मैं जीत सकूं. मोबाइल वेब पर शॉपिंग कार्ट छोड़ने की दर 97%तक हो सकती है. असल दुनिया में इसकी कल्पना करें. ज़रा सोचिए कि किसी सुपरमार्केट में 97% लोग, अपनी पसंद की चीज़ों से भरी गाड़ी में अपनी गाड़ी पलटते हुए बाहर निकल जाते हैं. अब, उनमें से कुछ लोग सिर्फ़ सामान की कीमत तय कर रहे हैं और उन पर खरीदारी का कोई इरादा नहीं था, लेकिन वेब पर खरीदारी करने से जुड़ा खराब उपयोगकर्ता अनुभव, इसमें ज़्यादा योगदान देता है. हम उपयोगकर्ताओं पर टैक्स देकर उनकी निजता का ध्यान रखते हैं. वेब पर, खास तौर पर मोबाइल पर पेमेंट का एक अच्छा अनुभव देने के बारे में सोचें. यह ऐप स्टोर है, है न? इसके अलावा, कम से कम इस तरह का कोई क्लोज़्ड सिस्टम जिसमें आपके क्रेडिट/डेबिट कार्ड की जानकारी पहले से मौजूद हो. यह एक समस्या है. इसके लिए, साइटों को पेमेंट की सेवा देने वाली किसी खास कंपनी से वादा करना होगा कि उपयोगकर्ता के पास पहले से ही खाता होना चाहिए और उसमें लॉग इन होना चाहिए. इसके अलावा, वे ऐसे प्लैटफ़ॉर्म से भी साइन इन कर सकती हैं जिसके लिए उपयोगकर्ताओं को पेमेंट की सेवा देने वाली किसी खास कंपनी के तौर पर लॉग इन करना ज़रूरी होता है. उदाहरण के लिए, एक ऐप स्टोरक्स जिसके लिए आपको सिर्फ़ उसी प्लैटफ़ॉर्म के लिए कोड करना पड़ता है. अगर आप इनमें से कोई भी काम नहीं करते हैं, तो उपयोगकर्ता को अपनी स्क्रीन या कीबोर्ड पर तब तक टैप करना पड़ता है, जब तक कि उसकी सारी उंगली हट न जाए या वह हार न मान ले. हमें उसे ठीक करना होगा.

requestAutocomplete

WebGL, WebRTC, और “Web” से शुरू होने वाले अन्य फ़ैंसी वेब एपीआई की दुनिया में, requestAutocomplete काफ़ी अलग है. हालांकि, बेज रंग के कपड़ों में यह एक सुपरहीरो है. एक छोटा, उबाऊ API, जो वेब भुगतान टाइम-वैंपायर के हृदय में दांव लगा सकता है.

इसके बजाय, साइट किसी खास पेमेंट की सेवा देने वाली कंपनी पर निर्भर होती है. इसके बजाय, वह उस ब्राउज़र से पेमेंट के तरीके की जानकारी मांगती है. इस ब्राउज़र में यह जानकारी, उपयोगकर्ता की ओर से सेव की जाती है. Chrome, requestAutocomplete() का वर्शन सिर्फ़ अमेरिका के उपयोगकर्ताओं (फ़िलहाल) के लिए Google Wallet के साथ इंटिग्रेट हो जाता है. हमारी टेस्ट साइट पर इसे आज़माएं.

form.requestAutocomplete

फ़ॉर्म एलिमेंट में अनुरोध का एक नया तरीका होता है. इस तरीके का इस्तेमाल करके, ब्राउज़र से फ़ॉर्म भरने के लिए कहा जाता है. ब्राउज़र, उपयोगकर्ता से अनुमति मांगने के लिए एक डायलॉग दिखाएगा. साथ ही, उन्हें यह चुनने की अनुमति देगा कि उन्हें कौनसी जानकारी देनी है. हालांकि, इसे कभी भी कॉल नहीं किया जा सकता. इंटरैक्शन वाले इवेंट के दौरान, इसे कॉल करना ज़रूरी है, जैसे कि माउस अप/डाउन, क्लिक, बटन, और टच इवेंट. यह जान-बूझकर की गई सुरक्षा से जुड़ी पाबंदी है.

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

// TODO: listen for autocomplete events on the form

इन इवेंट को देखने से पहले, हमें यह पक्का करना होगा कि ब्राउज़र आपके फ़ॉर्म फ़ील्ड को समझता है...

फ़ॉर्म से जुड़ी ज़रूरी शर्तें

जब इंटरनेट ब्लैक ऐंड व्हाइट था, तब Internet Explorer 5 ने फ़ॉर्म के इनपुट एलिमेंट में एक नया एट्रिब्यूट, autocomplete अपनाया. ब्राउज़र के सुझाव देने से रोकने के लिए, इसे "बंद" पर सेट किया जा सकता है और बस इतना ही. इस एपीआई को बढ़ा दिया गया था, ताकि “नाम” एट्रिब्यूट में बदलाव किए बिना, फ़ील्ड का वह कॉन्टेंट बताया जा सके जिसकी उम्मीद थी. requestAutocomplete इसी का इस्तेमाल करके, फ़ॉर्म फ़ील्ड को उपयोगकर्ता के डेटा से लिंक करता है.

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

खास जानकारी के तौर पर, requestAutocomplete का इस्तेमाल पेमेंट के हिसाब से नहीं किया जा सकता. हालांकि, Chrome का हाल ही में इस्तेमाल किया जा रहा है. आने वाले समय में, ब्राउज़र से अन्य तरह के डेटा को भी मैनेज किया जा सकेगा. उम्मीद है कि ब्राउज़र, लॉगिन की जानकारी, पासवर्ड जनरेटर, पासपोर्ट की जानकारी, और अवतार अपलोड करने जैसी चीज़ों को आसानी से मैनेज कर पाएंगे.

फ़िलहाल, Chrome में requestAutocomplete इनकी पहचान करता है:

पेमेंट

  • email
  • cc-name - कार्ड पर लिखा नाम
  • 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">

मैंने ऊपर जो “नाम” एट्रिब्यूट इस्तेमाल किए हैं वे सिर्फ़ उदाहरण हैं. किसी खास वैल्यू का इस्तेमाल करने की ज़रूरत नहीं है. अगर आपको उन उपयोगकर्ताओं के लिए इस फ़ॉर्म का फिर से इस्तेमाल करना है जिनके लिए requestAutocomplete सही नहीं है, तो बेहतर होगा कि आप उनमें लेबल, लेआउट, और HTML5 की बुनियादी पुष्टि करें.

आप इनपुट एलिमेंट तक सीमित नहीं हैं. आपके पास किसी भी फ़ॉर्म इनपुट प्रकार का इस्तेमाल करने का विकल्प है. उदाहरण के लिए, कार्ड की समयसीमा खत्म होने वाले फ़ील्ड के लिए, <select> का इस्तेमाल किया जा सकता है.

कंसोल मैसेज के बारे में ज़्यादा जानकारी.
कंसोल मैसेज के बारे में ज़्यादा जानकारी

पता

  • नाम - पूरा नाम. कई फ़ील्ड के बजाय, एक फ़ील्ड के तौर पर पूरा नाम लेना बेहतर है. नाम और उपनाम जैसे कई फ़ील्ड में पश्चिमी पक्ष का पूर्वाग्रह होता है. इसलिए, हो सकता है कि ये फ़ील्ड अन्य संस्कृतियों के लिए सही न हों. साथ ही, एक फ़ील्ड में टाइप करना आसान है

  • टेलीफ़ोन नंबर - देश कोड के साथ पूरा टेलीफ़ोन नंबर. इसे वैकल्पिक रूप से बांटा जा सकता है

    • tel-country-code - जैसे, +44
    • टेली-नैशनल - बाकी
  • मोहल्ले का पता - कॉमा लगाकर अलग किए गए कॉम्पोनेंट के साथ पूरा पता, इसे अलग-अलग हिस्सों में बांटा जा सकता है

    • पता-लाइन1
    • पता-लाइन2 - खाली हो सकता है
  • शहर - शहर/कस्बा

  • क्षेत्र - राज्य कोड, काउंटी या कैंटन

  • पिन कोड - पिन कोड, पिन कोड, पिन कोड

  • 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 को कॉल करना होगा. याद रखें, स्केलेटर की चेतावनी से बचने के लिए, आपको अपना कार्ट पेज एसएसएल की मदद से दिखाना होगा. शुरू करने के लिए, हमें अपना चेकआउट बटन छिपाना चाहिए, ताकि जब तक हम तैयार न हों, लोग उस पर क्लिक न कर सकें. हालांकि, हम ऐसा सिर्फ़ JavaScript का इस्तेमाल करने वाले लोगों के लिए करना चाहते हैं. इसलिए, अपने पेज के सबसे ऊपर:

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

आपकी सीएसएस में:

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

हमें अपने कार्ट पेज पर बिलिंग फ़ॉर्म शामिल करना होगा. ऐसा कहीं भी किया जा सकता है. ऊपर बताई गई सीएसएस यह पक्का करती है कि वह उपयोगकर्ता को न दिखे.

<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 के ज़रिए फ़ॉर्म एचटीएमएल को लोड करना चाहें. इसका मतलब है कि फ़ॉर्म को सिर्फ़ उन ब्राउज़र में लोड किया जा सकता है जो requestAutocomplete का इस्तेमाल करते हैं. साथ ही, आपको हर उस पेज पर फ़ॉर्म जोड़ना याद रखने की ज़रूरत नहीं है जिससे enhanceForm पर कॉल किया जा सकता है. डेमो साइट इस तरह काम करती है.

आपने अनुरोध ऑटोकंप्लीट नाम का इस्तेमाल किया है, अब आगे क्या?

अपने-आप पूरा होने की प्रोसेस एसिंक्रोनस होती है, 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
    });
  });
});