Zahlungstransaktionen mit einem Service Worker orchestrieren

Hier erfahren Sie, wie Sie Ihre webbasierte Zahlungsanwendung an Web Payments anpassen und so eine bessere Nutzererfahrung für Ihre Kunden bieten.

Sobald die Zahlungs-App registriert ist, kannst du Zahlungsanforderungen von Händlern akzeptieren. In diesem Beitrag wird erläutert, wie eine Zahlungstransaktion von einem Service Worker während der Laufzeit orchestriert wird (z.B. wenn ein Fenster angezeigt wird und der Nutzer damit interagiert).

Zahlungstransaktionen mit einem Service Worker orchestrieren
Zahlungstransaktionen mit einem Service Worker orchestrieren

„Änderungen der Laufzeitzahlungsparameter“ beziehen sich auf eine Reihe von Ereignissen, die es dem Händler und dem Zahlungs-Handler ermöglichen, Nachrichten auszutauschen, während der Nutzer mit dem Zahlungs-Handler interagiert. Weitere Informationen finden Sie unter Optionale Zahlungsinformationen mit einem Service Worker verarbeiten.

Ein Zahlungsanforderungsereignis vom Händler erhalten

Wenn ein Kunde mit deiner webbasierten Zahlungs-App bezahlt und der Händler PaymentRequest.show() aufruft, erhält dein Service Worker ein paymentrequest-Ereignis. Fügen Sie dem Service Worker einen Event-Listener hinzu, um das Ereignis zu erfassen und sich auf 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 beibehaltene PaymentRequestEvent enthält wichtige Informationen zu dieser Transaktion:

Property-Name Beschreibung
topOrigin Ein String, der den Ursprung der Webseite der obersten Ebene angibt (normalerweise der Händler des Zahlungsempfängers). Hiermit kann der Ursprungsort des Händlers identifiziert werden.
paymentRequestOrigin Ein String, der den Ursprung des Aufrufers angibt. Dieser Wert kann mit topOrigin identisch sein, wenn der Händler die Payment Request API direkt aufruft. Er kann sich jedoch unterscheiden, wenn die API von einem Drittanbieter, z. B. einem Zahlungs-Gateway, in einem iFrame aufgerufen wird.
paymentRequestId Die Eigenschaft id der PaymentDetailsInit, die an die Payment Request API gesendet wurde. Lässt der Händler dies aus, stellt der Browser eine automatisch generierte ID bereit.
methodData Die spezifischen Daten für Zahlungsmethoden, die vom Händler im Rahmen von PaymentMethodData bereitgestellt werden. Hiermit können Sie die Details der Zahlungstransaktion ermitteln.
total Der vom Händler im Rahmen von PaymentDetailsInit bereitgestellte Gesamtbetrag. Erstellen Sie damit eine Benutzeroberfläche, in der der Kunde über den zu zahlenden Gesamtbetrag informiert wird.
instrumentKey Der vom Nutzer ausgewählte Zahlungsmittelschlüssel. Dies entspricht der instrumentKey, die du im Voraus angegeben hast. Ein leerer String bedeutet, dass der Nutzer keine Zahlungsmittel angegeben hat.

Öffnen Sie das Fenster für die Zahlungs-Handler, um das Frontend der webbasierten Zahlungsanwendung anzuzeigen

Wenn ein paymentrequest-Ereignis empfangen wird, kann die Zahlungsanwendung durch Aufrufen von PaymentRequestEvent.openWindow() ein Zahlungs-Handler-Fenster öffnen. Im Fenster für die Zahlungsabwicklung wird dem Kunden die Oberfläche Ihrer Zahlungs-App angezeigt. Dort können sich Kunden authentifizieren, eine Versandadresse und Optionen auswählen und die Zahlung autorisieren. Wie Sie den Front-End-Code schreiben, erfahren Sie unter Zahlungen im Zahlungs-Front-End verarbeiten (demnächst verfügbar).

Bezahlvorgang mit einer webbasierten Zahlungs-App.

Übergeben Sie ein beibehaltenes Promise an PaymentRequestEvent.respondWith(), damit Sie es künftig mit einem Zahlungsergebnis klären 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);
  };
});
…

Du kannst einen praktischen PromiseResolver-Polyfill verwenden, um ein Promise zu einem beliebigen Zeitpunkt aufzulö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 Front-End der Zahlungs-App austauschen. Überwachen Sie message-Ereignisse, um Nachrichten vom Front-End zu erhalten.

[Zahlungs-Handler] service-worker.js:

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

Signal „Bereit“ vom Front-End empfangen

Nachdem das Fenster für den Zahlungs-Handler geöffnet wurde, sollte der Service Worker vom Front-End der Zahlungsanwendung auf ein Bereitschaftssignal warten. Der Service Worker kann wichtige Informationen an das Frontend weitergeben, sobald es bereit ist.

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

Senden Sie nun die Zahlungsdetails zurück. In diesem Fall senden Sie nur die Summe der Zahlungsanforderung, aber Sie können weitere Details angeben, wenn Sie möchten.

[Zahlungs-Handler] service-worker.js:

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

[Zahlungs-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 Front-End eine Post-Nachricht an den Service Worker senden, um fortzufahren. Du kannst das an PaymentRequestEvent.respondWith() weitergegebene Versprechen auflösen, um das Ergebnis an den Händler zurückzusenden. Übergeben Sie ein PaymentHandlerResponse-Objekt.

Property-Name Beschreibung
methodName Die ID der Zahlungsmethode, die für die Zahlung verwendet wird.
details Die spezifischen Daten der Zahlungsmethode, die Informationen enthalten, die der Händler zur Verarbeitung der Zahlung benötigt.

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

Zahlungstransaktion abbrechen

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

[Zahlungs-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 Beispielcodes, die Sie in diesem Dokument gesehen haben, sind Auszüge aus der folgenden funktionierenden Beispiel-App:

https://paymenthandler-demo.glitch.me

[Zahlungs-Handler] Service Worker

[Zahlungs-Handler] Frontend

Probieren Sie es aus:

  1. Rufen Sie https://paymentrequest-demo.glitch.me/ auf.
  2. Sehen Sie sich den Bereich ganz unten auf der Seite an.
  3. Klicken Sie auf Zahlungsschaltfläche hinzufügen.
  4. Geben Sie https://paymenthandler-demo.glitch.me in das Feld ID der Zahlungsmethode ein.
  5. Klicken Sie neben dem Feld auf die Schaltfläche Bezahlen.

Nächste Schritte

In diesem Artikel haben wir gelernt, wie eine Zahlungstransaktion von einem Service Worker orchestriert wird. Im nächsten Schritt lernen Sie, wie Sie dem Service Worker erweiterte Features hinzufügen.