วิธีปรับเปลี่ยนแอปการชำระเงินบนเว็บของคุณให้เป็น Web Payments และมอบประสบการณ์ของผู้ใช้ที่ดียิ่งขึ้นให้แก่ลูกค้า
เมื่อลงทะเบียนแอปการชำระเงินแล้ว คุณก็พร้อมที่จะยอมรับคำขอการชำระเงินจากผู้ขาย โพสต์นี้จะอธิบายวิธีจัดกลุ่มธุรกรรมการชำระเงินจาก Service Worker ระหว่างรันไทม์ (เช่น เมื่อหน้าต่างแสดงขึ้นและผู้ใช้กำลังโต้ตอบด้วย)
![การจัดการธุรกรรมการชำระเงินกับ Service Worker เป็นกลุ่ม](https://web.dev/static/articles/orchestrating-payment-transactions/image/orchestrating-payment-tra-dd17687ea595a.png?authuser=6&hl=th)
"การเปลี่ยนแปลงพารามิเตอร์การชำระเงินรันไทม์" หมายถึงชุดเหตุการณ์ที่อนุญาตให้ผู้ขายและเครื่องจัดการการชำระเงินแลกเปลี่ยนข้อความขณะที่ผู้ใช้โต้ตอบกับเครื่องจัดการการชำระเงิน ดูข้อมูลเพิ่มเติมในการจัดการข้อมูลการชำระเงินที่ไม่บังคับด้วย Service Worker
รับเหตุการณ์คำขอการชำระเงินจากผู้ขาย
เมื่อลูกค้าเลือกชำระเงินด้วยแอปการชำระเงินบนเว็บและผู้ขายเรียกใช้ PaymentRequest.show()
โปรแกรมทำงานของบริการจะได้รับเหตุการณ์ paymentrequest
เพิ่ม Listener เหตุการณ์ให้กับโปรแกรมทำงานของบริการเพื่อบันทึกเหตุการณ์และเตรียมพร้อมสำหรับการดำเนินการถัดไป
[เครื่องจัดการการชำระเงิน] 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()
หน้าต่างเครื่องมือจัดการการชำระเงินจะแสดงอินเทอร์เฟซแอปการชำระเงินต่อลูกค้าซึ่งลูกค้าสามารถตรวจสอบสิทธิ์ เลือกที่อยู่สำหรับจัดส่งและตัวเลือก และให้สิทธิ์การชำระเงินได้ เราจะพูดถึงวิธีเขียนโค้ดฟรอนท์เอนด์ในการจัดการการชำระเงินในส่วนหน้าการชำระเงิน (เร็วๆ นี้)
ให้สัญญาที่รักษาไว้ให้แก่ 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);
};
});
…
คุณสามารถใช้ Polyfill ของ PromiseResolver
เพื่อความสะดวกในการดำเนินการตามคำสัญญาในเวลาที่กำหนดเอง
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 });
}
รับสัญญาณที่พร้อมใช้งานจากฟรอนท์เอนด์
เมื่อเปิดหน้าต่างเครื่องจัดการการชำระเงินแล้ว โปรแกรมทำงานของบริการควรรอสัญญาณสถานะพร้อมจากฟรอนท์เอนด์ของแอปการชำระเงิน โปรแกรมทำงานของบริการจะส่งข้อมูลสำคัญไปยังฟรอนท์เอนด์ได้เมื่อพร้อมใช้งาน
[เครื่องจัดการการชำระเงิน] ฟรอนท์เอนด์:
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;
…
แสดงข้อมูลเข้าสู่ระบบการชำระเงินของลูกค้า
เมื่อลูกค้าอนุมัติการชำระเงิน ฟรอนท์เอนด์สามารถส่งข้อความโพสต์ไปยังโปรแกรมทำงานของบริการเพื่อดำเนินการต่อ คุณสามารถแก้ไขคำสัญญาที่ส่งไปยัง 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;
…
ยกเลิกธุรกรรมการชำระเงิน
หากต้องการอนุญาตให้ลูกค้ายกเลิกธุรกรรม ฟรอนท์เอนด์สามารถส่งข้อความโพสต์ไปยัง Service Worker เพื่อดำเนินการดังกล่าวได้ จากนั้น Service Worker จะแก้ไขคำสัญญาที่ส่งไปยัง 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;
…
รหัสตัวอย่าง
โค้ดตัวอย่างทั้งหมดที่คุณเห็นในเอกสารนี้เป็นข้อความที่ตัดตอนมาจากแอปตัวอย่างที่ใช้งานได้ต่อไปนี้
https://paymenthandler-demo.glitch.me
[เครื่องจัดการการชำระเงิน] Service Worker
[เครื่องจัดการการชำระเงิน] ฟรอนท์เอนด์
วิธีทดลองใช้มีดังนี้
- ไปที่ https://paymentrequest-demo.glitch.me/
- ไปที่ด้านล่างสุดของหน้า
- กดปุ่มเพิ่มการชำระเงิน
- ป้อน
https://paymenthandler-demo.glitch.me
ลงในช่องตัวระบุวิธีการชำระเงิน - กดปุ่มชำระเงินข้างช่อง
ขั้นตอนถัดไป
ในบทความนี้ เราได้เรียนรู้วิธีจัดการธุรกรรมการชำระเงินจาก Service Worker เป็นกลุ่ม ขั้นตอนต่อไปคือดูวิธีเพิ่มฟีเจอร์ขั้นสูงอื่นๆ ให้กับโปรแกรมทำงานของบริการ