SDK JavaScript 2.0.2
Le SDK ajoute un paiement CashChap à votre page en quelques lignes : il ouvre le widget par-dessus la page, sans redirection, puis vous rend le résultat confirmé par l'API v2. Aucune dépendance, un seul fichier, chargé une seule fois même s'il est inclus deux fois.
Installation
<script src="https://cdn.cashchap.com/v2/sdk.js"></script>
L'adresse https://cdn.cashchap.com/v2/sdk-2.0.2.js fige la version 2.0.2. Empreinte de ce fichier, pour vérifier une copie que vous hébergeriez vous-même : sha384-PO9WS5xBZTd5lAVcWfnXlbqE+uDVOaxj+t7rkK17uhHlAT1UQ4QTT55PgTGa5n1G (SHA-384, format SRI). Voir aussi Versions.
Le script expose window.CashChap (CashChap.version, CashChap.checkout(), CashChap.on()) et l'élément <cashchap-checkout>. Il n'utilise que votre clé publique : le mode (Live ou Sandbox) est celui de la clé.
Bouton prêt à l'emploi
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<title>Payer avec CashChap</title>
<script src="https://cdn.cashchap.com/v2/sdk.js"></script>
</head>
<body>
<cashchap-checkout
data-public-key="VOTRE_CLE_PUBLIQUE"
data-amount="2500"
data-currency="XOF"
data-reference="CMD-2026-00417"
data-customer-name="Koffi Mensah"
data-customer-email="koffi.mensah@example.com"
data-return-url="https://www.votre-site.bj/paiement/retour"
button-text="Payer 2 500 FCFA"></cashchap-checkout>
<script>
document.querySelector("cashchap-checkout").addEventListener("cashchap:success", function (e) {
// e.detail.transaction : objet transaction de l'API v2 (données du client masquées).
// Le navigateur ne prouve rien : confirmez côté serveur avant de livrer.
});
</script>
</body>
</html>
Attributs de l'élément
| Attribut | Obligatoire | Description |
|---|---|---|
data-public-key | Oui | Clé publique du service (Live ou Sandbox : c'est elle qui fixe le mode). |
data-amount | Oui | Prix en unités de la devise (2500 = 2 500 XOF), entier en XOF. |
data-currency | Oui | Devise active (XOF…). Le widget montre le prix, les frais et le total dans la devise du service (prix converti si besoin). |
data-reference | Recommandé | Votre référence de commande, unique : l'API refuse un second paiement avec la même référence. |
data-customer-name, data-customer-email, data-customer-phone | Non | Coordonnées du client, préremplies dans le widget ; numéro national (0197000000) ou international (2290197000000). |
data-description | Non | Libellé du paiement. |
data-payment-methods | Non | Moyens proposés, séparés par des virgules : mobile_money, card, direct_debit. |
data-metadata | Non | Objet JSON de vos données, renvoyé dans la transaction : 20 clés au plus (a-z, 0-9, _), valeurs chaînes ({"panier": "42"}, pas {"panier": 42}). |
data-return-url | Non | Adresse de retour après paiement, http ou https (voir Après le paiement). |
button-text | Non | Libellé du bouton (texte brut). |
L'élément émet des événements DOM : cashchap:success, cashchap:error, cashchap:pending et cashchap:close, avec event.detail.transaction (et event.detail.error pour une erreur).
Ouvrir un paiement en JavaScript
CashChap.checkout({
public_key: "VOTRE_CLE_PUBLIQUE", // le mode (Live ou Sandbox) est celui de la clé
amount: 2500,
currency: "XOF",
reference: "CMD-2026-00417", // unique par commande : protège du double paiement
customer: { name: "Koffi Mensah", email: "koffi.mensah@example.com", phone: "2290197000000" },
metadata: { panier: "42" },
return_url: "https://www.votre-site.bj/paiement/retour", // facultatif
onSuccess: function (transaction) { /* transaction.status === "succeeded" */ },
onError: function (erreur, transaction) { /* erreur.code, erreur.message (en français) */ },
onPending: function (transaction) { /* confirmation encore attendue : ne relancez pas le paiement */ },
onClose: function (transaction) { /* widget fermé ; transaction vaut null si rien n'a été payé */ }
}).then(function (resultat) {
// resultat.status : succeeded | failed | expired | cancelled | pending | closed
});
Options
| Option | Description |
|---|---|
public_key, amount, currency | Obligatoires, comme les attributs ci-dessus. |
reference, description, metadata, customer | Mêmes règles que dans l'API v2, sauf customer.phone : national ou international ; la page de paiement reconnaît le pays, affiche le numéro national et envoie toujours le format international sans « + ». |
payment_methods | Tableau : ["mobile_money", "card", "direct_debit"]. |
idempotency_key | Facultatif, sinon tiré au hasard à chaque ouverture : 1 à 128 caractères parmi lettres sans accent, chiffres, _ et - (un UUID ou commande-1024). Transmis au widget, qui l'envoie à l'API comme en-tête Idempotency-Key. |
metadata | Objet de 20 clés au plus ; clés de 1 à 40 caractères a-z, 0-9 ou _, sans le préfixe réservé cashchap_ ; valeurs chaînes de 500 caractères au plus. Un nombre s'écrit "42". |
return_url | Adresse de retour ; une adresse javascript: ou d'un autre schéma est refusée. |
onSuccess, onError, onPending, onClose | Rappels. Chaque résultat n'appelle qu'une fois onSuccess ou onError, même si le widget l'annonce deux fois. |
Un seul paiement est ouvert à la fois : un nouvel appel à CashChap.checkout() ferme le précédent.
Événements
CashChap.on("transaction.succeeded", function (transaction) { /* … */ });
CashChap.on("transaction.failed", function (transaction) { /* transaction.failure.message */ });
// Aussi : transaction.expired, transaction.cancelled, transaction.pending, checkout.closed
L'objet transaction est celui de l'API v2 (id, status, reference, amount, amount_charged = total payé par le client, fees, failure…), lu par le SDK avec votre clé publique : les données du client y sont masquées. Le deuxième argument des rappels indique sa source : {source: "api"}, ou {source: "widget"} si l'API n'a pas pu être lue.
Après le paiement
Avec return_url, le SDK renvoie le client vers votre page quand il ferme le widget (SDK 2.0.2 : le bouton devient « Fermer et revenir au site du marchand »), en ajoutant trois paramètres :
https://www.votre-site.bj/paiement/retour
?transaction_id=2f1c3b6e-9a0d-4c1e-8f5a-2b7d9e4c6a10
&reference=CMD-2026-00417
&status=succeeded
Avec le SDK 2.0.2, le widget ne se ferme plus de lui-même : il garde à l'écran le reçu détaillé, le QR code d'authentification, « Télécharger la facture » et le QR code de la facture, jusqu'à ce que le client touche Fermer ou ✕. Vos rappels (onSuccess, onError, onPending), les événements et la promesse partent dès le résultat, sans attendre la fermeture ; onClose suit la fermeture. Pour fermer plus tôt, appelez CashChap.close(). Avec le SDK 2.0.1, le widget se ferme 5 secondes après le résultat et return_url redirige aussitôt. Appuyez-vous sur onSuccess pour l'affichage et sur un webhook ou la lecture de la transaction côté serveur pour la commande.
Paiement encore en attente
Le client valide sur son téléphone : cela peut prendre du temps. Si la confirmation tarde, le widget l'indique au client (« Vérifier à nouveau ») et le SDK appelle onPending(transaction) (événement transaction.pending). Le paiement peut encore aboutir : ne le traitez pas comme un échec et ne relancez pas un second paiement. Suivez la transaction depuis votre serveur, comme décrit dans Confirmer un paiement.
Erreurs d'intégration
Options invalides (clé, montant, devise, adresse de retour…) : le SDK écrit le problème en français dans la console du navigateur, appelle onError avec {code: "invalid_options", message}, rejette la promesse avec la même erreur et n'ouvre aucune fenêtre. Testez votre page avec la console ouverte. Les refus de l'API arrivent dans onError avec le code et le message de l'API v2.
Sécurité
- Le widget s'ouvre dans un cadre sur
https://payment.cashchap.com; le SDK n'écoute que les messages de cette origine et de ce cadre. - Le SDK n'injecte aucune bibliothèque tierce. Si votre site applique une politique de sécurité du contenu (CSP), autorisez
script-src https://cdn.cashchap.com,frame-src https://payment.cashchap.cometconnect-src https://api.cashchap.com(voir CSP marchande). - Seule la clé publique figure dans la page. La clé secrète reste sur votre serveur.
Reçu du client dans le widget
Après un paiement réussi, le widget affiche le reçu complet avec son QR code d'authentification et propose au client Télécharger le reçu (image PNG), Partager (WhatsApp, SMS…) si son téléphone le permet, Télécharger la facture et le QR code de la facture : voir Reçu du client et Reçus et vérification. Le SDK 2.0.2 ouvre le widget dans un cadre autorisé à partager (allow="payment; web-share") ; avec le SDK 2.0.1, le bouton Partager reste masqué et le reçu se télécharge.
Si votre page envoie un en-tête Permissions-Policy qui restreint web-share, autorisez-le pour le domaine des paiements, sinon le bouton Partager restera masqué :
Versions
| Adresse | Version | Différence |
|---|---|---|
https://cdn.cashchap.com/v2/sdk.js | Dernière 2.x (2.0.2 aujourd'hui) | Recommandée : reçoit les corrections compatibles sans changer votre code. |
https://cdn.cashchap.com/v2/sdk-2.0.2.js | 2.0.2, figée | Widget gardé ouvert après le résultat jusqu'à ce que le client le ferme ; return_url à la fermeture ; partage du reçu depuis le widget. |
https://cdn.cashchap.com/v2/sdk-2.0.1.js | 2.0.1, figée | Toujours servie, inchangée : reçu téléchargeable, sans bouton Partager ; widget fermé 5 secondes après le résultat. |
Les options, les rappels, les événements et la promesse sont les mêmes dans toutes les versions 2.0 : passer de l'une à l'autre ne demande aucun changement de code (avec la 2.0.2, une return_url est appelée à la fermeture du widget plutôt qu'aussitôt). Le détail de chaque version est dans le journal des changements.
SDK 1.x (retiré)
Le SDK 1.x (https://cdn.cashchap.com/v1/sdk.js, objet CashChapPay, élément <cashchap-widget>, fonction openCashChapWidget()) est retiré depuis le 11 octobre 2026, avec l'API v1. L'adresse sert désormais un petit script qui n'ouvre plus aucun paiement : il écrit dans la console « Le SDK v1 de CashChap a été retiré : utilisez https://cdn.cashchap.com/v2/sdk.js » et appelle votre fonction onError si vous en avez fourni une. Remplacez-le par le SDK 2.0 en suivant la correspondance du guide de migration.