จัดการข้อมูลการชำระเงินที่ไม่บังคับด้วย Service Worker

วิธีปรับแอปการชำระเงินบนเว็บให้เข้ากับ Web Payments และมอบประสบการณ์การใช้งานที่ดีขึ้นแก่ลูกค้า

เมื่อแอปการชำระเงินบนเว็บได้รับคำขอการชำระเงินและเริ่มธุรกรรมการชำระเงิน Service Worker จะทำหน้าที่เป็นฮับสำหรับการสื่อสารระหว่างผู้ขายกับแอปการชำระเงิน โพสต์นี้จะอธิบายวิธีที่แอปการชำระเงินส่งข้อมูลเกี่ยวกับวิธีการชำระเงิน ที่อยู่สำหรับการจัดส่ง หรือข้อมูลติดต่อไปยังผู้ขายโดยใช้ Service Worker

การจัดการข้อมูลการชำระเงินที่ไม่บังคับด้วย Service Worker
การจัดการข้อมูลการชำระเงินที่ไม่บังคับด้วย Service Worker

แจ้งให้ผู้ขายทราบ

คุณควรแจ้งให้ผู้ขายทราบถึงการเปลี่ยนแปลงต่อไปนี้

การเปลี่ยนวิธีการชำระเงิน

แอปการชำระเงินรองรับเครื่องมือการชำระเงินหลายรายการด้วยวิธีการชำระเงินที่แตกต่างกันได้

ลูกค้า วิธีการชำระเงิน เครื่องมือการชำระเงิน
A ผู้ออกบัตรเครดิต 1 ****1234
ผู้ออกบัตรเครดิต 1 ****4242
ธนาคาร X ******123
B ผู้ออกบัตรเครดิต 2 ****5678
ธนาคาร X ******456

ตัวอย่างเช่น ในตารางด้านบน กระเป๋าเงินบนเว็บของลูกค้า ก. มีบัตรเครดิต 2 ใบและบัญชีธนาคาร 1 บัญชีที่ลงทะเบียนไว้ ในกรณีนี้ แอปจะจัดการเครื่องมือการชำระเงิน 3 รายการ (****1234, ****4242, ******123) และวิธีการชำระเงิน 2 รายการ (ผู้ออกบัตรเครดิต 1 และธนาคาร X) ในธุรกรรมการชำระเงิน แอปการชำระเงิน สามารถให้ลูกค้าเลือกเครื่องมือการชำระเงินรายการใดรายการหนึ่งและใช้เพื่อชำระเงิน ให้ผู้ขายได้

UI ของเครื่องมือเลือกวิธีการชำระเงิน
UI ตัวเลือกวิธีการชำระเงิน

แอปการชำระเงินสามารถแจ้งให้ผู้ขายทราบว่าลูกค้าเลือกวิธีการชำระเงินใดก่อนที่จะส่งการตอบกลับการชำระเงินทั้งหมด ซึ่งจะเป็นประโยชน์เมื่อผู้ขายต้องการเรียกใช้แคมเปญส่วนลดสำหรับแบรนด์วิธีการชำระเงินที่เฉพาะเจาะจง เป็นต้น

Payment Handler API ช่วยให้แอปการชำระเงินส่งเหตุการณ์ "การเปลี่ยนวิธีการชำระเงิน" ไปยังผู้ขายผ่าน Service Worker เพื่อแจ้งตัวระบุวิธีการชำระเงินใหม่ได้ Service Worker ควรเรียกใช้ PaymentRequestEvent.changePaymentMethod() พร้อมข้อมูลวิธีการชำระเงินใหม่

แจ้งให้ผู้ขายทราบถึงการเปลี่ยนแปลงวิธีการชำระเงิน
แจ้งให้ผู้ขายทราบถึงการเปลี่ยนแปลงวิธีการชำระเงิน

แอปการชำระเงินสามารถส่งออบเจ็กต์ methodDetails เป็นอาร์กิวเมนต์ที่ 2 ที่ไม่บังคับ สำหรับ 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;

ใช้ออบเจ็กต์เพื่ออัปเดต UI ในส่วนหน้า ดูแสดงรายละเอียดการชำระเงินที่อัปเดตแล้ว

เปลี่ยนที่อยู่สำหรับจัดส่ง

