Zahlungstransaktionen mit einem Service Worker orchestrieren

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

Sobald die Zahlungs-App registriert ist, Zahlungsanforderungen von Händlern akzeptieren. In diesem Beitrag wird erläutert, wie Sie Orchestrieren einer Zahlungstransaktion von einem Service Worker während der Laufzeit (d.h. 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“ sich auf eine Reihe von Ereignissen beziehen, Händler und Zahlungs-Handler tauschen Nachrichten aus, während der Nutzer interagiert mit dem Zahlungs-Handler. Weitere Informationen finden Sie unter Optionale Zahlungsinformationen mit einem Service Worker verarbeiten.

Ein Zahlungsanforderungsereignis vom Händler erhalten

Wenn ein Kunde mit Ihrer webbasierten Zahlungs-App bezahlen möchte und der Händler PaymentRequest.show() aufruft, erhält Ihr Service Worker das Ereignis paymentrequest. Fügen Sie dem Dienst-Worker einen Ereignis-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 aufbewahrte 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 wird die Händlerherkunft angegeben.
paymentRequestOrigin Ein String, der den Ursprung des Aufrufers angibt. Dieser Wert kann mit topOrigin übereinstimmen, wenn der Händler die Payment Request API direkt aufruft. Er kann sich jedoch unterscheiden, wenn die API von einem Drittanbieter wie einem Zahlungs-Gateway innerhalb eines iFrames aufgerufen wird.
paymentRequestId Die Eigenschaft id der PaymentDetailsInit, die an die Payment Request API gesendet wurde. Wenn der Händler dies unterlässt, 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 Instrumentschlüssel. Dieser Wert entspricht dem von Ihnen im Voraus angegebenen instrumentKey. 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 Zahlungs-App eine Zahlung öffnen Handler-Fenster durch Aufrufen von PaymentRequestEvent.openWindow(). Die Zahlung -Handler-Fenster zeigt dem Kunden die Benutzeroberfläche Ihrer Zahlungs-App an, in der kann er sich authentifizieren, eine Versandadresse und Optionen auswählen und Zahlung. Wie Sie Frontend-Code schreiben, erfahren Sie unter Zahlungen im Zahlungs-Frontend (demnächst verfügbar).

Direkter Bezahlvorgang mit einer webbasierten Zahlungs-App.

Übergeben Sie eine gespeicherte Zusicherung an PaymentRequestEvent.respondWith(), damit Sie sie in Zukunft mit einem Zahlungsergebnis abschließen können.

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

Du kannst einen praktischen PromiseResolver-Polyfill verwenden, um ein Versprechen aufzulösen: zu einem beliebigen Zeitpunkt.

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 der Frontend-Ansicht der Zahlungs-App austauschen. Wenn du Nachrichten vom Frontend erhalten möchtest, musst du message-Ereignisse überwachen.

[Zahlungs-Handler] service-worker.js:

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

Bereit-Signal vom Frontend empfangen

Sobald das Fenster des Zahlungsabwicklers geöffnet ist, sollte der Dienst-Worker auf ein Signal zum Bereitschaftsstatus vom Frontend der Zahlungs-App warten. Der Dienst-Worker kann wichtige Informationen an das Frontend weitergeben, sobald er bereit ist.

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

Transaktionsdetails an das Frontend übergeben

Senden Sie nun die Zahlungsdetails zurück. In diesem Fall senden Sie nur den Gesamtbetrag der Zahlungsanfrage. Sie können aber auch weitere Details angeben.

[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 Nachricht senden. an den Service Worker, um fortzufahren. Sie können das Versprechen auflösen, das an PaymentRequestEvent.respondWith(), um das Ergebnis an den Händler zurückzusenden. Übergeben Sie PaymentHandlerResponse -Objekt enthält.

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

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

Zahlungstransaktion stornieren

Damit der Kunde die Transaktion abbrechen kann, kann das Frontend eine Postnachricht an den Service Worker senden. Der Service Worker kann dann das an PaymentRequestEvent.respondWith() übergebene Versprechen mit null auflösen, um dem Händler zu signalisieren, 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 Beispielcodes, die Sie in diesem Dokument gesehen haben, sind Auszüge aus funktionierende Beispiel-App:

https://paymenthandler-demo.glitch.me

Service Worker für [Zahlungs-Handler]

[payment handler] frontend

So kannst du es ausprobieren:

  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 über einen Dienst-Worker orchestriert wird. Im nächsten Schritt erfahren Sie, wie Sie dem Dienst-Worker einige erweiterte Funktionen hinzufügen.