Documentation développeur
API Produits
Lis et exporte tes données Mepaye — produits, ventes, clients, boutique, codes promo, licences — vers ton site, ton app ou ton outil interne. API REST, lecture seule, format aligné Chariow.
Deux APIs distinctes
- API Produits (cette page) — menu
Clés API, scopes*:read, sans KYC. Sert à LIRE tes données. - API Paiement — menu
Développeur, scopepayments:write, KYC requis. Sert à ENCAISSER via pay.mepaye.com. Voir la doc Paiement →
👉 Pour accepter des paiements, utilise l'API Paiement. Cette API-ci sert à lire tes données.
Introduction
API REST/JSON. Base URL : https://mepaye.com/api/v1. Toutes les ressources sont en lecture seule (verbe GETuniquement) et scopées à ta boutique : une clé ne voit jamais les données d'une autre boutique.
Champs en snake_case, dates en ISO 8601 UTC, montants en minor units (voir Format). Si tu gères plusieurs boutiques, précise laquelle avec l'en-tête X-Store-Id.
Authentification
Crée une clé read-only dans le menu Clés API — aucun KYC requis(contrairement à l'API Paiement). Authentifie chaque requête :
Authorization: Bearer mp_live_xxxxxxxx
# ou : X-Api-Key: mp_live_xxxxxxxxChaque clé porte une liste de scopes ; un endpoint exige le sien :
store:read— la boutiqueproducts:read— les produitssales:read— les ventescustomers:read— les clientsdiscounts:read— les codes promolicenses:read— les clés de licence
Limite : 100 requêtes/minute par clé (en-têtes X-RateLimit-Remaining / X-RateLimit-Reset, puis 429 + Retry-After). Garde la clé côté serveur.
Format des réponses
Toute réponse est une enveloppe uniforme :
{
"message": "success",
"data": { /* objet, ou { data: [...], pagination: {...} } pour les listes */ },
"errors": []
}Pagination (curseur)
Les listes renvoient data.data (les éléments) + data.pagination. Contrôle la taille avec per_page (défaut 20, max 100) et avance avec cursor :
{
"message": "success",
"data": {
"data": [ /* … les éléments de la page … */ ],
"pagination": {
"next_cursor": "cmp6ljlhl0066jrmw33nbddkz",
"prev_cursor": null,
"has_more": true
}
},
"errors": []
}# Page 1
curl -H "Authorization: Bearer mp_live_xxx" \
"https://mepaye.com/api/v1/sales?per_page=50"
# → data.pagination.next_cursor = "cmqxshpz5001ojr40e071659h", has_more = true
# Page suivante : repasse le next_cursor reçu
curl -H "Authorization: Bearer mp_live_xxx" \
"https://mepaye.com/api/v1/sales?per_page=50&cursor=cmqxshpz5001ojr40e071659h"
# Boucle tant que has_more === true.next_cursor est null et has_more vaut false sur la dernière page.
Montants — minor units
⚠️ Tous les montants sont des entiers en minor units de leur devise (pas de décimales dans value). C'est la différence clé avec un format décimal : on évite toute erreur d'arrondi. Les champs formatted / shortsont fournis pour l'affichage.
"current_price": {
"value": 25000, // ENTIER en minor units (centimes)
"formatted": "25 000 XOF",
"short": "25000",
"currency": "XOF"
}
// XOF/XAF/GNF/CDF (0 décimale) : value = unité entière → 25000 = 25 000 FCFA
// EUR/USD (2 décimales) : value = centimes → 2599 = 25,99 €Store
GET/api/v1/store
Profil de ta boutique. Scope store:read. id préfixé str_.
curl -H "Authorization: Bearer mp_live_xxx" \
"https://mepaye.com/api/v1/store"{
"message": "success",
"data": {
"id": "str_cmo9u8zse0001jrof6fhec8rv",
"name": "Ma Boutique",
"slug": "ma-boutique",
"tagline": "Formations & guides",
"description": null,
"logo_url": null,
"favicon_url": null,
"cover_url": null,
"url": "https://ma-boutique.mepaye.shop",
"currency": "XOF",
"primary_color": "#10B981",
"seo": { "title": null, "description": null },
"refund_policy_days": 7,
"is_verified": true,
"created_at": "2026-04-22T09:16:29.871Z",
"updated_at": "2026-06-29T07:37:16.495Z"
},
"errors": []
}Products
GET/api/v1/products
GET/api/v1/products/{id}
Catalogue. Scope products:read. Filtres : search (nom), category, type, per_page, cursor.
curl -H "Authorization: Bearer mp_live_xxxxxxxx" \
"https://mepaye.com/api/v1/products?per_page=20"{
"id": "cmp6ljlhl0066jrmw33nbddkz",
"name": "Guide Chine",
"slug": "guide-chine",
"type": "downloadable",
"status": "PUBLISHED",
"category": { "value": "business_&_entrepreneuriat", "label": "Business & Entrepreneuriat" },
"is_free": false,
"pictures": {
"thumbnail": "/uploads/2026/05/7ec0…IMG_8975.png",
"cover": "/uploads/2026/05/7ec0…IMG_8975.png"
},
"pricing": {
"type": "one_time",
"current_price": { "value": 10000, "formatted": "10 000 XOF", "short": "10000", "currency": "XOF" },
"price": { "value": 10000, "formatted": "10 000 XOF", "short": "10000", "currency": "XOF" }
},
"tagline": null,
"refund_policy_days": 7,
"created_at": "2026-05-15T07:29:11.817Z",
"sales_count": 13,
"reviews_count": 0
}Types de produit (type)
downloadable | Ebook, template, fichier téléchargeable |
course | Formation / cours en ligne |
coaching | Coaching / accompagnement |
bundle | Pack de plusieurs produits |
license | Produit à clé de licence |
service | Service, communauté, prestation |
category.value est un slug best-effort, category.labell'intitulé lisible. Le détail/products/{id} renvoie le même objet pour un produit unique.
Sales
GET/api/v1/sales
GET/api/v1/sales/{id}
Commandes (tout le cycle de vie, pas seulement les payées). Scope sales:read. Filtres : status, customer_id, search, start_date, end_date (YYYY-MM-DD).
curl -H "Authorization: Bearer mp_live_xxx" \
"https://mepaye.com/api/v1/sales?status=completed&per_page=50"{
"id": "cmqxshpz5001ojr40e071659h",
"reference": "MEP-20260628-CB7866",
"status": "completed",
"refunded_at": null,
"original_amount": { "value": 25000, "formatted": "25 000 XOF", "short": "25000", "currency": "XOF" },
"amount": { "value": 25000, "formatted": "25 000 XOF", "short": "25000", "currency": "XOF" },
"discount_amount": { "value": 0, "formatted": "0 XOF", "short": "0", "currency": "XOF" },
"payment": { "amount": { "value": 25000, "currency": "XOF" }, "status": "success", "exchange_rate": 1 },
"product": { "id": "cmp6l0wf9005jjrmwlztzgtiu", "name": "Guide Chine", "type": "downloadable" },
"customer": { "id": "cus_YXdhQGV4ZW1wbGUuY29t", "email": "awa@exemple.com", "name": "Awa Diop", "country": "BJ" },
"discount": null,
"store": { "id": "cmo9u8zse0001jrof6fhec8rv", "name": "Ma Boutique", "slug": "ma-boutique" },
"post_purchase": {
"files": [
{ "id": "cmp6lfy020064jrmwu5phw9yv", "name": "guide.pdf", "size": 419348,
"download_url": "https://mepaye.com/api/download/eyJmaWxlSWQi…" }
],
"licences": [],
"instructions": null
},
"created_at": "2026-06-28T12:53:10.722Z",
"paid_at": "2026-06-28T12:55:23.243Z"
}Statuts (status)
awaiting_payment | Order PENDING — paiement initié, pas encore confirmé |
completed | Order PAID — payé (ou remboursé : voir refunded_at) |
failed | Order FAILED — paiement échoué |
abandoned | Order CANCELLED — abandonné / annulé |
Téléchargements sécurisés : pour une vente payée, chaque fichier de post_purchase.files porte un download_url signé et expirant (token /api/download/…, ~24 h) — jamais un chemin /uploads brut. customer.id (cus_*) relie la vente à Customers.
Customers
GET/api/v1/customers
GET/api/v1/customers/{id}
Clients agrégés par email. Scope customers:read. Filtres : search, start_date, end_date.
curl -H "Authorization: Bearer mp_live_xxx" \
"https://mepaye.com/api/v1/customers?search=awa"{
"id": "cus_YXdhQGV4ZW1wbGUuY29t",
"name": "Awa Diop",
"first_name": "Awa",
"last_name": "Diop",
"email": "awa@exemple.com",
"avatar_url": null,
"phone": { "number": "+221770000000", "country": null },
"store": {
"id": "cmo9u8zse0001jrof6fhec8rv",
"name": "Ma Boutique",
"logo_url": null,
"url": "https://ma-boutique.mepaye.shop"
},
"created_at": "2026-04-25T17:41:30.610Z",
"updated_at": "2026-04-25T17:41:30.610Z"
}Le customer_id (cus_*) est stable et déterministe(dérivé de l'email) : le même client porte le même id sur Sales et Customers. Récupère toutes ses commandes via /api/v1/sales?customer_id=cus_….
Discounts
GET/api/v1/discounts
GET/api/v1/discounts/{id}
Codes promo. Scope discounts:read. Filtre : search (code). id préfixé dis_.
curl -H "Authorization: Bearer mp_live_xxx" \
"https://mepaye.com/api/v1/discounts"{
"id": "dis_cmqzbw3rk0001jr2i6hl2zyf6",
"code": "BIENVENUE25",
"type": "percentage", // ou "fixed" (montant en minor units)
"value": 25, // 25 = -25 % · pour "fixed" : minor units
"is_active": true,
"expires_at": null,
"max_uses": 100,
"used_count": 3,
"min_order_xof_cents": null,
"created_at": "2026-06-29T14:44:00.656Z"
}type: "percentage" → value est un pourcentage (0–100). type: "fixed" → value est un montant en minor units.
Licenses
GET/api/v1/licenses
GET/api/v1/licenses/{id}
Clés de licence de tes produits. Scope licenses:read. Filtre : status (available / used). id préfixé lic_.
curl -H "Authorization: Bearer mp_live_xxx" \
"https://mepaye.com/api/v1/licenses?status=available"{
"id": "lic_cmqzbw3rv0003jr2ifk5u3w72",
"key": "XXXX-YYYY-ZZZZ-1234",
"status": "available", // "available" | "used"
"product": { "id": "cmp6of1fm002cjr3rga7gq3bq", "name": "Mon logiciel", "type": "license" },
"customer": null, // { id (cus_*), email, name } une fois attribuée
"used_at": null,
"created_at": "2026-06-29T14:44:00.668Z"
}activate / revoke / activations : Mepaye livreles clés, il n'est pas serveur d'activation. status reflète l'attribution (available → useddès qu'une clé est rattachée à une commande).Codes d'erreur
Même enveloppe en cas d'erreur : message = libellé HTTP, data = [], errors = messages lisibles.
{
"message": "Forbidden",
"data": [],
"errors": ["Cette clé n'a pas le scope requis (products:read)."]
}| HTTP | message | Signification |
|---|---|---|
| 401 | Unauthorised | Clé API manquante ou invalide (header Authorization / X-Api-Key). |
| 403 | Forbidden | La clé n'a pas le scope requis (ex. products:read). |
| 404 | Not Found | Ressource introuvable (ou hors de ta boutique). |
| 429 | Too Many Requests | Plus de 100 requêtes/minute pour cette clé. Voir Retry-After. |
Les filtres inconnus (ex. type ou status non reconnu) sont ignorés gracieusement plutôt que rejetés.
Prêt ? Crée ta clé read-only dans le menu Clés API. Besoin d'encaisser plutôt que de lire ? API Paiement →