كيفية تكييف تطبيق الدفع المستند إلى الويب مع Web Payments وتقديم تجربة مستخدم أفضل للعملاء.
بعد تسجيل تطبيق الدفع، تصبح جاهزًا لقبول طلبات الدفع من التجّار. تشرح هذه المشاركة كيفية تنسيق معاملة دفع من مشغّل الخدمات أثناء وقت التشغيل (أي عندما تظهر نافذة ويتفاعل المستخدم معها).
يشير مصطلح "تغييرات مَعلمات الدفع في وقت التشغيل" إلى مجموعة من الأحداث التي تتيح للتاجر والجهة المسؤولة عن معالجة المعاملات تبادل الرسائل أثناء تفاعل المستخدم مع معالج الدفع. يمكنك الاطّلاع على مزيد من المعلومات في مقالة التعامل مع معلومات الدفع الاختيارية مع عامل خدمات.
تلقّي حدث طلب الدفع من التاجر
عندما يختار العميل الدفع باستخدام تطبيق الدفع المستند إلى الويب ويستدعي التاجر
PaymentRequest.show()
،
سيتلقّى عامل الخدمة حدث paymentrequest
. أضف أداة معالجة الحدث إلى عامل الخدمة لتسجيل الحدث والاستعداد للإجراء التالي.
[معالج الدفع] service-worker.js:
…
let payment_request_event;
let resolver;
let client;
// `self` is the global object in service worker
self.addEventListener('paymentrequest', async e => {
if (payment_request_event) {
// If there's an ongoing payment transaction, reject it.
resolver.reject();
}
// Preserve the event for future use
payment_request_event = e;
…
تحتوي PaymentRequestEvent
التي تم الاحتفاظ بها على معلومات مهمة حول هذه المعاملة:
اسم الموقع | الوصف |
---|---|
topOrigin |
سلسلة تشير إلى أصل صفحة الويب ذات المستوى الأعلى (عادةً ما يكون التاجر المدفوع له). استخدِم هذا الحقل لتحديد مصدر التاجر. |
paymentRequestOrigin |
سلسلة تشير إلى أصل الداعي ويمكن أن يشبه هذا السمة topOrigin عندما يستدعي التاجر واجهة Payment Request API مباشرةً، ولكن قد يختلف إذا تم استدعاء واجهة برمجة التطبيقات من داخل إطار iframe من قِبل جهة خارجية، مثل بوابة الدفع.
|
paymentRequestId |
السمة id على PaymentDetailsInit التي يتم تقديمها إلى Payment Request API. إذا حذف التاجر، سيقدّم المتصفّح معرّفًا تم إنشاؤه تلقائيًا.
|
methodData |
البيانات الخاصة بطريقة الدفع التي يقدّمها التاجر كجزء من "PaymentMethodData "
ويمكنك الاستناد إليه لتحديد تفاصيل معاملة الدفع.
|
total |
المبلغ الإجمالي الذي يقدّمه التاجر كجزء من PaymentDetailsInit
استخدِم هذا الحقل لإنشاء واجهة مستخدم لإعلام العميل بإجمالي المبلغ المدفوع.
|
instrumentKey |
مفتاح الأداة الذي يختاره المستخدم. ويعكس ذلك مبلغ instrumentKey الذي قدّمته مسبقًا. تشير السلسلة الفارغة إلى أن المستخدم لم يحدد أي أدوات.
|
افتح نافذة معالج الدفع لعرض الواجهة الأمامية لتطبيق الدفع المستند إلى الويب.
عند تلقّي حدث paymentrequest
، يمكن لتطبيق الدفع فتح نافذة معالج
الدفع من خلال الاتصال بـ PaymentRequestEvent.openWindow()
. ستعرض نافذة معالج الدفع للعملاء واجهة تطبيق الدفع الخاص بك حيث يمكنهم المصادقة واختيار عنوان الشحن وخياراته والموافقة على عملية الدفع. سنتناول كيفية كتابة رمز الواجهة الأمامية في التعامل مع الدفعات في الواجهة الأمامية للدفع (قريبًا).
أرسِل وعودًا محتفظًا به إلى "PaymentRequestEvent.respondWith()
" كي تتمكّن من حلّه من خلال نتيجة دفع في المستقبل.
[معالج الدفع] service-worker.js:
…
self.addEventListener('paymentrequest', async e => {
…
// Retain a promise for future resolution
// Polyfill for PromiseResolver is provided below.
resolver = new PromiseResolver();
// Pass a promise that resolves when payment is done.
e.respondWith(resolver.promise);
// Open the checkout page.
try {
// Open the window and preserve the client
client = await e.openWindow(checkoutURL);
if (!client) {
// Reject if the window fails to open
throw 'Failed to open window';
}
} catch (err) {
// Reject the promise on failure
resolver.reject(err);
};
});
…
يمكنك استخدام رمز polyfill مناسب من PromiseResolver
للوفاء بالوعد في
توقيت عشوائي.
class PromiseResolver {
constructor() {
this.promise_ = new Promise((resolve, reject) => {
this.resolve_ = resolve;
this.reject_ = reject;
})
}
get promise() { return this.promise_ }
get resolve() { return this.resolve_ }
get reject() { return this.reject_ }
}
تبادل المعلومات مع الواجهة الأمامية
يمكن لمشغّل الخدمات في تطبيق الدفع تبادل الرسائل مع الواجهة الأمامية لتطبيق الدفع من خلال ServiceWorkerController.postMessage()
. لاستلام رسائل من الواجهة الأمامية، يُرجى الاستماع إلى أحداث "message
".
[معالج الدفع] service-worker.js:
// Define a convenient `postMessage()` method
const postMessage = (type, contents = {}) => {
if (client) client.postMessage({ type, ...contents });
}
تلقّي إشارة جاهزة من الواجهة الأمامية
بعد فتح نافذة معالج الدفع، يجب على عامل الخدمة الانتظار للحصول على إشارة جاهزة من الواجهة الأمامية لتطبيق الدفع. يمكن لعامل الخدمة تمرير معلومات مهمة إلى الواجهة الأمامية عندما تكون جاهزة.
الواجهة الأمامية لـ [معالج الدفع]:
navigator.serviceWorker.controller.postMessage({
type: 'WINDOW_IS_READY'
});
[معالج الدفع] service-worker.js:
…
// Received a message from the frontend
self.addEventListener('message', async e => {
let details;
try {
switch (e.data.type) {
// `WINDOW_IS_READY` is a frontend's ready state signal
case 'WINDOW_IS_READY':
const { total } = payment_request_event;
…
تمرير تفاصيل المعاملة إلى الواجهة الأمامية
يمكنك الآن إعادة إرسال تفاصيل الدفع. في هذه الحالة، ترسل فقط إجمالي طلب الدفع، ولكن يمكنك تمرير المزيد من التفاصيل إذا كنت ترغب في ذلك.
[معالج الدفع] service-worker.js:
…
// Pass the payment details to the frontend
postMessage('PAYMENT_IS_READY', { total });
break;
…
الواجهة الأمامية لـ [معالج الدفع]:
let total;
navigator.serviceWorker.addEventListener('message', async e => {
switch (e.data.type) {
case 'PAYMENT_IS_READY':
({ total } = e.data);
// Update the UI
renderHTML(total);
break;
…
إرجاع بيانات اعتماد الدفع الخاصة بالعميل
عندما يسمح العميل بالدفع، يمكن للواجهة الأمامية إرسال رسالة بريدية
إلى عامل الخدمة للمتابعة. يمكنك حلّ الوعد الذي تم إرساله إلى
PaymentRequestEvent.respondWith()
لإرسال النتيجة إلى التاجر.
مرِّر كائن
PaymentHandlerResponse
.
اسم الموقع | الوصف |
---|---|
methodName |
معرّف طريقة الدفع المُستخدَم لإجراء عملية الدفع |
details |
تمثّل هذه السمة البيانات الخاصة بطريقة الدفع التي توفّر المعلومات اللازمة للتاجر لمعالجة الدفعة. |
الواجهة الأمامية لـ [معالج الدفع]:
const paymentMethod = …
postMessage('PAYMENT_AUTHORIZED', {
paymentMethod, // Payment method identifier
});
[معالج الدفع] service-worker.js:
…
// Received a message from the frontend
self.addEventListener('message', async e => {
let details;
try {
switch (e.data.type) {
…
case 'PAYMENT_AUTHORIZED':
// Resolve the payment request event promise
// with a payment response object
const response = {
methodName: e.data.paymentMethod,
details: { id: 'put payment credential here' },
}
resolver.resolve(response);
// Don't forget to initialize.
payment_request_event = null;
break;
…
إلغاء معاملة الدفع
للسماح للعميل بإلغاء المعاملة، يمكن للواجهة الأمامية إرسال رسالة ما بعد
إلى عامل الخدمة لإجراء ذلك. يتمكّن عامل الخدمة بعد ذلك من حل
الوعد الذي تم تمريره إلى PaymentRequestEvent.respondWith()
من خلال null
لإعلام
التاجر بأنّه تم إلغاء المعاملة.
الواجهة الأمامية لـ [معالج الدفع]:
postMessage('CANCEL_PAYMENT');
[معالج الدفع] service-worker.js:
…
// Received a message from the frontend
self.addEventListener('message', async e => {
let details;
try {
switch (e.data.type) {
…
case 'CANCEL_PAYMENT':
// Resolve the payment request event promise
// with null
resolver.resolve(null);
// Don't forget to initialize.
payment_request_event = null;
break;
…
نموذج التعليمات البرمجية
جميع نماذج الرموز التي رأيتها في هذا المستند عبارة عن مقتطفات من نموذج تطبيق العمل التالي:
https://paymenthandler-demo.glitch.me
[معالج الدفع] مشغّل الخدمات
[معالج الدفع] الواجهة الأمامية
لتجربتها:
- انتقِل إلى https://paymentrequest-demo.glitch.me/.
- انتقل إلى أسفل الصفحة.
- اضغط على زر إضافة طريقة دفع.
- أدخِل
https://paymenthandler-demo.glitch.me
في الحقل معرّف طريقة الدفع. - اضغط على زر الدفع بجانب الحقل.
الخطوات التالية
في هذه المقالة، تعلمنا كيفية تنظيم معاملة دفع من عامل خدمة. والخطوة التالية هي معرفة كيفية إضافة المزيد من الميزات المتقدمة إلى مشغّل الخدمات.