> 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/crypto-to-merchant-balance.md).

# Crypto to Merchant balance

A POLYGON\_USDT (crypto) deposit crediting your USD merchant balance. Use this when a user pays you in crypto and you want to hold the value in USD rather than pass it on.

{% hint style="info" %}
Every response on this page is a **sandbox** capture — that is why the crypto leg carries a `depositSandboxForcedFlow` field and why the contract address is not the production one.
{% 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": "crypto",
    "currencyCode": "POLYGON_USDT",
    "paymentChannels": [
      {
        "name": "Crypto",
        "type": "crypto",
        "transferTypes": ["manual"],
        "isDepositAllowed": true,
        "isPayoutAllowed": true
      }
    ],
    "currencyDetails": {
      "network": "POLYGON",
      "asset": "USDT",
      "contractAddress": "0x3b3a06b48119c035a2e86afdb69d9ad930643b3d"
    },
    "pairs": ["fiat", "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 %}

POLYGON\_USDT allows deposits, and its `pairs` includes `merchant_balance`. So crypto → merchant balance USD is legal.
{% endstep %}

{% step %}

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

* depositPaymentChannel: "<mark style="color:yellow;">crypto</mark>"
* depositCurrencyType: "<mark style="color:yellow;">crypto</mark>"
* depositCurrencyCode: "<mark style="color:yellow;">POLYGON\_USDT</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": 1,
        "max": 500,
        "minUsd": 1,
        "maxUsd": 500,
        "supportsDecimals": true,
        "step": 0.000001
    },
    "payout": {
        "min": 1,
        "max": 500,
        "minUsd": 1,
        "maxUsd": 500,
        "supportsDecimals": true,
        "step": 0.01
    }
}
```

{% endcode %}

The user can send 1 to 500 POLYGON\_USDT, crediting 1 to 500 USD. Note the different `step` on each leg: six decimals on the crypto side, cents on the balance side.

We want 100 USD credited. Check the user's tier with the [KYC flow](/server-to-server/kyc-flow.md) first — pass the amounts so the answer covers this order. A crypto deposit is governed by the country's off-ramp KYC switch, which is on in South Africa only today; read `offrampKycRequired` rather than assuming. See [KYC](/kyc.md).
{% endstep %}

{% step %}

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

{% code title="Example request" %}

```json
{
  "deposit": {
    "paymentChannel": "crypto",
    "currencyType": "crypto",
    "currencyCode": "POLYGON_USDT"
  },
  "payout": {
    "paymentChannel": "merchant_balance",
    "currencyType": "merchant_balance",
    "currencyCode": "USD",
    "amount": 100
  }
}
```

{% endcode %}

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

```json
{
    "quoteId": "69c5443c5ea688026a418ca2",
    "quoteExpiresAt": "2026-03-26T15:05:40.842Z",
    "deposit": {
        "paymentChannel": "crypto",
        "currencyType": "crypto",
        "currencyCode": "POLYGON_USDT",
        "currencyDetails": {
            "network": "POLYGON",
            "asset": "USDT",
            "contractAddress": "0x3b3a06b48119c035a2e86afdb69d9ad930643b3d"
        },
        "cashout": {
            "amountBeforeFees": 100,
            "amountAfterFees": 100,
            "amountBeforeFeesUsd": 100,
            "amountAfterFeesUsd": 100,
            "chargedFees": [],
            "chargedFeesUsd": [],
            "totalChargedFees": 0,
            "totalChargedFeesUsd": 0,
            "exchangeRate": 1,
            "exchangeRateAfterFees": 1,
            "chargedFeesPerRecipient": {},
            "chargedFeesPerRecipientUsd": {},
            "feeSettings": []
        },
        "fieldsToCreateOrder": [
            {
                "key": "blockchainWalletAddress",
                "type": "string",
                "label": "Your wallet address",
                "required": false
            },
            {
                "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" }
                ]
            }
        ],
        "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 receive 100 USD the user sends 100 POLYGON\_USDT — the rate is 1:1 and no fees are charged on either leg here.