แอปการชำระเงินสามารถระบุที่อยู่จัดส่งของลูกค้าให้ผู้ขายเป็นส่วนหนึ่ง ของธุรกรรมการชำระเงินได้

ซึ่งเป็นประโยชน์สำหรับผู้ขายเนื่องจากสามารถมอบหมายการรวบรวมที่อยู่ให้กับแอปการชำระเงินได้ และเนื่องจากข้อมูลที่อยู่จะระบุในรูปแบบข้อมูลมาตรฐาน ผู้ขายจึงคาดหวังที่จะได้รับที่อยู่จัดส่งในโครงสร้างที่สอดคล้องกันได้

นอกจากนี้ ลูกค้ายังลงทะเบียนข้อมูลที่อยู่กับแอปการชำระเงินที่ต้องการและนำไปใช้ซ้ำกับผู้ขายรายอื่นได้ด้วย

UI ตัวเลือกที่อยู่สำหรับจัดส่ง
UI ตัวเลือกที่อยู่สำหรับจัดส่ง

แอปการชำระเงินสามารถแสดง UI เพื่อแก้ไขที่อยู่จัดส่งหรือเลือกข้อมูลที่อยู่ที่ลงทะเบียนไว้ล่วงหน้าสำหรับลูกค้าในธุรกรรมการชำระเงิน เมื่อกำหนดที่อยู่จัดส่งชั่วคราว แอปการชำระเงินจะแจ้งให้ผู้ขายทราบข้อมูลที่อยู่ซึ่งมีการปกปิดบางส่วน ซึ่งจะช่วยให้ผู้ขายได้รับประโยชน์หลายประการ ดังนี้

  • ผู้ขายสามารถพิจารณาได้ว่าลูกค้ามีคุณสมบัติตรงตามข้อจำกัดระดับภูมิภาค ในการจัดส่งสินค้าหรือไม่ (เช่น ภายในประเทศเท่านั้น)
  • ผู้ขายสามารถเปลี่ยนรายการตัวเลือกการจัดส่งตามภูมิภาคของ ที่อยู่สำหรับจัดส่งได้ (เช่น การจัดส่งระหว่างประเทศแบบธรรมดาหรือแบบด่วน)
  • ผู้ขายสามารถใช้ค่าจัดส่งใหม่ตามที่อยู่และอัปเดต ราคารวมได้

Payment Handler API ช่วยให้แอปการชำระเงินส่งเหตุการณ์ "เปลี่ยนที่อยู่จัดส่ง" ไปยังผู้ขายจาก Service Worker เพื่อแจ้งที่อยู่จัดส่งใหม่ได้ Service Worker ควรเรียกใช้ 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);
      

คำสำคัญ: ที่อยู่ที่ปิดบัง ในกรณีนี้ คุณไม่จำเป็นต้องแจ้งที่อยู่จัดส่งแบบเต็มแก่ผู้ขาย และอาจเสี่ยงต่อความเป็นส่วนตัวของลูกค้า ผู้ขายจะได้รับเฉพาะส่วนของที่อยู่ที่จำเป็นต่อการกำหนดค่าจัดส่ง โดยเฉพาะอย่างยิ่ง เบราว์เซอร์จะล้างช่อง organization, phone, recipient, addressLine จากที่อยู่ที่แอปการชำระเงินระบุไว้ก่อนที่จะเรียกใช้เหตุการณ์ shippingaddresschange ใน DOM ของผู้ขาย

ผู้ขายจะได้รับ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);
});

เมื่อผู้ขายตอบกลับ Promise PaymentRequestEvent.changeShippingAddress() ที่ส่งคืนจะได้รับการแก้ไขด้วยออบเจ็กต์ PaymentRequestDetailsUpdate

