Skip to Content
Référence APIHosted Checkout

Hosted Checkout

Avec le Hosted Checkout, vous ne choisissez pas l’opérateur : vous créez une intention de paiement, redirigez votre client vers checkout_url, et c’est lui qui choisit Airtel Money ou Moov Money sur la page Kadryza. Son choix crée une Payment Session, dont vous suivez le résultat comme d’habitude.

Payment SessionHosted Checkout
Qui choisit l’opérateurVousVotre client
Interface de paiementLa vôtre (ou checkout_url)Page Kadryza
RésultatWebhooks payment_session.*Webhooks payment_session.* de la session créée
SDK Node.jsPris en chargeNon pris en charge

Créer un Hosted Checkout

POST/v1/hosted-checkoutsX-API-Key

Portée de clé requise : write_transactions. L’environnement est celui de la clé.

ChampTypeRequisDescription
referencestringOuiVotre identifiant de commande, unique par environnement ; il sera aussi la référence de la Payment Session
amountintegerOuiMontant en XAF, entier strictement positif
currencystringOuiXAF
customer_phonestringNonTéléphone du payeur. Pour un paiement live, s’il est absent ici, la page le demande au client
descriptionstringNonAffichée au client sur la page de paiement
metadataobjectNonStockée, jamais renvoyée
ttl_minutesintegerNonValidité totale, de 1 à 60 minutes (défaut 10), choix de l’opérateur compris
return_urlstringNonAdresse de votre site où renvoyer le client une fois le paiement réglé. URL absolue https (http://localhost accepté avec une clé de test), 2048 caractères au plus, sans identifiants. Voir Retour sur votre site
pricing_versionintegerNon1 pour accepter un détail serveur avec frais client et total à payer. Requis quand la politique ajoute des frais au payeur.

Le détail pricing, lorsqu’il est présent, est figé dès la création de l’intention, avant le choix de l’opérateur. Une répétition de la même intention et sa future Payment Session gardent les mêmes montants, même si le tarif global a changé. amount retourné est le total à payer; le montant original de commande est pricing.original_amount. Voir le contrat de tarification.

curl -X POST https://api.kadryza.app/v1/hosted-checkouts \ -H "X-API-Key: $KADRYZA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "reference": "order_2026_002", "amount": 5000, "currency": "XAF", "description": "Commande #2026-002", "return_url": "https://boutique.example/commande/2026-002" }'
201 Created
{ "id": "ffd10eac-14d4-4646-a557-495784fcafb8", "reference": "order_2026_002", "amount": 5000, "currency": "XAF", "environment": "test", "status": "OPEN", "expires_at": "2026-06-05T12:40:00Z", "created_at": "2026-06-05T12:30:00Z", "checkout_url": "https://checkout.kadryza.com/pay/checkout/ffd10eac-14d4-4646-a557-495784fcafb8", "return_url": "https://boutique.example/commande/2026-002" }

Une fois l’opérateur choisi, la réponse (et les lectures suivantes côté page) porte selected_operator et payment_session_id.

Idempotence : recréer avec la même reference et le même contenu (return_url compris) renvoie l’intention existante ; avec un contenu différent, 409 IDEMPOTENCY_CONFLICT.

Retour sur votre site

Avec return_url, la page de paiement renvoie votre client chez vous une fois le paiement réglé :

  • paiement confirmé : bouton « Retour sur votre nom » et retour automatique au bout de 3 secondes, que le client peut annuler (une seule fois par paiement, recharger la page ne le relance pas) ;
  • en vérification, expiré, échoué ou annulé : bouton de retour, sans redirection automatique.

Kadryza ajoute deux paramètres à votre adresse, en conservant les vôtres :

ParamètreValeurs
kadryza_statussucceeded, under_review, expired, failed, cancelled
kadryza_referenceVotre reference
https://boutique.example/commande/2026-002?kadryza_status=succeeded&kadryza_reference=order_2026_002

Ces paramètres servent à afficher la bonne page, pas à livrer : n’importe qui peut taper une adresse. Confirmez toujours le paiement par le webhook payment_session.succeeded ou en lisant la session (GET /v1/payment-sessions/by-reference). Le webhook arrive en général quelques secondes après la confirmation, parfois avant le retour du client.

Statuts d’une intention

StatutSignification
OPENEn attente du choix de l’opérateur
SELECTEDOpérateur choisi, une Payment Session existe : suivez-la
EXPIREDDélai dépassé sans choix d’opérateur
CANCELLEDLe client a renoncé avant de choisir un opérateur

Aucune capacité n’est réservée tant que le client n’a pas choisi : la liste des opérateurs proposés est recalculée à chaque affichage et revérifiée au moment du choix. Si aucun opérateur n’est disponible, la page l’indique au client.

Endpoints utilisés par la page de paiement

Ces endpoints sont publics et appelés par la page hébergée. Vous n’avez pas à les appeler ; ils sont décrits pour comprendre les erreurs visibles par votre client.

GET/v1/checkout/intents/:idPublic · sans clé

Vue du paiement : marchand, montant, opérateurs éligibles, session éventuelle.

POST/v1/checkout/intents/:id/selectPublic · sans clé

Choix de l'opérateur ({ operator, customer_phone? }). Crée la Payment Session.

POST/v1/checkout/intents/:id/cancelPublic · sans clé

Renoncement du client, uniquement avant le choix de l'opérateur.

HTTPcodeCause
404NOT_FOUNDIntention inconnue
409OPERATOR_NO_LONGER_AVAILABLEL’opérateur n’est plus disponible au moment du choix
409OPERATOR_SELECTION_CONFLICTUn autre opérateur a déjà été choisi
409CHECKOUT_CANCELLED, CHECKOUT_NOT_CANCELLABLEIntention annulée, ou annulation après le choix
410CHECKOUT_EXPIREDDélai dépassé
503OPERATOR_AVAILABILITY_UNAVAILABLEDisponibilité des opérateurs momentanément invérifiable
429RATE_LIMIT_EXCEEDEDTrop de tentatives

Répéter le même choix renvoie la même session : un double clic ne crée pas deux paiements.

Suivre le résultat

Écoutez les webhooks payment_session.succeeded, payment_session.under_review et payment_session.expired (Webhooks). Leur champ data.reference est votre reference. En l’absence de webhook, lisez la session avec GET /v1/payment-sessions/by-reference?reference=….

L’annulation d’une intention par le client n’émet pas de webhook. Une intention EXPIRED ou CANCELLED n’a jamais créé de session.