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

# Initier un transfert interwallet

> Déplace des fonds entre deux wallets pays du même marchand

<Note>
  Le montant reste toujours sur la plateforme — un transfert interwallet ne fait que déplacer des fonds entre deux wallets **du même marchand**, jamais vers un tiers. Si les devises diffèrent, la conversion utilise le taux de change en vigueur ([Lister les taux de change](/api-reference/wallet/exchange-rates-list)) et des frais peuvent s'appliquer sur le montant converti.
</Note>

## Statut après création

* `PENDING` : votre marchand n'a pas l'auto-approbation activée — le transfert attend une validation admin avant que le wallet cible ne soit crédité. Un seul transfert `PENDING` à la fois est autorisé par marchand.
* `COMPLETED` : le transfert a été exécuté immédiatement (auto-approbation activée).

## Éviter un doublon en cas de coupure réseau

Le header `Idempotency-Key` est **optionnel** : sans lui, un simple retry réseau réserve le montant une seconde fois sur le wallet source. Voir [Idempotence](/api-reference/introduction#idempotence).


## OpenAPI

````yaml api-reference/openapi.json POST /wallet-transfers/
openapi: 3.1.0
info:
  title: AlphaPay API
  description: >-
    API d'encaissement et de paiement mobile money/carte pour l'Afrique de
    l'Ouest et du Centre. Toutes les routes marchand nécessitent une clé API
    secrète (header Authorization: Bearer sk_...).
  version: 1.0.0
servers:
  - url: https://api.alphapay.me/api/v1
security:
  - bearerAuth: []
paths:
  /wallet-transfers/:
    post:
      tags:
        - Wallet
      summary: Initier un transfert interwallet
      description: >-
        Déplace des fonds entre deux wallets pays du même marchand, avec
        conversion automatique de devise si besoin — jamais d'argent qui quitte
        la plateforme. Nécessite un scope de clé API `PAYOUT` ou `BOTH`. Un seul
        transfert `PENDING` à la fois par marchand : un nouvel appel tant qu'un
        précédent attend une approbation admin est rejeté (`422
        transfer_already_pending`). Header `Idempotency-Key` optionnel mais
        vivement recommandé (sans lui, un retry réseau réserve le montant une
        seconde fois).
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - from_country
                - to_country
                - from_amount
              properties:
                merchant:
                  type: string
                  format: uuid
                  description: >-
                    UUID du marchand visé. Ignoré pour une clé API (toujours
                    vous-même).
                from_country:
                  type: string
                  minLength: 2
                  maxLength: 2
                  example: BJ
                  description: Code ISO du wallet source (débité).
                to_country:
                  type: string
                  minLength: 2
                  maxLength: 2
                  example: CM
                  description: >-
                    Code ISO du wallet cible (crédité, après conversion si
                    devise différente).
                from_amount:
                  type: string
                  format: decimal
                  example: '50000.00'
                  description: Montant réservé sur le wallet source, dans sa devise.
            example:
              from_country: BJ
              to_country: CM
              from_amount: '50000.00'
      responses:
        '201':
          description: >-
            Transfert créé — `status` vaut `COMPLETED` si
            `WALLET_TRANSFER_AUTO_APPROVE` est activé pour votre marchand,
            `PENDING` sinon (validation admin requise avant que le wallet cible
            ne soit crédité).
          content:
            application/json:
              example:
                id: b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e
                reference: 9f8e7d6c5b4a3f2e1d0c9b8a7f6e5d4c
                merchant: 8a1f5c3e-0000-1111-2222-333344445555
                requested_by_member: null
                from_country: BJ
                to_country: CM
                from_amount: '50000.00'
                from_currency: XOF
                to_amount: '82000.00'
                to_currency: XAF
                exchange_rate: '1.64000000'
                fee_amount: '820.00'
                fee_percent_applied: '1.00'
                status: PENDING
                approved_by_admin: null
                approved_at: null
                completed_at: null
                rejection_reason: ''
                created_at: '2026-09-24T10:00:00Z'
                updated_at: '2026-09-24T10:00:00Z'
        '403':
          description: Scope de clé API insuffisant (`PAYIN` seul).
          content:
            application/json:
              example:
                message: >-
                  Cette clé API n'est pas autorisée pour les opérations payout
                  (décaissement) (scope actuel : Encaissement uniquement).
                code: api_key_scope_forbidden
        '422':
          description: >-
            Requête valide mais impossible à réaliser. Codes possibles :
            `same_country` (pays source = pays cible),
            `transfer_already_pending` (un transfert de ce marchand attend déjà
            une approbation admin), `wallet_frozen` (wallet source gelé pour les
            sorties), `insufficient_balance`.
          content:
            application/json:
              example:
                message: Solde disponible insuffisant.
                code: insufficient_balance
components:
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: >-
        Identifiant unique que **vous** générez pour cette tentative (un UUID
        par exemple). Optionnel : sans lui, chaque appel est traité comme une
        nouvelle demande. Avec lui, si vous renvoyez la même clé — après un
        timeout ou une coupure réseau — AlphaPay renvoie la réponse d'origine au
        lieu de créer un second paiement. Réutilisez la même clé pour les retrys
        d'une même tentative, changez-en pour toute nouvelle intention. La même
        clé avec un corps de requête différent renvoie une erreur `409`. Voir
        [Idempotence](/api-reference/introduction#idempotence).
      schema:
        type: string
        maxLength: 255
      example: 3fa85f64-5717-4562-b3fc-2c963f66afa6
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: sk_live_... / sk_test_...
      description: >-
        Clé API secrète du marchand — header Authorization: Bearer sk_live_xxx
        (ou sk_test_xxx en environnement de test).

````