L'API v1 est retirée : migrer vers l'API v2
Depuis le 11 octobre 2026, l'API v1 et le SDK 1.x sont retirés : CashChap ne sert plus que l'API v2 et le SDK 2.0. L'API v2 garde la même logique de paiement (mêmes opérateurs, mêmes frais, mêmes contrôles) avec une forme plus simple et plus sûre : une seule clé par appel, des réponses toujours identiques, de vrais codes HTTP, des messages en français, l'idempotence et une référence de commande unique. Si votre intégration utilise encore une adresse /v1, ce guide indique l'équivalent v2 de chaque élément.
Ce qui a changé
- API : toute adresse
https://api.cashchap.com/v1/…, quelle que soit la méthode, répond 410 Gone avec l'erreur ci-dessous. Aucun paiement, retrait ni lecture n'est plus traité en v1. - SDK :
https://cdn.cashchap.com/v1/sdk.jsn'ouvre plus le paiement. Il écrit dans la console du navigateur « Le SDK v1 de CashChap a été retiré : utilisez https://cdn.cashchap.com/v2/sdk.js » et appelle votre fonctiononErrorsi vous en avez fourni une. Passez au SDK 2.0. - Comptes, clés et transactions : inchangés. Vos clés et toutes les transactions créées en v1 se lisent en v2.
- Webhooks : inchangés (voir plus bas).
HTTP/1.1 410 Gone
Content-Type: application/json; charset=utf-8
{
"error": {
"code": "api_v1_removed",
"type": "gone",
"message": "La version 1 de l'API CashChap a été retirée. Utilisez l'API v2 (https://api.cashchap.com/v2) : le guide de migration indique l'équivalent de chaque route.",
"details": {},
"request_id": "req_01J9Z7Q8M4V2K6T3N5P0R8S1W4",
"doc_url": "https://cashchap.com/docs/migration-v2"
}
}
Les étapes
- Authentification : remplacez
X-Api-Public-KeyetX-Api-Secret-KeyparAuthorization: Bearer <clé>, avec la clé secrète pour vos appels serveur. - Encaissement :
POST /v1/collection/MobileMoneydevientPOST /v2/collections; envoyezIdempotency-Keyet unereferencepar commande. - Suivi :
POST /v1/transaction-statusdevientGET /v2/transactions/{id}?wait=5, avec l'idde la réponse 202. - Statuts :
VALIDATEDdevientsucceeded,FAILEDdevientfailedouexpired. - Erreurs : testez
error.codeau lieu desuccesset des codesExxx. - Recette en Sandbox (liste de recette), puis passage en Live.
Routes
| API v1 | API v2 |
|---|---|
GET /v1/authorized-gateways | GET /v2/payment-methods |
POST /v1/exchange-rate/{devise} | GET /v2/exchange-rates?from=&to= |
POST /v1/phone/{provider}/validate {phone_number} | POST /v2/phone-numbers/validate {phone, provider} |
POST /v1/collection/{MobileMoney|BankCard|DebitDirect} | POST /v2/collections avec payment_method = mobile_money, card ou direct_debit |
POST /v1/transaction-status {transactionId|externalId} | GET /v2/transactions/{id} ou GET /v2/transactions?reference= |
POST /v1/withdrawal | POST /v2/payouts |
POST /v1/withdrawal/{id}/cancel | POST /v2/transactions/{id}/cancel |
GET /v1/link/{live|sandbox}/{id} | GET /v2/payment-links/{id} (le mode vient du lien) |
GET /v1/countries | supprimée : le pays est dans GET /v2/payment-methods |
| — | Nouveautés : /v2/session, /v2/quotes, /v2/currencies, /v2/transactions (liste), /receipt, /v2/terminals, /v2/payment-links/{id}/collections |
En-têtes et champs de requête
| API v1 | API v2 |
|---|---|
X-Api-Public-Key, X-Api-Secret-Key, publicKey | Authorization: Bearer <clé> (une seule clé) |
X-Transaction-Id (UUID choisi par vous, devenait l'identifiant) | Idempotency-Key ; l'identifiant est toujours attribué par CashChap |
X-Finger-Print | X-Device-Fingerprint |
initBy | supprimé : le canal vient de la clé (le champ est refusé) |
collaborator_uuid | session de caisse (operator_id) |
amount (entier ou chaîne) | amount (nombre JSON, décimales selon la devise) |
provider absent (choix automatique) | "provider": "auto" |
customer.fullname | customer.name |
customer.phone ou phone | phone à la racine, au format international obligatoire, sans « + » (229…) |
externalId (UUID) | reference (1 à 64 caractères, unique par environnement) |
card_number, exp_date, cvv | card : number, exp_month, exp_year, cvc |
| champs inconnus ignorés | champs inconnus refusés (unknown_field) |
Champs de réponse
| API v1 | API v2 |
|---|---|
success | supprimé : le code HTTP fait foi ; enveloppe data / error |
code (Exxx) + message | error.code, error.type, error.message, error.details, error.request_id, error.doc_url |
status PENDING / VALIDATED / FAILED / CANCELLED | status pending / succeeded / failed (expired pour un délai dépassé) / cancelled |
transactionId | id |
externalId | reference |
mode LIVE / SANDBOX | mode live / sandbox |
payment.provider, payment.method, payment.network | provider, payment_method.type, payment_method.network |
payment.request.amount / .currency | amount / currency |
payment.gateway, currency{from,to,rate} | exchange{from, to, rate, amount} |
payment.debited_amount, amount_to_pay + currency_to_pay | amount_charged + charged_currency (total payé par le client, arrondi compris) |
payment.commission_fees, fees.amount + fees.paid_by | fees.amount, fees.currency, fees.payer, fees.rule |
payment.available_amount, payment.is_available | net_amount, available |
customer, phone 2290166000000 | customer (masqué hors clé secrète), customer.phone 2290166000000 |
message (raison de l'échec) | failure{code, message} |
transaction_created_at 10-10-2026 14:46:27 | created_at 2026-10-10T14:46:27Z (ISO 8601, UTC) |
completed_at 10-10-2026 14:46:40 | completed_at (ISO 8601, UTC) |
virement : state, reference, bankReference, transferDate, account | payout.state, payout.bank_reference, payout.transfer_on, payout.bank, payout.account_masked |
moyens : gateway_code, gateway_name, minimum_debited_amount, maximun_debited_amount, fees{type,value}, supported_currencies | provider, name, min_amount, max_amount, fees_preview, currencies |
taux : value{from,to,rate: "0.0015…"} | data{from, to, rate: 0.0015…, as_of} |
lien : amount_is_fixed (0/1), cover, public_key | amount_fixed (booléen), cover_url ; plus de clé exposée |
Erreurs
Chaque code Exxx a son équivalent v2, donné dans la page Codes internes et dans la colonne « Exxx » de la page Erreurs de l'API v2. Exemples :
Les échecs de paiement (E410 à E429) ne sont pas des erreurs HTTP en v2 : ils apparaissent dans failure.code de la transaction (customer_declined, customer_timeout, insufficient_funds…).
Exemple complet
# v1
curl -X POST https://api.cashchap.com/v1/collection/MobileMoney \
-H "X-Api-Public-Key: PKLIVE_…" \
-H "X-Transaction-Id: 7c9e6679-7425-40de-944b-e07fc1f90ae7" \
-H "Content-Type: application/json" \
-d '{ "amount": 1000, "provider": "mtn-benin", "currency": "XOF",
"customer": { "fullname": "Afi Dossou", "email": "afi@example.com", "phone": "0197000000" },
"externalId": "c0a8012e-1f2b-4d3c-9e8f-7a6b5c4d3e2f" }'
# v2
curl -X POST https://api.cashchap.com/v2/collections \
-H "Authorization: Bearer SKLIVE_…" \
-H "Idempotency-Key: CMD-2026-00417-1" \
-H "Content-Type: application/json" \
-d '{ "amount": 1000, "currency": "XOF", "provider": "mtn-benin", "phone": "2290197000000",
"customer": { "name": "Afi Dossou", "email": "afi@example.com" },
"reference": "CMD-2026-00417" }'
Webhooks
Rien ne change pour l'instant : les webhooks gardent leur format actuel (charge chiffrée, en-têtes X-CashChap-*, statuts VALIDATED/FAILED, transactionId), y compris pour les transactions créées en v2. L'id v2 d'une transaction est le transactionId du webhook. Un format v2 optionnel sera annoncé dans Webhooks, avec la correspondance :
| Webhook actuel | Objet v2 |
|---|---|
payment.success / payment.failed | status succeeded / failed ou expired |
withdrawal.* | transaction type = payout |
data.transactionId, data.externalId | id, reference |
data.payment.available_amount | net_amount |
SDK JavaScript
Remplacez https://cdn.cashchap.com/v1/sdk.js par https://cdn.cashchap.com/v2/sdk.js : openCashChapWidget({publicKey, …}) devient CashChap.checkout({public_key, …}), l'élément <cashchap-widget> devient <cashchap-checkout> et la page de retour reçoit transaction_id, reference et status.
| SDK 1.x | SDK 2.0 |
|---|---|
<script src=".../v1/sdk.js"> | <script src=".../v2/sdk.js"> |
<cashchap-widget>, bouton .CashChapPay + CashChapPay.init() | <cashchap-checkout> |
openCashChapWidget({…}) | CashChap.checkout({…}) |
publicKey (ou api_key, publicAPIKey) | public_key |
fullname, email, phoneNumber | customer.name, customer.email, customer.phone |
paymentMethods, partnerId | payment_methods, metadata.partner_id |
sandbox | supprimé : le mode vient de la clé |
callback (ou successCallback) | return_url |
buttontext | button-text |
countries, theme, position | supprimés |
| — | reference, description, metadata, idempotency_key |
retour ?transactionId=&externalId=&transaction_status=success|failed | retour ?transaction_id=&reference=&status=succeeded|failed|expired|cancelled |
onPending({transactionId, externalId, status: "PENDING"}) | onPending(transaction) |
statuts VALIDATED, FAILED, PENDING | succeeded, failed, expired, cancelled, pending |
Le SDK 2.0 ouvre le widget sur https://payment.cashchap.com (le SDK 1.x l'ouvrait sur https://widget.cashchap.com, retiré). Si votre page applique une politique de sécurité du contenu, autorisez https://payment.cashchap.com dans frame-src, sinon le paiement ne s'affichera pas (voir CSP marchande).