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

# Integrate Off-Ramp Widget

> Add the Off-Ramp widget to your app. Enable users to sell crypto and receive fiat payouts.

The Busha Off-Ramp widget provides a secure and straightforward solution for your users to convert their cryptocurrencies into fiat currency directly within your application or website. By integrating this widget, you empower your users to easily sell crypto and receive funds in their local currency, with Busha handling the complexities of crypto liquidation, regulatory compliance, and fiat payouts.

This guide will walk you through the essential steps to quickly embed and configure the Busha Off-Ramp widget, along with key design principles to optimize the user experience for seamless crypto-to-fiat conversions.

<Tip>
  **What You'll Achieve:**

  1. Understand key design principles for an optimal Off-Ramp user journey.
  2. Learn the quickest way to integrate the Off-Ramp widget using a client-side URL.
  3. Understand the basic parameters for configuring the Off-Ramp URL.
  4. Learn about handling post-transaction redirects.
</Tip>

## Prerequisites

* An active **Busha Business Account**.
* Your Public API Key (refer to the [How to Generate an API Key Guide](/guides/getting-started/generate-api-key) if you don't have one).
* A conceptual understanding of the Busha Off-Ramp Widget (refer to the [Understanding the Off-Ramp Widget](/overview/off-ramp-widget) Overview).
* Basic knowledge of web development (HTML, JavaScript) or mobile app development.

## How to Integrate the Off-Ramp Widget

<Steps>
  <Step title="Integration Design and User Experience Best Practices">
    A successful Off-Ramp integration isn't just about technical implementation. It's about crafting an intuitive and efficient user journey. By incorporating these design principles, you can significantly enhance your users' experience when buying crypto.

    <table style={{ width: "100%", borderCollapse: "collapse" }}>
      <thead>
        <tr>
          <th style={{ width: "30%", textAlign: "left", padding: "12px" }}>
            Requirement
          </th>

          <th style={{ width: "70%", textAlign: "left", padding: "12px" }}>
            Description
          </th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td style={{ padding: "12px" }}>Multiple entry points</td>

          <td style={{ padding: "12px" }}>
            All partner apps should add multiple entry points to the off-ramp.

            <ul style={{ margin: "8px 0", paddingLeft: "20px" }}>
              <li>Home screen</li>
              <li>Main app navigation</li>
              <li>Individual cryptocurrency screens</li>
            </ul>
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>Amount input</td>

          <td style={{ padding: "12px" }}>
            Partner apps with an amount input screen should show:

            <ul style={{ margin: "8px 0", paddingLeft: "20px" }}>
              <li>Add a max button and estimate network fees</li>

              <li>
                When opening the widget, pre-fill the fiat / crypto amount by using{" "}
                <code>cryptoAsset</code> with <code>cryptoAmount</code>
              </li>

              <li>
                Show the minimum and maximum sell limits set according to our API
              </li>
            </ul>
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>Payout method selection screen</td>

          <td style={{ padding: "12px" }}>
            Partner apps with a payout method selection screen should show:

            <ul style={{ margin: "8px 0", paddingLeft: "20px" }}>
              <li>All supported payment methods</li>
              <li>Payment method logos</li>
              <li>Estimated transaction completion times</li>
            </ul>
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>Provider selection screen</td>

          <td style={{ padding: "12px" }}>
            Partner apps with multiple providers should show:

            <ul style={{ margin: "8px 0", paddingLeft: "20px" }}>
              <li>
                Quotes from our Quote endpoint, using the correct{" "}
                <code>pay\_out</code> type.
              </li>

              <li>Estimated transaction completion times</li>
            </ul>
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>Handle crypto deposits</td>

          <td style={{ padding: "12px" }}>
            Partner apps with send functionality should handle crypto deposits for
            users to ensure high transaction success rates.

            <ul style={{ margin: "8px 0", paddingLeft: "20px" }}>
              <li>
                Get the deposit instructions by passing the <code>redirectUrl</code>{" "}
                widget parameter
              </li>

              <li>
                Show a screen or bottom sheet with the deposit details for the user
                to confirm the transaction
              </li>
            </ul>
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>Transaction tracking</td>

          <td style={{ padding: "12px" }}>
            All partner apps should display a toast message after the user completes
            their transaction and use the ramp transfers API to display the transfer
            event timeline.
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>Mobile app configuration</td>

          <td style={{ padding: "12px" }}>
            All partner mobile apps, configure app and browser so KYC and payment
            methods in the widget work correctly.

            <ul style={{ margin: "8px 0", paddingLeft: "20px" }}>
              <li>
                Use a fullscreen in-app browser and remove the navigation bar for a
                more native and seamless user experience
              </li>

              <li>
                Configure your app and in-app browser so that users can complete KYC
              </li>

              <li>
                Allow pop-ups at the in-app browser level so all payment methods
                work
              </li>
            </ul>
          </td>
        </tr>
      </tbody>
    </table>
  </Step>

  <Step title="Quick Start Integration with Off-Ramp URL">
    Integrating the Busha Off-Ramp widget via a URL redirect is the quickest way to get Busha's crypto buying functionality into your application. All you need to do is incorporate the integration design principles from Step 1, collect the necessary information from your users, and then construct a URL to which you redirect them.

    <Note>
      For sandbox requests, you can obtain test addresses from any of the providers
      listed in the Test Addresses reference.
    </Note>

    Here's a basic example of how you can attach a simple Off-Ramp URL to a button in your application's client-side code:

    ```html theme={null}
    <body>
      <div class="container">
        <button
          onclick="window.open('https://sandbox.sell.busha.io/?publicKey=pk_test_123', '_blank')"
        >
          Sell with Busha
        </button>
      </div>
    </body>
    ```

    In the example above, `https://sandbox.sell.busha.io/` is the base URL for the Busha Off-Ramp widget in the Sandbox environment, and `publicKey=pk_test_123` is your Public API Key passed as a query parameter.

    **Server-Side URL Construction**

    <Info>
      While direct client-side URL construction is quick, we strongly recommend that you **build the Off-Ramp URL on your application's server-side**. This approach offers several benefits:

      * **Security:** Keeps your Public API Key (though less sensitive than the Secret Key) from being directly exposed in your client-side source code, where it could be easily scraped.
      * **Flexibility:** Allows you to dynamically generate complex URLs with various parameters based on real-time data, user selections, and API responses (e.g., from the Pairs or Quotes API) without exposing your internal logic.
      * **Reliability:** Ensures that the URL is always correctly formatted and includes all necessary parameters.

      Your server can return the pre-configured Off-Ramp URL to the client, which then triggers the `window.open()` or redirect.
    </Info>
  </Step>

  <Step title="Configure the Integration URL with Parameters">
    To pre-fill information and customize the user experience (as described in Step 1), you'll add more query parameters to the base URL. This allows you to pass user selections directly to the widget, speeding up their journey.

    Common parameters you might include are:

    <table style={{ width: "100%", borderCollapse: "collapse" }}>
      <thead>
        <tr>
          <th style={{ width: "25%", textAlign: "left", padding: "12px" }}>
            Parameter
          </th>

          <th style={{ width: "15%", textAlign: "left", padding: "12px" }}>
            Required
          </th>

          <th style={{ width: "60%", textAlign: "left", padding: "12px" }}>
            Description
          </th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td style={{ padding: "12px" }}>
            <code>publicKey</code>
          </td>

          <td style={{ padding: "12px" }}>Yes</td>

          <td style={{ padding: "12px" }}>
            Specify the Business PublicKey to recognize that a transaction is
            referred by a specific business' application.
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>
            <code>side</code>
          </td>

          <td style={{ padding: "12px" }}>Yes</td>

          <td style={{ padding: "12px" }}>
            Specify whether the customer intends to buy or sell
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>
            <code>cryptoAsset</code>
          </td>

          <td style={{ padding: "12px" }}>No</td>

          <td style={{ padding: "12px" }}>
            Specify the cryptocurrency asset (e.g., BTC, ETH, MATIC) for the
            customer's purchase. The customer must use the specified cryptocurrency

            * no substitutions are allowed.
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>
            <code>network</code>
          </td>

          <td style={{ padding: "12px" }}>No</td>

          <td style={{ padding: "12px" }}>
            Specify the cryptocurrency network (e.g., ERC20, POLYGON) for the
            customer's purchase. The customer must use the specified network - no
            substitutions are allowed.
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>
            <code>fiatCurrency</code>
          </td>

          <td style={{ padding: "12px" }}>No</td>

          <td style={{ padding: "12px" }}>
            Specify the cryptocurrency asset (e.g., NGN, KES) for the customer's
            purchase. When passed, the customer must use the specified fiat currency

            * no substitutions are allowed.
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>
            <code>cryptoAmount</code>
          </td>

          <td style={{ padding: "12px" }}>No</td>

          <td style={{ padding: "12px" }}>
            Specify the crypto amount to be processed.
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>
            <code>fiatAmount</code>
          </td>

          <td style={{ padding: "12px" }}>No</td>

          <td style={{ padding: "12px" }}>
            Specify the fiat amount to be processed. If passed,{" "}
            <code>cryptoAmount</code> is ignored.
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>
            <code>redirectUrl</code>
          </td>

          <td style={{ padding: "12px" }}>Yes</td>

          <td style={{ padding: "12px" }}>
            URL to redirect the user to when they to complete a sell transaction.
          </td>
        </tr>
      </tbody>
    </table>

    **Example of a more configured URL:**

    ```shell theme={null}
        https://sandbox.sell.busha.co/?publicKey=PublicKey&cryptoAsset=ETH&network=ETH&fiatCurrency=NGN&cryptoAmount=0.005345&redirectUrl=https://www.partner.com
    ```

    **Redirect URL Parameters**

    After a user completes a ramp transfer, Busha will append various URL parameters to your specified `redirectUrl`. Some parameters you should expect are:

    <table style={{ width: "100%", borderCollapse: "collapse" }}>
      <thead>
        <tr>
          <th style={{ width: "30%", textAlign: "left", padding: "12px" }}>
            Parameter
          </th>

          <th style={{ width: "15%", textAlign: "left", padding: "12px" }}>
            Required
          </th>

          <th style={{ width: "55%", textAlign: "left", padding: "12px" }}>
            Description
          </th>
        </tr>
      </thead>

      <tbody>
        <tr>
          <td style={{ padding: "12px" }}>
            <code>transferId</code>
          </td>

          <td style={{ padding: "12px" }}>Yes</td>

          <td style={{ padding: "12px" }}>
            The represents the transfer that has just been completed or initiated.
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>
            <code>depositWalletAddress</code>
          </td>

          <td style={{ padding: "12px" }}>Yes</td>

          <td style={{ padding: "12px" }}>
            Denotes the address that you should deposit the{" "}
            <code>cryptoAmount</code> into.
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>
            <code>cryptoAsset</code>
          </td>

          <td style={{ padding: "12px" }}>Yes</td>

          <td style={{ padding: "12px" }}>
            The crypto asset that should be deposited
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>
            <code>network</code>
          </td>

          <td style={{ padding: "12px" }}>Yes</td>

          <td style={{ padding: "12px" }}>
            Specific network for the crypto asset.
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>
            <code>cryptoAmount</code>
          </td>

          <td style={{ padding: "12px" }}>Yes</td>

          <td style={{ padding: "12px" }}>
            Required for Off-Ramp transfers. Denotes the crypto amount that should
            be deposited in the address
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>
            <code>fiatCurrency</code>
          </td>

          <td style={{ padding: "12px" }}>No</td>

          <td style={{ padding: "12px" }}>
            Denotes the fiat currency for the transfer.
          </td>
        </tr>

        <tr>
          <td style={{ padding: "12px" }}>
            <code>fiatAmount</code>
          </td>

          <td style={{ padding: "12px" }}>No</td>

          <td style={{ padding: "12px" }}>
            Denotes the fiat amount that will be credited to the payout destination
            or was paid to complete the purchase.
          </td>
        </tr>
      </tbody>
    </table>

    **Sample redirect URL configuration**

    ```plaintext theme={null}
        https://www.partner.com/off-ramp?transferId={transferID}&depositWalletAddress=0xxxxxd134aCd3221a0xxxx80ADE3aF39Ce219037&cryptoAmount=0.005&cryptoAsset=BTC&network=ETH&fiatCurrency=NGN&fiatAmount=16075.87
    ```

    Your `redirectUrl` should be able to receive and handle the returned values and process the deposit of the `cryptoAmount` into the `depositWalletAddress` upon users' confirmation.
  </Step>
</Steps>

## Troubleshooting

* **Widget Not Loading/API Key Issues:** Ensure that your `publicKey` is correctly passed in the URL, and that it is active in your Busha dashboard.
* **Redirect Issues:** Verify that your `redirectUrl` is correctly configured in the widget URL, and that your application endpoint is ready to receive and process the redirect.
* **Parameter Errors:** Double-check that all passed URL parameters are spelled correctly and adhere to the expected format (e.g., correct currency codes, valid amounts).

## What's Next?

You've successfully learned how to integrate the Busha Off-Ramp widget! Consider these next steps to further enhance your Busha integration:

* [How to Integrate the On-Ramp Widget](/guides/widgets/integrate-on-ramp)
* [How to Generate an API Key](/guides/getting-started/generate-api-key): Review best practices for securing your credentials.
* [Busha API Reference](/api-reference/introduction): Explore other Busha APIs, such as the [Pairs API](/api-reference/pairs/list-trading-pairs), to dynamically fetch available currencies and limits for a more advanced integration.
