سازماندهی تراکنش های پرداخت با یک کارگر خدماتی

چگونه برنامه پرداخت مبتنی بر وب خود را با Web Payments تطبیق دهید و تجربه کاربری بهتری برای مشتریان فراهم کنید.

پس از ثبت برنامه پرداخت ، شما آماده پذیرش درخواست های پرداخت از سوی بازرگانان هستید. این پست توضیح می دهد که چگونه می توان یک تراکنش پرداخت از یک سرویس دهنده را در طول زمان اجرا (یعنی زمانی که یک پنجره نمایش داده می شود و کاربر در حال تعامل با آن است) هماهنگ کرد.

سازماندهی تراکنش های پرداخت با یک کارگر خدماتی
سازماندهی تراکنش های پرداخت با یک کارگر خدماتی

"تغییر پارامتر پرداخت در زمان اجرا" به مجموعه ای از رویدادها اشاره دارد که به تاجر و کنترل کننده پرداخت اجازه می دهد در حالی که کاربر در حال تعامل با کنترل کننده پرداخت است، پیام ها را مبادله کنند. در رسیدگی به اطلاعات پرداخت اختیاری با یک کارگر خدماتی بیشتر بیاموزید.

یک رویداد درخواست پرداخت از تاجر دریافت کنید

هنگامی که مشتری تصمیم می گیرد با برنامه پرداخت مبتنی بر وب شما پرداخت کند و تاجر PaymentRequest.show() را فراخوانی می کند ، کارمند خدمات شما یک رویداد paymentrequest دریافت می کند. برای ثبت رویداد و آماده شدن برای اقدام بعدی، شنونده رویداد را به کارگر سرویس اضافه کنید.

[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 رشته ای که مبدا فراخوان را نشان می دهد. زمانی که فروشنده مستقیماً API درخواست پرداخت را فراخوانی می‌کند، می‌تواند مانند topOrigin باشد، اما اگر API از داخل iframe توسط شخص ثالثی مانند دروازه پرداخت فراخوانی شود، ممکن است متفاوت باشد.
paymentRequestId ویژگی id PaymentDetailsInit به API درخواست پرداخت ارائه شده است. اگر تاجر حذف کند، مرورگر یک شناسه تولید شده خودکار ارائه می‌کند.
methodData داده‌های خاص روش پرداخت که توسط تاجر به عنوان بخشی از PaymentMethodData ارائه شده است. از این برای تعیین جزئیات تراکنش پرداخت استفاده کنید.
total کل مبلغ ارائه شده توسط تاجر به عنوان بخشی از PaymentDetailsInit . از این برای ایجاد یک رابط کاربری استفاده کنید تا مشتری از مبلغ کل پرداختی مطلع شود.
instrumentKey کلید ابزار انتخاب شده توسط کاربر. این نشان دهنده instrumentKey است که از قبل ارائه کرده اید. یک رشته خالی نشان می دهد که کاربر هیچ ابزاری را مشخص نکرده است.

پنجره کنترل کننده پرداخت را باز کنید تا نمای برنامه پرداخت مبتنی بر وب نمایش داده شود

هنگامی که یک رویداد paymentrequest دریافت می‌شود، برنامه پرداخت می‌تواند با فراخوانی PaymentRequestEvent.openWindow() پنجره کنترل‌کننده پرداخت را باز کند. پنجره کنترل کننده پرداخت، رابط برنامه پرداخت شما را به مشتریان نشان می دهد که می توانند احراز هویت، آدرس و گزینه های ارسال را انتخاب کنند و پرداخت را مجاز کنند. ما نحوه نوشتن کد ظاهری را در Handling pays در نمای پرداخت (به زودی) توضیح خواهیم داد.

جریان پرداخت با یک برنامه پرداخت مبتنی بر وب.

یک قول حفظ شده را به 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);
  };
});
…

شما می توانید از یک PromiseResolver polyfill مناسب برای حل یک وعده در زمان دلخواه استفاده کنید.

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

تبادل اطلاعات با فرانت اند

کارمند سرویس برنامه پرداخت می‌تواند از طریق ServiceWorkerController.postMessage() با بخش جلویی برنامه پرداخت پیام‌ها را مبادله کند. برای دریافت پیام‌ها از قسمت جلو، به رویدادهای message گوش دهید.

[Payment handler] 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'
});

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

[پرداخت کننده] فرانت اند:

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
  });

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

تراکنش پرداخت را لغو کنید

برای اینکه مشتری بتواند تراکنش را لغو کند، فرانت اند می تواند برای انجام این کار یک پیام پستی به کارمند خدمات ارسال کند. سپس سرویس‌کار می‌تواند قول ارسال شده به PaymentRequestEvent.respondWith() با null حل کند تا به تاجر نشان دهد که تراکنش لغو شده است.

[پرداخت کننده] فرانت اند:

  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

[پرداخت کننده] کارگر خدمات

[پرداخت کننده] فرانت اند

برای امتحان کردن:

  1. به https://paymentrequest-demo.glitch.me/ بروید.
  2. به پایین صفحه بروید.
  3. دکمه افزودن یک پرداخت را فشار دهید.
  4. https://paymenthandler-demo.glitch.me در قسمت شناسه روش پرداخت وارد کنید.
  5. دکمه پرداخت را در کنار فیلد فشار دهید.

مراحل بعدی

در این مقاله، نحوه تنظیم تراکنش پرداخت را از یک کارگر خدماتی یاد گرفتیم. گام بعدی این است که یاد بگیرید چگونه برخی ویژگی های پیشرفته تر را به سرویس کار اضافه کنید.

