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

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

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

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

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

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

عندما يختار العميل الدفع باستخدام تطبيق الدفع المستند إلى الويب ويستدعي التاجر 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، يمكن لتطبيق الدفع فتح نافذة معالج الدفع من خلال استدعاء 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);
  };
});

يمكنك استخدام PromiseResolver polyfill مناسب لحلّ وعد في توقيت عشوائي.

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;

إرجاع بيانات اعتماد الدفع الخاصة بالعميل

عندما يوافق العميل على الدفع، يمكن للواجهة الأمامية إرسال رسالة POST إلى عامل الخدمة للمتابعة. يمكنك حلّ الوعد الذي تم تمريره إلى 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;
      

إلغاء معاملة الدفع

للسماح للعميل بإلغاء المعاملة، يمكن للواجهة الأمامية إرسال رسالة POST إلى عامل الخدمة لإجراء ذلك. ويمكن لعامل الخدمة بعد ذلك حلّ الوعد الذي تم تمريره إلى 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;
      

نموذج التعليمات البرمجية

جميع الرموز النموذجية التي رأيتها في هذا المستند هي مقتطفات من ما يلي: عرض توضيحي لمعالج الدفع

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

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