Documentation API

MonCashConnect est une API REST pour accepter des paiements MonCash dans votre application, votre site WordPress ou votre SaaS — sans gérer OAuth, jetons ou la complexité de la passerelle officielle.

Chaque requête est authentifiée avec la clé secrète de votre projet sk_proj_…. Les webhooks signés HMAC-SHA256 garantissent l'intégrité des notifications de paiement.

HMAC-SHA256
Webhooks fiables
REST + JSON
URL de base : https://api.moncashconnect.com/v1
Toutes les requêtes doivent être en HTTPS. Le corps des requêtes POST doit être en application/json.
Assistant IA de code ? On a un serveur MCP (Model Context Protocol) : npx -y @moncashconnect/mcp connecte Cursor, Claude Code ou Codex à MonCashConnect en lecture seule, avec une clé sk_ro_… qui ne peut pas déplacer d'argent. Voir le guide MCP.

Quickstart

Intégrez MonCash en moins de 5 minutes. Voici le flux minimal de bout en bout.

Nouveau sur MonCashConnect ? Commencez par le Quickstart Sandbox — testez votre intégration de bout en bout sans déplacer d'argent réel, puis passez en live en échangeant deux secrets (aucun changement de code).
1

Créez un projet dans le tableau de bord

Rendez-vous dans Développeur → Projets et créez un projet. Vous obtiendrez une clé secrète sk_proj_… — conservez-la en lieu sûr, elle ne s'affiche qu'une seule fois.

2

Créez un paiement côté serveur

curl -X POST https://api.moncashconnect.com/v1/pay-create \
  -H "Authorization: Bearer sk_proj_xxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 500,
    "referenceId": "order_001",
    "returnUrl": "https://votresite.com/merci"
  }'

La réponse contient paymentUrl — redirigez votre client vers cette URL.

3

Redirigez le client vers MonCash

const { paymentUrl } = await res.json();
// Côté serveur (Express, Next.js, etc.)
res.redirect(paymentUrl);
4

Recevez la confirmation par webhook

Configurez une URL webhook dans votre projet. MonCashConnect envoie un POST signé HMAC-SHA256 dès que le paiement est confirmé par MonCash.

import { constructEvent, MonCashError } from "@moncashconnect/sdk";

// Express — lire le corps brut AVANT JSON.parse
app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
  try {
    const event = constructEvent(
      req.body,
      req.headers["x-mcc-signature"],
      req.headers["x-mcc-timestamp"],
      process.env.MCC_WEBHOOK_SECRET,
    );
    if (event.event === "payment.completed") {
      // Créditez la commande dans votre base de données
    }
    res.sendStatus(200);
  } catch (err) {
    if (err instanceof MonCashError) return res.status(err.statusCode).send(err.message);
    res.sendStatus(500);
  }
});

Authentification

Chaque projet possède une clé secrète unique préfixée sk_proj_. Passez-la dans l'en-tête Authorization de chaque requête.

curl -H "Authorization: Bearer sk_proj_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
     https://api.moncashconnect.com/v1/pay-balance
Ne transmettez jamais la clé secrète depuis le navigateur (front-end). Faites toujours les appels API depuis votre serveur. En cas de fuite, révoquez la clé immédiatement depuis Développeur → Projets.

Domaines autorisés (CORS)

Si vous configurez des domaines autorisés sur votre projet, les requêtes provenant d'autres origines seront rejetées avec un 403. Laissez la liste vide pour autoriser toutes les origines (usage serveur uniquement).

La liste est tout-ou-rien : dès qu'elle contient au moins un domaine, toutes les autres origines sont bloquées — y compris localhost, vos URLs de staging et les previews. Ajoutez chaque environnement (prod, staging, dev) explicitement.

Créer un paiement

POST
https://api.moncashconnect.com/v1/pay-create

Crée une transaction en attente et renvoie une URL de paiement MonCash. Redirigez votre client vers cette URL. La transaction expire après 15 minutes.

Paramètres (JSON body)

