การจัดการธุรกรรมการชำระเงินกับ Service Worker

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

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

การประสานงานธุรกรรมการชำระเงินด้วย Service Worker
จัดระเบียบธุรกรรมการชำระเงินด้วย Service Worker

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

รับเหตุการณ์คำขอการชำระเงินจากผู้ขาย

เมื่อลูกค้าเลือกชำระเงินด้วยแอปการชำระเงินบนเว็บและผู้ขาย เรียกใช้ PaymentRequest.show() Service Worker จะได้รับเหตุการณ์ paymentrequest เพิ่มเครื่องฟังกิจกรรม ลงใน Service Worker เพื่อบันทึกกิจกรรมและเตรียมพร้อมสำหรับการดำเนินการถัดไป

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 โดยตรง แต่ก็อาจแตกต่างกันหาก API ถูกเรียกใช้จากภายใน iframe โดยบุคคลที่สาม เช่น เกตเวย์การชำระเงิน
paymentRequestId id ของ PaymentDetailsInit ที่ระบุใน Payment Request API หากผู้ขายละเว้นไม่ระบุ เบราว์เซอร์จะระบุรหัสที่สร้างขึ้นโดยอัตโนมัติ
methodData ข้อมูลเฉพาะวิธีการชำระเงินที่ผู้ขายระบุเป็นส่วนหนึ่งของ PaymentMethodData ใช้เพื่อกำหนดรายละเอียดธุรกรรมการชำระเงิน
total จํานวนเงินทั้งหมดที่ผู้ขายระบุเป็นส่วนหนึ่งของ PaymentDetailsInit ใช้ข้อมูลนี้เพื่อสร้าง UI ที่จะแจ้งให้ลูกค้าทราบจำนวนเงินทั้งหมดที่ต้องชำระ
instrumentKey คีย์เครื่องดนตรีที่ผู้ใช้เลือก ซึ่งแสดงถึงinstrumentKeyที่คุณให้ไว้ล่วงหน้า สตริงว่างระบุว่าผู้ใช้ไม่ได้ระบุเครื่องดนตรีใดๆ

เปิดหน้าต่างเครื่องจัดการการชำระเงินเพื่อแสดงส่วนหน้าของแอปการชำระเงินบนเว็บ

เมื่อได้รับpaymentrequestเหตุการณ์ แอปการชำระเงินจะเปิดหน้าต่างตัวแฮนเดิลการชำระเงิน ได้โดยการเรียกใช้ PaymentRequestEvent.openWindow() หน้าต่างตัวแฮนเดิลการชำระเงินจะแสดงอินเทอร์เฟซของแอปการชำระเงินต่อลูกค้า ซึ่งลูกค้าสามารถ ตรวจสอบสิทธิ์ เลือกที่อยู่และตัวเลือกการจัดส่ง รวมถึงให้สิทธิ์การชำระเงินได้ เราจะอธิบายวิธีเขียนโค้ดส่วนหน้าในการจัดการการชำระเงินในส่วนหน้าของการชำระเงิน (เร็วๆ นี้)

ขั้นตอนการชำระเงินด้วยแอปการชำระเงินบนเว็บ

ส่งต่อ Promise ที่เก็บไว้ไปยัง 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);
  };
});

คุณสามารถใช้ PromiseResolver Polyfill ที่สะดวกเพื่อแก้ไข Promise ใน เวลาที่กำหนดได้

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_ }
}

แลกเปลี่ยนข้อมูลกับส่วนหน้า

Service Worker ของแอปการชำระเงินสามารถแลกเปลี่ยนข้อความกับส่วนหน้าของแอปการชำระเงินผ่าน ServiceWorkerController.postMessage() ได้ หากต้องการรับข้อความ จากส่วนหน้า ให้ฟังmessageเหตุการณ์

service-worker.js ของ [ตัวแฮนเดิลการชำระเงิน]

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

รับสัญญาณพร้อมจากส่วนหน้า

เมื่อเปิดหน้าต่างเครื่องจัดการการชำระเงินแล้ว Service Worker ควรรอสัญญาณสถานะพร้อมจากส่วนหน้าของแอปการชำระเงิน Service Worker สามารถส่งข้อมูลสำคัญไปยังส่วนหน้าได้เมื่อพร้อม

ส่วนหน้าของ [ตัวแฮนเดิลการชำระเงิน]

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;

ส่งคืนข้อมูลเข้าสู่ระบบการชำระเงินของลูกค้า

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

ยกเลิกธุรกรรมการชำระเงิน

หากต้องการอนุญาตให้ลูกค้ายกเลิกธุรกรรมได้ ส่วนหน้าสามารถส่งข้อความ POST ไปยัง Service Worker เพื่อดำเนินการดังกล่าวได้ จากนั้น Service Worker จะแก้ไข Promise ที่ส่งไปยัง 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;
      

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

โค้ดตัวอย่างทั้งหมดที่คุณเห็นในเอกสารนี้เป็นส่วนที่คัดลอกมาจาก ตัวอย่าง Payment Handler

ขั้นตอนถัดไป

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