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

# Fund Wallet (Mobile Money)

> Top up a wallet by charging a mobile-money account. Convenience wrapper around POST /payment/collect that targets a specific wallet.

## Overview

`POST /wallets/fund` tops up a wallet by charging a mobile-money account. It is functionally similar to [`POST /payment/collect`](/api-reference/endpoint/post-payment-collect) but is wallet-centric: you specify which wallet to credit by ID rather than by `(country, currency)`.

The call returns immediately with a transaction record; the final outcome reaches you asynchronously (operator OTP / USSD may be required).

## When to use it

* Top up a specific wallet from your own funds (e.g. via your treasury phone).
* Use when you already know the wallet you want to credit (rather than letting Cartevo route by country/currency).

For end-user collection (charging your customers), use [`POST /payment/collect`](/api-reference/endpoint/post-payment-collect) instead.

## Prerequisites

* The target wallet must belong to your company and be `is_active: true`.
* The mobile-money account must have sufficient balance to cover `amount` plus the operator's fee.

## Request

### Headers

| Name            | Required | Description             |
| --------------- | -------- | ----------------------- |
| `Authorization` | Yes      | `Bearer <access_token>` |
| `Content-Type`  | Yes      | `application/json`      |

### Query parameters

| Name      | Type   | Required | Description                                          |
| --------- | ------ | -------- | ---------------------------------------------------- |
| `purpose` | string | No       | Free-form description that appears in the dashboard. |

### Body

| Field      | Type   | Required | Constraints / format                                                                                                                                                            |
| ---------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `walletId` | string | Yes      | The wallet to credit (UUID).                                                                                                                                                    |
| `amount`   | number | Yes      | Minimum `0.01`. Major currency unit of the wallet's `currency`.                                                                                                                 |
| `currency` | string | Yes      | Must match the target wallet's currency. Sanity check.                                                                                                                          |
| `operator` | string | No       | Mobile-money operator (`mtn`, `orange`, `moov`, `wave`, etc.). Defaults to `mtn`.                                                                                               |
| `phone`    | string | No       | Phone number to charge. Country code + local number, **no `+`** (e.g. `237670000000`).                                                                                          |
| `userId`   | string | No       | Internal user ID for audit trail (filled by the platform if omitted).                                                                                                           |
| `trxId`    | string | No       | Idempotency key. Auto-generated UUID if omitted (you lose idempotency).                                                                                                         |
| `otpCode`  | string | No       | One-time code the payer generates on their phone, **required by some operators** (notably **Orange Burkina Faso** and **Orange Senegal**). See the Orange Money workflow below. |

```json theme={null}
{
  "walletId": "w1a2b3c4-d5e6-7890-abcd-ef1234567890",
  "amount": 5000,
  "currency": "XAF",
  "operator": "mtn",
  "phone": "237670000000",
  "trxId": "FUND-2026-001"
}
```

### Orange Money workflow (Burkina Faso & Senegal)

For **Orange Money** in **Burkina Faso** and **Senegal**, the payer must
**generate a one-time code (OTP)** themselves and you submit it in `otpCode`:

1. The payer dials the Orange USSD code to generate the OTP:
   * **Burkina Faso:** `*144*4*6*<amount>#` (where `<amount>` is the amount)
   * **Senegal:** `#144*391#`
2. The payer gives you the OTP.
3. You call `POST /wallets/fund` with `operator: "orange"`, the Orange phone
   number, and the OTP in `otpCode`.

```json theme={null}
{
  "walletId": "w1a2b3c4-d5e6-7890-abcd-ef1234567890",
  "amount": 1000,
  "currency": "XOF",
  "operator": "orange",
  "phone": "22670000000",
  "otpCode": "123456",
  "trxId": "FUND-2026-002"
}
```

<Warning>
  The OTP is short-lived and single-use. If it expires the funding fails — the
  payer generates a fresh one and you retry with a new `trxId`.
</Warning>

## Response

### 200 — Funding initiated

```json theme={null}
{
  "success": true,
  "statusCode": 200,
  "message": "Wallet funding initiated",
  "data": {
    "transaction": {
      "id": "txn_5b7c9d2e4f6a8b1c3d5e7f9a",
      "wallet_id": "w1a2b3c4-d5e6-7890-abcd-ef1234567890",
      "amount": 5000,
      "currency": "XAF",
      "category": "WALLET",
      "type": "FUND",
      "status": "PENDING",
      "phone_number": "237670000000",
      "operator": "mtn",
      "wallet_balance_before": 125000,
      "wallet_balance_after": 125000,
      "created_at": "2026-05-09T10:15:00.000Z"
    },
    "paymentResult": {
      "orderId": "AFB-202605091015-XYZ",
      "providerResponse": { "status": "PENDING", "message": "Awaiting OTP" }
    },
    "feeInfo": {
      "feeAmount": 50,
      "feePercentage": 1.0,
      "totalAmount": 5050
    }
  }
}
```

