Come adattare la tua app di pagamento basata sul web a Web Payments e offrire una migliore esperienza utente ai clienti.
Una volta registrata l'app di pagamento, puoi accettare le richieste di pagamento dai commercianti. Questo post spiega come orchestrare una transazione di pagamento da un service worker durante l'runtime (ovvero quando viene visualizzata una finestra e l'utente interagisce con essa).

"Modifiche dei parametri di pagamento in fase di runtime" si riferisce a un insieme di eventi che consente al commerciante e al gestore dei pagamenti di scambiarsi messaggi mentre l'utente interagisce con il gestore dei pagamenti. Scopri di più su Gestione delle informazioni di pagamento facoltative con un service worker.
Ricevere un evento di richiesta di pagamento dal commerciante
Quando un cliente sceglie di pagare con la tua app di pagamento basata sul web e il commerciante
richiama
PaymentRequest.show()
,
il service worker riceverà un evento paymentrequest
. Aggiungi un listener di eventi
al service worker per acquisire l'evento e prepararti per l'azione successiva.
service-worker.js di [gestore dei pagamenti]:
…
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;
…
Il PaymentRequestEvent
conservato contiene informazioni importanti su questa
transazione:
Nome proprietà | Descrizione |
---|---|
topOrigin |
Una stringa che indica l'origine della pagina web di primo livello (di solito il commerciante beneficiario). Utilizza questo campo per identificare l'origine del commerciante. |
paymentRequestOrigin |
Una stringa che indica l'origine del chiamante. Può essere uguale a topOrigin quando il commerciante richiama direttamente l'API Payment Request, ma può essere diverso se l'API viene richiamata da un iframe da una terza parte, ad esempio un gateway di pagamento.
|
paymentRequestId |
La proprietà id di PaymentDetailsInit fornita all'API Payment Request. Se il commerciante lo omette, il browser fornirà un ID generato automaticamente.
|
methodData |
I dati specifici del metodo di pagamento forniti dal commerciante nell'ambito di PaymentMethodData .
Utilizza questo campo per determinare i dettagli della transazione di pagamento.
|
total |
L'importo totale fornito dal commerciante nell'ambito di PaymentDetailsInit .
Utilizza questo campo per creare un'interfaccia utente che comunichi al cliente l'importo totale da pagare.
|
instrumentKey |
La chiave dello strumento selezionata dall'utente. Ciò riflette i instrumentKey che hai fornito in anticipo. Una stringa vuota indica che l'utente non ha specificato strumenti.
|
Apri la finestra del gestore dei pagamenti per visualizzare il frontend dell'app di pagamento basata sul web
Quando viene ricevuto un evento paymentrequest
, l'app di pagamento può aprire una finestra di gestione dei pagamenti chiamando PaymentRequestEvent.openWindow()
. La finestra di gestione dei pagamenti mostrerà ai clienti l'interfaccia dell'app di pagamento in cui potranno autenticarsi, scegliere l'indirizzo e le opzioni di spedizione e autorizzare il pagamento. Spiegheremo come scrivere il codice frontend in Gestione dei pagamenti nel
frontend dei pagamenti (disponibile a breve).
Passa una promessa preservata a PaymentRequestEvent.respondWith()
in modo da poterla risolvere con un risultato di pagamento in futuro.
service-worker.js di [gestore dei pagamenti]:
…
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);
};
});
…
Puoi utilizzare un comodo polyfill PromiseResolver
per risolvere una promessa in
un momento arbitrario.
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_ }
}
Scambiare informazioni con il frontend
Il service worker dell'app di pagamento può scambiare messaggi con il frontend dell'app di pagamento tramite ServiceWorkerController.postMessage()
. Per ricevere messaggi
dal frontend, ascolta gli eventi message
.
service-worker.js di [gestore dei pagamenti]:
// Define a convenient `postMessage()` method
const postMessage = (type, contents = {}) => {
if (client) client.postMessage({ type, ...contents });
}
Ricevere il segnale di pronto dal frontend
Una volta aperta la finestra del gestore dei pagamenti, il service worker deve attendere un segnale di stato pronto dal frontend dell'app di pagamento. Il service worker può trasmettere informazioni importanti al frontend quando è pronto.
[payment handler] frontend:
navigator.serviceWorker.controller.postMessage({
type: 'WINDOW_IS_READY'
});
service-worker.js di [gestore dei pagamenti]:
…
// 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;
…
Trasferisci i dettagli della transazione al frontend
Ora invia di nuovo i dati di pagamento. In questo caso, invii solo il totale della richiesta di pagamento, ma puoi fornire maggiori dettagli se vuoi.
service-worker.js di [gestore dei pagamenti]:
…
// 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;
…
Restituisci le credenziali di pagamento del cliente
Quando il cliente autorizza il pagamento, il frontend può inviare un messaggio post
al service worker per procedere. Puoi risolvere la promessa passata a
PaymentRequestEvent.respondWith()
per inviare il risultato al commerciante.
Passa un
oggetto
PaymentHandlerResponse
.
Nome proprietà | Descrizione |
---|---|
methodName |
L'identificatore del metodo di pagamento utilizzato per effettuare il pagamento. |
details |
I dati specifici del metodo di pagamento che forniscono le informazioni necessarie al commerciante per elaborare il pagamento. |
[payment handler] frontend:
const paymentMethod = …
postMessage('PAYMENT_AUTHORIZED', {
paymentMethod, // Payment method identifier
});
service-worker.js di [gestore dei pagamenti]:
…
// 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;
…
Annullare la transazione di pagamento
Per consentire al cliente di annullare la transazione, il frontend può inviare un messaggio post
al service worker per farlo. Il service worker può quindi risolvere la
promessa passata a PaymentRequestEvent.respondWith()
con null
per indicare al
commerciante che la transazione è stata annullata.
[payment handler] frontend:
postMessage('CANCEL_PAYMENT');
service-worker.js di [gestore dei pagamenti]:
…
// 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;
…
Codice di esempio
Tutti gli esempi di codice che hai visto in questo documento sono estratti da quanto segue: Payment Handler Demo
Passaggi successivi
In questo articolo abbiamo imparato a orchestrare una transazione di pagamento da un service worker. Il passaggio successivo consiste nell'aggiunta di funzionalità più avanzate al service worker.