Afficher le checkout
Trois façons d'afficher la page de paiement Wajub et les options de chacune.
Le checkout hébergé est la page de paiement complète affichée par Wajub, choix du moyen de paiement, récapitulatif de commande, OTP et 3DS, en ligne, en superposition ou après une redirection, avec la même configuration. Les coupons et l'étape de livraison n'y sont pas disponibles, quel que soit le contenu de la session.
Vous cherchez plutôt la présentation du produit ?
Cette page présente l'interface d'intégration. Pour découvrir les fonctionnalités de la page hébergée destinées au payeur et savoir quand la préférer à votre propre mise en page, consultez Paiements, Checkout hébergé.
Quelle option choisir ?
En ligne avec mount(el, config), dans une fenêtre modale avec open(config), ou sur la page de
paiement hébergée avec checkout(config). Les quatre modes, champs de paiement compris, sont
comparés côte à côte sur la vue d'ensemble.
Les trois options nécessitent un sessionId, qui correspond à la valeur authorization_token de
POST /payments. Aucune ne nécessite de clé.
Les modes en ligne et en superposition affichent le checkout dans un cadre de votre page. Déclarez les origines qui l'intègrent dans Paramètres → Intégration de la page de paiement avant d'encaisser en live : une fois la liste remplie, seules ces origines peuvent l'afficher. La page existe sur tous les plans. Voir où le checkout peut être intégré.
En ligne
mount accepte un sélecteur ou un élément et renvoie l'instance que vous pouvez ensuite piloter.
import { mount } from '@wajub/js';
const checkout = await mount('#checkout', {
sessionId,
onSuccess: () => (window.location.href = '/order/complete'),
onError: (error) => showRetry(error),
});Vous n'avez pas besoin de réserver la hauteur
Le checkout se dimensionne seul. Un élément vide <div id="checkout"></div> suffit.
L'absence de sessionId ou un sélecteur qui ne correspond à aucun élément échoue aussitôt avec une
simple Error : window.wajub la lève, et les helpers de @wajub/js sont rejetés avec elle.
Configuration
| Option | Type | Valeur par défaut | Fonction |
|---|---|---|---|
sessionId | string | Obligatoire | La valeur authorization_token de votre serveur |
locale | string | Valeur de la session | La langue dans laquelle le checkout s'ouvre : fr, en, es, pt, ar |
layout | CheckoutLayout | Valeur de la session | classic, compact, tabs, accordion |
appearance | AppearanceConfig | Votre image de marque du Dashboard | Apparence |
loadingText | string | Vide | Texte dans l'espace réservé |
showLoading | boolean | true | Définissez false pour afficher votre propre squelette |
Callbacks
await mount('#checkout', {
sessionId,
onReady: (instance) => (checkoutRef = instance),
onSuccess: (transaction) => markPaidInTheInterface(transaction),
onError: (error) => console.error(error.code, error.message),
onLoadError: (error) => showSessionExpired(error),
onBreakdown: (b) => (total.textContent = `${b.total.toLocaleString()} ${b.currency}`),
});| Callback | Déclenchement | Valeur reçue |
|---|---|---|
onReady | Session chargée et formulaire visible | CheckoutInstance |
onSuccess | Paiement réussi | PaymentSuccess : id, reference, amount en unités normales… |
onError | Échec du paiement, ou submit() sans bouton sur lequel appuyer (nothing_to_submit) | WajubError |
onLoadError | Le checkout n'a pas pu démarrer : jeton inconnu, jeton qui n'est plus valide, ou refus de chargement de l'iframe | WajubError |
onCancel | Annulation explicite par le payeur | Rien |
onExpired | Expiration de la session pendant le paiement | Rien |
onBreakdown | Modification des totaux | { subtotal, discount, tax, total, currency }, en unités normales |
onStateChange | Passage du checkout à un autre état | { state, method } |
onMethodChange | Choix d'un autre moyen de paiement par le payeur | { methodId } |
onResize | Modification de la hauteur de l'iframe, uniquement en ligne | height en pixels |
onClose | Fermeture de la superposition, bouton Terminé de la confirmation en ligne, ou appel à close() | Rien |
onLoadError contient session_not_found pour un jeton que Wajub ne connaît pas,
session_terminal_expired pour un jeton dont le paiement est terminé et qui n'est plus valide, et
load_error lorsque l'iframe elle-même n'a pas chargé. onError n'en reçoit aucun : il concerne
un paiement qui a échoué. Juste après le callback, la superposition se ferme ou le checkout en ligne
quitte la page. onClose n'est pas appelé : le checkout n'a jamais
démarré, rien n'a donc été fermé. Affichez votre propre message depuis le callback.
onResize est fourni à titre informatif
Utilisez ce callback pour déplacer un autre élément de la page, comme un récapitulatif fixe ou un pied de page.
onSuccess se déclenche dans un navigateur. Traitez-le comme un signal de l'interface. Livrez la commande à la réception du
webhook. Il reçoit le résumé du paiement par le checkout :
id est l'identifiant Wajub du paiement, celui que prend GET /payments/{id}, reference est la
vôtre, et amount est en unités normales comme dans l'API.
En ligne, la confirmation garde un bouton Terminé. Quand le payeur l'utilise, onClose se
déclenche et le checkout quitte la page : placez-y votre propre étape suivante.
Piloter l'instance
checkout.getState(); // 'COLLECTING_DETAILS', 'PROCESSING', …
checkout.update({ locale: 'en' });
checkout.update({ appearance: { colorScheme: 'dark' } });
checkout.update({ currency: 'USD' }); // multi currency sessions only
checkout.selectMethod('pm_momo');
checkout.submit(); // presses the checkout's own pay button
checkout.retry();
checkout.cancel();
checkout.unmount(); // off the page, the instance is kept
checkout.mount(); // back on the page
checkout.destroy();locale, appearance, currency et layout s'appliquent en direct, en ligne comme en
superposition.
appearance.inherit donne au checkout le style de votre propre page : mount() le lit autour de
son conteneur, open() sur toute la page, sous les clés que vous donnez. Voir
Reprendre le style de votre page.
update({ appearance }) change ensuite les clés données et garde les autres : une clé donnée à
undefined ou null est effacée, et appearance: undefined efface tout, pour revenir à l'image de
marque de votre Dashboard Wajub. Avec inherit, chaque appel relit la page. Un nouveau preset
theme remplace le précédent. Voir
Modifier l'apparence après le montage.
submit() appuie sur le bouton de paiement du moyen en cours. Le checkout valide le formulaire
comme il le fait pour le payeur et affiche ses propres messages. Suivez donc le résultat avec
onStateChange. S'il n'y a aucun bouton sur lequel appuyer (avant le choix d'un moyen, sur une
étape d'OTP ou de confirmation, avec Apple Pay et Google Pay, qui ne répondent qu'au geste du
payeur, et pendant qu'un paiement est déjà en cours), rien n'est pressé et onError reçoit une
WajubError de code nothing_to_submit.
unmount() retire le checkout de la page et conserve l'instance. mount() le remet en place, en
ligne comme en superposition. À son retour, onReady se déclenche à nouveau, avec la locale, l'apparence et la mise en page transmises au
dernier update(). En superposition, unmount() n'appelle pas onClose. Après destroy(), ou
close() en superposition, mount() n'a plus d'effet.
Superposition
Même configuration, mêmes callbacks et même instance, avec la fenêtre modale en plus.
import { open } from '@wajub/js';
const popup = await open({
sessionId,
width: 960,
closeOnOverlay: true,
onSuccess: (transaction) => fulfillOrder(transaction),
onClose: () => console.log('dismissed'),
});
popup.isOpen();| Option | Valeur par défaut | Fonction |
|---|---|---|
width | 920 | Largeur maximale de la fenêtre modale en pixels |
height | 680 | Hauteur de la fenêtre modale en pixels |
closeOnOverlay | false | Ferme lors d'un clic sur l'arrière-plan |
closeOnEscape | true | Ferme avec la touche Échap |
closeOnSuccess | true | Ferme peu après l'exécution de onSuccess |
closeOnCancel | true | Ferme peu après l'exécution de onCancel |
closeOnExpired | true | Ferme peu après l'exécution de onExpired |
La fermeture de la fenêtre modale masque uniquement l'interface. La session reste ouverte jusqu'à sa réussite, son expiration ou son annulation dans le checkout. Le même jeton permet donc encore de la monter.
onResize ne se déclenche jamais en mode superposition, car la fenêtre modale possède une hauteur fixe.
Redirection
Ce mode demande le moins de code et constitue le seul où callback est utile.
// The URL your server already received from POST /payments
window.location.href = authorizationUrl;
// Or, when the browser only has the token
import { checkout } from '@wajub/js';
await checkout({ sessionId });Le payeur revient sur l'URL de callback définie lors de la création du paiement, avec
?status=succeeded|cancelled|failed|expired, reference, l'identifiant Wajub du paiement, et
trxref, votre propre référence, quelle que soit l'issue. Lisez le paiement avec ce reference sur
votre serveur : ces paramètres d'URL sont une indication. Le
webhook fournit la confirmation. Consultez
Sessions et sécurité pour le détail.
Avec un framework
Dans @wajub/react, @wajub/vue et @wajub/svelte, le checkout en ligne est le composant
CheckoutEmbed, et dans @wajub/angular c'est <wajub-checkout-embed>. Ses options sont des props,
des inputs en Angular, à côté de celles du composant : la session, une classe, un style dans React et
Vue, sur l'élément hôte en Angular, et la hauteur réservée pendant le chargement du checkout,
480 pixels par défaut. React et Svelte acceptent toutes les options de
EmbeddedConfig ; Vue et Angular en acceptent
une liste fermée, donnée sur Vue et
Angular. En Angular, les callbacks sont des outputs.
L'intégration suit ses props. Un changement d'appearance, appearance.inherit compris, de
locale ou de layout s'applique au checkout monté sans rechargement : un objet appearance
écrit en ligne convient donc. Une clé de premier niveau d'appearance retirée
depuis le dernier rendu est effacée, et une appearance devenue undefined ou {} revient à votre
image de marque. Une nouvelle session charge un nouveau checkout dans le même conteneur.
loadingText et showLoading sont lus au chargement du checkout, et un nouveau handler prend le
relais sans rechargement.
// Une nouvelle valeur s'applique sans rechargement.
<CheckoutEmbed
sessionId={sessionId}
appearance={{ colorScheme: dark ? 'dark' : 'light' }}
/>;Le provider, les props exactes et le câblage côté serveur sont sur React, Vue, Svelte et Angular.
Style
Le checkout utilise déjà l'image de marque de votre compte, configurée une fois dans le Dashboard.
Transmettez appearance uniquement pour modifier cette intégration précise, par exemple pour un
bouton de mode sombre ou la couleur d'une campagne.
await mount('#checkout', {
sessionId,
layout: 'tabs',
appearance: { theme: 'night', primaryColor: '#6366f1', labels: 'floating' },
});La liste complète des clés figure dans Apparence. Les valeurs par défaut du compte sont présentées dans Image de marque et thème.