معالجة معلومات الدفع الاختيارية مع مشغّل الخدمات

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

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

التعامل مع معلومات الدفع الاختيارية باستخدام Worker
معالجة معلومات الدفع الاختيارية باستخدام عامل خدمة

إبلاغ التاجر بتغيير طريقة الدفع

يمكن أن تتيح تطبيقات الدفع استخدام عدة أدوات دفع بطرائق دفع مختلفة.

العميل طريقة الدفع وسيلة الدفع
A جهة إصدار بطاقة الائتمان 1 ****1234
جهة إصدار بطاقة الائتمان 1 ****4242
البنك X ******123
B جهة إصدار بطاقة الائتمان 2 ****5678
البنك X ******456

على سبيل المثال، في الجدول أعلاه، تحتوي المحفظة المستندة إلى الويب للعميل "أ" على بطاقتَي ئتمان وحساب مصرفي واحد مسجَّلَين. في هذه الحالة، يتعامل التطبيق مع ثلاثة أدوات دفع (****1234 و****4242 و******123) وطريقتَي دفع (جهة إصدار بطاقة الائتمان 1 والمصرف "س"). في معاملة الدفع، يمكن لتطبيق الدفع السماح للعميل باختيار أحد أدوات الدفع واستخدامه للدفع للتاجر.

واجهة مستخدم أداة اختيار طريقة الدفع
واجهة مستخدم أداة اختيار طريقة الدفع

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

باستخدام Payment Handler API، يمكن لتطبيق الدفع إرسال حدث "تغيير طريقة الدفع" إلى التاجر من خلال عامل خدمة لإعلامه بمعرّف طريقة الدفع الجديدة. يجب أن يستدعي عامل الخدمة PaymentRequestEvent.changePaymentMethod() مع معلومات طريقة الدفع الجديدة.

إبلاغ التاجر بتغيير طريقة الدفع
إبلاغ التاجر بتغيير طريقة الدفع

يمكن لتطبيقات الدفع تمرير عنصر methodDetails كوسيطة ثانية اختيارية لـ PaymentRequestEvent.changePaymentMethod(). يمكن أن يحتوي هذا العنصر على تفاصيل طريقة دفع عشوائية مطلوبة للتاجر لمعالجة حدث التغيير.

