إدارة معاملات الدفع مع عامل الخدمات

كيفية تكييف تطبيق الدفع المستند إلى الويب مع Web Payments وتوفير تجربة مستخدم أفضل للعملاء

بعد تسجيل تطبيق الدفع، ستصبح مستعدًا لقبول طلبات الدفع من التجّار. توضّح هذه المشاركة كيفية تنسيق معاملة دفع من عامل خدمة أثناء وقت التشغيل (أي عند عرض نافذة ويتفاعل معها المستخدم).

تنظيم معاملات الدفع باستخدام عامل خدمة
تنظيم معاملات الدفع باستخدام عامل خدمة

تشير "تغييرات مَعلمات الدفع أثناء التشغيل" إلى مجموعة من الأحداث التي تسمح للتاجر ومعالج الدفع بتبادل الرسائل أثناء تفاعل المستخدم مع معالج الدفع. اطّلِع على مزيد من المعلومات في مقالة معالجة معلومات الدفع الاختيارية باستخدام Worker Service.

تلقّي حدث طلب دفع من التاجر

عندما يختار أحد العملاء الدفع باستخدام تطبيق الدفع المستند إلى الويب ويُطلِق التاجر PaymentRequest.show()، سيتلقّى عامل الخدمة حدث paymentrequest. أضِف مستمعًا للأحداث إلى الخدمة العاملة لتسجيل الحدث والاستعداد لتنفيذ الإجراء التالي.

[payment handler] 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، يمكن لتطبيق الدفع فتح نافذة معالج payment من خلال استدعاء PaymentRequestEvent.openWindow(). ستعرض نافذة معالج الدفع للعملاء واجهة تطبيق الدفع الذي تستخدمه، والتي يمكنهم من خلالها مصادقة حساباتهم واختيار عنوان الشحن وخياراته وتفويض الدفع. سنتناول كيفية كتابة رمز الواجهة الأمامية في مقالة معالجة الدفعات على واجهة الدفع (قريبًا).

عملية الدفع باستخدام تطبيق دفع مستند إلى الويب

أرسِل وعدًا محفوظًا إلى PaymentRequestEvent.respondWith() حتى تتمكّن من حلّه من خلال نتيجة دفع في المستقبل.

[payment handler] 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.

[payment handler] service-worker.js:

// Define a convenient `postMessage()` method
const postMessage = (type, contents = {}) => {
  if (client) client.postMessage({ type, ...contents });
}

تلقّي إشارة الاستعداد من الواجهة الأمامية

بعد فتح نافذة معالج الدفع، يجب أن ينتظر مشغّل الخدمة إشارة إعلام بالاستعداد من واجهة تطبيق الدفع. يمكن لعامل الخدمة تمرير معلومات مهمة إلى الواجهة الأمامية عندما تكون جاهزة.

[payment handler] frontend:

navigator.serviceWorker.controller.postMessage({
  type: 'WINDOW_IS_READY'
});

[payment handler] 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;
…

تمرير تفاصيل المعاملة إلى الواجهة الأمامية

يُرجى الآن إعادة إرسال تفاصيل الدفع. في هذه الحالة، لن ترسل سوى إجمالي طلب الدفع، ولكن يمكنك إرسال المزيد من التفاصيل إذا أردت.

[payment handler] service-worker.js:

…
        // Pass the payment details to the frontend
        postMessage('PAYMENT_IS_READY', { total });
        break;
…

[payment handler] frontend:

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 البيانات الخاصة بطريقة الدفع التي تقدّم المعلومات اللازمة للتاجر لمعالجة الدفع

[payment handler] frontend:

  const paymentMethod = …

  postMessage('PAYMENT_AUTHORIZED', {
    paymentMethod,              // Payment method identifier
  });

[payment handler] 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 للإشارة إلى التاجر بأنّه تم إلغاء المعاملة.

[payment handler] frontend:

  postMessage('CANCEL_PAYMENT');

[payment handler] 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

[payment handler] service worker

[payment handler] frontend

لتجربة هذه الميزة:

  1. انتقِل إلى https://paymentrequest-demo.glitch.me/.
  2. انتقل إلى أسفل الصفحة.
  3. اضغط على إضافة زر دفع.
  4. أدخِل https://paymenthandler-demo.glitch.me في حقل معرّف طريقة الدفع.
  5. اضغط على الزر الدفع بجانب الحقل.

الخطوات التالية

في هذه المقالة، تعرّفنا على كيفية تنسيق معاملة دفع من أحد العاملِين في الخدمة. الخطوة التالية هي التعرّف على كيفية إضافة بعض الميزات المتقدّمة إلى الخدمة العاملة.