،

چگونه برنامه پرداخت مبتنی بر وب خود را با Web Payments تطبیق دهید و تجربه کاربری بهتری برای مشتریان فراهم کنید.

پس از ثبت برنامه پرداخت ، شما آماده پذیرش درخواست های پرداخت از سوی بازرگانان هستید. این پست توضیح می دهد که چگونه می توان یک تراکنش پرداخت از یک سرویس دهنده را در طول زمان اجرا (یعنی زمانی که یک پنجره نمایش داده می شود و کاربر در حال تعامل با آن است) هماهنگ کرد.

سازماندهی تراکنش های پرداخت با یک کارگر خدماتی
سازماندهی تراکنش های پرداخت با یک کارگر خدماتی

"تغییر پارامتر پرداخت در زمان اجرا" به مجموعه ای از رویدادها اشاره دارد که به تاجر و کنترل کننده پرداخت اجازه می دهد در حالی که کاربر در حال تعامل با کنترل کننده پرداخت است، پیام ها را مبادله کنند. در رسیدگی به اطلاعات پرداخت اختیاری با یک کارگر خدماتی بیشتر بیاموزید.

یک رویداد درخواست پرداخت از تاجر دریافت کنید

هنگامی که مشتری تصمیم می گیرد با برنامه پرداخت مبتنی بر وب شما پرداخت کند و تاجر PaymentRequest.show() را فراخوانی می کند ، کارمند خدمات شما یک رویداد paymentrequest دریافت می کند. برای ثبت رویداد و آماده شدن برای اقدام بعدی، شنونده رویداد را به کارگر سرویس اضافه کنید.

[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 رشته ای که مبدا فراخوان را نشان می دهد. زمانی که فروشنده مستقیماً API درخواست پرداخت را فراخوانی می‌کند، می‌تواند مانند topOrigin باشد، اما اگر API از داخل iframe توسط شخص ثالثی مانند دروازه پرداخت فراخوانی شود، ممکن است متفاوت باشد.
paymentRequestId ویژگی id PaymentDetailsInit به API درخواست پرداخت ارائه شده است. اگر تاجر حذف کند، مرورگر یک شناسه تولید شده خودکار ارائه می‌کند.
methodData داده‌های خاص روش پرداخت که توسط تاجر به عنوان بخشی از PaymentMethodData ارائه شده است. از این برای تعیین جزئیات تراکنش پرداخت استفاده کنید.
total کل مبلغ ارائه شده توسط تاجر به عنوان بخشی از PaymentDetailsInit . از این برای ایجاد یک رابط کاربری استفاده کنید تا مشتری از مبلغ کل پرداختی مطلع شود.
instrumentKey کلید ابزار انتخاب شده توسط کاربر. این نشان دهنده instrumentKey است که از قبل ارائه کرده اید. یک رشته خالی نشان می دهد که کاربر هیچ ابزاری را مشخص نکرده است.

پنجره کنترل کننده پرداخت را باز کنید تا نمای برنامه پرداخت مبتنی بر وب نمایش داده شود

هنگامی که یک رویداد paymentrequest دریافت می‌شود، برنامه پرداخت می‌تواند با فراخوانی PaymentRequestEvent.openWindow() پنجره کنترل‌کننده پرداخت را باز کند. پنجره کنترل کننده پرداخت، رابط برنامه پرداخت شما را به مشتریان نشان می دهد که می توانند احراز هویت، آدرس و گزینه های ارسال را انتخاب کنند و پرداخت را مجاز کنند. ما نحوه نوشتن کد ظاهری را در Handling pays در نمای پرداخت (به زودی) توضیح خواهیم داد.

جریان پرداخت با یک برنامه پرداخت مبتنی بر وب.

یک قول حفظ شده را به 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);
  };
});
…

شما می توانید از یک PromiseResolver polyfill مناسب برای حل یک وعده در زمان دلخواه استفاده کنید.

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

تبادل اطلاعات با فرانت اند

کارمند سرویس برنامه پرداخت می‌تواند از طریق ServiceWorkerController.postMessage() با بخش جلویی برنامه پرداخت پیام‌ها را مبادله کند. برای دریافت پیام‌ها از قسمت جلو، به رویدادهای message گوش دهید.

[Payment handler] 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'
});

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

[پرداخت کننده] فرانت اند:

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
  });

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

تراکنش پرداخت را لغو کنید

برای اینکه مشتری بتواند تراکنش را لغو کند، فرانت اند می تواند برای انجام این کار یک پیام پستی به کارمند خدمات ارسال کند. سپس سرویس‌کار می‌تواند قول ارسال شده به 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

[پرداخت کننده] کارگر خدمات

[پرداخت کننده] فرانت اند

برای امتحان کردن:

  1. به https://paymentrequest-demo.glitch.me/ بروید.
  2. به پایین صفحه بروید.
  3. دکمه افزودن یک پرداخت را فشار دهید.
  4. https://paymenthandler-demo.glitch.me در قسمت شناسه روش پرداخت وارد کنید.
  5. دکمه پرداخت را در کنار فیلد فشار دهید.

مراحل بعدی

در این مقاله، نحوه تنظیم تراکنش پرداخت را از یک کارگر خدماتی یاد گرفتیم. گام بعدی این است که یاد بگیرید چگونه برخی ویژگی های پیشرفته تر را به سرویس کار اضافه کنید.