> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sahelpay.ml/llms.txt
> Use this file to discover all available pages before exploring further.

# API Overview

> Vue d'ensemble de l'API SahelPay

# API Reference

L'API SahelPay est une API REST qui utilise JSON pour les requêtes et réponses.

## Base URL

| Environnement | URL |
| - | - |
| **Sandbox** | `https://api.sahelpay.ml` |
| **Production** | `https://api.sahelpay.ml` |

Le mode est déterminé par la clé (`sk_test_...` ou `sk_live_...`). Pour le simulateur SahelPay sans appel opérateur, ajoutez `metadata.sahelpay_mock: true` à la création du paiement ; `metadata.sandbox: true` appelle l'environnement de test d'Orange.

## Authentification

Toutes les requêtes marchandes incluent votre clé secrète :

```bash theme={null}
Authorization: Bearer sk_test_xxx
```

Une clé live n'est acceptée qu'avec un compte ouvert en production et un abonnement payé en cours (voir [Authentification](/authentication)).

## Format des réponses

### Succès

```json theme={null}
{
  "success": true,
  "data": {
    // Données de la ressource
  }
}
```

### Erreur

```json theme={null}
{
  "success": false,
  "error": {
    "code": "IDEMPOTENCY_KEY_REQUIRED",
    "message": "Le header X-Idempotency-Key est requis pour cette opération"
  }
}
```

Voir [Codes d'erreur](/resources/error-codes).

## Codes HTTP

| Code | Description |
| - | - |
| `200` / `201` | Succès |
| `400` | Requête invalide |
| `401` | Non authentifié |
| `403` | Accès refusé (abonnement, plafond, éligibilité) |
| `404` | Ressource non trouvée |
| `409` | Conflit (idempotence, frais modifiés) |
| `429` | Rate limit dépassé |
| `5xx` | Erreur serveur ou service indisponible |

## Rate limiting

Limite par défaut : **100 requêtes par minute**. Certaines routes sont plus strictes, notamment `POST /v1/payments` (10 par minute), `POST /v1/payments/{id}/reconcile` (10 par minute) et `POST /v1/webhooks/test` (5 par minute). Au-delà : `429 RATE_LIMIT_EXCEEDED`.

## Idempotence

`X-Idempotency-Key` (128 caractères maximum) est **obligatoire** sur `POST /v1/payments` et `POST /v1/withdrawals`, recommandé sur `POST /v1/secure-orders`. La même clé rejouée avec la même demande renvoie le même résultat ; avec une demande différente, la requête est refusée (`409`).

## Endpoints disponibles

### Paiements

| Endpoint | Méthode | Description |
| - | - | - |
| `/v1/payments` | `POST` | Créer un paiement Orange Money |
| `/v1/payments/{id}/status` | `GET` | Statut d'un paiement (clé secrète) |
| `/v1/payments/{id}` | `GET` | Statut public (sans clé, utilisé par les pages de paiement) |
| `/v1/payments/{id}/details` | `GET` | Détails complets (frais, écritures) |
| `/v1/payments/{id}/reconcile` | `POST` | Revérifier auprès de l'opérateur |
| `/v1/payments/{id}/expire` | `POST` | Expirer un paiement non terminal dont `expires_at` est dépassé (émet `payment.expired`) |
| `/v1/payments/search` | `GET` | Rechercher par `client_reference` |
| `/v1/payments/history` | `GET` | Historique (voir la limite documentée) |

### Liens de paiement

| Endpoint | Méthode | Description |
| - | - | - |
| `/v1/payment-links` | `POST` | Créer un lien de paiement |
| `/v1/payment-links` | `GET` | Lister vos liens |
| `/v1/payment-links/{slug}` | `GET` | Lien public par slug |
| `/v1/payment-links/{id}/activate` | `PATCH` | Activer un lien |
| `/v1/payment-links/{id}/deactivate` | `PATCH` | Désactiver un lien |
| `/v1/payment-links/{slug}/qr` | `GET` | QR code du lien |

### Retraits

| Endpoint | Méthode | Description |
| - | - | - |
| `/v1/withdrawals` | `POST` | Demande de retrait (traitement manuel) |
| `/v1/withdrawals` | `GET` | Lister les retraits |
| `/v1/withdrawals/balance` | `GET` | Solde disponible |
| `/v1/withdrawals/quote` | `GET` | Frais avant confirmation |
| `/v1/withdrawals/{id}/cancel` | `PATCH` | Annuler une demande `PENDING` |

### Paiement sécurisé à la livraison (pilote)

| Endpoint | Méthode | Description |
| - | - | - |
| `/v1/secure-orders` | `POST` | Créer |
| `/v1/secure-orders` | `GET` | Lister |
| `/v1/secure-orders/{id}` | `GET` | Détail |
| `/v1/secure-orders/{id}/confirm-delivery` | `POST` | Confirmer la livraison avec le code |
| `/v1/secure-orders/{id}/cancel` | `POST` | Annuler ou rembourser |

### Abonnements clients

| Endpoint | Méthode | Description |
| - | - | - |
| `/v1/billing/plans` | `POST` / `GET` | Créer / lister les plans |
| `/v1/billing/plans/{id}` | `PATCH` / `DELETE` | Modifier / supprimer (ou désactiver) un plan |
| `/v1/billing/subscriptions` | `POST` / `GET` | Créer / lister les abonnements |
| `/v1/billing/subscriptions/with-payment` | `POST` | Abonnement + premier lien de paiement |
| `/v1/billing/subscriptions/{id}` | `DELETE` | Annuler un abonnement |
| `/v1/billing/customers` | `GET` | Lister vos clients |
| `/v1/public/plans?merchant_id=` | `GET` | Plans publics (sans clé) |

### Programme Partenaires SPAY

| Endpoint | Méthode | Description |
| - | - | - |
| `/v1/merchants/partner-products` | `GET` / `POST` | Catalogue / proposer un produit |
| `/v1/merchants/partner-products/{id}` | `PATCH` / `DELETE` | Modifier (nouvelle validation) / archiver |

### Customer Portal

| Endpoint | Méthode | Description |
| - | - | - |
| `/v1/portal/sessions` | `POST` | Créer une session portail client |

### Remboursements

| Endpoint | Méthode | Description |
| - | - | - |
| `/v1/refunds` | `POST` | **Indisponible** (réponse `503`) |

### Webhooks

| Endpoint | Méthode | Description |
| - | - | - |
| `/v1/webhooks/test` | `POST` | Envoyer `webhook.test` vers l'URL configurée |
| `/v1/webhooks/logs` | `GET` | Historique des livraisons |
| `/v1/webhooks/logs/{id}/retry` | `POST` | Relancer une livraison |

### Utilitaires

| Endpoint | Méthode | Description |
| - | - | - |
| `/v1/providers/enabled` | `GET` | Disponibilité d'Orange Money (public) |
| `/v1/sahelpay/plans` | `GET` | Forfaits SahelPay (public) |
| `/v1/merchant/plan` | `GET` | Votre forfait SahelPay |
| `/v1/merchant/subscription` | `GET` | Votre abonnement SahelPay |

<Note>
  Non disponibles : `POST /v1/payouts` (payouts automatiques, refusés), les splits et le flux OPR en production.
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.