Nom / CodeType / LimiteDescription
amount*integerMontant en HTG, entier entre 1 et 1 000 000
referenceId*stringIdentifiant unique [a-zA-Z0-9-_], 100 caractères max. Unique par projet.
returnUrlstringURL HTTPS de retour après paiement — fortement recommandé
customerNamestringNom du client — affiché sur la page MonCash (optionnel)
customerEmailstringEmail du client — enregistré dans la transaction (optionnel)
curl -X POST https://api.moncashconnect.com/v1/pay-create \
  -H "Authorization: Bearer sk_proj_xxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 500,
    "referenceId": "order_12345",
    "returnUrl": "https://votresite.com/merci",
    "customerName": "Jean Dupont",
    "customerEmail": "jean@example.com"
  }'

Réponse (200)

{
  "paymentUrl": "https://pay.moncashconnect.com/c/abc123...",
  "reference":  "order_12345",
  "expiresAt":  "2026-05-05T15:30:00.000Z"
}
referenceId doit être unique par projet. Réutiliser un referenceId existant retourne 409 Conflict.

Reprise sûre avec Idempotency-Key

Une requête /pay-create qui échoue (erreur réseau, timeout, 502 passerelle) peut avoir déjà créé la transaction. Pour rendre les retries sûrs, ajoutez l'en-tête Idempotency-Key avec une chaîne unique par tentative logique (UUID, hash de commande, etc.) : un second appel avec la même clé et le même corps renvoie l'URL de paiement d'origine au lieu de créer un doublon.

