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
POST /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://app.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).
Récupérer une payment session
GET /v1/payment-sessions/:idRetourne la vue merchant-safe. La session est filtrée par votre merchant et
votre environnement : une session d’un autre merchant 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
POST /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 merchant |
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.