Signatur
Beschreibung
paymentRequestId ist eine schreibgeschützte Eigenschaft des PaymentRequestEvent-Interfaces aus der Payment Handler API. Das Ereignis paymentrequest wird im Service Worker einer Zahlungs-App (Payment Handler) ausgelöst, wenn ein Händler auf seiner Seite PaymentRequest.prototype.show() aufruft und der Nutzer diese Zahlungs-App auswählt.
Der Wert entspricht der Eigenschaft PaymentRequest.id auf Händlerseite. Hat der Händler im details-Objekt des Konstruktors ein id-Feld angegeben, wird genau dieser Wert übergeben. Sonst erzeugt der Browser automatisch eine eindeutige Kennung, meist eine UUID.
Wofür man die ID braucht:
- Zuordnung: Die Zahlungs-App kann eine Transaktion in ihrem Backend eindeutig der Bestellung des Händlers zuordnen.
- Protokollierung und Fehlersuche: Über die ID lassen sich Zahlungsvorgänge über mehrere Systeme hinweg nachverfolgen.
- Doppelte Vorgänge vermeiden: Die ID eignet sich als Schlüssel für idempotente Anfragen, damit eine Zahlung nicht zweimal verarbeitet wird.
Die Eigenschaft steht nur im Kontext eines Service Workers zur Verfügung, und zwar im Ereignisobjekt, das der Handler von paymentrequest erhält.
Rückgabewert
PaymentRequest-Objekts: entweder der Wert von details.id auf Händlerseite oder eine vom Browser erzeugte eindeutige Kennung.Beispiele
ID im Service Worker auslesen
// service-worker.js der Zahlungs-App
self.addEventListener('paymentrequest', (event) => {
console.log('Zahlungsanfrage-ID:', event.paymentRequestId);
console.log('Händler:', event.topOrigin);
});
Händlerseite: eigene ID vergeben
// Auf der Seite des Händlers
const methods = [{ supportedMethods: 'https://pay.example/methode' }];
const details = {
id: 'order-2024-00815', // landet als paymentRequestId im Payment Handler
total: { label: 'Summe', amount: { currency: 'EUR', value: '49.90' } }
};
const request = new PaymentRequest(methods, details);
console.log(request.id);
const response = await request.show();
await response.complete('success');
ID als Schlüssel für eine idempotente Backend-Anfrage
// service-worker.js der Zahlungs-App
self.addEventListener('paymentrequest', (event) => {
const { paymentRequestId, total, methodData } = event;
event.respondWith((async () => {
const res = await fetch('https://pay.example/api/charge', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Idempotency-Key': paymentRequestId // verhindert doppelte Belastung
},
body: JSON.stringify({ paymentRequestId, total })
});
const { token } = await res.json();
return {
methodName: methodData[0].supportedMethods,
details: { token, paymentRequestId }
};
})());
});
ID an ein Zahlungsfenster weitergeben
self.addEventListener('paymentrequest', (event) => {
const url = `/checkout.html?prid=${encodeURIComponent(event.paymentRequestId)}`;
event.respondWith((async () => {
const client = await event.openWindow(url);
// Antwort kommt später z. B. per postMessage aus dem Fenster zurück
return new Promise((resolve) => {
self.addEventListener('message', (e) => {
if (e.data?.prid === event.paymentRequestId) resolve(e.data.response);
});
});
})());
});
// Wichtig · Fallstricke
- Experimentell: Die Payment Handler API wird nur in Chromium-basierten Browsern (Chrome, Edge, Opera) unterstützt. Firefox und Safari unterstützen sie nicht. Vor der Nutzung sollte man z. B. mit
'PaymentRequestEvent' in selfprüfen, ob die API vorhanden ist. - Nur im Service Worker:
PaymentRequestEventgibt es ausschließlich im Service-Worker-Kontext, nicht im Fenster (window). Außerdem ist ein sicherer Kontext (HTTPS) nötig. - Nicht eindeutig über Händler hinweg: Vergibt der Händler die ID selbst, ist nur garantiert, dass sie für diesen Händler eindeutig ist. Im Backend sollte man sie deshalb zusammen mit
topOriginbzw.paymentRequestOriginspeichern. - Keine Vertrauensgrundlage: Den Wert legt die Händlerseite fest. Er darf nicht als Echtheitsnachweis gelten und muss auf dem Server geprüft werden. Wer ihn in URLs oder HTML einsetzt, muss ihn kodieren bzw. maskieren (
encodeURIComponent). - Die Eigenschaft ist schreibgeschützt. Eine Zuweisung wird ohne Fehlermeldung ignoriert, im Strict Mode wirft sie einen
TypeError.