תזמור עסקאות תשלום עם קובץ שירות (service worker)

איך להתאים את אפליקציית התשלומים מבוססת האינטרנט לתשלומים באינטרנט ולספק ללקוחות חוויית משתמש טובה יותר.

אחרי שאפליקציית התשלומים תירשם, תוכלו לקבל בקשות תשלום מעסקים. במאמר הזה נסביר איך לתזמור עסקת תשלום מ-service worker במהלך זמן הריצה (כלומר, כשחלון מוצג והמשתמש מבצע איתו אינטראקציה).

תזמור עסקאות תשלום באמצעות שירות עובד (service worker)
תזמור עסקאות תשלום באמצעות שירות עובד (service worker)

'שינויים בפרמטרים של תשלום בסביבת זמן ריצה' מתייחסים לקבוצת אירועים שמאפשרת למוכרים ולמפעילי התשלומים להחליף הודעות בזמן שהמשתמשים מבצעים אינטראקציה עם מפעיל התשלומים. מידע נוסף זמין במאמר טיפול בפרטי תשלום אופציונליים באמצעות שירות עובד.

קבלת אירוע של בקשת תשלום מהסוחר

כשלקוח בוחר לשלם באמצעות אפליקציית התשלום שלכם באינטרנט והמוכר מפעיל את PaymentRequest.show(), אירוע paymentrequest יישלח ל-service worker. מוסיפים ל-service worker מאזין לאירועים כדי לתעד את האירוע ולהתכונן לפעולה הבאה.

[payment handler] 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. אפשר להשתמש במאפיין הזה כדי ליצור ממשק משתמש שיציג ללקוח את הסכום הכולל לתשלום.
instrumentKey מפתח הכלי שנבחר על ידי המשתמש. הסכום הזה משקף את instrumentKey שסיפקתם מראש. מחרוזת ריקה מציינת שהמשתמש לא ציין כלים.

פתיחת חלון הטיפול בתשלומים כדי להציג את ממשק הקצה של אפליקציית התשלומים מבוססת האינטרנט

כשמתקבל אירוע paymentrequest, אפליקציית התשלומים יכולה לפתוח חלון של טיפול בתשלום באמצעות קריאה ל-PaymentRequestEvent.openWindow(). בחלון של שירותי עיבוד התשלומים יוצג ללקוחות הממשק של אפליקציית התשלומים שלכם, שבו הם יוכלו לבצע אימות, לבחור כתובת למשלוח ואפשרויות משלוח ולאשר את התשלום. במאמר טיפול בתשלומים בחזית הלקוח (בקרוב) נסביר איך לכתוב את הקוד של חזית הלקוח.

תהליך התשלום באמצעות אפליקציית תשלום מבוססת-אינטרנט.

מעבירים הבטחה ששמורה ב-PaymentRequestEvent.respondWith() כדי שתוכלו לפתור אותה עם תוצאת תשלום בעתיד.

[payment handler] 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.

[payment handler] service-worker.js:

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

קבלת האות 'מוכן' מהחזית

אחרי שחלון הטיפול בתשלומים נפתח, קובץ השירות צריך להמתין לאות מצב מוכן מחזית אפליקציית התשלומים. כשהוא מוכן, ה-service worker יכול להעביר מידע חשוב לקצה הקדמי.

[payment handler] frontend:

navigator.serviceWorker.controller.postMessage({
  type
: 'WINDOW_IS_READY'
});

[payment handler] 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;

העברת פרטי העסקה לקצה הקדמי

עכשיו יש לשלוח בחזרה את פרטי התשלום. במקרה כזה, שולחים רק את הסכום הכולל של בקשת התשלום, אבל אפשר להעביר פרטים נוספים אם רוצים.

[payment handler] service-worker.js:


       
// Pass the payment details to the frontend
        postMessage
('PAYMENT_IS_READY', { total });
       
break;

[payment handler] frontend:

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;

החזרת פרטי התשלום של הלקוח

כשהלקוח מאשר את התשלום, ממשק הקצה יכול לשלוח הודעת פוסט ל-service worker כדי להמשיך בתהליך. אפשר לפתור את ההבטחה שהועברה ל-PaymentRequestEvent.respondWith() כדי לשלוח את התוצאה בחזרה אל המוכר. מעבירים אובייקט PaymentHandlerResponse.

שם הנכס תיאור
methodName מזהה אמצעי התשלום ששימש לביצוע התשלום.
details הנתונים הספציפיים של אמצעי התשלום, שמספקים את המידע הנדרש למוכר כדי לעבד את התשלום.

[payment handler] frontend:

  const paymentMethod = 

  postMessage
('PAYMENT_AUTHORIZED', {
    paymentMethod
,              // Payment method identifier
 
});

[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_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 יכול לפתור את ההבטחה שהועברה אל PaymentRequestEvent.respondWith() באמצעות null כדי להצביע בפני המוכר שהעסקה בוטלה.

[payment handler] frontend:

  postMessage('CANCEL_PAYMENT');

[payment handler] 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

[payment handler] service worker

[payment handler] frontend

כדי לנסות:

  1. נכנסים לכתובת https://paymentrequest-demo.glitch.me/.
  2. עבור לתחתית הדף.
  3. לוחצים על הוספת לחצן תשלום.
  4. מזינים https://paymenthandler-demo.glitch.me בשדה מזהה אמצעי התשלום.
  5. לוחצים על הלחצן תשלום לצד השדה.

השלבים הבאים

במאמר הזה למדנו איך לתזמור עסקת תשלום מ-service worker. בשלב הבא תלמדו איך להוסיף ל-service worker תכונות מתקדמות יותר.