{"openapi":"3.1.0","info":{"title":"API YiriwaPay","version":"1","description":"Encaissez par Mobile Money (Orange Money, Moov Money, MTN MoMo, Wave, Free Money, Airtel Money, M-Pesa, Afrimoney et QMoney) au Burkina Faso, au Sénégal, en Côte d'Ivoire, au Bénin, au Cameroun, au Congo-Brazzaville, en RD Congo et en Gambie. Tous les montants sont des entiers, sans décimales. Le champ currency indique la devise du paiement (XOF, XAF, CDF, GMD selon le pays du compte). Le client peut payer dans la devise de son réseau si un taux direct est actif ; XOF/XAF restent à parité fixe 1:1. La clé secrète se met uniquement sur votre serveur. Documentation : https://yiriwapay.com/docs"},"servers":[{"url":"https://yiriwapay.com/api/v1"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Paiements"},{"name":"Solde"}],"paths":{"/payments":{"post":{"tags":["Paiements"],"summary":"Créer un paiement","description":"Renvoie `checkout_url` : redirigez votre client vers cette adresse. Le retour du client sur `success_url` ne prouve pas qu'il a payé : confirmez avec une notification ou `GET /payments/{id}`.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","maxLength":100},"description":"Valeur unique par commande : un nouvel essai renvoie le même paiement au lieu d'en créer un second."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePayment"}}}},"responses":{"201":{"description":"Paiement créé.","headers":{"X-RateLimit-Limit":{"description":"Requêtes permises par minute.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requêtes encore permises dans la minute en cours.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Fin de la minute en cours (heure Unix, secondes).","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Payment"}}}},"401":{"description":"Clé API absente, invalide ou révoquée (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Compte suspendu, ou mode live pas encore activé (account_suspended, live_not_enabled).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Clé d'idempotence réutilisée avec d'autres paramètres (conflict).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Données invalides : le message indique le champ (invalid_request).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Trop de requêtes (rate_limited). Rien n'a été fait : attendez Retry-After secondes puis réessayez.","headers":{"X-RateLimit-Limit":{"description":"Requêtes permises par minute.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requêtes encore permises dans la minute en cours.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Fin de la minute en cours (heure Unix, secondes).","schema":{"type":"integer"}},"Retry-After":{"description":"Secondes à attendre.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"tags":["Paiements"],"summary":"Lister vos paiements","description":"Du plus récent au plus ancien. Tant que `has_more` est vrai, redemandez avec `starting_after` = l'identifiant du dernier paiement reçu.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"starting_after","in":"query","schema":{"type":"string","format":"uuid"},"description":"Identifiant du dernier paiement de la page précédente."},{"name":"status","in":"query","schema":{"type":"string","enum":["created","pending","succeeded","failed","expired","cancelled"]}},{"name":"reference","in":"query","schema":{"type":"string"},"description":"Référence exacte de votre commande."}],"responses":{"200":{"description":"Liste de paiements.","headers":{"X-RateLimit-Limit":{"description":"Requêtes permises par minute.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requêtes encore permises dans la minute en cours.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Fin de la minute en cours (heure Unix, secondes).","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentList"}}}},"401":{"description":"Clé API absente, invalide ou révoquée (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Compte suspendu, ou mode live pas encore activé (account_suspended, live_not_enabled).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Trop de requêtes (rate_limited). Rien n'a été fait : attendez Retry-After secondes puis réessayez.","headers":{"X-RateLimit-Limit":{"description":"Requêtes permises par minute.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requêtes encore permises dans la minute en cours.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Fin de la minute en cours (heure Unix, secondes).","schema":{"type":"integer"}},"Retry-After":{"description":"Secondes à attendre.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/payments/{id}":{"get":{"tags":["Paiements"],"summary":"Lire un paiement","description":"Source de vérité : vérifiez que `status` vaut `succeeded` et que `amount` et `reference` correspondent à votre commande avant de livrer.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Identifiant du paiement."}],"responses":{"200":{"description":"Le paiement.","headers":{"X-RateLimit-Limit":{"description":"Requêtes permises par minute.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requêtes encore permises dans la minute en cours.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Fin de la minute en cours (heure Unix, secondes).","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Payment"}}}},"401":{"description":"Clé API absente, invalide ou révoquée (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Compte suspendu, ou mode live pas encore activé (account_suspended, live_not_enabled).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Paiement introuvable (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Trop de requêtes (rate_limited). Rien n'a été fait : attendez Retry-After secondes puis réessayez.","headers":{"X-RateLimit-Limit":{"description":"Requêtes permises par minute.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requêtes encore permises dans la minute en cours.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Fin de la minute en cours (heure Unix, secondes).","schema":{"type":"integer"}},"Retry-After":{"description":"Secondes à attendre.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/payments/{id}/cancel":{"post":{"tags":["Paiements"],"summary":"Annuler un paiement","description":"Possible seulement tant que le client n'a pas commencé à payer.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Identifiant du paiement."}],"responses":{"200":{"description":"Le paiement annulé.","headers":{"X-RateLimit-Limit":{"description":"Requêtes permises par minute.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requêtes encore permises dans la minute en cours.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Fin de la minute en cours (heure Unix, secondes).","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Payment"}}}},"401":{"description":"Clé API absente, invalide ou révoquée (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Compte suspendu, ou mode live pas encore activé (account_suspended, live_not_enabled).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Paiement introuvable (not_found).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Le paiement est déjà commencé (conflict).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Trop de requêtes (rate_limited). Rien n'a été fait : attendez Retry-After secondes puis réessayez.","headers":{"X-RateLimit-Limit":{"description":"Requêtes permises par minute.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requêtes encore permises dans la minute en cours.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Fin de la minute en cours (heure Unix, secondes).","schema":{"type":"integer"}},"Retry-After":{"description":"Secondes à attendre.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/balance":{"get":{"tags":["Solde"],"summary":"Lire vos soldes","description":"`available` est retirable ; `pending` attend la fin du délai de règlement.","responses":{"200":{"description":"Vos soldes.","headers":{"X-RateLimit-Limit":{"description":"Requêtes permises par minute.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requêtes encore permises dans la minute en cours.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Fin de la minute en cours (heure Unix, secondes).","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Balance"}}}},"401":{"description":"Clé API absente, invalide ou révoquée (invalid_api_key).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Compte suspendu, ou mode live pas encore activé (account_suspended, live_not_enabled).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Trop de requêtes (rate_limited). Rien n'a été fait : attendez Retry-After secondes puis réessayez.","headers":{"X-RateLimit-Limit":{"description":"Requêtes permises par minute.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requêtes encore permises dans la minute en cours.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Fin de la minute en cours (heure Unix, secondes).","schema":{"type":"integer"}},"Retry-After":{"description":"Secondes à attendre.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Clé secrète : `sk_test_…` (aucun argent réel) ou `sk_live_…` (argent réel). `Authorization: Bearer sk_test_…`"}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","examples":["invalid_request"]},"message":{"type":"string"}}}}},"CreatePayment":{"type":"object","required":["amount","reference"],"properties":{"amount":{"type":"integer","minimum":200,"maximum":1000000,"description":"Montant entier dans currency, ou dans la devise du compte si currency n'est pas précisée."},"reference":{"type":"string","minLength":1,"maxLength":100,"description":"Numéro de votre commande."},"description":{"type":"string","maxLength":500},"customer":{"type":"object","properties":{"name":{"type":"string","maxLength":120},"email":{"type":"string","format":"email","maxLength":200},"phone":{"type":"string","maxLength":30,"description":"Numéro local, avec ou sans indicatif."}}},"success_url":{"type":"string","format":"uri","description":"http(s) : retour du client après paiement."},"cancel_url":{"type":"string","format":"uri","description":"http(s) : retour du client après abandon."},"metadata":{"type":"object","maxProperties":20,"additionalProperties":{"type":["string","number","boolean","null"]},"description":"20 paires clé / valeur au plus, renvoyées dans les notifications."},"fee_payer":{"type":"string","enum":["merchant","customer"],"description":"Qui paie les frais. Par défaut : le réglage de votre compte."},"currency":{"type":"string","enum":["XOF","XAF","CDF","GMD"],"description":"Devise du paiement. Par défaut : celle de votre compte."},"expires_in_minutes":{"type":"integer","minimum":5,"maximum":1440,"default":30}}},"Payment":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"object":{"const":"payment"},"reference":{"type":"string"},"status":{"type":"string","enum":["created","pending","succeeded","failed","expired","cancelled"]},"amount":{"type":"integer","description":"Montant demandé."},"charged_amount":{"type":"integer","description":"Ce que le client paie, dans charged_currency."},"fee_amount":{"type":"integer","description":"Frais YiriwaPay, dans charged_currency (estimation tant que le client n'a pas choisi son réseau)."},"net_amount":{"type":"integer","description":"Net crédité au marchand, dans currency."},"currency":{"type":"string","enum":["XOF","XAF","CDF","GMD"]},"charged_currency":{"type":"string","enum":["XOF","XAF","CDF","GMD"],"description":"Devise débitée au client selon le pays du réseau choisi. Les autres conversions nécessitent un taux direct actif défini par l'administration ; l'inverse n'est pas automatique."},"fee_payer":{"type":"string","enum":["merchant","customer"]},"operator":{"type":["string","null"]},"description":{"type":["string","null"]},"metadata":{"type":"object"},"livemode":{"type":"boolean"},"checkout_url":{"type":"string","format":"uri"},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"paid_at":{"type":["string","null"],"format":"date-time"},"failure_reason":{"type":["string","null"]}}},"PaymentList":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Payment"}},"has_more":{"type":"boolean"}}},"Balance":{"type":"object","properties":{"object":{"const":"balance"},"livemode":{"type":"boolean"},"pending":{"type":"integer"},"available":{"type":"integer"},"currency":{"type":"string","enum":["XOF","XAF","CDF","GMD"]}}}}}}