{"openapi":"3.0.3","info":{"title":"AxiaPayHub API","version":"2026-07-16","description":"Agrégateur de paiement mobile money multi-pays. Toutes les routes exigent Authorization: Bearer <clé secrète> (axp_sk_test_… en sandbox, axp_sk_live_… en production) sauf indication contraire."},"servers":[{"url":"https://axiapayhub.com"}],"components":{"securitySchemes":{"secretKey":{"type":"http","scheme":"bearer","bearerFormat":"axp_sk_*"}},"schemas":{"Error":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string"},"code":{"type":"string","enum":["missing_api_key","invalid_api_key","server_error","country_required","country_not_activated","not_business","kyb_required","session_not_found","forbidden","already_paid","session_expired","insufficient_balance","provider_validation","provider_error","rate_limited"]}}},"Operator":{"type":"object","required":["name","slug","requiresOtp"],"properties":{"name":{"type":"string","example":"Orange Money Sénégal"},"slug":{"type":"string","example":"orange-sn"},"requiresOtp":{"type":"boolean"},"ussdCode":{"type":"string","nullable":true,"example":"#144#391*CODE#"}}},"PayinSession":{"type":"object","required":["sessionId","status","amount","currency","country","reference","fees","totals","operators","expiresAt","createdAt","env"],"properties":{"sessionId":{"type":"string","example":"payin_9c1a…"},"status":{"type":"string","enum":["en_attente"]},"amount":{"type":"number","example":15000},"currency":{"type":"string","example":"XOF"},"country":{"type":"string","example":"SN"},"reference":{"type":"string"},"description":{"type":"string","nullable":true},"metadata":{"type":"object","nullable":true,"additionalProperties":true},"fees":{"type":"object","properties":{"percent":{"type":"number","example":6},"amount":{"type":"number","example":900},"description":{"type":"string"}}},"totals":{"type":"object","properties":{"clientPays":{"type":"number","example":15900},"youReceive":{"type":"number","example":15000},"afterFees":{"type":"number","example":14100}}},"operators":{"type":"array","items":{"$ref":"#/components/schemas/Operator"}},"expiresAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"env":{"type":"string","enum":["sandbox","production"]}}},"PayinConfirmResponse":{"type":"object","properties":{"sessionId":{"type":"string"},"status":{"type":"string","enum":["confirmé","otp_required"]},"message":{"type":"string"},"otpRequired":{"type":"boolean"},"operator":{"type":"string"},"ussdCode":{"type":"string","nullable":true},"transactionId":{"type":"string","nullable":true}}},"PayinStatus":{"type":"object","properties":{"sessionId":{"type":"string","example":"payin_9c1a…"},"status":{"type":"string","example":"paye"},"amount":{"type":"number","example":15000},"currency":{"type":"string","example":"XOF"},"country":{"type":"string","example":"SN"},"reference":{"type":"string","example":"cmd-4821"},"operator":{"type":"string","nullable":true,"example":"orange"},"payer":{"type":"object","nullable":true,"additionalProperties":true},"customer":{"type":"object","nullable":true,"additionalProperties":true},"metadata":{"type":"object","nullable":true,"additionalProperties":true},"transactionId":{"type":"string","nullable":true,"example":"sebpay_tx_xxx"},"fees":{"type":"number","nullable":true,"example":900},"netCredited":{"type":"number","nullable":true,"example":14100},"env":{"type":"string","enum":["sandbox","production"]},"expiresAt":{"type":"string","format":"date-time"},"paidAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time","nullable":true}}},"PayoutResponse":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"externalReference":{"type":"string","example":"axp_out_…"},"transactionId":{"type":"string","nullable":true},"status":{"type":"string","enum":["processing"]},"amount":{"type":"number"},"currency":{"type":"string"},"country":{"type":"string"},"env":{"type":"string","enum":["sandbox","production"]}}},"PayoutStatus":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","example":"reussi"},"amount":{"type":"number"},"currency":{"type":"string"},"country":{"type":"string"},"operator":{"type":"string","nullable":true},"fees":{"type":"number","nullable":true},"totalDebit":{"type":"number","nullable":true},"beneficiary":{"type":"object","additionalProperties":true},"externalReference":{"type":"string"},"transactionId":{"type":"string","nullable":true},"env":{"type":"string","enum":["sandbox","production"]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time","nullable":true}}}}},"security":[{"secretKey":[]}],"paths":{"/api/public/v1/operators":{"get":{"summary":"Liste les opérateurs mobile money activés pour un pays","security":[],"parameters":[{"name":"country","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":2}},{"name":"service","in":"query","required":false,"schema":{"type":"string","enum":["payin","payout"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"country":{"type":"string"},"service":{"type":"string"},"operators":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"slug":{"type":"string"},"otp_required":{"type":"boolean"},"ussd_code":{"type":"string","nullable":true}}}}}}}}}}}},"/api/public/v1/payins":{"post":{"summary":"Créer une session de collecte (payin)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amount","currency","country","reference"],"properties":{"amount":{"type":"number","minimum":1},"currency":{"type":"string","minLength":3,"maxLength":3},"country":{"type":"string","minLength":2,"maxLength":2},"reference":{"type":"string","minLength":1,"maxLength":120},"description":{"type":"string","maxLength":500},"metadata":{"type":"object","additionalProperties":true},"customer":{"type":"object","properties":{"email":{"type":"string","format":"email"},"phone":{"type":"string"}}},"ttlSeconds":{"type":"integer","minimum":60,"maximum":86400}}}}}},"responses":{"201":{"description":"Session créée","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayinSession"}}}},"401":{"description":"Clé API manquante ou invalide","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Pays non activé sur ce compte","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit dépassé","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/v1/payins/{sessionId}/confirm":{"post":{"summary":"Confirmer la collecte avec le numéro + opérateur saisis par le payeur","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["phone","operator"],"properties":{"phone":{"type":"string","minLength":4,"maxLength":32},"operator":{"type":"string","minLength":2,"maxLength":64},"otp":{"type":"string","minLength":3,"maxLength":12}}}}}},"responses":{"200":{"description":"En cours ou OTP requis","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayinConfirmResponse"}}}},"403":{"description":"Session appartient à un autre compte","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Session introuvable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Session expirée, déjà payée, ou validation opérateur/OTP","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Erreur remontée par SebPay","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/v1/payins/{sessionId}":{"get":{"summary":"Récupérer le statut d'une collecte (sessionId, reference ou transactionId)","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Statut courant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayinStatus"}}}},"403":{"description":"Session appartient à un autre compte","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Session introuvable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/v1/payins/{sessionId}/status":{"get":{"summary":"Alias explicite pour récupérer le statut d'une collecte","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Statut courant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayinStatus"}}}},"404":{"description":"Session introuvable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/v1/payouts/{id}":{"get":{"summary":"Récupérer le statut d'un payout (id, external_reference ou transactionId)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Statut courant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayoutStatus"}}}},"404":{"description":"Payout introuvable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/v1/payouts/{id}/status":{"get":{"summary":"Alias explicite pour récupérer le statut d'un payout","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Statut courant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayoutStatus"}}}},"404":{"description":"Payout introuvable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/public/v1/payouts":{"post":{"summary":"Payout instantané mobile money (comptes entreprise KYB uniquement)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["beneficiary_first_name","beneficiary_last_name","phone","operator","country","amount","currency"],"properties":{"beneficiary_first_name":{"type":"string","minLength":1,"maxLength":90},"beneficiary_last_name":{"type":"string","minLength":1,"maxLength":90},"phone":{"type":"string","minLength":6},"operator":{"type":"string","minLength":2},"country":{"type":"string","minLength":2,"maxLength":2},"amount":{"type":"number","minimum":1},"currency":{"type":"string","minLength":3,"maxLength":3},"description":{"type":"string","maxLength":200}}}}}},"responses":{"202":{"description":"Payout accepté, statut final par webhook","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayoutResponse"}}}},"403":{"description":"KYB requis ou pays non activé","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Solde insuffisant ou validation opérateur","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Erreur remontée par SebPay","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"x-webhooks":{"description":"AxiaPayHub POST vers chaque URL enregistrée dans /business → Webhooks. L'en-tête X-AxiaPay-Signature: sha256=<hex> est calculé sur le corps brut avec le secret de l'endpoint. X-Axia-Signature est aussi envoyé comme alias compatible.","events":[{"type":"payin.paye","example":{"id":"evt_abc123","type":"payin.paye","created_at":"2026-07-16T10:12:34.000Z","env":"production","data":{"sessionId":"payin_9c1a","reference":"cmd-4821","amount":15000,"currency":"XOF","country":"SN","fees":900,"netCredited":14100,"operator":"orange","transactionId":"sebpay_tx_xxx","payer":{"phone":"221701234567","msisdn":"221701234567","operator":"orange","country":"SN"},"customer":{"email":"client@example.com","phone":"+221701234567"},"metadata":{"userId":"user-123"}}}},{"type":"payin.echoue","example":{"id":"evt_abc124","type":"payin.echoue","created_at":"2026-07-16T10:12:34.000Z","env":"production","data":{"sessionId":"payin_9c1a","reference":"cmd-4821","reason":"rejected_by_provider"}}},{"type":"payout.reussi","example":{"id":"evt_abc125","type":"payout.reussi","created_at":"2026-07-16T10:12:34.000Z","env":"production","data":{"id":"…uuid…","externalReference":"axp_out_…","amount":50000,"currency":"XOF","country":"CI","operator":"orange","transactionId":"sebpay_tx_yyy"}}},{"type":"payout.echoue","example":{"id":"evt_abc126","type":"payout.echoue","created_at":"2026-07-16T10:12:34.000Z","env":"production","data":{"id":"…uuid…","externalReference":"axp_out_…","reason":"rejected_by_provider"}}}]}}