Crypto Onramp/Offramp

This guide walks you through common scenarios for converting fiat currency into cryptocurrency (On-Ramp) and cryptocurrency back into fiat currency for withdrawal (Off-Ramp) using Fuze's API capabilities. These processes allow Customers to move funds between traditional fiat systems and the digital asset ecosystem.

Prerequisites:

Before initiating these flows, ensure that:

Crypto On-Ramp (Buying Crypto with Fiat)

This flow enables a Customer to convert funds from their Internal Fiat Account into a cryptocurrency, which is then held in their Internal Crypto Wallet.

Goal: A Customer wants to convert 1000 USD from their Fuze fiat account into Bitcoin (BTC).

Step 1: Get a Trade Quote (Fiat to Crypto)

First, request a quote to determine the current exchange rate and the amount of crypto the Customer will receive for their fiat, or the fiat amount needed for a specific crypto sum.

  • Purpose: To provide the Customer with a time-sensitive conversion rate for the desired trade.

  • API Call (Conceptual): POST /api/v1/ol/quote/create (or a similar quote generation endpoint for trading)

  • Sample Request Body:

    • Specify the customerId, the from currency (e.g., USD) and amount (e.g., 1000), and the to currency (e.g., BTC).
    {
      "customerId": "customer_identifier_123",
      "from": {
        "currency": "USD",
        "amount": 1000
      },
      "to": {
        "currency": "BTC"
        // "amount" for BTC is calculated by Fuze in the quote response
      }
    }
  • Sample Response Body:

    • Fuze returns a quoteId, the amounts for both currencies, the conversionRate, and an expiryTime for the quote.
    {
      "code": 200,
      "error": null,
      "data": {
        "quoteId": 123456,
        "from": {
          "currency": "USD",
          "amount": 1000
        },
        "to": {
          "currency": "BTC",
          "amount": 0.0281 // Illustrative amount
        },
        "conversionRate": 35587.18, // Illustrative rate
        "expiryTime": 1696147260, // Unix timestamp
        "createdAt": "2023-10-01T00:00:00Z",
        "updatedAt": "2023-10-01T00:00:00Z"
      }
    }
    🚧

    Quotes are Time-Sensitive

    The provided quoteId and conversionRate are valid only until the expiryTime. The trade must be executed before this time.

Step 2: Execute the Trade (Create Order - Buy Crypto)

Once the Customer agrees to the quote, create an order to execute the fiat-to-crypto conversion.

  • Purpose: To confirm and finalize the conversion based on the agreed-upon quote.

  • API Call (Conceptual): POST /api/v1/ol/order/create (or a similar trade execution endpoint)

  • Sample Request Body:

    • Provide the customerId and the quoteId obtained in Step 1.
    {
      "customerId": "customer_identifier_123",
      "quoteId": 123456
    }
  • Sample Response Body:

    • Fuze confirms the order creation, returning an orderId and the trade details, including the status and the filled amounts.
    {
      "code": 200,
      "error": null,
      "data": {
        "orderId": 789012,
        "from": {
          "currency": "USD",
          "amount": 1000
        },
        "to": {
          "currency": "BTC",
          "amount": 0.0281
        },
        "conversionRate": 35587.18,
        "status": "COMPLETED",
        "filled": 0.0281, // Amount of BTC filled
        "createdAt": "2023-10-01T00:00:30Z",
        "updatedAt": "2023-10-01T00:00:30Z"
      }
    }
  • Outcome: The Customer's Internal USD Account is debited, and their Internal BTC Wallet is credited with the traded amount of Bitcoin.


Crypto Off-Ramp (Selling Crypto for Fiat and Withdrawing)

This flow enables a Customer to convert a cryptocurrency from their Internal Crypto Wallet into a fiat currency in their Internal Fiat Account, and then withdraw these fiat funds to an external bank account.

Goal: A Customer wants to sell 0.5 ETH from their Fuze crypto wallet for EUR, and then withdraw the EUR to a linked bank account.

Step 1: Get a Trade Quote (Crypto to Fiat)