Nom / CodeType / LimiteDescription
Idempotency-Key (en-tête)ASCII imprimable, ≤ 200 charsIdentifiant stable côté merchant. Validité : 15 min (fenêtre TTL de l'URL de paiement).
Réponses possibles avec Idempotency-Key
Nom / CodeType / LimiteDescription
200même clé + même corpsRéponse d'origine renvoyée (header Idempotent-Replay: true). paymentUrl identique.
422idempotency_key_mismatchMême clé, corps différent — refusé pour éviter une transaction silencieusement modifiée.
409idempotent_request_in_progressRequête précédente avec cette clé encore en cours. Header Retry-After: 2 — réessayer.
502idempotent_replay_failedLa requête précédente avec cette clé a échoué — utilisez une nouvelle clé pour réessayer.
410idempotent_replay_expiredL'URL en cache a > 15 min ; utilisez une nouvelle Idempotency-Key (la précédente a expiré).
curl -X POST https://api.moncashconnect.com/v1/pay-create \
  -H "Authorization: Bearer sk_proj_xxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order_12345-attempt-1" \
  -d '{ "amount": 500, "referenceId": "order_12345", "returnUrl": "https://votresite.com/merci" }'
Sans Idempotency-Key (compatible avec le comportement antérieur) : si vous recevez un 409 ou un échec réseau, appelez GET /pay-status?referenceId=… pour vérifier qu'une transaction existe avant de générer un nouveau referenceId. Le code de fallback ci-dessous reste valide pour les intégrations legacy.
Fallback sans Idempotency-Key : reprise via /pay-status

Règle générale : sondez /pay-status avant de générer un nouveau referenceId. Ne ré-essayez /pay-create avec un identifiant frais que si /pay-status renvoie 404 (transaction jamais créée).

Vérifier le statut

GET
https://api.moncashconnect.com/v1/pay-status?referenceId=order_12345

Interrogez le statut d'une transaction par son referenceId. Utile après la redirection du client ou pour un polling de secours si le webhook n'est pas configuré.

curl -H "Authorization: Bearer sk_proj_xxxx" \
  "https://api.moncashconnect.com/v1/pay-status?referenceId=order_12345"

Réponse (200)

{
  "reference":            "order_12345",
  "status":               "completed",
  "amount":               500,
  "netAmount":            485,
  "completedAt":          "2026-05-05T14:21:18.000Z",
  "failedAt":             null,
  "failureReason":        null,
  "moncashTransactionId": "MC-123456789",
  "createdAt":            "2026-05-05T14:05:00.000Z"
}
Nom / CodeType / LimiteDescription
statusstringpending · completed · failed
amountinteger (HTG)Montant brut encaissé
netAmountinteger (HTG)Montant après déduction de la commission (ex : 500 × 97 % = 485 HTG en plan Free)
moncashTransactionIdstring | nullID de transaction MonCash — disponible après confirmation
failureReasonstring | nullMotif d'échec si status = failed

Solde

GET
https://api.moncashconnect.com/v1/pay-balance

Renvoie le solde HTG de votre compte marchand MonCashConnect — c'est-à-dire le total des paiements acceptés qui se sont décantés, moins les retraits déjà effectués. Cet endpoint ne renvoie aucune information sur un client ou un paiement particulier ; il sert à automatiser les retraits vers MonCash via votre tableau de bord.

curl -H "Authorization: Bearer sk_proj_xxxx" \
  "https://api.moncashconnect.com/v1/pay-balance"
{
  "balanceHtg":      12500,
  "withdrawableHtg":  5000,
  "dailyCapHtg":      5000,
  "usedTodayHtg":        0
}
Nom / CodeType / LimiteDescription
balanceHtgintegerSolde total disponible dans le compte
withdrawableHtgintegerMontant retirable maintenant (min(solde, cap - utilisé))
dailyCapHtgintegerPlafond journalier de retrait selon votre plan
usedTodayHtgintegerDéjà retiré aujourd'hui

Les retraits se demandent depuis la page Retraits du tableau de bord et sont approuvés avant envoi MonCash.

Payouts (paiements sortants)

Il existe plusieurs façons d'envoyer de l'argent depuis MonCashConnect. Choisissez la bonne selon votre besoin :

Vous voulez…RouteComment
Payer vos propres utilisateurs (marketplace, wallet, app)payout-createAPI self-serve, clé sk_proj_, dès que le KYC est validé. Vos utilisateurs vivent dans votre base ; MCC ne voit qu'un compte, le vôtre.
Retirer votre solde vers votre propre numéro, automatiquementRetraits autoInterrupteur sur la page Retraits, sans code. Détails plus bas.
Payer plusieurs numéros d'un coup (import CSV)Paiement en massePage /payouts/new. Activé par l'équipe.
Une app externe paie depuis les comptes MCC d'autres personnesexternal-payout-createPartner / Connect, token OAuth. Cas type HaiPay, réservé et activé par l'équipe. Voir la doc Partenaires.
Retrait manuel vers votre propre numéroPage RetraitsEn un clic depuis /withdrawals.
Ne confondez pas les deux API sortantes. payout-create déplace votre argent vers vos utilisateurs (self-serve, ci-dessous). Partner/Connect (external-payout-create) permet à une app externe d'agir sur le solde d'autres titulaires de comptes MCC, avec leur consentement OAuth (réservé, activé par l'équipe). Si vous payez vos propres utilisateurs, vous voulez payout-create, pas Connect.

Automatiser les paiements vers vos utilisateurs (API)

POST
https://api.moncashconnect.com/v1/payout-create

Envoie des fonds depuis votre solde marchand vers n'importe quel numéro MonCash. Votre compte MonCashConnect agit comme un pool commun : vous encaissez les paiements de vos utilisateurs, puis redistribuez vers chacun d'eux — gérez leur solde individuel dans votre propre base de données.

Modèle de frais : le destinataire reçoit exactement le montant amount que vous indiquez. Les frais réseau sont prélevés en sus sur votre solde (voir champ fee_htg dans la réponse).

Paramètres (JSON body)

Nom / CodeType / LimiteDescription
amount*integerMontant en HTG à envoyer au destinataire, entier entre 1 et 100 000 par payout. Le destinataire reçoit ce montant exact ; les frais sont prélevés en plus sur votre solde.
moncashNumberstringNuméro MonCash du destinataire (brut, ex : 50912345678). Requis si recipientCode absent.
recipientCodestringCode d'un destinataire sauvegardé dans votre projet. Alternative à moncashNumber.
referenceIdstringVotre identifiant d'idempotence [a-zA-Z0-9-_], 100 caractères max. Un doublon retourne 409 duplicate_reference.
curl -X POST https://api.moncashconnect.com/v1/payout-create \
  -H "Authorization: Bearer sk_proj_xxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: payout-user42-2026-06-24" \
  -d '{
    "amount": 5000,
    "moncashNumber": "50912345678",
    "referenceId": "payout-user42-2026-06-24"
  }'

Réponse (201)

{
  "status": "success",
  "payout": {
    "reference":                "wd_123",
    "status":                   "queued",
    "amount_htg":               5000,
    "fee_htg":                  250,
    "net_htg":                  5000,
    "recipient_account_masked": "509****1234"
  }
}
Nom / CodeType / LimiteDescription
payout.referencestringIdentifiant interne du payout (préfixe wd_)
payout.statusstringÉtat initial : queued. Cycle complet : queued → processing → completed | failed
payout.amount_htgintegerMontant demandé (ce que reçoit le destinataire)
payout.fee_htgintegerFrais réseau prélevés en sus sur votre solde
payout.net_htgintegerMontant effectivement reçu par le destinataire (= amount_htg)
payout.recipient_account_maskedstringNuméro MonCash masqué du destinataire, pour affichage sécurisé

Idempotence

Passez un referenceId unique ou l'en-tête Idempotency-Key pour rendre les retries sûrs. Un second appel avec le même identifiant retourne 409 duplicate_reference au lieu de créer un doublon.

Webhook de confirmation

MonCashConnect envoie un POST signé HMAC-SHA256 à votre URL webhook dès que le payout est réglé. La signature se vérifie exactement comme pour les webhooks pay-in (X-MCC-Signature: sha256=…, X-MCC-Timestamp).

payout.completed
Le payout a été transmis et le destinataire a reçu les fonds sur son numéro MonCash.
{
  "event": "payout.completed",
  "reference": "wd_123",
  "amount": 5000,
  "status": "completed",
  "recipient_account_masked": "509****1234",
  "completedAt": "2026-06-24T16:21:18.000Z",
  "failureReason": null
}
payout.failed
Le payout a échoué (numéro invalide, compte MonCash injoignable, etc.). Consultez failureReason.
{
  "event": "payout.failed",
  "reference": "wd_124",
  "amount": 5000,
  "status": "failed",
  "recipient_account_masked": "509****5678",
  "completedAt": null,
  "failureReason": "recipient_account_not_found"
}

Codes d'erreur spécifiques aux payouts

Nom / CodeType / LimiteDescription
missing_bearer_token401En-tête Authorization absent
invalid_key_type401La clé fournie n'est pas une clé de projet sk_proj_…
invalid_api_key401Clé invalide ou révoquée
kyc_required403Vérification d'identité requise avant d'activer les payouts
account_suspended403Compte marchand suspendu
invalid_amount400Le montant n'est pas un entier valide
invalid_moncash_number400Format de numéro MonCash incorrect
recipient_required400Ni moncashNumber ni recipientCode fourni
invalid_reference400referenceId ne respecte pas le format [a-zA-Z0-9-_] / dépasse 100 caractères
insufficient_balance402Solde insuffisant pour couvrir amount + frais réseau
below_minimum422Montant inférieur au minimum autorisé
above_maximum422Montant supérieur à 100 000 HTG par payout
recipient_not_found404recipientCode introuvable dans votre projet
duplicate_reference409referenceId ou Idempotency-Key déjà utilisé — le payout existe déjà

Retraits automatiques (sans code)

Pas besoin de coder pour automatiser vos propres retraits. Sur la page Retraits, activez les paiements automatiques : choisissez un numéro de retrait enregistré, indiquez « Envoyer quand le solde atteint » un seuil (minimum 100 HTG), et un plafond optionnel par paiement. Dès que votre solde franchit le seuil, MonCashConnect envoie automatiquement vers ce numéro, avec un délai minimum de 30 minutes entre deux envois. Mêmes frais réseau que pour un retrait manuel.

Idéal pour « je veux juste que mon argent arrive sur mon MonCash sans y penser ». Pour payer d'autres personnes automatiquement (vos utilisateurs), utilisez plutôt l'API payout-create ci-dessus.

Webhooks

Configurez une URL webhook dans votre projet pour recevoir les événements de paiement en temps réel. MonCashConnect envoie un POST signé HMAC-SHA256 à votre URL dès qu'un paiement est finalisé par MonCash.

Intégration Connect / partenaire ? Les webhooks de payouts sortants (external_payout.*) utilisent un schéma de signature distinct (t=…,v1=…) avec en-tête de déduplication X-MCC-Event-Id. Voir la documentation partenaire →

En-têtes envoyés

Nom / CodeType / LimiteDescription
X-MCC-Signaturestringsha256=<hex_hmac> — HMAC-SHA256 du corps JSON brut, signé avec votre webhook secret
X-MCC-TimestampstringTimestamp Unix (secondes) de l'envoi — rejetez si > 5 min d'écart
Content-Typestringapplication/json

Événements

payment.completed
Le paiement MonCash a été confirmé et le montant net crédité à votre solde.
{
  "event": "payment.completed",
  "reference": "order_12345",
  "amount": 500,
  "status": "completed",
  "completedAt": "2026-05-05T14:21:18.000Z"
}
payment.failed
Le paiement a expiré, été annulé ou rejeté par MonCash.
{
  "event": "payment.failed",
  "reference": "order_12345",
  "amount": 500,
  "status": "failed",
  "completedAt": null
}

Vérification de la signature

Lisez le corps brut (req.body en Buffer) avant tout JSON.parse(). Rejetez toute requête dont la signature est invalide ou dont le timestamp dépasse 5 minutes.

# Générer une signature de test en local
SECRET="whsec_votre_secret_webhook"
BODY='{"event":"payment.completed","reference":"test_001","amount":500,"status":"completed","completedAt":"2026-05-05T14:21:18.000Z"}'
TS=$(date +%s)
SIG="sha256=$(echo -n "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | sed 's/.*= //')"

