پولم را بگیر نه وقتم را
مقدمه
من وب را دوست دارم. در مجموع، فکر می کنم ایده بسیار خوبی است. به این ترتیب، من وارد بسیاری از بحث های وب در مقابل بومی می شوم. طولی نمی کشد که طرف مقابل شروع به صحبت در مورد سهولت پرداخت از طریق سیستم های بومی می کند. پاسخ معمول من این است که یک بمب دودزا بیندازم و با خنده دیوانه وار از اتاق فرار کنم، زیرا این بحثی نیست که بتوانم برنده شوم. رها شدن سبد خرید در وب تلفن همراه می تواند به 97٪ برسد . آن را در دنیای واقعی تصور کنید. تصور کنید 97 درصد از مردم در یک سوپرمارکت، با یک گاری پر از چیزهایی که میخواهند، سبد خرید خود را برمیگردانند و بیرون میروند. اکنون، برخی از این افراد فقط کالاها را قیمتگذاری میکنند و هرگز قصد خرید نداشتهاند، اما تجربه وحشتناک کاربر از خرید در وب نقش مهمی در این امر دارد. ما به کاربران با مالیات بر سلامت عقلشان ضربه می زنیم. به یک تجربه پرداخت لذت بخش در وب، به خصوص در تلفن همراه، فکر کنید. این یک فروشگاه برنامه است، درست است؟ یا حداقل یک سیستم بسته مشابه که قبلاً اطلاعات پرداخت شما را دارد. این یک مشکل است. سایتها را ملزم میکند که به یک ارائهدهنده پرداخت خاص که کاربر باید قبلاً با آن حساب داشته باشد و وارد آن شده باشد، متعهد شوند، یا به پلتفرمی که کاربران را ملزم به ورود به یک ارائهدهنده پرداخت خاص میکند، مانند فروشگاههای برنامهای که به شما نیاز دارند، متعهد شوند. برای کدنویسی فقط برای آن پلتفرم. اگر یکی از این کارها را انجام ندهید، کاربر محکوم است که به صفحه یا صفحه کلید خود ضربه بزند تا زمانی که تمام پوست انگشتش از بین برود یا تسلیم شود. ما باید آن را درست کنیم.
درخواست تکمیل خودکار
در دنیای WebGL، WebRTC و دیگر APIهای وب فانتزی که با «Web» شروع میشوند، requestAutocomplete
نسبتاً غیر جذاب است. با این حال، این یک ابرقهرمان در لباس بژ است. یک API کوچک و خسته کننده که می تواند سهمی را در قلب زمان خون آشام پرداخت های وب ایجاد کند.
به جای اینکه سایت به یک ارائه دهنده پرداخت خاص متکی باشد، جزئیات پرداخت را از مرورگر درخواست می کند که آنها را از طرف کاربر ذخیره می کند. نسخه کروم از requestAutocomplete() نیز با Google Wallet فقط برای کاربران ایالات متحده (در حال حاضر) ادغام می شود. آن را در سایت آزمایشی ما امتحان کنید .
form.request تکمیل خودکار
عناصر فرم دارای یک روش جدید به نام requestAutocomplete هستند که از مرورگر می خواهد فرم را پر کند. مرورگر یک گفتگو را برای کاربر نمایش می دهد که از کاربر اجازه می خواهد و به کاربر اجازه می دهد جزئیاتی را که می خواهد ارائه دهد انتخاب کند. شما نمی توانید هر زمان که بخواهید آن را فراخوانی کنید، باید در هنگام اجرای رویدادهای تعاملی خاص مانند رویدادهای ماوس بالا/پایین، کلیک، کلید و لمس فراخوانی شود. این یک محدودیت امنیتی عمدی است.
button.addEventListener('click', function(event) {
form.requestAutocomplete();
event.preventDefault();
});
// TODO: listen for autocomplete events on the form
قبل از اینکه به رویدادها نگاه کنیم، باید مطمئن شویم که مرورگر فیلدهای فرم شما را درک کرده است…
الزامات فرم
زمانی که اینترنت سیاه و سفید بود، اینترنت اکسپلورر 5 ویژگی جدیدی autocomplete
در عناصر ورودی فرم به کار گرفت. میتوان آن را روی «خاموش» تنظیم کرد تا پیشنهادات مرورگر را متوقف کند، و تمام. این API گسترش یافته است تا بتوانید محتوای مورد انتظار فیلد را بدون تغییر ویژگی "name" مشخص کنید، و این همان چیزی است که requestAutocomplete
برای پیوند دادن فیلدهای فرم به داده های کاربر استفاده می کند.
<input name="fullname" autocomplete="name">
به عنوان یک مشخصات، requestAutocomplete
مختص پرداختها نیست، اما پیادهسازی فعلی کروم تقریباً اینگونه است. در آینده، انتظار داشته باشید که مرورگرها بتوانند با انواع دیگر دادهها، مانند جزئیات ورود و تولید رمز عبور، اطلاعات پاسپورت و حتی آپلود یک آواتار، مقابله کنند.
در حال حاضر در Chrome، requestAutocomplete
موارد زیر را تشخیص میدهد:
پرداخت
- ایمیل
- cc-name - نام روی کارت
- شماره سی سی - شماره کارت
- 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>
برای فیلدهای انقضای کارت استفاده کنید.
آدرس
نام - نام کامل. استفاده از یک نام کامل به عنوان یک فیلد واحد به مراتب بهتر از چندین فیلد است. چندین فیلد مانند نام و نام خانوادگی نشان دهنده تعصب غربی است و ممکن است برای فرهنگ های دیگر معنی نداشته باشد، همچنین تایپ کردن در یک فیلد ساده تر است.
تلفن - شماره تلفن کامل از جمله کد کشور، می تواند به طور متناوب تقسیم شود
- tel-country-code - به عنوان مثال +44
- تلفن ملی - بقیه
آدرس خیابان - آدرس کامل با اجزای جدا شده با کاما، می تواند به تقسیم شود
- آدرس-خط 1
- address-line2 - ممکن است خالی باشد
محل - شهر/شهرک
منطقه - کد ایالت، شهرستان یا کانتون
کد پستی - کد پستی، کد پستی، کد پستی
کشور
موارد فوق باید در ترکیب با: - صورتحساب - حمل و نقل استفاده شود
<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 ارائه دهید. برای شروع، باید دکمه پرداخت خود را مخفی کنیم تا کاربر نتواند روی آن کلیک کند تا زمانی که ما آماده شویم، اما ما فقط می خواهیم این کار را برای کاربران دارای جاوا اسکریپت انجام دهیم. بنابراین، در سر صفحه شما:
<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 & shipping if relevant…
</form>
اکنون جاوا اسکریپت ما می تواند شروع به تنظیم همه چیز کند:
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
بلافاصله برمی گردد. برای اینکه بفهمیم چطور پیش رفت، به چند رویداد جدید گوش می دهیم:
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 استفاده نمیکنید، جزئیات شما به صورت اختیاری در مرورگر برای استفاده مجدد ذخیره میشود. این وضعیت در حال حاضر است، اما در آینده کروم و سایر مرورگرها ممکن است از ارائه دهندگان پرداخت اضافی استفاده کنند.
آسان کردن پرداخت ها
این یک جور مضحک است که کاربران باید هر زمان که می خواهند خریدی انجام دهند، اطلاعات پرداخت خود را بارها و بارها وارد کنند. وقتی یک سایت جزئیات پرداخت شما را ذخیره می کند، همه چیز آسان تر می شود، من از اینکه چه تعداد از سایت ها جزئیات کارت من را ذخیره می کنند، کمی نگران هستم. این یک مشکل عالی برای حل استانداردهای وب است. 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
});
});
});