> For the complete documentation index, see [llms.txt](https://docs.omni.integratedcommerce.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.omni.integratedcommerce.io/hosted-payment-form/hosted-payment-form.md).

# Overview

Embed a secure iframe so card data never touches your environment.

The Integrated Commerce Omni-Channel Payment API offers a secure Hosted Payment Form (HPF) solution that simplifies payment collection while maintaining strong security and compliance standards.

The customer enters their card details into the form, which is hosted outside your environment. Your servers never see or store card data.

## How it works

```mermaid
sequenceDiagram
    participant S as Your server
    participant A as Omni API
    participant B as Customer's browser
    participant W as Your webhook endpoint
    S->>A: POST /transactions/virtual-sale<br/>(returnUrl, useJavaScriptCallback)
    A-->>S: Session URL, session ID, expiry
    S->>B: Your page embeds the session URL in an iframe
    B->>A: Customer submits card details in the form
    A->>A: Process the payment
    A-->>B: JavaScript callback and/or redirect to returnUrl,<br/>or the default success or issue screen
    A->>W: Webhook with the transaction outcome
```

{% stepper %}
{% step %}

## Initiate the session

Your backend server makes a POST request to the API (for example `/payment-methods/virtual`, `/transactions/virtual-sale`) with your transaction details.

You can include a `returnUrl` parameter to control where customers are redirected after completing payment or tokenizing a card. The `returnUrl` is typically used to direct customers to order confirmation pages, receipt pages, or to grant immediate access to purchased digital content after successful payment.

You can also include a `useJavaScriptCallback` flag to have the iframe post a message to the parent page with the transaction response.
{% endstep %}

{% step %}

## Receive the session URL

The API returns a short-lived, unique iframe URL specific to this transaction, along with a session ID and expiration timestamp.
{% endstep %}

{% step %}

## Embed the form

You embed this iframe URL in your payment page. The iframe contains a fully-styled, responsive payment form.
{% endstep %}

{% step %}

## The customer enters payment info

The customer enters their payment information (card details, billing address) directly into the secure form, which is isolated from your website's environment.
{% endstep %}

{% step %}

## The API processes the payment

When the customer submits the form, the API processes the payment outside your environment.
{% endstep %}

{% step %}

## The flow completes

The flow completes differently depending on which parameters were included in your initial request. See [Flow completion](#flow-completion) below.
{% endstep %}

{% step %}

## Your system receives a webhook

Configured endpoints receive [webhook notifications](/webhooks/webhooks.md) for transaction outcomes. A local form error or abandoned session does not guarantee a transaction webhook.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
Configured webhooks report transaction outcomes independently of the customer's browser. A session or local validation error might not produce a transaction webhook. Use verified webhooks and authenticated transaction retrieval for your records, and use redirects and callbacks to update the customer's experience.
{% endhint %}

## Flow completion

Depending on the parameters in your initial request, the behaviour at the end of the transaction flow will be different:

| `useJavaScriptCallback` | `returnUrl`  | What happens                                                                                                                                                                                                                                                                                                                        |
| ----------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `true`                  | Provided     | The iframe sends the transaction response to your parent page via a JavaScript function, so you can direct the rest of the customer experience based on the outcome. The customer is then redirected to the `returnUrl`, with [transaction result parameters](/hosted-payment-form/transaction-results.md) in the URL query string. |
| `true`                  | Not provided | The iframe sends the transaction response to your parent page via a JavaScript function. The customer is redirected to the default success or issue screen.                                                                                                                                                                         |
| Omitted or `false`      | Provided     | No JavaScript function is called on the parent page. The customer is redirected to the `returnUrl`, with [transaction result parameters](/hosted-payment-form/transaction-results.md) in the URL query string.                                                                                                                      |
| Omitted or `false`      | Not provided | No JavaScript function is called on the parent page. The customer is redirected to the [default success or issue screen](/hosted-payment-form/screens.md).                                                                                                                                                                          |

## Next steps

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Form configuration</strong></td><td>Control how much billing information the form collects.</td><td><a href="/hosted-payment-form/form-configuration.md">Form configuration</a></td></tr><tr><td><strong>Verifying the redirect</strong></td><td>Validate the HMAC hash before trusting a redirect. Do not skip this.</td><td><a href="/hosted-payment-form/redirect-verification.md">Verifying the redirect</a></td></tr><tr><td><strong>JavaScript callbacks</strong></td><td>Handle the postMessage payload in your parent page.</td><td><a href="/hosted-payment-form/javascript-callbacks.md">JavaScript callbacks</a></td></tr><tr><td><strong>Best practices</strong></td><td>Origin validation, session timeouts, and responsive layout.</td><td><a href="/hosted-payment-form/best-practices.md">Implementation best practices</a></td></tr></tbody></table>

{% hint style="info" %}
If you need Apple Pay or Google Pay, use the [Payment SDK](/payment-sdk/payment-sdk.md) instead. It wraps the same sessions in a web component and adds wallet buttons.
{% endhint %}
