Aller au contenu

Sessions et sécurité

Où utiliser chaque clé, comment créer un jeton de session et ce qu'il permet de faire.

Toutes les fonctionnalités Wajub côté navigateur reposent sur une chaîne à courte durée de vie : le jeton de session. Cette page explique son origine, ce qu'il remplace et pourquoi la clé qui le crée ne doit jamais quitter votre serveur.

Trois identifiants, trois emplacements

Le préfixe d'une clé Wajub indique à lui seul où la clé peut être utilisée. Les clés live commencent par sk. ou pk., les clés de sandbox par sk_test. ou pk_test..

IdentifiantFormatEmplacementPossibilités
Clé publiquepk. ou pk_test.Navigateur, votre HTMLCréer une session, rien d'autre
Clé secrètesk. ou sk_test.Serveur, variable d'environnementTout faire sur l'API
Jeton de sessionauthorization_tokenNavigateur, comme sessionIdRégler un seul paiement, une seule fois

Grâce au jeton de session, les deux autres clés sont inutiles dans le navigateur. Il est limité à un seul paiement, ne donne aucun accès au compte et expire avec ce paiement.

Le flux correct

Respectez toujours ces deux étapes dans cet ordre.

  1. Votre serveur appelle POST /payments avec la clé secrète et reçoit un authorization_token.
  2. Votre navigateur reçoit uniquement ce jeton et le transmet comme sessionId.
curl https://api.wajub.com/payments \
-H "Authorization: sk_test.xxxxxxxxxxxxxxxx…" \
-H "Content-Type: application/json" \
-d '{
  "amount": 35000,
  "currency": "XOF",
  "reference": "ORDER-123",
  "customer": { "email": "[email protected]" }
}'

La réponse contient trois éléments à conserver.

ChampUtilité
authorization_tokenLe sessionId du navigateur. Envoyez-lui uniquement cette valeur
authorization_urlLa page hébergée pour un checkout avec redirection
transaction.idVotre clé de rapprochement à la réception du webhook
Étape 2, dans le navigateur
const { sessionId } = await fetch('/api/checkout/session', { method: 'POST' })
  .then((r) => r.json());

await mount('#checkout', { sessionId });

Avant que la commande existe

Les champs de paiement affichés pendant que l'acheteur est encore sur le checkout précèdent la commande. Créez leur session avec deferred: true : le paiement est seulement préparé, reste hors de vos paiements et n'envoie aucun webhook tant que votre serveur ne l'a pas activé avec le total final et le client. Avant que la commande existe détaille les trois appels.

Créer une session depuis le navigateur

Wajub(publishableKey).createPayment() existe et fonctionne avec une clé de sandbox : en 1.5.0, une clé live, pk.…, est lue comme un id de session, et en live la session se crée donc sur votre serveur. Cet outil convient à un prototype ou à une page de démonstration dont le prix est fixe. Il ne convient pas à une boutique, car le montant serait alors défini par du code que le client contrôle.

Sandbox uniquement
const client = Wajub('pk_test.xxxxxxxxxxxxxxxx…');

const { sessionId } = await client.createPayment({
  amount: 35000,
  currency: 'XOF',
  customer: { email: '[email protected]' },
});

await client.mount('#checkout');

Ce que le jeton permet de faire

Le jeton de session autorise exactement un paiement. L'environnement d'exécution applique cette limite.

  • Il monte le checkout, ouvre la superposition ou pilote les composants de champs.
  • Il lit l'aperçu de la session avec fetchSession(sessionId).
  • Sur un paiement préparé, il affiche les moyens de paiement et ne débite rien : tout débit répond 409 tant que votre serveur n'a pas activé le paiement. L'activation conserve le jeton.
  • Il reste valide tant que le paiement n'a pas atteint un état final, puis expire peu après succeeded, failed, expired ou cancelled.
  • Il reste valide après un nouveau montage. Un composant démonté puis remonté réutilise donc le même jeton.
  • Il vit aussi longtemps que le paiement : 24 heures par défaut, ou les expires.in minutes fixées sur POST /payments (de 5 à 43 200). Au-delà, le paiement expire, onExpired se déclenche sur le checkout et un champ de paiement rejette avec session_expired.
  • Les tentatives de paiement sur une session sont limitées. Au-delà de la limite, la tentative est refusée avec rate_limited jusqu'à ce qu'un court délai soit écoulé.

Monter un jeton qui n'est plus valide appelle onLoadError avec session_terminal_expired, et un jeton que Wajub ne connaît pas l'appelle avec session_not_found. L'intégration elle-même reste vide. Configurez donc ce callback, même sur une page où vous pensez que ce cas ne peut pas se produire. Tant que le jeton est valide, un checkout monté sur un paiement terminé signale plutôt son résultat, par onSuccess, onError, onExpired ou onCancel.

L'URL de callback

callback est une destination de redirection. Elle ne concerne donc que le flux avec redirection. Transmettez une URL HTTPS de base sans vos propres paramètres d'URL. Wajub ajoute les siens.

Paramètre d'URLValeurs
statussucceeded, cancelled, failed, expired
referenceL'identifiant Wajub du paiement, celui que prend GET /payments/{id}, si disponible
trxrefVotre propre référence, si disponible

Chaque retour porte reference et trxref, y compris celui d'un paiement échoué, qui ne portait que status.

Destination du payeur
https://shop.example.com/order/complete?status=succeeded&reference=trx_CSUGajfv9xh0XQ5wu2lx&trxref=ORDER-123

Une intégration ne quitte jamais votre page, callback n'y a donc aucun effet. Utilisez onSuccess pour l'interface et le webhook comme source fiable.

Boutiques sur plusieurs domaines

Un domaine unique ne demande aucune configuration. Si votre checkout s'exécute sur un second domaine, indiquez explicitement le domaine canonique.

Checkout hébergé et champs de paiement
await mount('#checkout', { sessionId, embedOrigin: 'https://shop.example.com' });

const factory = await components(sessionId, {
  componentOrigin: 'https://shop.example.com',
});

Avant de passer en live

RègleRaison
HTTPS sur votre site et pour callbackLes iframes de paiement et les redirections refusent le HTTP simple
sk. uniquement dans les variables d'environnement du serveurJamais dans un bundle ni dans une variable PUBLIC_
Seul authorization_token atteint le navigateurC'est le seul identifiant qui ne donne aucun accès sensible
Montage par le SDKLe checkout ne fonctionne que lorsque le SDK le monte
Confirmation par webhookonSuccess est un événement du navigateur, qui peut être fermé

Que pensez-vous de ce contenu ?