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

# Exécuter une opération

> Exécuter une opération financière entre deux instruments de paiement de l'écosystème GIMpay.

C'est l'appel qui débite l'instrument de paiement de l'initiateur et crédite celui du bénéficiaire, via un service proposé par un contributeur. Tous les appels précédents du parcours (solde, frais, OTP) servent à préparer celui-ci.

## Avant d'appeler

<Steps>
  <Step title="Vérifiez le solde de l'initiateur">
    `GET /wallets/{referenceWallet}/balance` — le solde doit couvrir le montant **et** les frais si le mode d'application est `ADDITION`.
  </Step>

  <Step title="Calculez les frais">
    [`GET /services/{referenceService}/fees`](/endpoints/services/fees) vous donne `montantFrais` et surtout `modeApplication`, qui change le montant à envoyer ici.
  </Step>

  <Step title="Obtenez puis validez un OTP">
    [Générez l'OTP](/endpoints/otp/generate), faites-le saisir par l'usager, puis transmettez-le dans `authData`.
  </Step>
</Steps>

## Montant et frais : la subtilité à connaître

Le champ `montant` correspond au **montant à débiter hors frais lorsque le mode est `ADDITION`**. Le comportement diffère selon ce que retourne le calcul de frais :

| `modeApplication` | Ce que vous envoyez dans `montant` | Ce qui est débité | Ce que reçoit le bénéficiaire |
| ----------------- | ---------------------------------- | ----------------- | ----------------------------- |
| `ADDITION`        | Le montant net souhaité            | `montant` + frais | `montant`                     |
| `SOUSTRACTION`    | Le montant total                   | `montant`         | `montant` − frais             |

<Warning>
  Ne réutilisez pas aveuglément le montant saisi par l'utilisateur : en mode `ADDITION`, le débit réel dépasse ce montant. Assurez-vous que le solde le couvre et que l'utilisateur en est informé avant validation.
</Warning>

## Désigner le bénéficiaire

Deux cas de figure, selon que le bénéficiaire est déjà connu de GIMpay ou non :

<Tabs>
  <Tab title="Bénéficiaire interne à GIMpay">
    Renseignez `refInstrumentPaiementBeneficiaire` avec la référence GIMpay de son instrument de paiement.
  </Tab>

  <Tab title="Bénéficiaire chez un contributeur tiers">
    Identifiez-le par le champ correspondant à son type d'instrument :

    | Champ                    | Type d'instrument |
    | ------------------------ | ----------------- |
    | `msidnBeneficiaire`      | Mobile wallet     |
    | `panBeneficiaire`        | Carte bancaire    |
    | `compteBeneficiaire`     | Compte bancaire   |
    | `codeClientBeneficiaire` | Carte prépayée    |
  </Tab>
</Tabs>

## Points de vigilance

<AccordionGroup>
  <Accordion title="Un statut retourné ne signifie pas toujours « terminé »" icon="clock">
    `statutOperation` peut valoir `INITIEE`, `ENCOURS` ou `SUSPENDUE` : l'opération n'est pas finalisée. Ne considérez comme définitifs que `SUCCES`, `ECHOUE`, `ANNULEE` et `EXTOURNE`. En cas d'échec, `raisonEchec` en donne le motif.

    Pour un suivi asynchrone, renseignez `callbackUrl` : GIMpay y notifiera l'évolution de l'état.
  </Accordion>
</AccordionGroup>

## Réponses

Le corps utile arrive dans `body`, à l'intérieur de l'enveloppe commune `{ message, status, body, timestamp }`. Consultez le [glossaire](/glossary/enumerations#statutoperation) pour les valeurs de `statutOperation` et `natureOperation`.

En cas d'erreur, un `400` signale une donnée incorrecte ou indisponible (solde insuffisant, OTP invalide…), un `404` une entité introuvable. Voir la [référence des codes d'erreur](/getting-started/errors).

## Et ensuite ?

<CardGroup cols={2}>
  <Card title="Annuler une opération" icon="rotate-left" href="/api-reference/introduction">
    `PUT /operations/{referenceOperation}/cancel` pour extourner une opération.
  </Card>

  <Card title="Consulter l'historique" icon="clock-rotate-left" href="/api-reference/introduction">
    `GET /wallets/{referenceWallet}/operations` et `/movements`.
  </Card>
</CardGroup>


## OpenAPI

````yaml openapi.json POST /api/v1/operations
openapi: 3.0.3
info:
  title: Registre des APIs GIM Gar Sud
  version: 1.0.9-sdk0.3.0
  description: >
    APIs exposées par GIM Gar Sud pour permettre aux Contributeurs Tiers de
    Service Financier (CTSF) de consommer les services de GIMpay : enrôlement
    d'usagers et d'instruments de paiement, opérations financières, OTP,
    consentements, documents d'identité et fidélité.
  contact:
    name: Support intégrateurs GimPay
    email: support@it-centrex.com
servers:
  - url: https://egimgarsud.gimpayapp.com
    variables:
      environnement:
        default: egimgarsud
        description: Sous-domaine de l'environnement (sandbox ou production).
security:
  - bearerAuth: []
tags:
  - name: Authentification
  - name: Wallets
    description: Instruments de paiement (cartes, comptes bancaires, mobile wallets)
  - name: Opérations
  - name: OTP
  - name: Usagers
  - name: Bénéficiaires
  - name: MMP favorites
  - name: Pays
  - name: Contributeurs
  - name: Mini-places de marché
  - name: Services
  - name: Terminaux
  - name: Documents
  - name: Consentements & demandes
paths:
  /api/v1/operations:
    post:
      tags:
        - Opérations
      summary: Exécuter une opération de paiement
      description: >
        Le header `requestId` sert de clé anti-doublon : un `requestId` déjà
        utilisé est rejeté (HTTP 409). Il ne rejoue pas l'opération et ne
        renvoie pas son résultat ; fournir un identifiant unique par opération.
      operationId: executeOperation
      parameters:
        - name: requestId
          in: header
          required: true
          description: Clé anti-doublon, unique par opération.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OperationRequest'
      responses:
        '200':
          description: Opération exécutée.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ApiEnvelope'
                  - type: object
                    properties:
                      body:
                        $ref: '#/components/schemas/OperationResponse'
        '400':
          $ref: '#/components/responses/Error400'
        '401':
          $ref: '#/components/responses/Error401'
        '409':
          $ref: '#/components/responses/Error409'
        '500':
          $ref: '#/components/responses/Error500'
components:
  schemas:
    OperationRequest:
      type: object
      required:
        - libelle
        - montant
        - refInstrumentPaiementInitiateur
        - typeOperation
        - refService
        - refContributeurBeneficiaire
      properties:
        libelle:
          type: string
          example: Paiement facture électricité
          description: Libellé de l'opération
        montant:
          type: number
          format: double
          example: 15000
          description: Montant de l'opération
        refInstrumentPaiementInitiateur:
          type: string
          description: >-
            Réference de l'instrument de paiement utilisé par l'initiateur de
            l'opération
        refInstrumentPaiementBeneficiaire:
          type: string
          description: >-
            Réference de l'instrument de paiement utilisé par le bénéficiare de
            l'opération
        typeOperation:
          $ref: '#/components/schemas/TypeOperation'
        refService:
          type: string
          description: La référence du service concerné par l'opération
        msisdnBeneficiaire:
          type: string
          description: >-
            Numéro mobile money du bénéficiaire (typo `msisdn` conforme au
            contrat).
        panBeneficiaire:
          type: string
          description: Le numéro de carte bancaire du bénéficiaire
        compteBeneficiaire:
          type: string
          description: Le numéro de compte du bénéficiaire
        codeClientBeneficiaire:
          type: string
          description: Le code client du bénéficiaire
        refContributeurInitiateur:
          type: string
          description: >-
            La référence du contributeur émetteur de l'instrument de paiement de
            l'initiateur
        refContributeurBeneficiaire:
          type: string
          description: >-
            La référence du contributeur émetteur de l'instrument de paiement du
            bénéficiaire
        authData:
          type: string
          description: Donnée d'authentification (ex. OTP).
        callbackUrl:
          type: string
          description: URL de callback pour l'opération
    ApiEnvelope:
      type: object
      description: Enveloppe standard de toutes les réponses (sauf auth).
      properties:
        message:
          type: string
          description: Message technique décrivant le résultat de l'appel.
        status:
          type: integer
          description: Code de statut HTTP de la réponse.
        timestamp:
          type: string
          format: date-time
          description: Horodatage de la réponse.
    OperationResponse:
      type: object
      properties:
        referenceOperation:
          type: string
        dateHeureOperation:
          type: string
          format: date-time
        dateHeureAnnulationOperation:
          type: string
          format: date-time
        libelleOperation:
          type: string
        montantHToperation:
          type: number
          format: double
        montantHTfraisOperation:
          type: number
          format: double
        montantADebiter:
          type: number
          format: double
        montantACrediter:
          type: number
          format: double
        montantTotalOperation:
          type: number
          format: double
        typeOperation:
          $ref: '#/components/schemas/TypeOperation'
        natureOperation:
          $ref: '#/components/schemas/NatureOperation'
        statutOperation:
          $ref: '#/components/schemas/StatutOperation'
        refUsagerInitiateur:
          type: string
        typeInstrumentPaiementDebite:
          $ref: '#/components/schemas/TypeInstrument'
        identifiantInstrumentPaiementDebite:
          type: string
          description: Identifiant de l'instrument débité chez son contributeur.
        refUsagerBeneficiaire:
          type: string
          description: La reference de l'usager du bénéficiaire
        typeInstrumentPaiementCredite:
          $ref: '#/components/schemas/TypeInstrument'
        identifiantInstrumentPaiementCredite:
          type: string
          description: Identifiant de l'instrument crédité chez son contributeur.
        refContributeurInitiateur:
          type: string
          description: >-
            La référence du contributeur émetteur de l'instrument de paiement de
            l'initiateur
        refContributeurBeneficiaire:
          type: string
          description: >-
            La référence du contributeur émetteur de l'instrument de paiement du
            bénéficiaire
        dateDernierStatut:
          type: string
          format: date-time
        refService:
          type: string
          description: La référence du service concerné par l'opération
        raisonEchec:
          type: string
          description: Renseigné si l'opération a échoué.
    TypeOperation:
      type: string
      description: P = particulier, B = business, G = gouvernement.
      enum:
        - P2P
        - P2B
        - P2G
        - B2B
        - B2P
        - B2G
        - G2P
        - G2B
    NatureOperation:
      type: string
      description: >
        Flux entre types d'instruments (A = compte, M = mobile, F = fidélité, CD
        = carte débit, CP = carte prépayée, C = cash).
      enum:
        - A2A
        - A2M
        - A2F
        - A2CD
        - A2CP
        - M2M
        - M2A
        - M2F
        - M2CD
        - M2CP
        - CD2CD
        - CP2CP
        - CD2A
        - CP2A
        - CD2M
        - CP2M
        - CP2F
        - CD2F
        - F2F
        - F2A
        - F2M
        - F2CD
        - F2CP
    StatutOperation:
      type: string
      enum:
        - INITIEE
        - ENCOURS
        - SUSPENDUE
        - ANNULEE
        - ECHOUE
        - EXTOURNE
        - SUCCES
    TypeInstrument:
      type: string
      enum:
        - COMPTE_BANCAIRE
        - CARTE_BANCAIRE
        - MOBILE_WALLET
        - COMPTE_FIDELITE
    ErrorEnvelope:
      allOf:
        - $ref: '#/components/schemas/ApiEnvelope'
        - type: object
          properties:
            body:
              nullable: true
  responses:
    Error400:
      description: Requête invalide (champ manquant ou mal formé).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    Error401:
      description: Non autorisé — jeton manquant, invalide ou expiré.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    Error409:
      description: Conflit — ressource déjà existante (ex. `requestId` déjà utilisé).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    Error500:
      description: Erreur interne du serveur.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Jeton émis par `POST /api/v1/auth/token`.

````