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

# Airtel Money

> Airtel Africa Open API — sandbox openapiuat.airtel.africa

<div style={{ display: "inline-block", width: "1rem", height: "1rem", background: "#ED1C24", borderRadius: "2px", marginRight: "0.5rem", verticalAlign: "middle" }} />

**Airtel Money** — Open API merchant payments.

## Pays couverts

| Pays   | Code | Devise |
| ------ | ---- | ------ |
| Rwanda | RW   | RWF    |

D'autres marchés Airtel (Ouganda, Tanzanie, RDC…) seront ajoutés post-launch.

## URLs

| Type        | URL                                                          |
| ----------- | ------------------------------------------------------------ |
| Portail dev | [developers.airtel.africa](https://developers.airtel.africa) |
| Sandbox UAT | `https://openapiuat.airtel.africa`                           |
| Token OAuth | `https://openapiuat.airtel.africa/auth/oauth2/token`         |
| Payment     | `https://openapiuat.airtel.africa/merchant/v1/payments/`     |
| USSD client | `*185#`                                                      |

## Credentials requis

À renseigner dans **Settings → Stores → Airtel** :

| Champ           | Type     | Description                                      |
| --------------- | -------- | ------------------------------------------------ |
| `client_id`     | text     | OAuth `client_id` de votre app Airtel Developer. |
| `client_secret` | password | Secret OAuth associé.                            |

## Particularités

* **OAuth client\_credentials avec corps JSON** : contrairement à Orange (qui attend du `x-www-form-urlencoded`), Airtel exige un corps JSON `{ "client_id": ..., "client_secret": ..., "grant_type": "client_credentials" }` sur le token endpoint. SandPay gère cette variante via `oauthClientCredentialsJsonBody`.
* En-têtes `X-Country` et `X-Currency` obligatoires sur l'appel `POST /merchant/v1/payments/` — déduits du MSISDN ou explicitement passés via le champ `country`.
* `msisdn` envoyé **sans le `+`** dans le subscriber.
* Le payload Airtel sépare `subscriber` (le payeur) et `transaction` (le mouvement) — SandPay copie `reference` dans les deux champs `id` pour rester idempotent.
* Réponse imbriquée : `data.transaction.id` — c'est cette valeur qui est stockée comme `provider_tx_id`.

## Voir aussi

* [Scénarios](/fr/scenarios) — driver de résultat indépendant de l'opérateur
* [MTN](/fr/operators/mtn), [Orange](/fr/operators/orange), [Moov](/fr/operators/moov)
