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

# Widget

> Launch payins and payouts with a hosted link or an embedded, prefilled widget.

The Zapyd widget runs the whole user journey (sign-up, KYC, bank linking, payin and payout) in a UI that carries your logo, colors and emails. You don't build any payment screens.

<img src="https://mintcdn.com/dollarpe/LGQPeWoIOylM_7_o/static/illustrations/widget-branding.svg?fit=max&auto=format&n=LGQPeWoIOylM_7_o&q=85&s=32e28986dc3c0b7c5458cb25e470676b" alt="Widget sign-in screen branded for a sample partner: the partner's logo in the header, and the partner's brand color on the consent checkbox, the terms link and the Continue button." className="dp-ncode-capture--widget" width="720" height="600" loading="lazy" data-path="static/illustrations/widget-branding.svg" />

## Two ways to open it

| | Hosted link | Initialize API |
| - | - | - |
| Setup | None: build a URL | One signed server call per session |
| Prefill | No | Flow, asset, network, amount, wallet |
| Opens in | New tab, redirect, webview or iframe | iframe, new tab or webview |
| Best for | Launching this week | A buy or sell button inside your app |

## Hosted link

Send users to the widget with your `app_id`. It works on desktop and mobile.

```text theme={null}
https://app.zapyd.com?app_id={your_app_id}
```

Your `app_id` comes with onboarding. Sandbox and production have different `app_id` values.

## Initialize API

Use this when your app already knows what the user wants, for example "sell 10 USDT on Tron".

<Steps>
  <Step title="Call Widget Initialize from your server">
    [Widget Initialize](/api-reference-exchange/endpoint/widget/initialize) takes a buy or a sell body:

    <CodeGroup>
      ```json Buy theme={null}
      {
        "flow_type": "buy",
        "asset_code": "USDT",
        "network_code": "tron",
        "fiat_currency": "INR",
        "fiat_amount": "1000",
        "payment_method": "IMPS",
        "wallet_address": "TXqH4MnDw46f3yyrRwau3JF92Y1ie3pAXf"
      }
      ```

      ```json Sell theme={null}
      {
        "flow_type": "sell",
        "asset_code": "USDT",
        "network_code": "tron",
        "fiat_currency": "INR",
        "asset_amount": "10"
      }
      ```
    </CodeGroup>

    <Warning>
      Widget Initialize uses its own signature: lowercase hex of HMAC-SHA256 over the raw body followed by the timestamp. See [Widget Initialize signing](/guides/development-and-testing/authentication#widget-initialize-uses-a-different-signature).
    </Warning>
  </Step>

  <Step title="Pass the link to your frontend">
    The response contains `data.widget_link`. Send only this URL to the browser. Your API secret stays on the server.
  </Step>

  <Step title="Embed it">
    ```html theme={null}
    <iframe
      src="{widget_link}"
      width="100%"
      height="700"
      style="border: none; border-radius: 12px;"
      allow="camera; microphone"
      title="Zapyd widget"
    ></iframe>
    ```

    Keep `allow="camera; microphone"`. The KYC selfie and document capture need the camera.
  </Step>
</Steps>

## Your backend's job

The widget handles the screens, but your backend still has to:

* Register a [webhook URL](/guides/development-and-testing/webhooks) and verify each event's signature.
* Act on final statuses. For example, don't credit a payin that is `ON_HOLD`.
* Record order IDs for reconciliation and support.

See [User journey](/guides/no-code/user-journey) for what users see and which webhooks each step sends.

## Branding

Zapyd sets your branding during onboarding, and it applies to both the hosted link and embedded sessions. To change it, email [support@zapyd.com](mailto:support@zapyd.com).

| Item | Where it appears |
| - | - |
| Logo | Widget header and emails |
| Primary color | Buttons and primary actions |
| Secondary color | Secondary UI and backgrounds |
| Email templates | Onboarding and transaction emails |

The widget at the top of this page shows the sample partner "Acme". Emails get the same branding:

<img src="https://mintcdn.com/dollarpe/LGQPeWoIOylM_7_o/static/illustrations/email-branding.svg?fit=max&auto=format&n=LGQPeWoIOylM_7_o&q=85&s=ed871a7ae0c05c85e2e308d4b1f57bef" alt="Verification email branded for a sample partner: the partner's logo at the top, the partner's brand color on the code and labels, and the partner's name in the body and footer." className="dp-ncode-capture--email" width="720" height="720" loading="lazy" data-path="static/illustrations/email-branding.svg" />

## Test it in sandbox

Open the hosted link with your sandbox `app_id`, or call Widget Initialize with sandbox credentials. The widget runs against sandbox data, and no real money moves.