curl -X POST https://votresite.com/webhook \
  -H "Content-Type: application/json" \
  -H "X-MCC-Signature: $SIG" \
  -H "X-MCC-Timestamp: $TS" \
  -d "$BODY"

Politique de retry

Si votre endpoint ne répond pas avec un 2xx dans les 10 secondes, MonCashConnect enregistre l'échec et planifie une nouvelle tentative après 60 secondes. Assurez-vous que votre handler est idempotent — il peut recevoir le même événement plusieurs fois.

SDKs officiels

Des SDKs officiels couvrent les trois langages principaux. Chaque SDK inclut la gestion des erreurs, la vérification HMAC des webhooks et des types TypeScript / annotations Python.

Node.js / TypeScript

@moncashconnect/sdk
npm install @moncashconnect/sdk
import { MonCashClient } from "@moncashconnect/sdk";

const client = new MonCashClient(
  process.env.MCC_SECRET_KEY
);

const payment = await client.createPayment(
  500, "order_001",
  { returnUrl: "https://site.ht/merci" }
);
res.redirect(payment.paymentUrl);

Python / pip

moncashconnect
pip install moncashconnect
from moncashconnect import MonCashClient
import os

client = MonCashClient(
  os.environ["MCC_SECRET_KEY"]
)

payment = client.create_payment(
  500, "order_001",
  return_url="https://site.ht/merci"
)
# redirect(payment["paymentUrl"])

