API Cartes
Des cartes pour tes clients
Cartes virtuelles USD émises par API. Les pièces du porteur sont transmises par API, l'identité est vérifiée par Monniz, l'émission exige un porteur approuvé.
Le principe
L'émission exige un porteur dont l'identité a été vérifiée par Monniz. Les pièces — photo de la pièce d'identité et selfie — sont transmises via POST /v1/issuing/cardholders/{id}/documents, la vérification est effectuée par Monniz et l'issue est notifiée par cardholder.approved ou cardholder.rejected.
pending : porteur créé, pièces non déposées · in_review : pièces déposées, vérification en cours · approved : émission possible · rejected : motif transmis, un nouveau dépôt est accepté sur le même porteur.
Démarrage rapide
- 1
Génère ta clé test
Dans Paramètres → Développeur — la clé n'est affichée qu'une fois.
- 2
Déclare ton client
bashcurl -X POST "https://api.monniz.shop/v1/issuing/cardholders" \ -H "Authorization: Bearer mnz_sk_test_..." \ -H "Content-Type: application/json" \ -d '{ "first_name": "Aminata", "last_name": "Diallo", "email": "[email protected]", "external_ref": "cli_4821" }' - 3
Transmets ses pièces
Pièce d'identité et selfie se déposent sur
/cardholders/{id}/documentsenmultipart/form-data. Le dossier passe enin_review. - 4
Émets une fois le porteur approuvé
Le webhook
cardholder.approvedsignale l'approbation.POST /v1/issuing/cardsémet la carte, débitée de ton wallet Business.
Le mode test simule tout sauf la vérification
Porteurs
- POST
/v1/issuing/cardholdersDéclarer un client et ouvrir sa vérification - GET
/v1/issuing/cardholdersListe — filtre status - GET
/v1/issuing/cardholders/{id}Statut courant + can_issue_card - POST
/v1/issuing/cardholders/{id}/documentsDéposer les pièces (multipart)
{
"success": true,
"data": {
"cardholder": {
"id": "chd_01J8XKQ2M4N7P9R2S5T8V1W4X7",
"status": "pending",
"can_issue_card": false,
"email": "[email protected]",
"external_ref": "cli_4821"
},
"created": true
}
}À la déclaration, quatre champs optionnels complètent le dossier : phone, country_code (code ISO-3166 à 2 lettres, ex. BJ), date_of_birth (format YYYY-MM-DD, forcément dans le passé) et metadata (objet libre pour tes propres données, rendu tel quel).
Rejouer la création ne crée pas de doublon
created: false, sans double dépôt.L'état civil déclaré ne fait pas foi
Vérification d'identité
Les pièces — photo de la pièce d'identité (recto, verso le cas échéant) et photo du visage — se déposent en multipart/form-data sur /cardholders/{id}/documents. Le dossier passe en in_review ; la vérification est effectuée par Monniz.
curl -X POST "https://api.monniz.shop/v1/issuing/cardholders/chd_01J8XKQ2M4N7P9R2S5T8V1W4X7/documents" \ -H "Authorization: Bearer mnz_sk_test_..." \ -F "[email protected]" \ -F "[email protected]" \ -F "[email protected]" \ -F "id_document_type=national_id" \ -F "id_document_number=BJ0123456" \ -F "date_of_birth=1994-07-12"
Formats acceptés
JPG, PNG, WEBP et HEIC — PDF accepté pour la pièce uniquement. 8 Mo par fichier.
Redépôt après un refus
Un nouveau dépôt sur le même porteur remplace le précédent en entier : tous les fichiers doivent être renvoyés, pas seulement celui corrigé.
Tu es responsable des documents que tu détiens
Ce que l'API restitue d'un porteur
Émettre une carte
curl -X POST "https://api.monniz.shop/v1/issuing/cards" \
-H "Authorization: Bearer mnz_sk_test_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 8f4e2a10-77b3-4c1e-9b1a-2d6c58c01a42" \
-d '{
"cardholder": "chd_01J8XKQ2M4N7P9R2S5T8V1W4X7",
"label": "Carte Aminata",
"brand": "VISA",
"initial_funding_usd_cents": 2000
}'monthly_limit_usd_cents (entier ≥ 0, optionnel) fixe le plafond mensuel de dépenses de la carte, en cents USD.
L'émission est asynchrone
card.created confirme l'existence de la carte. L'en-tête Idempotency-Key est obligatoire sur POST /v1/issuing/cards, POST /v1/issuing/cards/{id}/fund et POST /v1/issuing/cards/{id}/terminate — sans lui, la requête est refusée (428).Débit sur le wallet Business
Tarification
Le bloc cost est le montant débité du wallet Business.
- GET
/v1/issuing/pricingLa grille : taux, prix de carte, frais, bornes - POST
/v1/issuing/quoteChiffrer une opération — ne débite rien
{
"success": true,
"data": {
"pricing": {
"currency": "XOF",
"cost": {
"fx_xof_per_usd": 605,
"card_price_xof": 5000,
"funding_provider_fee_usd": 1,
"funding_provider_fee_xof": 605
},
"limits": { "min_fund_usd": 5, "max_fund_usd": 5000, "max_cards_per_cardholder": 3 }
}
}
}curl -X POST "https://api.monniz.shop/v1/issuing/quote" \
-H "Authorization: Bearer mnz_sk_test_..." \
-H "Content-Type: application/json" \
-d '{ "include_card": true, "funding_usd_cents": 2000 }'{
"success": true,
"data": {
"quote": {
"currency": "XOF",
"funding_usd_cents": 2000,
"cost": { "card_xof": 5000, "funding_xof": 12100, "provider_fee_xof": 605, "total_xof": 17705 },
"fx_xof_per_usd": 605,
"funding_within_limits": true
}
}
}Le frais fixe fournisseur s'applique à tout financement
funding_usd_cents est supérieur à zéro, le frais fixe fournisseur s'ajoute. standalone_funding est déprécié et sans effet. Les réponses de POST /cards et POST /cards/{id}/fund incluent déjà le bloc pricing.Piloter une carte
- GET
/v1/issuing/cardsListe — filtre cardholder - GET
/v1/issuing/cards/{id}Détail + solde à jour - GET
/v1/issuing/cards/{id}/transactionsOpérations de la carte - POST
/v1/issuing/cards/{id}/fundRecharger (amount_usd_cents) - POST
/v1/issuing/cards/{id}/freezeBloquer temporairement - POST
/v1/issuing/cards/{id}/unfreezeDébloquer - POST
/v1/issuing/cards/{id}/terminateRésilier — définitif
Le numéro complet ne passe pas par l'API
Webhooks
L'endpoint se configure dans l'onglet Développeur. Les événements sont signés t=…,v1=… ; la signature se vérifie avec le secret whsec_….
cardholder.submitted pièces déposées cardholder.approved identité vérifiée — émission possible cardholder.rejected refusé, avec rejection_reason card.created carte active card.creation_failed échec fournisseur card.terminated carte résiliée
cardholder.approved et card.created
cardholder.approved signale qu'une carte peut être émise ; card.created que la carte existe. GET /v1/issuing/cardholders/{id} rend le même statut.Limites & conditions
KYB obligatoire
Ton propre business doit être vérifié (KYB), en test comme en live.
Étanchéité test/live
Un porteur créé en test ne peut pas porter une carte live.
Cartes par porteur
Le plafond max_cards_per_cardholder s'applique par porteur, pas par compte.
Devise
Cartes virtuelles en USD. Ton wallet est en XOF : la conversion se fait au débit, au taux du moment.
Aller plus loin
Prêt à proposer des cartes ?
Ouvre ton compte, génère ta clé test et déclare ton premier porteur en cinq minutes.