Payment Sessions
Une payment session assigne un numéro Mobile Money Kadryza vers lequel votre
client envoie l’argent. La confirmation est asynchrone : Kadryza reçoit le SMS
de crédit, le rapproche de la session, puis la confirme de façon sûre. Écoutez les
webhooks payment_session.* ou interrogez GET /v1/payment-sessions/:id.
Tous les endpoints utilisent l’authentification publique :
X-API-Key: <cle_api_kadryza>L’environnement est déduit de la clé (kadryza_test_... → session test,
kadryza_live_... → session live). Ne passez jamais merchant_id,
is_test ou environment dans le body — ils sont imposés par la clé.
assigned_collection_number est le numéro à afficher à votre client : c’est
là qu’il doit envoyer le paiement.
Créer une payment session
/v1/payment-sessionsPayload :
| Champ | Type | Requis | Description |
|---|---|---|---|
reference | string | Oui | Votre identifiant de commande (merchant_order_id), unique par environnement |
amount | integer | Oui | Montant entier en XAF (> 0) |
currency | string | Oui | XAF |
operator | string | Oui | AIRTEL ou MOOV |
customer_phone | string | Non | Téléphone du payeur |
description | string | Non | Description courte |
metadata | object | Non | Données arbitraires, stockées mais non renvoyées dans les réponses (voir note) |
ttl_minutes | integer | Non | Durée de vie 1–60 (défaut 10) |
reference est votre identifiant de commande (merchant_order_id) : utilisez-le
pour rapprocher la session de votre commande. metadata est stockée côté
Kadryza mais n’est pas exposée dans les réponses publiques ni les webhooks —
ne comptez pas la relire via l’API.
curl -X POST https://api.kadryza.app/v1/payment-sessions \
-H "X-API-Key: $KADRYZA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"reference": "order_2026_001",
"amount": 5000,
"currency": "XAF",
"operator": "AIRTEL"
}'Réponse 201 Created :
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"reference": "order_2026_001",
"ticket": "KDRZ-8F3K2",
"amount": 5000,
"currency": "XAF",
"operator": "AIRTEL",
"status": "AWAITING_PAYMENT",
"environment": "live",
"assigned_collection_number": "074000001",
"expires_at": "2026-06-05T12:40:00Z",
"created_at": "2026-06-05T12:30:00Z",
"instructions": "Envoyez 5000 XAF vers le numéro 074000001 (AIRTEL), puis conservez la référence KDRZ-8F3K2.",
"checkout_url": "https://dashboard.kadryza.app/pay/payment-sessions/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}checkout_url est l’URL de la page checkout hébergée par Kadryza pour cette
session. Elle est optionnelle : utilisez-la comme fallback ou cible de
redirection si vous ne voulez pas construire votre propre écran. Les champs
POST, GET et cancel renvoient tous le même DTO, donc checkout_url y figure.
C’est un lien de commodité (pas un secret).
Erreurs : 400 (paramètres invalides / ttl_minutes hors 1–60), 409
(reference déjà utilisée pour cet environnement), 503 (aucun numéro de
collecte disponible ou rail live non prêt).
Si une clé live déclenche PROVIDER_RAIL_NOT_READY, ne l’affichez pas comme une
erreur technique brute. Expliquez que le rail live n’est pas encore prêt pour
l’opérateur demandé, que le mode Test reste disponible, et que l’activation live
dépend de la validation opérationnelle Kadryza. La réponse inclut
failed_checks pour aider votre équipe à diagnostiquer le rail concerné.
Exemple 503 Service Unavailable :
{
"error": "payment provider rail is not ready for live payment sessions",
"code": "PROVIDER_RAIL_NOT_READY",
"operator": "AIRTEL",
"environment": "live",
"failed_checks": [
{
"name": "gateway_connected",
"ready": false,
"reason": "no matching gateway connected to hub",
"count": 0
}
]
}Récupérer une payment session
/v1/payment-sessions/:idRetourne la vue côté marchand. La session est filtrée par votre compte et
votre environnement : une session d’un autre marchand ou d’un autre
environnement renvoie 404.
curl https://api.kadryza.app/v1/payment-sessions/a1b2c3d4-e5f6-7890-abcd-ef1234567890 \
-H "X-API-Key: $KADRYZA_API_KEY"Annuler une payment session
/v1/payment-sessions/:id/cancelAutorisé uniquement tant que status = AWAITING_PAYMENT. Une session déjà
SUCCESS, UNDER_REVIEW, EXPIRED, FAILED ou CANCELLED renvoie 409.
Un paiement qui arriverait après l’annulation n’est jamais confirmé automatiquement.
curl -X POST https://api.kadryza.app/v1/payment-sessions/a1b2c3d4-e5f6-7890-abcd-ef1234567890/cancel \
-H "X-API-Key: $KADRYZA_API_KEY"SDK Node / TypeScript
import Kadryza from '@kadryza/sdk'
const kadryza = new Kadryza({ apiKey: process.env.KADRYZA_API_KEY! })
// Créer
const session = await kadryza.paymentSessions.create({
reference: 'order_2026_001',
amount: 5000,
currency: 'XAF',
operator: 'AIRTEL',
ttl_minutes: 15,
})
// Affichez session.assigned_collection_number à votre client.
// Récupérer
const fresh = await kadryza.paymentSessions.retrieve(session.id)
// Annuler (si AWAITING_PAYMENT)
const cancelled = await kadryza.paymentSessions.cancel(session.id)Custom Checkout (votre propre UI)
Vous pouvez garder votre propre interface et ne pas afficher la page hébergée. Dans ce mode, affichez vous-même les champs de la réponse :
amount+currency,operator;assigned_collection_number— le numéro Mobile Money vers lequel le client paie ;ticket(référence Kadryza),expires_at(compte à rebours),status.
Kadryza reste le moteur de paiement derrière votre UI : réception du SMS de crédit, rapprochement et confirmation sûre côté serveur. Vous n’avez rien à confirmer manuellement.
Suivi du statut — bonnes pratiques :
- Les webhooks d’abord : abonnez-vous à
payment_session.succeeded/payment_session.under_review/payment_session.expired(voir Webhooks). C’est la source de vérité. - Polling en complément : si vous interrogez
GET /v1/payment-sessions/:id, limitez-vous à une fois toutes les 5 secondes maximum pendantAWAITING_PAYMENT. - Arrêtez ou ralentissez le polling dès un état terminal (
SUCCESS,EXPIRED,FAILED,CANCELLED) ouUNDER_REVIEW— n’interrogez plus en boucle.
checkout_url reste disponible comme fallback (lien de secours / redirection)
si vous voulez basculer ponctuellement sur la page hébergée.
Statuts
| Statut | Signification |
|---|---|
AWAITING_PAYMENT | En attente du paiement du client |
SUCCESS | Paiement reçu et confirmé |
UNDER_REVIEW | Paiement reçu hors délai / à vérifier — jamais confirmé automatiquement |
EXPIRED | Expirée sans paiement |
FAILED | Échec |
CANCELLED | Annulée par le marchand |
Webhooks
Kadryza envoie, après décision sûre :
payment_session.succeeded— la session est passée enSUCCESS;payment_session.under_review— paiement à vérifier (jamais transformé en succès) ;payment_session.expired— la sessionAWAITING_PAYMENTa dépassé sa fenêtre d’expiration + grâce backend sans paiement confirmé (aucun ledger créé).
Le payload inclut environment. Pour un événement test, l’en-tête
X-Kadryza-Test: true est ajouté. Voir Webhooks.
Test vs Live
- Clé test (
kadryza_test_...) → session test (environment: "test"). - Clé live (
kadryza_live_...) → session live (environment: "live"). - Le champ
environmentde la réponse reflète l’environnement. - Les webhooks d’événements test portent l’en-tête
X-Kadryza-Test: true. - Une session test peut atteindre
SUCCESSmais n’affecte jamais votre solde, vos settlements ni vos rapports financiers live.