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

# Embed the portal

> Mount the full payment portal inside your site with an iframe.

You can show the payment portal **inside your own site** with an iframe, instead of sending the user to `app.tapipay.la`. The user sees their debts and pays without leaving your page.

## Minimal iframe

```html theme={null}
<iframe
  src="https://app.tapipay.la/s/acme-corp/portal/CLI-00042"
  width="100%"
  height="700"
  style="border: none;"
  allow="payment"
  title="Payment portal"
></iframe>
```

That is all you need. The `src` follows the same structure as a [payment link](/en/payment-portal/payment-link), so you can also identify your company by `companyCode`:

```html theme={null}
<iframe src="https://app.tapipay.la/c/MX-S-12345/portal/CLI-00042" ...></iframe>
```

### The attributes that matter

<ResponseField name="allow" type="&#x22;payment&#x22;">
  Enables the Payment Request API inside the iframe, which is what wallet payment methods rely on. The SDK always sets it, so it is worth setting it on a hand-built iframe too for the same behavior.
</ResponseField>

<ResponseField name="height" type="number">
  The iframe does **not** resize itself. Pick a value that fits the longest list of debts you expect (700px is a reasonable starting point) or let the SDK handle the height, which it does automatically.
</ResponseField>

<ResponseField name="width" type="string" default="100%">
  With `100%` the portal adapts to its container width. The portal is responsive: check how it looks on both mobile and desktop.
</ResponseField>

## Iframe or SDK

The manual iframe is the simplest route, but the [SDK](/en/payment-portal/payment-methods-sdk) handles things you do not get by hand:

|                     | Manual iframe        | SDK                                                                 |
| ------------------- | -------------------- | ------------------------------------------------------------------- |
| Content height      | Fixed, you define it | **Automatic**, the widget reports its height and the SDK applies it |
| Loading state       | Blank until it loads | **Skeleton** while loading, with a transition                       |
| Payment events      | None                 | `paymentWindowOpened`, `paymentSubmitted`, `paymentCancelled`       |
| `allow="payment"`   | You set it           | The SDK sets it                                                     |
| Unmounting in a SPA | Manual               | `destroy()` cleans up the iframe and listeners                      |
| Scope               | Full portal          | Payment methods only, or autopay only                               |

<Tip>
  Use the **manual iframe** if you want the full portal (debt list included) inside a static page. Use the **SDK** if you need to react to the payment from your code, if you are in a SPA, or if you want to show only the payment methods step.
</Tip>

## Considerations

<Warning>
  Use the `app.tapipay.la` domain in `src`. The `www.tapipay.la` and `tapipay.la` domains redirect there, and a redirect inside an iframe adds latency to the first render.
</Warning>

* **One iframe per user.** The `identifierValue` in the `src` determines whose debts are shown. Build it on your server using the identifier of the user with the open session.
* **No credentials in `src`.** The portal URL carries no tokens or API keys. Do not add yours: the portal is a public screen that resolves access from the identifier.
