Encaisser un paiement
Créer
curl -X POST "$VALSORIA_BASE/v1-payments" \
-H "Authorization: Bearer $VALSORIA_CLE" \
-H "Idempotency-Key: cmd-2026-00412" \
-H "Content-Type: application/json" \
-d '{
"amount": 10000,
"currency": "XOF",
"operator": "orange_ci",
"counterparty": { "msisdn": "0779149021" },
"merchant_reference": "CMD-2026-00412"
}'
{
"id": "txn_6INMt2lIL1Pv_y6RgqZvag",
"object": "payment",
"amount": 10000,
"currency": "XOF",
"status": "created",
"operator": "orange_ci",
"merchant_reference": "CMD-2026-00412",
"livemode": false,
"created_at": "2026-08-26T09:12:44.318Z"
}
Le cycle de vie
Un paiement passe par des états, et la réponse HTTP ne vous donne que le premier. Le payeur doit encore valider sur son téléphone.
| Statut | Ce que ça veut dire |
|---|---|
created | Le paiement existe. Rien n'est parti chez l'opérateur. |
pending | L'opérateur travaille. Le payeur valide, ou pas. |
succeeded | L'argent est encaissé. C'est le seul état où vous pouvez livrer. |
failed | Refusé. failure_code dit pourquoi. |
expired | Le payeur n'a jamais répondu. |
refunded / partially_refunded | Voir remboursements. |
Ne livrez jamais sur created ni sur pending. Attendez succeeded, par webhook — c'est ce pour quoi il existe.
L'idempotence, et pourquoi elle vous concerne
Idempotency-Key est obligatoire. Rejouez la même clé avec le même corps : vous recevez la réponse d'origine, statut compris, et aucun second paiement n'est créé.
Un rejeu rend donc 201, comme la création. 201 signifie « voici le paiement qui correspond à cette clé », pas « un de plus ». Fiez-vous à l'id, jamais au code HTTP, pour savoir si vous devez décrémenter un stock.
La clé doit venir de votre commande — cmd-2026-00412 — et pas d'un uuid() régénéré à chaque tentative. Une clé neuve par tentative ne protège de rien : c'est l'erreur la plus fréquente, et la plus coûteuse.
Réutiliser une clé avec un corps différent rend 422 idempotency_key_reused : c'est une erreur d'intégration, pas une reprise, et vous le dire tôt évite de vous rendre la réponse d'une autre requête.
merchant_reference
Votre référence, unique par marchand. Une seconde transaction portant la même valeur est refusée en 409 duplicate_reference. C'est une seconde protection contre le double encaissement, indépendante de l'idempotence — utile quand la reprise ne vient pas du même processus.
Lire un paiement
curl "$VALSORIA_BASE/v1-payments/txn_6INMt2lIL1Pv_y6RgqZvag" \
-H "Authorization: Bearer $VALSORIA_CLE"
Le paiement d'un autre marchand rend 404, jamais 403 : répondre 403 confirmerait son existence.
N'interrogez pas en boucle. Le webhook vous prévient ; le GET sert à réconcilier, ou à répondre à un client qui appelle.
Version d'API 2026-08-25 ·
changements ·
spécification OpenAPI