> For the complete documentation index, see [llms.txt](https://docs.pay.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.pay.io/api-reference/user-payment-api/add-on-ramping-to-your-site.md).

# Add On-Ramping To Your Site

This guide gives an overview on how to implement the On-Ramping functionality using Pay.io's Payment Gateway and User Payment API. \
\
Learn more about the feature and benefits in [On-Ramping: Buying Crypto with Fiat](/on-ramping-buying-crypto-with-fiat.md).

{% hint style="info" %}
**API endpoint used in this guide  ->** [**Create a Payment Session**](/api-reference/user-payment-api/create-a-payment-session.md)
{% endhint %}

## Integration Flow

The integration relies on a **single** **backend** **API** **call** to generate a unique **URL**, which is then rendered on your frontend within an iframe.

```mermaid
sequenceDiagram
    participant User as End User
    participant Frontend as Merchant Cashier UI
    participant Backend as Merchant Backend
    participant PayIO as Pay.io API
    participant Provider as Onramp Provider

    User->>Frontend: Clicks "Buy Crypto" button
    Frontend->>Backend: Request onramp session
    Backend->>PayIO: POST /v1/user/payments
    PayIO-->>Backend: Returns secure URL (link)
    Backend-->>Frontend: Passes URL to UI
    Frontend->>Frontend: Renders URL inside iFrame
    User->>Provider: Completes KYC & buys crypto via Fiat
    Provider-->>PayIO: Executes crypto transfer to user wallet
    PayIO-->>Frontend: Balance updated (Standard Deposit)
```

## **Generate the On Ramp URL (Backend)**

To initiate the flow, your backend must call the Pay.io User Payments API to generate a unique, user-specific URL.

**Endpoint**: [`POST /v1/user/payments`](/api-reference/user-payment-api/create-a-payment-session.md)

**Authentication**: API Key (`Bearer YOUR_API_KEY` in the header)

{% code title="Request payload example" %}

```json
{
  "payment_type": "ON_RAMP",              // required
  "country": "GB",                        // required — ISO 3166-1 alpha-2
  "currency_id": "123e4567-e89b-12d3-a456-426614174000", // required
  "user_reference_id": "player_98765",    // required unless custom_wallet_address is set
  "custom_wallet_address": "0xabc123...", // optional — self-custody destination
  "amount": "100",                        // required for ON_RAMP
  "fiat_currency": "GBP",                 // required for ON_RAMP
  "redirect_url": "https://yourcasino.io/deposit-complete", // required
  "session_reference": "order_9981",      // optional
  "metadata": {}                          // optional
}
```

{% endcode %}

**Key Parameters**

* `country` - The user's ISO 3166-1 alpha-2 country code (e.g.`GB`,`DE`). Required, no default — dictates which payment methods (like Apple Pay) are displayed in the widget, and is locked into the widget once set.
* `currency_id` - UUID of the target cryptocurrency the user is buying. Must be a currency your merchant account has enabled with the provider.
* `user_reference_id` - Your platform's stable, unique player ID. Required *unless* `custom_wallet_address` is supplied — used to attribute the session to a system-custody wallet and is echoed back in webhooks as the customer identifier.
* `custom_wallet_address` - The user's own (self-custody) wallet address to receive funds instead of your platform's managed wallet. Optional.\
  Only honoured if your merchant account has the custom-external-wallet flag enabled — otherwise the request is rejected with `403 custom_wallet_not_allowed_for_merchant`. Contact your account manager to enable it.
* `amount`/`fiat_currency` - The fiat amount and 3-letter ISO 4217 currency the user is paying with. Both required for ON\_RAMP and locked into the widget, so the user can't change them mid-flow.
* `redirect_url`  - Where the widget sends the user after completing (or abandoning) the flow. Must start with `http://`  or `https://`.
* `session_reference`*(optional) -* Your own idempotency/tracking ID for this session. Echoed back in webhooks alongside `correlation_key`.

{% code title="Response example" %}

```json
{
  "link": "https://onramp.example.com/session/abc123...",
  "correlation_key": "f47ac10b-58cc-4372-a567-0e02b2c3d479:order_9981",
  "expires_at": null
}
```

{% endcode %}

## **Render the iframe (Frontend)**

Once your backend receives the `link` from the API, pass it to your frontend. You will need to embed this URL seamlessly into your Cashier UI, so the user does not feel like they are leaving your site.

{% hint style="info" %}
**Best Practices**

* Ensure the iframe width is 100% of its container, especially for mobile users.
* Give the iframe a sufficient minimum height (e.g., `600px` to `700px`) to prevent awkward inner scrolling during the KYC steps.
* Remove default borders to make the widget look native to your platform.
  {% endhint %}

{% code title="Example for frontend HTML for the Iframe" %}

```html
<div class="onramp-widget-container">
  <iframe 
    src="YOUR_GENERATED_URL_HERE" 
    title="Buy Crypto Securely"
    allow="camera; microphone; payment" 
    frameborder="0">
  </iframe>
</div>

<style>
  .onramp-widget-container {
    width: 100%;
    max-width: 500px; /* Adjust based on your UI */
    margin: 0 auto;
    border-radius: 12px;
    overflow: hidden;
  }
  .onramp-widget-container iframe {
    width: 100%;
    height: 700px;
    border: none;
  }
</style>
```

{% endcode %}

{% hint style="info" %}
The `allow="camera; microphone"` attributes are crucial, as users may need their device camera to upload ID documents for the **KYC** **verification** **step**.
{% endhint %}


---

# 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.pay.io/api-reference/user-payment-api/add-on-ramping-to-your-site.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.
