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://hvlmeoqyxaguzcujpmit.supabase.co/functions/v1
Toutes les requêtes doivent être en HTTPS. Le corps des requêtes POST doit être en application/json.

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://hvlmeoqyxaguzcujpmit.supabase.co/functions/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://hvlmeoqyxaguzcujpmit.supabase.co/functions/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://hvlmeoqyxaguzcujpmit.supabase.co/functions/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://hvlmeoqyxaguzcujpmit.supabase.co/functions/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.bazik.io/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 (la fenêtre TTL de l'URL Bazik).
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é côté Bazik).
curl -X POST https://hvlmeoqyxaguzcujpmit.supabase.co/functions/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://hvlmeoqyxaguzcujpmit.supabase.co/functions/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://hvlmeoqyxaguzcujpmit.supabase.co/functions/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,
  "bazikOrderId":         "BZK-987654321",
  "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://hvlmeoqyxaguzcujpmit.supabase.co/functions/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://hvlmeoqyxaguzcujpmit.supabase.co/functions/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.

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 de Bazik (notre passerelle vers Digicel MonCash) et de Digicel. Nous les transmettons à l'identique — aucune marge ajoutée.

Frais détaillés

Nom / CodeType / LimiteDescription
Encaissement2,9 % (Bazik)Prélevé par Bazik sur chaque paiement entrant via MonCash. Sur 1 000 HTG encaissés, vous recevez 971 HTG.
Retrait MonCash5 % (Bazik)Prélevé par Bazik à 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, Business, Lifetime) 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.

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 (Bazik) — 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.