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

# Transactions

> Créer une transaction, consulter son statut et lister les transactions du compte.

Les trois opérations ci-dessous couvrent le cycle de vie d'une transaction : l'enregistrement de la
demande, la vérification de son statut réel, puis la relecture de l'ensemble des transactions du
compte. La section [Sandbox](#sandbox) en fin de page regroupe les valeurs de test à utiliser avant
un passage en production.

## Créer une transaction

Cette opération enregistre une demande de paiement pour le compte authentifié et renvoie les
références à conserver. Le statut renvoyé à la création n'est pas définitif : vérifiez toujours
le statut final côté serveur, avec [Consulter une transaction](#get-payments-reference)
ou via les [webhooks](/guides/webhooks), avant de livrer une commande.

Le compte doit être validé pour l'environnement ciblé : dans le cas contraire, l'API répond `403`
sans créer de transaction.

### En-têtes et environnements

Sandbox et Live sont deux comptes distincts, avec des clés distinctes : une clé Sandbox utilisée
avec `Ipay-Target-Environment: live` est refusée, et inversement. Voir
[Authentification](/api-reference/authentification) pour obtenir et stocker ces clés.

### Paramètres

`transaction_id` est votre propre référence de commande. Elle doit être unique pour votre compte :
c'est elle que vous retrouverez ensuite sous le nom `external_reference`, et elle est acceptée
comme identifiant de recherche par [Consulter une transaction](#get-payments-reference).

### Exemple de requête

Les valeurs du corps d'exemple sont celles du contrat OpenAPI, prévues pour l'environnement
Sandbox : remplacez-les par vos propres valeurs. La commande n'aboutit pas tant que les variables
listées ci-dessus ne sont pas renseignées.

### Réponse et champs

Conservez `reference` : c'est l'identifiant iMoney Encaissement de la transaction, accepté par les opérations de
consultation. `public_reference` est la référence affichable à votre client.

### Erreurs et limites

* **Doublons.** Il n'existe pas d'en-tête de clé d'idempotence. La création applique une détection
  de doublon **au niveau applicatif** sur `external_reference` — c'est-à-dire sur la valeur du
  `transaction_id` que vous envoyez : **en Live**, un second appel avec la même valeur reçoit `422`
  (`{"status": "failed", "message": "External Reference Not Valid"}`) et ne crée pas de seconde
  transaction. **En Sandbox, la réponse à un doublon n'est pas garantie identique à celle du Live** :
  le refus y passe par un autre chemin de code et la forme exacte de la réponse n'est pas établie —
  à confirmer auprès du support avant d'en faire une assertion de test automatisé. Dans les deux
  environnements, la seconde transaction n'est pas créée.
  **Cette détection n'est pas garantie sous appels concurrents** : deux requêtes envoyées
  au même instant avec le même `transaction_id` peuvent toutes les deux réussir. Rejouer un appel
  resté sans réponse avec le même `transaction_id` n'est donc pas une opération sûre par
  construction. Recommandation (et non comportement garanti par l'API) : générez un
  `transaction_id` unique par tentative, et vérifiez le statut avec
  [Consulter une transaction](#get-payments-reference) avant de retenter une transaction dont vous n'avez
  pas reçu la réponse.
* **Méthode de paiement.** Cette opération ne prend en charge que `Ipay-Payment-Type: mobile` (mobile money). Les autres moyens de
  paiement sont disponibles via les [liens de paiement](/api-reference/liens-de-paiement) : voir la liste des [moyens de paiement](/guides/reversement#frais-par-moyen-de-paiement).
* **Montant minimum.** Il est de `25` XOF en Live pour `mobile`. Le minimum appliqué en Sandbox diffère : voir
  [Sandbox](#sandbox).
* **Limitation de débit.** Aucune limite de débit n'est documentée dans le contrat de l'API à ce
  jour — à confirmer auprès du support avant un envoi massif.
* La liste complète des messages d'erreur communs à toutes les opérations est regroupée dans
  [Erreurs](/api-reference/erreurs).

## Consulter une transaction

Utilisez cette opération pour connaître le statut réel d'une transaction, plutôt que de vous fier au
statut renvoyé à la création : c'est elle (ou un [webhook](/guides/webhooks)) qui doit
déclencher la livraison d'une commande, jamais la réponse de
[Créer une transaction](#post-payments).

### Paramètres

La référence dans l'URL accepte deux valeurs interchangeables : la référence interne renvoyée par
iMoney Encaissement à la création, ou votre propre `transaction_id` (retrouvé sous le nom
`external_reference` dans les réponses). Inutile de conserver les deux si vous ne gardez que
`transaction_id` côté marchand.

### Exemple de requête

Les variables d'environnement et la référence à substituer sont celles utilisées pour créer la
transaction d'origine.

### Réponse et champs

Le statut renvoyé fait partie du même cycle de vie que celui utilisé à la création : une transaction
`pending` peut encore devenir `succeeded`, `failed` ou `refunded`. Attendez un statut définitif (ou
un webhook) avant de considérer la vérification terminée.

### Erreurs et limites

Une référence qui ne correspond à aucune transaction du compte authentifié renvoie `404`, y compris si
elle existe pour un autre compte ou un autre environnement (Sandbox/Live). La liste complète des
messages d'erreur communs (en-têtes, authentification) est dans
[Erreurs](/api-reference/erreurs).

## Lister les transactions

Utile pour une vue d'ensemble ou une réconciliation périodique. Pour vérifier une transaction précise
que vous venez de créer, préférez [Consulter une transaction](#get-payments-reference), plus direct et
qui accepte votre propre `transaction_id`.

### Paramètres

`query` filtre en texte libre ; les autres paramètres filtrent sur une valeur exacte ou une plage
de dates. Combinez-les librement : ils s'appliquent tous en même temps (ET logique), pas en
alternative.

### Exemple de requête

L'exemple n'illustre qu'un sous-ensemble des filtres disponibles ; ajoutez ou retirez des
paramètres de requête selon vos besoins.

### Réponse et champs

Les valeurs de `status` et `payment_method` (voir les [moyens de paiement](/guides/reversement#frais-par-moyen-de-paiement)) de cette liste sont mises en forme pour l'affichage et
ne correspondent pas aux valeurs machine utilisées par les autres opérations (ex.
[Consulter une transaction](#get-payments-reference)) : ne les comparez pas directement dans votre
code, n'utilisez cette liste que pour de l'affichage ou de l'export.

### Erreurs et limites

Aucune limite de débit n'est documentée pour cette opération à ce jour — à confirmer auprès du
support avant un usage intensif (sondage fréquent, export massif). Pour un suivi en temps réel
d'une transaction donnée, préférez les [webhooks](/guides/webhooks) à un sondage répété de
cette liste. Messages d'erreur communs : [Erreurs](/api-reference/erreurs).

## Sandbox

L'environnement Sandbox utilise les mêmes opérations que le Live, avec une clé Sandbox et
`Ipay-Target-Environment: sandbox` ; aucune transaction réelle n'est déclenchée. Les requêtes elles-mêmes
ne sont pas répétées ici : reprenez l'[exemple de requête de « Créer une transaction »](#post-payments--exemple-de-requete)
et celui de [« Consulter une transaction »](#get-payments-reference--exemple-de-requete), et remplacez
seulement les valeurs par celles ci-dessous.

### Numéros de test mobile

Pour `Ipay-Payment-Type: mobile` en Sandbox, seuls les dix numéros ci-dessous sont acceptés et
simulent chacun un résultat fixe. Tout autre `msisdn` sur ce type renvoie
`400 Bad Request: Incorrect MSISDN`, même bien formé : ce n'est pas un simulateur générique
acceptant n'importe quel numéro.

| MSISDN        | Résultat simulé                              | Statut final renvoyé par l'API                  |
| ------------- | -------------------------------------------- | ----------------------------------------------- |
| `40410000000` | Succès                                       | `succeeded`                                     |
| `40410000001` | Succès                                       | `succeeded`                                     |
| `40410000002` | Erreur                                       | `failed`                                        |
| `40410000003` | Erreur                                       | `failed`                                        |
| `40410000004` | Fonds insuffisants                           | `failed`                                        |
| `40410000005` | Fonds insuffisants                           | `failed`                                        |
| `40410000006` | Refusé                                       | `failed`                                        |
| `40410000007` | Refusé                                       | `failed`                                        |
| `40410000008` | Mise en attente, puis résolution automatique | `pending`, puis `succeeded` après \~90 secondes |
| `40410000009` | Mise en attente, puis résolution automatique | `pending`, puis `succeeded` après \~90 secondes |

« Erreur », « Fonds insuffisants » et « Refusé » partagent le même statut final `failed` : l'API
n'expose pas de sous-catégorie supplémentaire dans le champ `status` pour distinguer ces trois cas.
Les deux numéros de mise en attente ne restent pas indéfiniment `pending` : ils passent
automatiquement à `succeeded` après une résolution différée d'environ 90 secondes — ce n'est ni un
état bloqué à corriger manuellement, ni un résultat aléatoire.

### Montant minimum en Sandbox

Pour `mobile`, le minimum accepté **en Sandbox** est de `50` XOF, alors que le minimum Live du même
type est de `25` XOF. Un montant compris entre `25` et `49` XOF est donc refusé en Sandbox alors
qu'il serait accepté en Live : n'en déduisez pas le comportement de production, et testez votre
gestion d'erreur avec un montant clairement inférieur aux deux seuils.

### Cas à couvrir avant la production

| Cas                  | Valeurs à utiliser                                                                                                                       | Résultat attendu                                                                                                                                                                                                                                                                                |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Transaction réussie  | `msisdn` `40410000000`, montant ≥ `50` XOF, `transaction_id` neuf — [exemple de requête](#post-payments--exemple-de-requete)             | `200`, puis `succeeded` à la [consultation](#get-payments-reference)                                                                                                                                                                                                                            |
| Erreur de validation | même corps, montant sous le minimum (ex. `10` XOF) — [exemple de requête](#post-payments--exemple-de-requete)                            | `400 Bad Request: Amount Not Valid`, aucune transaction créée                                                                                                                                                                                                                                   |
| Doublon de référence | même corps que le premier cas, en réutilisant le `transaction_id` déjà envoyé — [exemple de requête](#post-payments--exemple-de-requete) | Refus, sans seconde transaction créée. **La forme de la réponse en Sandbox n'est pas garantie identique au `422 External Reference Not Valid` du Live** (à confirmer auprès du support) : n'en faites pas une assertion de test — voir [Erreurs et limites](#post-payments--erreurs-et-limites) |
| Référence inconnue   | une référence jamais créée sur votre compte — [exemple de requête](#get-payments-reference--exemple-de-requete)                          | `404 Payment Not Found`                                                                                                                                                                                                                                                                         |

Traitez l'erreur de validation comme une erreur de saisie côté client, pas comme un incident à
relancer automatiquement. La liste complète des codes et messages est dans
[Erreurs](/api-reference/erreurs).
