วิธีปรับแอปการชำระเงินบนเว็บให้เข้ากับ Web Payments และมอบประสบการณ์การใช้งานที่ดีขึ้นแก่ลูกค้า
เมื่อลงทะเบียนแอปการชำระเงินแล้ว คุณ ก็พร้อมรับคำขอการชำระเงินจากผู้ขาย โพสต์นี้อธิบายวิธี จัดระเบียบธุรกรรมการชำระเงินจาก 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