Request a quote to determine the current exchange rate for selling crypto to fiat.

  • Purpose: To provide the Customer with a time-sensitive conversion rate.

  • API Call (Conceptual): POST /api/v1/ol/quote/create

  • Sample Request Body:

    • Specify customerId, the from currency (e.g., ETH) and amount (e.g., 0.5), and the to currency (e.g., EUR).
    {
      "customerId": "customer_identifier_456",
      "from": {
        "currency": "ETH",
        "amount": 0.5
      },
      "to": {
        "currency": "EUR"
      }
    }
  • Sample Response Body:

    • Fuze returns a quoteId, amounts, conversionRate, and expiryTime.
    {
      "code": 200,
      "error": null,
      "data": {
        "quoteId": 654321,
        "from": {
          "currency": "ETH",
          "amount": 0.5
        },
        "to": {
          "currency": "EUR",
          "amount": 950.75 // Illustrative amount
        },
        "conversionRate": 1901.50, // Illustrative rate
        "expiryTime": 1696147560,
        "createdAt": "2023-10-01T00:05:00Z",
        "updatedAt": "2023-10-01T00:05:00Z"
      }
    }

Step 2: Execute the Trade (Create Order - Sell Crypto)

Once the Customer agrees to the quote, create an order to execute the crypto-to-fiat conversion.

  • Purpose: To confirm and finalize the conversion.

  • API Call (Conceptual): POST /api/v1/ol/order/create

  • Sample Request Body:

    • Provide the customerId and the quoteId.
    {
      "customerId": "customer_identifier_456",
      "quoteId": 654321
    }
  • Sample Response Body:

    • Fuze confirms the order, returning an orderId and trade details.
    {
      "code": 200,
      "error": null,
      "data": {
        "orderId": 901234,
        "from": {
          "currency": "ETH",
          "amount": 0.5
        },
        "to": {
          "currency": "EUR",
          "amount": 950.75
        },
        "conversionRate": 1901.50,
        "status": "COMPLETED",
        "filled": 950.75, // Amount of EUR filled
        "createdAt": "2023-10-01T00:05:30Z",
        "updatedAt": "2023-10-01T00:05:30Z"
      }
    }
  • Outcome: The Customer's Internal ETH Wallet is debited, and their Internal EUR Account is credited with the traded amount of Euro.

Step 3: Withdraw Fiat to External Bank Account

After the crypto is converted to fiat and available in the Customer's Internal Fiat Account, they can initiate a withdrawal to their linked and verified external bank account.

  • Purpose: To move the fiat currency from Fuze to the Customer's (or organization's) external bank.

  • API Call (Conceptual): This would typically be a POST /transfers/create (for same-currency external payouts) or a specific Payout API endpoint from the Payments/Remittance suite (e.g., POST /api/v1/payment/remittance/payouts/create). The exact endpoint should be confirmed in the API Reference.

  • Prerequisites: The Customer must have a suitable Counterparty record (e.g., a SELF type for direct withdrawals, or a pre-registered company account if an Organizational User is performing the off-ramp for company funds) with a verified External Fiat Account linked to it for the currency being withdrawn (EUR in this case).

  • Sample Request Body (Illustrative - adapt based on Fuze's specific Payout API):

    {
      "customerId": "customer_identifier_456",
      "counterpartyId": "relevant_counterparty_id_for_eur_bank",
      "externalAccountId": "eur_bank_account_uuid_linked_to_counterparty",
      "amount": 950.00,
      "currency": "EUR",
      "description": "Withdrawal of ETH sale proceeds"
      // A clientOrderId for idempotency is recommended here
    }
  • Sample Response Body (Illustrative):

    • The API confirms the withdrawal request has been initiated and provides a transaction ID and status.
    {
      "code": 200,
      "error": null,
      "data": {
        "transactionId": "payout_eur_abc_123",
        "status": "PENDING", // Or INITIATED, PROCESSING
        "message": "EUR withdrawal initiated successfully."
      }
    }
  • Outcome: The withdrawal is processed, and the Customer's Internal EUR Account balance is debited. You'll receive status updates (ideally via Webhooks) until the funds are credited to their external bank account.