[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;

ใช้ออบเจ็กต์เพื่ออัปเดต UI ในส่วนหน้า ดูแสดงรายละเอียดการชำระเงินที่อัปเดตแล้ว

แจ้งให้ผู้ขายทราบถึงการเปลี่ยนแปลงตัวเลือกการจัดส่ง

ตัวเลือกการจัดส่งคือวิธีการนำส่งที่ผู้ขายใช้ในการจัดส่งสินค้าที่ลูกค้าซื้อไปยังลูกค้า ตัวเลือกการจัดส่งโดยทั่วไปมีดังนี้

  • จัดส่งฟรี
  • การจัดส่งแบบด่วน
  • การจัดส่งระหว่างประเทศ
  • การจัดส่งระหว่างประเทศแบบพรีเมียม

โดยแต่ละอย่างจะมีค่าใช้จ่ายของตัวเอง โดยปกติแล้ว วิธีการและตัวเลือกที่เร็วกว่าจะมีราคาแพงกว่า

ผู้ขายที่ใช้ Payment Request API สามารถมอบสิทธิ์การเลือกนี้ให้กับแอปการชำระเงินได้ แอปการชำระเงินสามารถใช้ข้อมูลเพื่อสร้าง UI และให้ลูกค้าเลือกตัวเลือกการจัดส่งได้

UI เครื่องมือเลือกตัวเลือกการจัดส่ง
UI ตัวเลือกการจัดส่ง

รายการตัวเลือกการจัดส่งที่ระบุใน Payment Request API ของผู้ขายจะ ส่งต่อไปยัง Service Worker ของแอปการชำระเงินเป็นพร็อพเพอร์ตี้ของ 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 ช่วยให้แอปการชำระเงินส่งเหตุการณ์ "เปลี่ยนตัวเลือกการจัดส่ง" ไปยังผู้ขายจาก Service Worker ได้ Service Worker ควร เรียกใช้ 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;

ใช้ออบเจ็กต์เพื่ออัปเดต UI ในส่วนหน้า ดูแสดงรายละเอียดการชำระเงินที่อัปเดตแล้ว

แสดงรายละเอียดการชำระเงินที่อัปเดตแล้ว

เมื่อผู้ขายอัปเดตรายละเอียดการชำระเงินเสร็จแล้ว สัญญาที่ส่งคืนจาก .changePaymentMethod(), .changeShippingAddress() และ .changeShippingOption() จะได้รับการแก้ไขด้วยออบเจ็กต์ PaymentRequestDetailsUpdate ทั่วไป ตัวแฮนเดิลการชำระเงินสามารถใช้ผลลัพธ์เพื่อแสดงราคารวมและตัวเลือกการจัดส่งที่อัปเดตแล้วใน UI

ผู้ขายอาจแสดงข้อผิดพลาดด้วยเหตุผลต่อไปนี้

  • ระบบไม่ยอมรับวิธีการชำระเงิน
  • ที่อยู่ในการจัดส่งอยู่นอกภูมิภาคที่รองรับ
  • ที่อยู่จัดส่งมีข้อมูลที่ไม่ถูกต้อง
  • เลือกตัวเลือกการจัดส่งสำหรับที่อยู่จัดส่งที่ระบุไม่ได้ หรือ อาจมีสาเหตุอื่นๆ

ใช้พร็อพเพอร์ตี้ต่อไปนี้เพื่อแสดงสถานะข้อผิดพลาด

  • error: สตริงข้อผิดพลาดที่มนุษย์อ่านได้ นี่คือสตริงที่ดีที่สุดที่จะแสดง ต่อลูกค้า
  • shippingAddressErrors: AddressErrors ออบเจ็กต์ที่มีสตริงข้อผิดพลาดแบบละเอียดต่อพร็อพเพอร์ตี้ที่อยู่ ซึ่งมีประโยชน์มากหากคุณต้องการเปิดแบบฟอร์มที่ให้ลูกค้าแก้ไขที่อยู่ และคุณต้องนำลูกค้าไปยังช่องที่ไม่ถูกต้องโดยตรง
  • paymentMethodErrors: ออบเจ็กต์ข้อผิดพลาดเฉพาะวิธีการชำระเงิน คุณขอให้ ผู้ขายระบุข้อผิดพลาดที่มีโครงสร้างได้ แต่ผู้เขียนข้อกำหนดการชำระเงินบนเว็บ แนะนำให้ใช้สตริงแบบง่าย

โค้ดตัวอย่าง

ตัวอย่างโค้ดส่วนใหญ่ที่คุณเห็นในเอกสารนี้เป็นข้อความที่คัดลอกมาจากแอปพลิเคชันตัวอย่าง

วิธีลองใช้

  1. ไปที่ https://paymentrequest-demo.glitch.me/
  2. ไปที่ด้านล่างสุดของหน้า
  3. กดเพิ่มปุ่มชำระเงิน
  4. ป้อน https://paymenthandler-demo.glitch.me ลงในช่องตัวระบุวิธีการชำระเงิน
  5. กดปุ่มชำระเงินข้างช่อง