Cas d'utilisation
Six intégrations réelles et les raisons qui déterminent la forme de chacune.
Tous les modèles ci-dessous reposent sur les trois mêmes éléments : une session créée sur votre serveur, une interface dans le navigateur et un webhook de confirmation. Seuls l'emplacement de l'interface et la part de la page que vous contrôlez changent.
Une boutique en ligne avec le checkout sur la page
Vous gardez le contrôle du panier, le paiement en constitue une section et le client ne quitte
jamais votre domaine. onBreakdown maintient le total à jour lorsqu'un coupon ou un choix de
livraison le modifie.
import { mount } from '@wajub/js';
const { sessionId } = await fetch('/api/checkout/session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ cartId }),
}).then((r) => r.json());
await mount('#checkout', {
sessionId,
layout: 'tabs',
onBreakdown: (b) => {
cartTotal.textContent = `${b.total.toLocaleString()} ${b.currency}`;
},
onSuccess: () => (window.location.href = '/order/complete'),
onError: (error) => showToast(error.message),
});Le flux hébergé complet est inclus : coupons, OTP, 3DS et livraison. Les couleurs et le logo proviennent de l'image de marque de votre compte. Vous n'avez rien à styliser ici, sauf si vous souhaitez donner une apparence différente à cette page.
Une landing page avec un minimum de code
Votre serveur a déjà reçu authorization_url depuis POST /payments. Redirigez-y le client.
window.location.href = authorizationUrl;Le client revient sur votre URL de callback avec un paramètre d'URL status. Lisez-le pour choisir
la page à afficher, puis confirmez correctement le paiement grâce au
webhook. Consultez Sessions et sécurité
pour plus de détails.
Cette solution est la plus rapide à mettre en place et la plus facile à maintenir. Elle constitue donc la meilleure première intégration pour la plupart des marchands.
Une mise à niveau dans une application
Le client effectue déjà une action. Le paiement l'interrompt et doit lui rendre la page une fois terminé.
import { open } from '@wajub/js';
upgradeButton.onclick = async () => {
const { sessionId } = await fetch('/api/billing/upgrade', { method: 'POST' })
.then((r) => r.json());
await open({
sessionId,
closeOnOverlay: false,
onSuccess: () => refreshAccount(),
onCancel: () => track('upgrade_cancelled'),
});
};closeOnOverlay: false est la valeur par défaut et convient à ce cas. Un clic accidentel ne doit
pas interrompre un paiement en cours.
La fermeture de la fenêtre modale ne fait que la masquer. La session reste ouverte. Si le client change d'avis, le même jeton permet de la remonter.
Un formulaire d'abonnement conçu par vos soins
Vous contrôlez le sélecteur de plan et le bouton. Wajub affiche uniquement les champs de carte.
'use client';
import { useRef, useState } from 'react';
import type { ComponentInstance } from '@wajub/js';
import { CardComponent, useConfirmPayment } from '@wajub/react';
export function Subscribe({ sessionId }: { sessionId: string }) {
const { confirm, isConfirming } = useConfirmPayment(sessionId);
const card = useRef<ComponentInstance | null>(null);
const [canPay, setCanPay] = useState(false);
return (
<>
<h2>Pro plan, 25 000 XAF per month</h2>
<CardComponent
sessionId={sessionId}
appearance={{ labels: 'floating' }}
onInstance={(instance) => (card.current = instance)}
onChange={(event) => setCanPay(Boolean(event.complete))}
/>
<button
disabled={!canPay || isConfirming}
onClick={() => card.current && confirm(card.current)}
>
{isConfirming ? 'Processing…' : 'Subscribe'}
</button>
</>
);
}useConfirmPayment renvoie un objet, pas une fonction. Déstructurez-le. isConfirming empêche un
second clic d'ouvrir un autre paiement.
Ce mode ne prend en charge ni les coupons ni les OTP. Si la page du plan doit accepter un code promotionnel, le checkout hébergé est la solution la plus directe.
Mobile Money avec les moyens de paiement dans des onglets
Le composant payment contient le sélecteur et le formulaire correspondant. Un seul composant couvre
donc les cartes, le Mobile Money et les portefeuilles.
import { components, confirmPayment } from '@wajub/js';
const factory = await components(sessionId, { layout: 'tabs' });
const payment = factory
.create('payment', { collectName: true, fields: { phone: 'always' } })
.on('change', (event) => (payButton.disabled = !event.complete))
.mount('#payment');
payButton.onclick = () => confirmPayment({ sessionId, components: payment });Configurez fields.phone: 'always' si le Mobile Money est votre canal principal. Avec auto, le
champ apparaît uniquement lorsque le moyen de paiement choisi l'exige, ce qui provoque un décalage du formulaire.
Afficher le montant avant le chargement du checkout
fetchSession lit la session avec le jeton lui-même. Il fonctionne donc dans le navigateur avant
le montage de tout autre élément.
import { fetchSession, preload } from '@wajub/js';
const preview = await fetchSession(sessionId);
amount.textContent = `${preview.amount.toLocaleString()} ${preview.currency}`;
merchant.textContent = preview.merchant_name;
if (preview.environment === 'sandbox') showSandboxBanner();
if (preview.saved_methods?.length) showReturningCustomerHint();
preload(sessionId);preload(sessionId) ouvre une connexion vers l'origine du checkout. L'iframe n'a donc plus rien à
négocier lors de son montage. Appelez cette fonction lorsque le client arrive dans le panier, pas
lorsqu'il clique sur le bouton de paiement.
preload(sessionId, { iframe: true }) va plus loin et charge tout le checkout dans une iframe
masquée. Le montage semble instantané, mais coûte le chargement d'une page complète. Utilisez cette
option uniquement lorsque le client est très susceptible de payer.
Choisir un modèle
| Votre situation | Modèle |
|---|---|
| Une page de checkout de boutique | mount en ligne avec onBreakdown |
| Une landing page ou un MVP | Redirection vers authorization_url |
| Un paiement dans une application en cours d'utilisation | Superposition open() |
| Un tunnel que vous avez déjà conçu | Champs de paiement et votre propre bouton |
| WordPress ou HTML simple | Script CDN et mount |
| Next.js, Nuxt, SvelteKit | Provider du framework et CheckoutEmbed |
Utiliser un framework