Nothing on this quote is `required: true`. The merchant-balance leg asks for nothing at all: it is your own balance, so there is no destination to collect. `blockchainWalletAddress` on the deposit leg is optional; send it if you know it and the user sees it echoed back as `senderWalletAddress`.

{% hint style="info" %}
**Sandbox tip:** set `depositSandboxForcedFlow` to force a successful or an invalid deposit and exercise your error paths without moving real funds. Take the values from the field's own `options` array — each offer and each side publishes its own list, and the merchant-balance leg publishes none.
{% endhint %}
{% endstep %}

{% step %}

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

The amount stays on the same leg you quoted — the payout, here.

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

```json
{
    "quoteId": "69c5443c5ea688026a418ca2",
    "userCountryIsoCode": "NG",
    "userEmail": "someuser@example.com",
    "userIp": "223.134.123.12",
    "deposit": {
        "paymentChannel": "crypto",
        "currencyType": "crypto",
        "currencyCode": "POLYGON_USDT"
    },
    "payout": {
        "paymentChannel": "merchant_balance",
        "currencyType": "merchant_balance",
        "currencyCode": "USD",
        "amount": 100
    },
    "fieldsToCreateOrder": {
        "blockchainWalletAddress": "0x5b7ae3c6c87f4a3f94b35c77233b13191ebfad20"
    }
}
```

{% endcode %}

{% code title="Example response (transfer instructions excerpt)" overflow="wrap" expandable="true" %}

```json
{
    "quoteUsed": true,
    "order": {
        "_id": "69c545ea57cb634f272a57f2",
        "countryIsoCode": "NG",
        "userId": "69c54529ca181e1811eeb37b",
        "userEmail": "someuser@example.com",
        "status": "deposit_awaiting",
        "deposit": {
            "paymentChannel": "crypto",
            "currencyType": "crypto",
            "currencyCode": "POLYGON_USDT",
            "providedFieldsToCreateOrder": {
                "blockchainWalletAddress": "0x5b7ae3c6c87f4a3f94b35c77233b13191ebfad20"
            },
            "transferInstructions": {
                "type": "manual",
                "instructionsText": "Please send the exact amount of crypto to the address below. Make sure to send only USDT on the Polygon network. Sending any other assets or using a different network may result in loss of funds.",
                "transferDetails": [
                    { "id": "recipientWalletAddress", "label": "Wallet address to send", "value": "0xdc9cbad0c43f912a66cd44cd22a15c04368e659f" },
                    { "id": "senderWalletAddress", "label": "Your wallet address", "value": "0x5b7ae3c6c87f4a3f94b35c77233b13191ebfad20" },
                    { "id": "amountToSend", "label": "Amount to send", "value": "100" },
                    { "id": "cryptoTransactionRequestAdditionalData", "label": "Crypto transaction additional data", "value": "" }
                ],
                "fieldsToConfirmOrder": [
                    { "key": "blockchainTransactionHash", "type": "string", "label": "Transaction hash", "required": true }
                ]
            }
        },
        "payout": {
            "paymentChannel": "merchant_balance",
            "currencyType": "merchant_balance",
            "currencyCode": "USD",
            "currencyDetails": { "merchantName": "Your company" },
            "providedFieldsToCreateOrder": {}
        },
        "statusChangeLogs": [],
        "createdAt": "2026-03-26T14:42:51.252Z",
        "updatedAt": "2026-03-26T14:42:51.252Z",
        "expiresAt": "2026-03-26T15:12:50.857Z"
    }
}
```

{% endcode %}

The user must send exactly 100 USDT on Polygon to `0xdc9cbad0c43f912a66cd44cd22a15c04368e659f`. `fieldsToConfirmOrder` asks for `blockchainTransactionHash`, so you will need it in the next step.
{% endstep %}

{% step %}

#### The user sends the crypto

{% endstep %}

{% step %}

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

```json
{
  "orderId": "69c545ea57cb634f272a57f2",
  "fieldsToConfirmOrder": {
    "blockchainTransactionHash": "0xe168c39bf7165c0eaa88e4df1e21e987666e44f11f2bea6f9be1c145f382dade"
  }
}
```

{% endstep %}

{% step %}

#### We confirm the transaction on-chain 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/crypto-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.