[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_METHOD_CHANGED':
        const newMethod = e.data.paymentMethod;
        const newDetails = e.data.methodDetails;
        // Redact or check that no sensitive information is passed in
        // `newDetails`.
        // Notify the merchant of the payment method change
        details =
          await payment_request_event.changePaymentMethod(newMethod, newDetails);
      …

عندما يتلقّى التاجر حدث paymentmethodchange من Payment Request API، يمكنه تعديل تفاصيل الدفع والردّ باستخدام عنصر PaymentDetailsUpdate.

[merchant]

request.addEventListener('paymentmethodchange', e => {
  if (e.methodName === 'another-pay') {
    // Apply $10 discount for example.
    const discount = {
      label: 'special discount',
      amount: {
        currency: 'USD',
        // The value being string complies the spec
        value: '-10.00'
      }
    };
    let total = 0;
    details.displayItems.push(discount);
    for (let item of details.displayItems) {
     total += parseFloat(item.amount.value);
    }
    // Convert the number back to string
    details.total.amount.value = total.toString();
  }
  // Pass a promise to `updateWith()` and send updated payment details
  e.updateWith(details);
});

عندما يردّ التاجر، سيتم حلّ الوعد الذي تم PaymentRequestEvent.changePaymentMethod() إرجاعه باستخدام عنصر PaymentRequestDetailsUpdate.

[payment handler] service-worker.js

…
        // Notify the merchant of the payment method change
        details = await payment_request_event.changePaymentMethod(newMethod, newDetails);
        // Provided the new payment details,
        // send a message back to the frontend to update the UI
        postMessage('UPDATE_REQUEST', details);
        break;
…

استخدِم العنصر لتعديل واجهة المستخدم في الواجهة الأمامية. راجِع مقالة عرض تفاصيل الدفع المعدَّلة.

إبلاغ التاجر بتغيير عنوان الشحن

يمكن لتطبيقات الدفع تقديم عنوان شحن العميل للتاجر كجزء من عملية الدفع.

ويُعدّ ذلك مفيدًا للتجّار لأنّه يمكنهم تفويض جمع العناوين إلى تطبيقات الدفع. وبما أنّه سيتم تقديم بيانات العنوان بـ تنسيق البيانات العادي، يمكن للمتاجر أن تتوقّع تلقّي عناوين الشحن بتنسيق ثابت.

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

واجهة مستخدم أداة اختيار عنوان الشحن
واجهة مستخدم أداة اختيار عنوان الشحن

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

  • يمكن للتاجر تحديد ما إذا كان العميل يستوفي القيود الإقليمية لشحن السلعة (على سبيل المثال، الشحن المحلي فقط).
  • يمكن للتاجر تغيير قائمة خيارات الشحن استنادًا إلى منطقة عنوان الشحن (على سبيل المثال، الشحن العادي أو السريع الدولي).
  • يمكن للتاجر تطبيق تكلفة الشحن الجديدة استنادًا إلى العنوان وتعديل السعر الإجمالي.

باستخدام Payment Handler API، يمكن لتطبيق الدفع إرسال حدث "تغيير عنوان الشحن" إلى التاجر من خلال الخدمة العاملة لإعلامه بعنوان الشحن الجديد. يجب أن يستدعي عامل الخدمة PaymentRequestEvent.changeShippingAddress() باستخدام العنصر العنوان الجديد.

إبلاغ التاجر بتغيير عنوان الشحن
إبلاغ التاجر بتغيير عنوان الشحن

[payment handler] service-worker.js

...
// Received a message from the frontend
self.addEventListener('message', async e => {
  let details;
  try {
    switch (e.data.type) {
      …
      case 'SHIPPING_ADDRESS_CHANGED':
        const newAddress = e.data.shippingAddress;
        details =
          await payment_request_event.changeShippingAddress(newAddress);
      …

سيتلقّى التاجر حدث shippingaddresschange من Payment Request API حتى يتمكّن من الردّ باستخدام PaymentDetailsUpdate المعدَّل.

[merchant]

request.addEventListener('shippingaddresschange', e => {
  // Read the updated shipping address and update the request.
  const addr = request.shippingAddress;
  const details = getPaymentDetailsFromShippingAddress(addr);
  // `updateWith()` sends back updated payment details
  e.updateWith(details);
});

عندما يردّ التاجر، سيتم حلّ الوعد المُعاد باستخدام عنصر PaymentRequestDetailsUpdate .PaymentRequestEvent.changeShippingAddress()

[payment handler] service-worker.js

…
        // Notify the merchant of the shipping address change
        details = await payment_request_event.changeShippingAddress(newAddress);
        // Provided the new payment details,
        // send a message back to the frontend to update the UI
        postMessage('UPDATE_REQUEST', details);
        break;
…

استخدِم العنصر لتعديل واجهة المستخدم في الواجهة الأمامية. راجِع مقالة عرض تفاصيل الدفع المعدَّلة.

إبلاغ التاجر بتغيير خيار الشحن

خيارات الشحن هي طرق التسليم التي يستخدمها التجّار لشحن السلع التي يشتريها العملاء. تشمل خيارات الشحن الشائعة ما يلي:

  • شحن مجاني
  • الشحن السريع
  • الشحن الدولي
  • الشحن الدولي المميّز

ولكل منها تكلفة خاصة به. وعادةً ما تكون الطرق أو الخيارات الأسرع أكثر تكلفة.

يمكن للتجّار الذين يستخدمون واجهة برمجة التطبيقات Payment Request API تفويض هذا الاختيار إلى أحد تطبيقات الدفع. ويمكن لتطبيق الدفع استخدام المعلومات لإنشاء واجهة مستخدم والسماح للعميل باختيار خيار شحن.

واجهة مستخدِم أداة اختيار خيار الشحن
واجهة مستخدم أداة اختيار خيارات الشحن

تتم مشاركة قائمة خيارات الشحن المحدّدة في Payment Request API الخاصة بالتاجر مع عامل الخدمة في تطبيق الدفع باعتباره خاصية PaymentRequestEvent.

[merchant]

const request = new PaymentRequest([{
  supportedMethods: 'https://bobbucks.dev/pay',
  data: { transactionId: '****' }
}], {
  displayItems: [{
    label: 'Anvil L/S Crew Neck - Grey M x1',
    amount: { currency: 'USD', value: '22.15' }
  }],
  shippingOptions: [{
    id: 'standard',
    label: 'Standard',
    amount: { value: '0.00', currency: 'USD' },
    selected: true
  }, {
    id: 'express',
    label: 'Express',
    amount: { value: '5.00', currency: 'USD' }
  }],
  total: {
    label: 'Total due',
    amount: { currency: 'USD', value : '22.15' }
  }
}, {  requestShipping: true });

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

باستخدام Payment Handler API، يمكن لتطبيق الدفع إرسال حدث "تغيير خيار الشحن" إلى التاجر من خلال الخدمة العاملة. يجب أن يُطلِق العامل في الخدمة PaymentRequestEvent.changeShippingOption() معرّف خيار الشحن الجديد.

إبلاغ التاجر بتغيير خيار الشحن
إبلاغ التاجر بتغيير خيار الشحن

[payment handler] service-worker.js

…
// Received a message from the frontend
self.addEventListener('message', async e => {
  let details;
  try {
    switch (e.data.type) {
      …
      case 'SHIPPING_OPTION_CHANGED':
        const newOption = e.data.shippingOptionId;
        details =
          await payment_request_event.changeShippingOption(newOption);
      …

سيتلقّى التاجر حدث shippingoptionchange من واجهة برمجة التطبيقات Payment Request API. على التاجر استخدام المعلومات لتعديل السعر الإجمالي ثم الردّ باستخدام السعر المعدَّل PaymentDetailsUpdate.

[merchant]

request.addEventListener('shippingoptionchange', e => {
  // selected shipping option
  const shippingOption = request.shippingOption;
  const newTotal = {
    currency: 'USD',
    label: 'Total due',
    value: calculateNewTotal(shippingOption),
  };
  // `updateWith()` sends back updated payment details
  e.updateWith({ total: newTotal });
});

عندما يردّ التاجر، سيتم حلّ الوعد الذي تم PaymentRequestEvent.changeShippingOption() إرجاعه باستخدام عنصر PaymentRequestDetailsUpdate.

[payment handler] service-worker.js

…
        // Notify the merchant of the shipping option change
        details = await payment_request_event.changeShippingOption(newOption);
        // Provided the new payment details,
        // send a message back to the frontend to update the UI
        postMessage('UPDATE_REQUEST', details);
        break;
…

استخدِم العنصر لتعديل واجهة المستخدم في الواجهة الأمامية. راجِع مقالة عرض تفاصيل الدفع المعدَّلة.

عرض تفاصيل الدفع المعدَّلة

بعد أن ينتهي التاجر من تعديل تفاصيل الدفع، سيتم حلّ الوعود التي تم إرجاعها من .changePaymentMethod() و.changeShippingAddress() و .changeShippingOption() باستخدام عنصر PaymentRequestDetailsUpdate شائع. يمكن لمعالج الدفع استخدام النتيجة لعرض السعر الإجمالي المعدَّل وخيارات الشحن في واجهة المستخدم.

قد يعرض التجّار أخطاء لعدة أسباب:

  • طريقة الدفع غير مقبولة.
  • يقع عنوان الشحن خارج المناطق التي تتوفّر فيها الخدمة.
  • يحتوي عنوان الشحن على معلومات غير صالحة.
  • لا يمكن اختيار خيار الشحن لعنوان الشحن المقدَّم أو لسبب آخر.

استخدِم السمات التالية للإشارة إلى حالة الخطأ:

  • error: سلسلة أخطاء قابلة للقراءة هذه هي أفضل سلسلة لعرضها للعملاء.
  • shippingAddressErrors: AddressErrors عنصر يحتوي على سلسلة أخطاء تفصيلية لكل سمة عنوان يكون ذلك مفيداً إذا كنت تريد فتح نموذج يتيح للعميل تعديل عنوانه وكنت بحاجة إلى توجيهه مباشرةً إلى الحقول غير الصالحة.
  • paymentMethodErrors: عنصر خطأ خاص بطريقة الدفع يمكنك أن تطلب من التجّار تقديم خطأ منظَّم، ولكن ينصح مؤلفو مواصفات Web Payments باستخدام سلسلة بسيطة.

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

معظم الرموز النموذجية التي رأيتها في هذا المستند كانت مقتطفات من المثال التالي لتطبيق صالح:

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. اضغط على الزر الدفع بجانب الحقل.