| Field                   | Description                                                                                                       |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `transaction.id`        | Cartevo wallet-transaction ID.                                                                                    |
| `transaction.status`    | `PENDING` immediately. Other values: `PROCESSING`, `SUCCESS`, `FAILED`. Wallet balance updates only on `SUCCESS`. |
| `paymentResult.orderId` | Reference at the upstream payment provider (Afribapay).                                                           |
| `feeInfo`               | Breakdown of the fee charged by the operator.                                                                     |

### Error responses

| Status | `message` example                        | Trigger                                                              |
| ------ | ---------------------------------------- | -------------------------------------------------------------------- |
| `400`  | `"Currency mismatch with target wallet"` | `currency` doesn't match the wallet's currency.                      |
| `400`  | `"Operator not enabled for this wallet"` | The operator hasn't been enabled for this wallet's country/currency. |
| `404`  | `"Wallet not found"`                     | `walletId` is invalid or belongs to another company.                 |

## Webhooks fired

* A status update fires when the funding settles or fails (same shape as `payment.collect`).

## Code examples

```bash cURL theme={null}
curl -X POST https://api.cartevo.co/api/v1/wallets/fund \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "walletId": "w1a2b3c4-d5e6-7890-abcd-ef1234567890",
    "amount": 5000,
    "currency": "XAF",
    "operator": "mtn",
    "phone": "237670000000",
    "trxId": "FUND-2026-001"
  }'
```

## Related

* [`POST /payment/collect`](/api-reference/endpoint/post-payment-collect) — the more general collection endpoint.
* [`GET /wallets/{id}`](/api-reference/endpoint/get-wallet-by-id) — verify the new balance after settlement.
* [Payment guidelines](/api-reference/endpoint/payment_guide_lines) — supported operators per country.


## OpenAPI

````yaml POST /wallets/fund
openapi: 3.1.0
info:
  title: Cartevo API
  description: Essential endpoints for wallets, transactions, customers and conversion.
  version: 1.0.0
servers:
  - url: https://api.cartevo.co/api/v1
security:
  - bearerAuth: []
paths:
  /wallets/fund:
    post:
      summary: Fund wallet
      description: Initiate wallet funding transaction
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                walletId:
                  type: string
                  format: uuid
                  description: ID of the wallet to fund.
                amount:
                  type: number
                  minimum: 0.01
                  description: Amount to fund, in the wallet currency.
                currency:
                  type: string
                  description: Currency of the funding amount.
                  example: XAF
                phone:
                  type: string
                  description: Mobile-money phone number being charged.
                  example: '237600000000'
                operator:
                  type: string
                  description: Mobile-money operator. Defaults to `mtn` if omitted.
                  example: mtn
                userId:
                  type: string
                  format: uuid
                  description: Optional ID of the user initiating the funding.
                trxId:
                  type: string
                  description: >-
                    Optional client-supplied transaction reference.
                    Auto-generated (UUID) if omitted.
                reason:
                  type: string
                  description: Optional free-text reason, persisted on the transaction.
                reason_category:
                  type: string
                  description: Optional categorical reason code.
              required:
                - walletId
                - amount
                - currency
      responses:
        '200':
          description: Funding request initiated successfully. The transaction is pending.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PostWalletFundResponse'
        '400':
          description: Bad request, e.g., invalid phone number or amount.
components:
  schemas:
    PostWalletFundResponse:
      allOf:
        - $ref: '#/components/schemas/StandardResponse'
        - type: object
          properties:
            data:
              $ref: '#/components/schemas/WalletFundingResponse'
    StandardResponse:
      type: object
      properties:
        success:
          type: boolean
          example: true
        statusCode:
          type: integer
          example: 200
        message:
          type: string
          example: Data retrieved successfully
    WalletFundingResponse:
      type: object
      properties:
        transaction:
          $ref: '#/components/schemas/WalletTransaction'
        paymentResult:
          type: object
          properties:
            orderId:
              type: string
              example: order_123456
            providerResponse:
              type: object
              description: Raw response from payment provider
        feeInfo:
          type: object
          properties:
            feeAmount:
              type: number
              example: 100
            feePercentage:
              type: number
              example: 0.02
            totalAmount:
              type: number
              example: 5100
    WalletTransaction:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 7d1cdfa3-9904-4a17-bce5-092554170c0e
        amount:
          type: number
          example: 5000
        amount_with_fee:
          type: number
          example: 5100
        fee_amount:
          type: number
          example: 100
        net_amount:
          type: number
          example: 5000
        currency:
          type: string
          example: XAF
        status:
          type: string
          example: PENDING
        type:
          type: string
          example: FUND
        category:
          type: string
          example: WALLET
        operator:
          type: string
          example: mtn
        phone_number:
          type: string
          example: '650695112'
        reference:
          type: string
          nullable: true
        order_id:
          type: string
          nullable: true
        wallet_balance_before:
          type: number
          example: 10000
        wallet_balance_after:
          type: number
          example: 15000
        created_at:
          type: string
          format: date-time
        completed_at:
          type: string
          format: date-time
          nullable: true
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````