Comment adapter votre application de paiement Web aux paiements Web et offrir une meilleure expérience utilisateur.
Une fois l'application de paiement enregistrée, vous pouvez accepter les demandes de paiement des marchands. Cet article explique comment orchestrer une transaction de paiement d'un service worker pendant l'exécution (c'est-à-dire lorsqu'une fenêtre s'affiche et que l'utilisateur interagit avec elle).
Les "modifications des paramètres de paiement à l'exécution" font référence à un ensemble d'événements qui permet au marchand et au gestionnaire de paiement d'échanger des messages pendant que l'utilisateur interagit avec le gestionnaire de paiement. Pour en savoir plus, consultez la page Gérer les informations de paiement facultatives avec un service worker.
Recevoir un événement de demande de paiement de la part du marchand
Lorsqu'un client choisit de payer avec votre application de paiement Web et que le marchand appelle PaymentRequest.show()
, votre service worker reçoit un événement paymentrequest
. Ajoutez un écouteur d'événements au service worker pour capturer l'événement et préparer l'action suivante.
[gestionnaire de paiement] 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;
…
Le fichier PaymentRequestEvent
conservé contient des informations importantes sur cette transaction:
Nom de propriété | Description |
---|---|
topOrigin |
Chaîne indiquant l'origine de la page Web de premier niveau (généralement le marchand bénéficiaire). Utilisez cet attribut pour identifier l'origine du marchand. |
paymentRequestOrigin |
Chaîne indiquant l'origine de l'appelant. Il peut être identique à topOrigin lorsque le marchand appelle directement l'API Payment Request. Toutefois, il peut être différent si l'API est appelée depuis un iFrame par un tiers (une passerelle de paiement, par exemple).
|
paymentRequestId |
Propriété id du PaymentDetailsInit fournie à l'API Payment Request. Dans le cas contraire, le navigateur fournit un ID généré automatiquement.
|
methodData |
Données spécifiques au mode de paiement fournies par le marchand dans PaymentMethodData .
Utilisez-le pour déterminer les détails de la transaction de paiement.
|
total |
Montant total fourni par le marchand dans PaymentDetailsInit .
Utilisez-le pour créer une UI indiquant au client le montant total à payer.
|
instrumentKey |
Clé d'instrumentation sélectionnée par l'utilisateur. Il s'agit du instrumentKey que vous avez fourni à l'avance. Une chaîne vide indique que l'utilisateur n'a spécifié aucun instrument.
|
Ouvrez la fenêtre du gestionnaire de paiement pour afficher l'interface de l'application de paiement Web
Lorsqu'un événement paymentrequest
est reçu, l'application de paiement peut ouvrir une fenêtre de gestionnaire de paiement en appelant PaymentRequestEvent.openWindow()
. La fenêtre du gestionnaire de paiement affiche l'interface de votre application de paiement. Elle permet aux clients de s'authentifier, de choisir une adresse et des options de livraison, et d'autoriser le paiement. Nous verrons comment écrire le code frontend dans Gérer les paiements sur l'interface de paiement (bientôt disponible).
Transmettez une promesse préservée à PaymentRequestEvent.respondWith()
afin de pouvoir la résoudre avec un résultat de paiement à l'avenir.
[gestionnaire de paiement] 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);
};
});
…
Vous pouvez utiliser un polyfill PromiseResolver
pratique pour résoudre une promesse à un moment arbitraire.
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_ }
}
Échanger des informations avec l'interface
Le service worker de l'application de paiement peut échanger des messages avec l'interface de l'application de paiement via ServiceWorkerController.postMessage()
. Pour recevoir des messages de l'interface, écoutez les événements message
.
[gestionnaire de paiement] service-worker.js :
// Define a convenient `postMessage()` method
const postMessage = (type, contents = {}) => {
if (client) client.postMessage({ type, ...contents });
}
Recevoir le signal prêt de l'interface
Une fois la fenêtre du gestionnaire de paiement ouverte, le service worker doit attendre un signal prêt de l'interface de l'application de paiement. Le service worker peut transmettre des informations importantes à l'interface lorsqu'elle est prête.
Interface [gestionnaire de paiement] :
navigator.serviceWorker.controller.postMessage({
type: 'WINDOW_IS_READY'
});
[gestionnaire de paiement] 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;
…
Transmettre les détails de la transaction à l'interface
Renvoyez maintenant les informations de paiement. Dans ce cas, vous n'envoyez que le total de la demande de paiement, mais vous pouvez transmettre d'autres informations si vous le souhaitez.
[gestionnaire de paiement] service-worker.js :
…
// Pass the payment details to the frontend
postMessage('PAYMENT_IS_READY', { total });
break;
…
Interface [gestionnaire de paiement] :
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;
…
Renvoyer les identifiants de paiement du client
Lorsque le client autorise le paiement, l'interface peut envoyer un message de publication au service worker pour qu'il continue. Vous pouvez résoudre la promesse transmise à PaymentRequestEvent.respondWith()
pour renvoyer le résultat au marchand.
Transmettez un objet PaymentHandlerResponse
.
Nom de propriété | Description |
---|---|
methodName |
Identifiant du mode de paiement utilisé pour effectuer le paiement. |
details |
Données spécifiques au mode de paiement qui fournissent les informations nécessaires au marchand pour traiter le paiement. |
Interface [gestionnaire de paiement] :
const paymentMethod = …
postMessage('PAYMENT_AUTHORIZED', {
paymentMethod, // Payment method identifier
});
[gestionnaire de paiement] 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;
…
Annuler la transaction de paiement
Pour permettre au client d'annuler la transaction, l'interface peut envoyer un message post
au service worker. Il peut ensuite résoudre la promesse transmise à PaymentRequestEvent.respondWith()
avec null
pour indiquer au marchand que la transaction a été annulée.
Interface [gestionnaire de paiement] :
postMessage('CANCEL_PAYMENT');
[gestionnaire de paiement] 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;
…
Exemple de code
Tous les exemples de code que vous avez vus dans ce document sont des extraits de l'application exemple fonctionnelle suivante:
https://paymenthandler-demo.glitch.me
service worker [gestionnaire de paiement]
Interface [gestionnaire de paiement]
Pour essayer:
- Accédez à la page https://paymentrequest-demo.glitch.me/.
- Accédez au bas de la page.
- Appuyez sur le bouton Ajouter un paiement.
- Saisissez
https://paymenthandler-demo.glitch.me
dans le champ Identifiant du mode de paiement. - Appuyez sur le bouton Payer à côté du champ.
Étapes suivantes
Dans cet article, nous avons découvert comment orchestrer une transaction de paiement d'un service worker. L'étape suivante consiste à apprendre à ajouter des fonctionnalités plus avancées au service worker.