PHP / Composer

moncashconnect/php-sdk
composer require moncashconnect/php-sdk
use MonCashConnect\Client;

$client = new Client(
  $_ENV['MCC_SECRET_KEY']
);

$payment = $client->createPayment(
  500, 'order_001',
  ['returnUrl' => 'https://site.ht/merci']
);
header('Location: '.$payment['paymentUrl']);

Guides par framework

Frais

MonCashConnect prend 0 % sur vos transactions.

Les frais que vous voyez sur la passerelle viennent du réseau Digicel MonCash. Nous les transmettons à l'identique — aucune marge ajoutée.

Frais détaillés

Nom / CodeType / LimiteDescription
Encaissement2,9 %Prélevé sur chaque paiement entrant via MonCash. Sur 1 000 HTG encaissés, vous recevez 971 HTG.
Retrait MonCash5 %Prélevé à l'envoi vers un numéro MonCash. Pour envoyer 1 000 HTG, votre solde diminue de 1 050 HTG.
Envois entre comptes MCC0 %Gratuits — aucun frais réseau, aucune commission MCC.
Commission MonCashConnect0 %Nous ne prélevons rien sur les transactions, peu importe le plan.

Pourquoi un abonnement existe alors ?

L'abonnement (Pro, Early Visionary Pass) débloque deux choses uniquement : plus d'un projet API sur votre compte, et des plafonds journaliers plus élevés sur les retraits. Tant que vous tenez sur un seul projet et le plafond Free, vous n'avez aucune raison de payer. Voir les plans →

