Signatur
Beschreibung
PaymentRequestEvent gehört zur Payment Handler API. Damit kann eine Web-Anwendung selbst als Zahlungsanbieter (z. B. Wallet, Bank-App oder PSP) auftreten. Ruft ein Händler new PaymentRequest(...).show() auf und wählt der Nutzer die Zahlungsart des Anbieters, feuert der Browser im registrierten Service Worker des Anbieters das Event paymentrequest. Das Handler-Objekt ist dann ein PaymentRequestEvent.
Das Event enthält alle Angaben, die der Händler übergeben hat:
methodData: die unterstützten Zahlungsarten mit ihren Detailstotal: der Gesamtbetragmodifiers: zahlungsartabhängige AnpassungenpaymentRequestId: die ID der AnfragepaymentRequestOriginundtopOrigin: die Herkunft der Anfrage bzw. der obersten Seite- je nach Browser auch
paymentOptionsundshippingOptions
Die wichtigsten Methoden sind:
openWindow(url): öffnet ein Zahlungsfenster, in dem sich der Nutzer anmeldet und die Zahlung bestätigtrespondWith(promise): übergibt dem Händler das Ergebnis, ein Objekt mitmethodNameunddetailschangePaymentMethod(methodName, methodDetails): meldet dem Händler eine Änderung der Zahlungsart, etwa damit er den Preis anpasst- je nach Browser auch
changeShippingAddress()undchangeShippingOption()
Weil das Interface von ExtendableEvent erbt, bleibt der Service Worker aktiv, bis das an respondWith() übergebene Promise erfüllt ist. Typischer Ablauf: Event empfangen → Fenster öffnen → per postMessage auf die Bestätigung des Nutzers warten → Promise mit dem Ergebnis auflösen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Nur für den Konstruktor new PaymentRequestEvent(type, options): der Event-Name, normalerweise "paymentrequest". |
|
| $options | object | {} | Nur für den Konstruktor: Initialisierungswerte wie methodData, total, modifiers, paymentRequestId, paymentRequestOrigin und topOrigin. |
| $url (openWindow) Pflicht | string | URL des Zahlungsfensters. Sie muss denselben Ursprung wie der Service Worker haben. | |
| $promise (respondWith) Pflicht | Promise<PaymentHandlerResponse> | Promise, das mit { methodName, details } erfüllt wird. Wird es abgelehnt, bricht die Zahlung beim Händler ab. |
|
| $methodName, methodDetails (changePaymentMethod) | string, object | Name der neu gewählten Zahlungsart und zusätzliche Details. Beim Händler wird dadurch paymentmethodchange ausgelöst. |
Rückgabewert
PaymentRequestEvent zurück. openWindow() gibt ein Promise<WindowClient | null> zurück, changePaymentMethod() ein Promise<PaymentRequestDetailsUpdate | null> und respondWith() gibt undefined zurück.Beispiele
paymentrequest-Event im Service Worker verarbeiten
// sw.js des Zahlungsanbieters
let resolver = null;
self.addEventListener('paymentrequest', (event) => {
console.log('Händler:', event.paymentRequestOrigin);
console.log('Betrag:', event.total.value, event.total.currency);
event.respondWith(new Promise((resolve, reject) => {
resolver = { resolve, reject };
// Zahlungsfenster öffnen (gleicher Ursprung!)
event.openWindow('/pay/checkout.html').then((client) => {
if (!client) reject(new Error('Fenster konnte nicht geöffnet werden'));
});
}));
});
// Antwort aus dem Zahlungsfenster empfangen
self.addEventListener('message', (e) => {
if (!resolver) return;
if (e.data.status === 'ok') {
resolver.resolve({
methodName: 'https://pay.example.com',
details: { token: e.data.token }
});
} else {
resolver.reject(new Error('Vom Nutzer abgebrochen'));
}
resolver = null;
});
Zahlungsfenster meldet das Ergebnis an den Service Worker
// /pay/checkout.html – Skript im geöffneten Fenster
const confirmBtn = document.querySelector('#confirm');
const cancelBtn = document.querySelector('#cancel');
confirmBtn.addEventListener('click', async () => {
const res = await fetch('/api/authorize', { method: 'POST' });
const { token } = await res.json();
navigator.serviceWorker.controller.postMessage({ status: 'ok', token });
});
cancelBtn.addEventListener('click', () => {
navigator.serviceWorker.controller.postMessage({ status: 'cancel' });
});
Zahlungsart wechseln und Preis-Update abwarten
self.addEventListener('paymentrequest', (event) => {
event.respondWith((async () => {
// Nutzer wählt z. B. Kreditkarte statt Lastschrift
const update = await event.changePaymentMethod('https://pay.example.com', {
type: 'credit'
});
console.log('Neuer Betrag:', update?.total?.amount?.value);
return {
methodName: 'https://pay.example.com',
details: { type: 'credit', token: 'abc123' }
};
})());
});
Event manuell konstruieren (z. B. für Tests)
// Im Service-Worker-Kontext
const evt = new PaymentRequestEvent('paymentrequest', {
paymentRequestId: 'order-42',
total: { currency: 'EUR', value: '9.99' },
methodData: [{ supportedMethods: 'https://pay.example.com' }]
});
console.log(evt.type, evt.paymentRequestId);
// Wichtig · Fallstricke
Kompatibilität: Die API ist experimentell. Sie wird nur von Chromium-Browsern unterstützt (Chrome, Edge, Opera, Samsung Internet), nicht von Firefox und nicht von Safari. Die API steht nur im Service Worker und nur in einem sicheren Kontext (HTTPS) zur Verfügung.
openWindow()darf nur innerhalb despaymentrequest-Handlers aufgerufen werden, während das Event noch aktiv ist. Die URL muss denselben Ursprung wie der Service Worker haben.respondWith()muss synchron im Handler aufgerufen werden. Ein späterer Aufruf, etwa nach einemawait, wirft einenInvalidStateError.- Damit der Browser den Handler anbietet, braucht der Zahlungsanbieter eine Payment Method Manifest-Datei und ein Web-App-Manifest. Ohne gültiges Manifest wird der Handler nicht angezeigt.
instrumentKeyundPaymentManager.instrumentssind veraltet. Verlasse dich nicht darauf.- Sicherheit: Prüfe
paymentRequestOriginundtopOrigin, bevor du sensible Daten anzeigst. BehandlemethodDataundtotalals nicht vertrauenswürdige Eingaben: Den tatsächlichen Betrag immer serverseitig prüfen, nie blind aus dem Event übernehmen.