Aller au contenu

Dépannage de Wajub Components

Le symptôme, sa cause et la ligne qui le corrige.

Presque tous les problèmes de Wajub Components proviennent de quatre causes : un jeton qui n'est plus valide, une page qui a chargé le SDK sur le serveur, un callback non configuré ou une clé de configuration ignorée silencieusement par le SDK. Commencez ici avant de lire le code.

Rien ne s'affiche

SymptômeCauseCorrection
Conteneur vide sans erreurJeton inconnu, ou jeton qui n'est plus valide parce que son paiement est terminéConfigurez onLoadError. Il contient session_not_found ou session_terminal_expired. À partir de Wajub.js 1.6.0, le checkout quitte la page juste après, sans onClose
Intégration embed incorrecte (Embed configuration error en anglais)URL de checkout collée manuellement dans une iframeAppelez mount(), open() ou CheckoutEmbed
Aucune action ni requête réseaumount() s'est exécuté sur le serveurImportez depuis @wajub/js/pure ou marquez le fichier avec 'use client'
Error lors de l'appelAucun sessionId ou sélecteur sans correspondanceAvant toute requête. window.wajub la lève de façon synchrone ; les helpers de @wajub/js (mount(), open()…) sont asynchrones et renvoient plutôt une promesse rejetée : attendez-les avec await dans un try
L'iframe n'apparaît jamaisload_error dans onLoadErrorL'origine du checkout est inaccessible. Vérifiez l'onglet réseau et les règles de contenu
Un cadre vide sur un site, normal sur un autre, sans aucun callbackSettings → Checkout embedding ne contient pas l'origine de cette pageAjoutez https:// suivi du domaine, port compris s'il y en a un. Où le checkout peut être intégré
La console signale une violation de Content Security PolicyLa politique de votre page n'autorise pas les hôtes de WajubAutorisez les hôtes listés dans Content Security Policy

onLoadError explique une intégration vide

onError concerne les paiements qui échouent. onLoadError concerne les checkouts qui ne démarrent jamais, comme dans la plupart des lignes ci-dessus. Configurez-le en premier dans chaque intégration.

Clés

Les clés live commencent par pk. ou sk., les clés de sandbox par pk_test. ou sk_test..

SymptômeCauseCorrection
secret_key_in_browserClé sk. transmise à Wajub()Le navigateur reçoit un jeton de session, jamais une clé secrète
invalid_publishable_keyLa valeur n'est pas une clé publiqueElle commence par pk et ne correspond pas au jeton de session
missing_publishable_keyAppel de createPayment() sans cléConfigurez-la sur le client ou créez la session sur votre serveur
Réponse 403 de l'API et e-mailClé secrète envoyée depuis un navigateurL'API la refuse et alerte son propriétaire. Renouvelez la clé
CORS sur createPaymentAppel direct de l'API depuis le code de la pageCréez la session sur votre backend

Pour distinguer la sandbox du mode live dans le navigateur, lisez la session plutôt que la clé.

La session connaît l'environnement
import { fetchSession } from '@wajub/js';

const preview = await fetchSession(sessionId);
if (preview.environment === 'sandbox') showSandboxBanner();

Champs de paiement

SymptômeCauseCorrection
complete ne devient jamais trueChamp obligatoire encore vide ou invalideEnregistrez event.error dans le handler change, il identifie le champ
confirmPayment rejette avec wallet_not_supportedComposant walletApple Pay et Google Pay utilisent leur propre bouton
confirmPayment rejette avec address_not_paymentComposant addressIl collecte sans débiter. Lisez-le avec getValue()
confirmPayment rejette avec missing_componentAucun composant transmis ou composant jamais montéConservez l'instance de onInstance ou de l'événement ready
confirmation_timeout après une minuteAucun résultat reçu à temps. Le paiement continue et peut encore réussirAugmentez timeout ou transmettez 0 pour attendre indéfiniment. Avant de proposer de payer à nouveau, écoutez success ou attendez le webhook
confirmPayment rejette avec checkout_validationonBeforeSubmit a renvoyé false, a levé une exception ou a dépassé 30 secondesRépondez en moins de 30 secondes, et ne renvoyez false que si la commande a été refusée
confirmPayment rejette avec payment_error, « Validate the order before confirming this payment. »Le paiement a été préparé avec deferred: true et jamais activéActivez-le depuis votre endpoint de commande avant que onBeforeSubmit renvoie true
getValue() renvoie nullAucune valeur encore saisieLa valeur arrive au premier change. Lisez-la dans le handler

