> For the complete documentation index, see [llms.txt](https://docs.fonbnk.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fonbnk.com/server-to-server/integration-guide/flow-examples/fiat-to-merchant-balance.md).

# Fiat to Merchant balance

An NGN (fiat) deposit crediting your USD merchant balance. This is the collections flow: a user pays in local currency and you hold the value in USD.

{% hint style="info" %}
Every response on this page is a **sandbox** capture — hence "Sandbox Bank" in the bank list and the `depositSandboxForcedFlow` field on the deposit leg.
{% endhint %}

{% stepper %}
{% step %}

#### Call [Get available currencies](/server-to-server/api-endpoints/get-available-currencies.md)

{% code title="Example response (trimmed to the two entries we need)" overflow="wrap" expandable="true" %}

```json
[
  {
    "currencyType": "fiat",
    "currencyCode": "NGN",
    "paymentChannels": [
      {
        "name": "Bank transfer",
        "type": "bank",
        "transferTypes": ["manual"],
        "isDepositAllowed": true,
        "isPayoutAllowed": true
      },
      {
        "name": "Airtime",
        "type": "airtime",
        "transferTypes": [],
        "isDepositAllowed": false,
        "isPayoutAllowed": true,
        "carriers": [
          { "code": "ng_mtn", "name": "MTN Nigeria" },
          { "code": "ng_airtel", "name": "Airtel Nigeria" },
          { "code": "ng_glo", "name": "Glo Mobile Nigeria" },
          { "code": "ng_9mobile", "name": "9Mobile Nigeria" }
        ]
      }
    ],
    "currencyDetails": { "countryIsoCode": "NG" },
    "pairs": ["crypto", "merchant_balance"]
  },
  {
    "currencyType": "merchant_balance",
    "currencyCode": "USD",
    "paymentChannels": [
      {
        "name": "Merchant balance",
        "type": "merchant_balance",
        "transferTypes": ["manual"],
        "isDepositAllowed": true,
        "isPayoutAllowed": true
      }
    ],
    "currencyDetails": { "merchantName": "Your company" },
    "pairs": ["fiat", "crypto"]
  }
]
```

{% endcode %}

NGN takes deposits over `bank`, and its `pairs` includes `merchant_balance`. So NGN → merchant balance USD over `bank` is legal. Airtime is payout-only, so it cannot be the deposit leg here.
{% endstep %}

{% step %}

#### Call [Get order limits](/server-to-server/api-endpoints/get-order-limits.md)

* depositPaymentChannel: "<mark style="color:yellow;">bank</mark>"
* depositCurrencyType: "<mark style="color:yellow;">fiat</mark>"
* depositCurrencyCode: "<mark style="color:yellow;">NGN</mark>"
* depositCountryIsoCode: "<mark style="color:yellow;">NG</mark>"
* payoutPaymentChannel: "<mark style="color:yellow;">merchant\_balance</mark>"
* payoutCurrencyType: "<mark style="color:yellow;">merchant\_balance</mark>"
* payoutCurrencyCode: "<mark style="color:yellow;">USD</mark>"

{% code title="Example response" %}

```json
{
  "deposit": {
    "min": 1523,
    "max": 761469,
    "minUsd": 1,
    "maxUsd": 500,
    "step": 1,
    "supportsDecimals": false
  },
  "payout": {
    "min": 1,
    "max": 500,
    "minUsd": 1,
    "maxUsd": 500,
    "step": 0.01,
    "supportsDecimals": true
  }
}
```

{% endcode %}

The user can pay 1,523 to 761,469 NGN, crediting 1 to 500 USD. We want 100 USD credited.

KYC applies to the person paying — run the [KYC flow](/server-to-server/kyc-flow.md) against their email and country, passing the amounts.
{% endstep %}

{% step %}

#### Call [Create quote](/server-to-server/api-endpoints/create-quote.md)

{% code title="Example request" %}

```json
{
  "deposit": {
    "paymentChannel": "bank",
    "currencyType": "fiat",
    "currencyCode": "NGN",
    "countryIsoCode": "NG"
  },
  "payout": {
    "paymentChannel": "merchant_balance",
    "currencyType": "merchant_balance",
    "currencyCode": "USD",
    "amount": 100
  }
}
```

{% endcode %}

{% code title="Example response" overflow="wrap" expandable="true" %}

```json
{
    "quoteId": "692ee3e2f34fda2f154d4496",
    "quoteExpiresAt": "2025-12-02T13:34:34.797Z",
    "deposit": {
        "paymentChannel": "bank",
        "currencyType": "fiat",
        "currencyCode": "NGN",
        "currencyDetails": { "countryIsoCode": "NG" },
        "cashout": {
            "amountBeforeFees": 152206,
            "amountAfterFees": 146879,
            "amountBeforeFeesUsd": 103.626795,
            "amountAfterFeesUsd": 100,
            "chargedFees": [
                { "id": "service_fee", "type": "percentage", "recipient": "platform", "amount": 3805.15 },
                { "id": "merchant_fee", "type": "percentage", "recipient": "merchant", "amount": 1522.06 }
            ],
            "chargedFeesUsd": [
                { "id": "service_fee", "type": "percentage", "recipient": "platform", "amount": 2.59067 },
                { "id": "merchant_fee", "type": "percentage", "recipient": "merchant", "amount": 1.036268 }
            ],
            "totalChargedFees": 5327.21,
            "totalChargedFeesUsd": 3.626938,
            "exchangeRate": 1468.79,
            "exchangeRateAfterFees": 1522.06,
            "chargedFeesPerRecipient": { "platform": 3805.15, "merchant": 1522.06 },
            "chargedFeesPerRecipientUsd": { "platform": 2.59067, "merchant": 1.036268 },
            "feeSettings": [
                { "id": "service_fee", "recipient": "platform", "type": "percentage", "value": 2.5, "min": 0, "max": "Infinity" },
                { "id": "merchant_fee", "recipient": "merchant", "type": "percentage", "value": 1, "min": 0, "max": "Infinity" }
            ]
        },
        "fieldsToCreateOrder": [
            { "key": "phoneNumber", "label": "Phone Number", "required": true, "type": "phone" },
            {
                "key": "bankCode",
                "label": "Bank name",
                "required": true,
                "type": "enum",
                "options": [
                    { "label": "Sandbox Bank", "value": "1" },
                    { "label": "Sandbox Bank 2", "value": "2" },
                    { "label": "Sandbox Bank 3", "value": "3" }
                ]
            },
            { "key": "bankAccountNumber", "label": "Bank Account Number", "required": true, "type": "string" },
            {
                "key": "depositSandboxForcedFlow",
                "type": "enum",
                "label": "Sandbox deposit forced flow",
                "required": false,
                "defaultValue": "deposit_success",
                "options": [
                    { "label": "Deposit success", "value": "deposit_success" },
                    { "label": "Deposit invalid", "value": "deposit_invalid" },
                    { "label": "Deposit underpayment (50%)", "value": "deposit_underpayment" },
                    { "label": "Deposit overpayment (200%)", "value": "deposit_overpayment" }
                ]
            }
        ],
        "transferType": "manual"
    },
    "payout": {
        "paymentChannel": "merchant_balance",
        "currencyType": "merchant_balance",
        "currencyCode": "USD",
        "currencyDetails": { "merchantName": "Your company" },
        "cashout": {
            "amountBeforeFees": 100,
            "amountAfterFees": 100,
            "amountBeforeFeesUsd": 100,
            "amountAfterFeesUsd": 100,
            "chargedFees": [],
            "chargedFeesUsd": [],
            "totalChargedFees": 0,
            "totalChargedFeesUsd": 0,
            "exchangeRate": 1,
            "exchangeRateAfterFees": 1,
            "chargedFeesPerRecipient": {},
            "chargedFeesPerRecipientUsd": {},
            "feeSettings": []
        },
        "fieldsToCreateOrder": []
    }
}
```

{% endcode %}

For you to be credited 100 USD the user pays 152,206 NGN. The fees come off the deposit leg: 2.5% platform and 1% merchant — that `merchant_fee` is yours.

Required fields, all on the deposit leg:

* <mark style="color:yellow;">phoneNumber</mark>
* <mark style="color:yellow;">bankCode</mark> (from the enum options)
* <mark style="color:yellow;">bankAccountNumber</mark>

The payout leg needs nothing — the destination is your own balance.

{% hint style="info" %}
**Sandbox tip:** set <mark style="color:yellow;">depositSandboxForcedFlow</mark> to force a success, a failure, an underpayment or an overpayment. It is the easy way to exercise your error paths without moving real funds. Read the values from the field's own `options` array — they differ by offer, and the merchant-balance leg publishes no forced-flow field at all.
{% endhint %}
{% endstep %}

{% step %}

#### Call [Create order](/server-to-server/api-endpoints/create-order.md)

Send only the fields the quote asked for — there is no wallet address in this flow.

{% code title="Example request" overflow="wrap" expandable="true" %}

```json
{
    "quoteId": "692ee3e2f34fda2f154d4496",
    "userCountryIsoCode": "NG",
    "userEmail": "someuser@example.com",
    "userIp": "223.134.123.12",
    "deposit": {
        "paymentChannel": "bank",
        "currencyType": "fiat",
        "currencyCode": "NGN",
        "countryIsoCode": "NG"
    },
    "payout": {
        "paymentChannel": "merchant_balance",
        "currencyType": "merchant_balance",
        "currencyCode": "USD",
        "amount": 100
    },
    "fieldsToCreateOrder": {
        "phoneNumber": "2348012345678",
        "bankCode": "1",
        "bankAccountNumber": "1234567890"
    }
}
```

{% endcode %}

{% code title="Example response (trimmed)" overflow="wrap" expandable="true" %}

```json
{
    "quoteUsed": true,
    "order": {
        "_id": "692ee4bba60e213546387b1e",
        "countryIsoCode": "NG",
        "userId": "686671f07730d8d1a9b2260a",
        "userEmail": "someuser@example.com",
        "status": "deposit_awaiting",
        "deposit": {
            "paymentChannel": "bank",
            "currencyType": "fiat",
            "currencyCode": "NGN",
            "currencyDetails": { "countryIsoCode": "NG" },
            "providedFieldsToCreateOrder": {
                "phoneNumber": "2348012345678",
                "bankCode": "1",
                "bankAccountNumber": "1234567890"
            },
            "transferInstructions": {
                "type": "manual",
                "instructionsText": "It is a sandbox offer. Confirm the transfer from your side and system will automatically confirm the transfer within 1 minute.",
                "warningText": "Non-confirmed orders will be automatically canceled after 5 minutes.",
                "transferDetails": [
                    { "id": "recipientBankName", "label": "Bank name", "value": "Sandbox Bank" },
                    { "id": "recipientBankAccountNumber", "label": "Bank account number", "value": "1073315490" },
                    { "id": "recipientBankAccountName", "label": "Bank account name", "value": "SANDY BOXERRITTO" },
                    { "id": "amountToSend", "label": "Amount to send", "value": "152206" }
                ],
                "fieldsToConfirmOrder": []
            }
        },
        "payout": {
            "paymentChannel": "merchant_balance",
            "currencyType": "merchant_balance",
            "currencyCode": "USD",
            "currencyDetails": { "merchantName": "Your company" },
            "providedFieldsToCreateOrder": {}
        },
        "statusChangeLogs": [],
        "createdAt": "2025-12-02T13:08:11.013Z",
        "updatedAt": "2025-12-02T13:08:11.013Z",
        "expiresAt": "2025-12-02T13:13:10.972Z"
    }
}
```

{% endcode %}

The `recipient*` values are the agent's account — where the user sends the money — not the `bankAccountNumber` you collected, which is the user's own.
{% endstep %}

{% step %}

#### The user transfers the exact amount

In production a bank transfer also carries a narration the user must copy. Show every entry of `transferDetails` as it comes.
{% endstep %}

{% step %}

#### Call [Confirm order](/server-to-server/api-endpoints/confirm-order.md)

`fieldsToConfirmOrder` is empty, so the order ID is all you need.

```json
{
  "orderId": "692ee4bba60e213546387b1e"
}
```

{% endstep %}

{% step %}

#### We validate the deposit and credit your balance

{% endstep %}

{% step %}

#### Wait for "<mark style="color:yellow;">payout\_successful</mark>"

Then [Get merchant balances](/server-to-server/api-endpoints/merchant-balance/get-merchant-balances.md) shows the new total.
{% endstep %}
{% endstepper %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.fonbnk.com/server-to-server/integration-guide/flow-examples/fiat-to-merchant-balance.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
