Champs de paiement
Votre mise en page et votre bouton de paiement, Wajub affiche uniquement les champs sécurisés.
Les champs de paiement inversent le principe du checkout hébergé. Vous conservez la page, le récapitulatif de commande et le bouton de paiement. Wajub affiche dans des iframes séparées les champs qui ne doivent pas toucher à votre DOM. Vous les envoyez lorsque vous êtes prêt.
Ce compromis vous donne le contrôle de la mise en page, mais retire les parties de la page hébergée qui nécessitent un flux complet : coupons, champs personnalisés, OTP et étape de livraison complète. Si vous en avez besoin, utilisez plutôt le checkout hébergé.
Les cinq composants
| Type | Affichage | Déclenchement du paiement |
|---|---|---|
card | Les champs de carte du fournisseur (Stripe, Adyen, Mollie), le bouton carte de PayPal, ou un bouton qui ouvre la fenêtre de paiement du fournisseur (Paystack, Flutterwave, FedaPay, Paddle, PayDunya, CinetPay, Kkiapay) | Vous, avec confirmPayment() |
mobileMoney | Opérateur et numéro de téléphone | Vous, avec confirmPayment() |
payment | Sélecteur de moyen de paiement et formulaire correspondant | Vous, avec confirmPayment() |
address | Adresse de livraison ou de facturation | Personne, lisez-la avec getValue() |
wallet | Apple Pay ou Google Pay | Bouton natif dans le composant |
Structure générale
Une fabrique conserve la session et les options partagées. Chaque appel create() crée un composant,
puis mount() le place sur la page.
import { components, confirmPayment } from '@wajub/js';
const factory = await components(sessionId, {
locale: 'fr',
appearance: { primaryColor: '#2563eb', labels: 'floating' },
});
const card = factory
.create('card')
.on('change', (event) => (payButton.disabled = !event.complete))
.mount('#card');
payButton.onclick = () => confirmPayment({ sessionId, components: card });Les options transmises à la fabrique deviennent les valeurs par défaut de tous ses composants. Les
options transmises à create() sont prioritaires pour le composant concerné.
Les composants se dimensionnent automatiquement
Chaque composant démarre avec min-height: 120px. Le SDK définit la hauteur de l'iframe depuis le
checkout à chaque modification du contenu. Vous n'avez rien à mesurer ni à réserver.
Configuration
| Option | Type | Composants concernés | Fonction |
|---|---|---|---|
sessionId | string | Tous | Obligatoire, défini une fois sur la fabrique |
locale | string | Tous | fr, en, es, pt, ar |
appearance | AppearanceConfig | Tous | Apparence |
layout | CheckoutLayout | payment | Disposition du sélecteur de moyen de paiement |
collectAddress | shipping ou billing | payment | Ajoute un bloc d'adresse dans le formulaire |
addressMode | shipping ou billing | address | Ensemble de libellés à utiliser |
collectName | boolean | payment, address | Ajoute le champ de nom du payeur |
fields.phone | always, auto, never | payment, address | Visibilité du champ de téléphone |
componentOrigin | string | Tous | Votre origine canonique pour les boutiques sur plusieurs domaines |
componentOrigin utilise par défaut l'origine de la page qui effectue le montage. Un domaine unique
ne nécessite donc aucune configuration.
factory
.create('address', { addressMode: 'shipping', collectName: true, fields: { phone: 'auto' } })
.mount('#address');
factory
.create('payment', { collectAddress: 'shipping', collectName: true, layout: 'tabs' })
.mount('#payment');Événements
Abonnez-vous avec .on(event, handler), qui renvoie le composant et permet de chaîner les appels.
Les mêmes handlers existent sous les noms onReady, onChange et autres dans ComponentConfig.
| Événement | Payload | Déclenchement |
|---|---|---|
ready | ComponentInstance | Composant monté et interactif |
change | { complete, empty, error, value } | Modification d'un champ ou de sa validité |
focus | Rien | Prise de focus par un champ |
blur | Rien | Perte de focus par un champ |
success | Transaction | Réussite du paiement |
error | WajubError | Échec du paiement |
loaderror | WajubError | Échec du chargement du composant |
resize | { height } | Agrandissement ou réduction du composant |
statechange | { state, method } | Passage du checkout à un autre état |
methodchange | { methodId } | Choix d'un autre moyen de paiement par le payeur |
component.on('change', (event) => {
payButton.disabled = !event.complete;
errorLabel.textContent = event.error ? event.error.message : '';
});complete signifie valide, pas payé
change.complete indique que les champs réussiraient la validation. L'argent est transféré lors
de success, mais seul votre webhook le confirme.
Envoyer le paiement
confirmPayment reçoit la session et un composant monté, l'envoie et attend le résultat.
try {
const { status, transaction } = await confirmPayment({ sessionId, components: card });
showReceipt(status, transaction);
} catch (error) {
showRetry(error.code, error.message);
}| Option | Valeur par défaut | Fonction |
|---|---|---|
sessionId | Obligatoire | Session utilisée pour créer le composant |
components | Obligatoire | Un composant card, mobileMoney ou payment monté |
timeout | 60000 | Millisecondes avant le rejet avec confirmation_timeout. 0 attend indéfiniment |
Quatre rejets se produisent avant tout envoi. Ils signalent donc des erreurs d'intégration, pas des échecs de paiement.
| Code | Cause |
|---|---|
missing_component | Aucun composant transmis ou objet incapable d'envoyer le paiement |
wallet_not_supported | Composant wallet, dont le bouton natif déclenche le paiement |
address_not_payment | Composant address, à lire avec getValue() |
confirmation_timeout | Aucun résultat reçu avant timeout |
Piloter un composant
| Méthode | Fonction |
|---|---|
mount(container) | S'attache à un sélecteur ou un élément |
update({ locale, appearance, layout }) | Applique la modification en direct sans nouveau montage |
focus(), blur() | Donne ou retire le focus au premier champ |
submit() | Envoie sans confirmPayment, vous gérez les événements |
selectMethod(id) | Change de moyen de paiement sur un composant payment |
isComplete() | Indique si les champs réussiraient la validation |
getState() | CheckoutState actuel, INITIATED avant toute action |
getError() | Dernière WajubError, ou null |
getValue() | Valeurs de l'adresse, { name, phone, address, mode } |
unmount(), destroy() | Retire le composant du DOM, en conservant ou non l'instance |
update() fonctionne ici, contrairement à l'intégration hébergée
Un composant envoie locale, appearance et layout à son iframe, puis se redessine. Le checkout
hébergé applique tout sauf layout. Cette différence existe réellement.
getValue() renvoie null jusqu'à ce que le composant d'adresse signale une valeur lors de son
premier change. Lisez-la dans le handler ou lors de l'envoi par le payeur, pas au montage.
Avec un framework
Chaque composant existe sous forme d'enveloppe prête à l'emploi, avec les mêmes options comme props.
L'enveloppe surveille aussi appearance, locale et layout, puis appelle update() pour vous.
const { confirm, isConfirming } = useConfirmPayment(sessionId);
const field = useRef<ComponentInstance | null>(null);
<PaymentComponent sessionId={sessionId} onInstance={(i) => (field.current = i)} />;
<button disabled={isConfirming} onClick={() => field.current && confirm(field.current)}>
Pay now
</button>;Le provider, les tableaux de props et l'intégration côté serveur figurent dans React, Vue et Svelte.
Fonctionnalités abandonnées
| Fonctionnalité | Checkout hébergé | Champs de paiement |
|---|---|---|
| Moyens de paiement enregistrés | Oui | Oui |
| 3DS | Oui | Oui |
| Portefeuilles | Oui | Oui, avec le bouton natif |
| Coupons | Oui | Non |
| Champs de checkout personnalisés | Oui | Non |
| Flux de livraison complet | Oui | Bloc d'adresse uniquement |
| OTP | Oui | Non |
Pages associées
- ApparenceStylisez les champs comme l'intégration.
- Checkout hébergéLa page clé en main lorsque ce travail est trop important.
- Référence APIToutes les méthodes, tous les types et tous les événements au même endroit.
- Dépannage de Wajub ComponentsPourquoi rien ne s'affiche et pourquoi confirm rejette l'appel.