Style sans effet

Le SDK filtre appearance avant son départ du navigateur. Une clé inconnue est ignorée sans avertissement. Une faute de frappe ressemble donc exactement à un bug du checkout.

SymptômeCause
Bloc rules ignoréLe sélecteur n'est pas .Input ou .Label avec au maximum un pseudo-élément autorisé
Propriété d'une règle ignoréeElle ne figure pas parmi les 31 propriétés autorisées
Image d'arrière-plan ou importation de police ignoréeCertaines valeurs sont refusées par sécurité, dont toute valeur qui chargerait une ressource externe
Clé variables ignoréeSeules les seize clés documentées sont acceptées
update({ layout }) ne change rienLe checkout hébergé l'enregistre localement sans l'envoyer
Les props appearance ne changent rien après le montageCheckoutEmbed n'appelle jamais lui-même update()

Les trois listes figurent dans Apparence. Le comportement propre à chaque framework est présenté dans React, Vue et Svelte.

Mise en page et dimensions

SymptômeCauseCorrection
L'intégration est coupéeParent avec overflow: hidden ou hauteur fixeLe SDK définit lui-même la hauteur de l'iframe. Laissez le parent grandir
La page se décale au chargement du checkoutAucun espace réservé autour de votre contenuLe SDK réserve déjà 480px. Réservez votre récapitulatif, pas l'intégration
Un composant de champ reste minusculeSon parent utilise display: none lors du montageMontez-le une fois visible ou après l'ouverture de l'onglet

onResize est fourni à titre informatif. Le SDK a déjà appliqué la hauteur lors de son déclenchement. Utilisez-le pour déplacer un autre élément de la page.

Paiement

SymptômeCauseCorrection
Moyen de paiement absent du checkoutLa session ne contient pas ce canalLisez fetchSession().payment_methods avant le montage
Commande livrée deux foisonSuccess et le webhook déclenchent tous deux la livraisonLivrez avec le webhook et utilisez onSuccess pour l'interface
Commande jamais livréeonSuccess s'est exécuté puis l'onglet s'est ferméMême réponse. Le navigateur n'est pas une source fiable
onError se déclenche avec un decline_codeLe prestataire a refusé le paiementretryable indique si une nouvelle tentative doit être proposée
onError se déclenche avec nothing_to_submitsubmit() n'a trouvé aucun bouton de paiement sur lequel appuyer : aucun moyen choisi, une étape d'OTP, le bouton propre d'un wallet, ou un paiement déjà en coursAppelez submit() une fois que le payeur a choisi un moyen, et pas pendant un paiement en cours

Avant de passer en live

  • onError et onLoadError sont tous deux configurés.
  • La session est créée sur votre serveur avec la clé secrète dans une variable d'environnement.
  • Votre site et votre URL de callback utilisent HTTPS.
  • La commande est livrée à la réception du webhook, pas dans le navigateur.
  • L'intégration utilise mount(), open() ou un composant de framework, jamais une URL construite à la main.
  • onBreakdown maintient votre total à jour s'il apparaît à côté d'une intégration en ligne.
  • Un paiement réel d'un petit montant a été effectué en mode live.

Les cartes et numéros Mobile Money de test figurent dans Scénarios de test.

Le problème persiste ?

Écrivez à [email protected] avec la référence de transaction, le domaine de votre marchand et le code de onLoadError ou onError. N'envoyez jamais de clé.

Que pensez-vous de ce contenu ?