Limites de débit

Les limites s'appliquent par clé secrète de projet et par adresse IP. Un dépassement retourne un 429 Too Many Requests.

Nom / CodeType / LimiteDescription
POST /pay-create60 / min / clé30 / min / IP
GET /pay-status120 / min / clé60 / min / IP
GET /pay-balance120 / min / clé60 / min / IP

En cas de dépassement répété, implémentez un backoff exponentiel avec jitter entre les tentatives. Évitez le polling intensif sur pay-status — préférez les webhooks pour les confirmations en temps réel.

Pages hébergées (QR de dépôt & factures)

Les pages de paiement hébergées par MonCashConnect — la page de dépôt par QR code et la page de règlement de facture — sont chargées par le navigateur de votre client, pas par votre serveur. Elles possèdent leurs propres limites, appliquées par adresse IP et par jeton public ; un dépassement retourne également un 429 Too Many Requests avec un en-tête Retry-After: 60.

Nom / CodeType / LimiteDescription
Page de dépôt QR (création)20 / min / IP30 / min / jeton
Dépôt QR — infos payeur120 / min / IPLecture publique (affichage)
Dépôt QR — statut120 / min / IPPolling de la page de confirmation
Page de facture (paiement)20 / min / IP30 / min / jeton
Facture — infos120 / min / IPLecture publique (affichage)

Ces limites protègent les pages hébergées contre les abus ; elles n'affectent pas vos appels serveur authentifiés par clé sk_proj_.

Codes d'erreur

Toutes les erreurs renvoient un objet JSON { "error": "message" }.

Nom / CodeType / LimiteDescription
400Bad RequestParamètre invalide ou manquant — vérifiez amount, referenceId, returnUrl
401UnauthorizedClé API absente, invalide ou révoquée
403ForbiddenOrigine non autorisée (CORS) ou compte suspendu
404Not FoundTransaction introuvable pour ce referenceId et ce projet
409ConflictreferenceId déjà utilisé pour ce projet — utilisez un identifiant unique
429Too Many RequestsLimite de débit atteinte — attendez avant de réessayer (backoff exponentiel)
500Internal ErrorErreur interne — contactez le support si le problème persiste
502Bad GatewayErreur passerelle de paiement — réessayez dans quelques secondes

Codes d'erreur structurés (réponse 400)

Au-delà des codes HTTP, certaines réponses 400 incluent un champ code machine-lisible. Utilisez-le pour brancher la logique côté client.

Nom / CodeType / LimiteDescription
invalid_request400Paramètre manquant ou mal formé (amount, referenceId, returnUrl, etc.)
amount_below_minimum400Montant inférieur au minimum (1 HTG côté création, 1 000 HTG côté retrait)
invalid_token401Token OAuth ou clé d'API invalide / expirée (intégrations Connect)
insufficient_scope403Le token n'a pas le scope requis (balance.read, payout.request, etc.)
connection_revoked403Le marchand a révoqué l'accès de votre application (intégrations Connect)
connection_not_found404Aucune connexion active entre votre application et ce marchand
insufficient_balance402Solde marchand insuffisant pour le retrait demandé
partner_daily_cap_exceeded429Plafond journalier de votre application atteint (intégrations Connect)
plan_daily_cap_exceeded429Plafond journalier du plan du marchand atteint
rate_limit_exceeded429Limite de débit dépassée — attendez et réessayez avec backoff
auth_unavailable503Service d'authentification temporairement indisponible — réessayez
server_misconfigured500Erreur de configuration côté MonCashConnect — contactez le support
not_found404Ressource (transaction, payout, connexion) introuvable

Exemple de réponse d'erreur

{
  "error": "referenceId already exists for this project",
  "code":  "duplicate_reference"
}

Le champ code est stable ; le champ error est destiné aux humains et peut être traduit ou reformulé.

Prêt à intégrer ?

Créez un projet et obtenez vos clés API en moins d'une minute.