Zahlungstransaktionen mit einem Service Worker orchestrieren

So passen Sie Ihre webbasierte Zahlungs-App an Web Payments an und bieten Kunden eine bessere Nutzererfahrung.

Sobald die Zahlungs-App registriert ist, können Sie Zahlungsanfragen von Händlern annehmen. In diesem Beitrag wird erläutert, wie Sie eine Zahlungstransaktion während der Laufzeit über einen Service Worker orchestrieren können, d.h. wenn ein Fenster angezeigt wird und der Nutzer damit interagiert.

Zahlungsvorgänge mit einem Service Worker orchestrieren
Zahlungsvorgänge mit einem Service Worker orchestrieren

„Laufzeitparameter für die Zahlung ändern“ bezieht sich auf eine Reihe von Ereignissen, die es dem Händler und dem Zahlungsabwickler ermöglichen, Nachrichten auszutauschen, während der Nutzer mit dem Zahlungsabwickler interagiert. Weitere Informationen zum Umgang mit optionalen Zahlungsinformationen mit einem Service Worker

Eine Zahlungsanforderungsbenachrichtigung vom Händler erhalten

Wenn ein Kunde mit Ihrer webbasierten Zahlungs-App bezahlt und der Händler PaymentRequest.show() aufruftPaymentRequest.show(), erhält Ihr Service Worker ein paymentrequest-Ereignis. Fügen Sie dem Service Worker einen Event-Listener hinzu, um das Ereignis zu erfassen und die nächste Aktion vorzubereiten.

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

Die aufbewahrte PaymentRequestEvent enthält wichtige Informationen zu dieser Transaktion:

Property-Name Beschreibung
topOrigin Ein String, der den Ursprung der Top-Level-Webseite angibt (in der Regel der Zahlungsempfänger). Damit können Sie die Herkunft des Händlers identifizieren.
paymentRequestOrigin Ein String, der den Ursprung des Aufrufers angibt. Das kann mit topOrigin identisch sein, wenn der Händler die Payment Request API direkt aufruft. Es kann jedoch abweichen, wenn die API von einem Drittanbieter wie einem Zahlungs-Gateway über einen iFrame aufgerufen wird.
paymentRequestId Die id-Eigenschaft des PaymentDetailsInit, das der Payment Request API bereitgestellt wird. Wenn der Händler sie weglässt, stellt der Browser eine automatisch generierte ID bereit.
methodData Die zahlungsmethodenspezifischen Daten, die vom Händler im Rahmen von PaymentMethodData bereitgestellt werden. Damit können Sie die Details der Zahlungstransaktion ermitteln.
total Der Gesamtbetrag, der vom Händler im Rahmen von PaymentDetailsInit bereitgestellt wurde. Verwenden Sie diese Informationen, um eine Benutzeroberfläche zu erstellen, auf der der Kunde den zu zahlenden Gesamtbetrag sehen kann.
instrumentKey Der vom Nutzer ausgewählte Instrumentschlüssel. Das entspricht den instrumentKey, die Sie im Voraus angegeben haben. Ein leerer String bedeutet, dass der Nutzer keine Instrumente angegeben hat.

Öffnen Sie das Fenster zur Zahlungsabwicklung, um das Frontend der webbasierten Zahlungs-App anzuzeigen.

Wenn ein paymentrequest-Ereignis empfangen wird, kann die Zahlungs-App ein Zahlungs-Handler-Fenster öffnen, indem sie PaymentRequestEvent.openWindow() aufruft. Im Fenster des Zahlungshandlers wird die Benutzeroberfläche Ihrer Zahlungs-App angezeigt, über die Kunden sich authentifizieren, Versandadresse und ‑optionen auswählen und die Zahlung autorisieren können. Wie Sie den Frontend-Code schreiben, wird im Abschnitt Zahlungen im Zahlungs-Frontend verarbeiten (in Kürze verfügbar) beschrieben.

Kaufvorgang mit einer webbasierten Zahlungs-App.

Übergeben Sie ein aufbewahrtes Promise an PaymentRequestEvent.respondWith(), damit Sie es in Zukunft mit einem Zahlungsergebnis auflösen können.

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

Mit einem praktischen PromiseResolver-Polyfill können Sie ein Promise zu einem beliebigen Zeitpunkt auflösen.

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

Informationen mit dem Frontend austauschen

Der Service Worker der Zahlungs-App kann über ServiceWorkerController.postMessage() Nachrichten mit dem Frontend der Zahlungs-App austauschen. Wenn Sie Nachrichten vom Frontend empfangen möchten, müssen Sie auf message-Ereignisse warten.

[Zahlungs-Handler] service-worker.js:

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

Bereitschaftssignal vom Frontend empfangen

Sobald das Fenster zur Zahlungsabwicklung geöffnet ist, sollte der Service Worker auf ein Signal vom Frontend der Zahlungs-App warten, dass der Status „Bereit“ erreicht wurde. Der Service Worker kann wichtige Informationen an das Frontend weitergeben, sobald er bereit ist.

[payment handler] frontend:

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

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

Transaktionsdetails an das Frontend übergeben

Sende uns nun die Zahlungsdetails zurück. In diesem Fall senden Sie nur die Gesamtsumme der Zahlungsanfrage, können aber auch weitere Details übergeben.

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

Zahlungsanmeldedaten des Kunden zurückgeben

Wenn der Kunde die Zahlung autorisiert, kann das Frontend eine Post-Nachricht an den Service Worker senden, um fortzufahren. Sie können das an PaymentRequestEvent.respondWith() übergebene Promise auflösen, um das Ergebnis an den Händler zurückzusenden. Übergeben Sie ein PaymentHandlerResponse-Objekt.

Property-Name Beschreibung
methodName Die Kennung der Zahlungsmethode, die für die Zahlung verwendet wurde.
details Die zahlungsmethodenspezifischen Daten, die dem Händler die für die Zahlungsabwicklung erforderlichen Informationen liefern.

[payment handler] frontend:

  const paymentMethod = 

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

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

Zahlungsvorgang abbrechen

Damit der Kunde die Transaktion abbrechen kann, kann das Frontend eine Post-Nachricht an den Service Worker senden. Der Service Worker kann dann das an PaymentRequestEvent.respondWith() übergebene Promise mit null auflösen, um dem Händler mitzuteilen, dass die Transaktion abgebrochen wurde.

[payment handler] frontend:

  postMessage('CANCEL_PAYMENT');

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

Beispielcode

Alle Codebeispiele in diesem Dokument sind Auszüge aus der Demo für Zahlungshandler.

Nächste Schritte

In diesem Artikel haben wir gelernt, wie eine Zahlungstransaktion über einen Service Worker orchestriert wird. Im nächsten Schritt erfahren Sie, wie Sie dem Service Worker einige erweiterte Funktionen hinzufügen.