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

# Checkout integration - Integration steps

> The complete process for integrating payments using the Waffo hosted Checkout.

Checkout is the simplest integration method—redirect users to a Waffo-hosted payment page without handling sensitive card information.

## Workflow

```mermaid theme={null}
sequenceDiagram
    participant M as Merchant server
    participant W as Waffo
    participant U as User

    M->>W: 1. Create order (API)
    W-->>M: 2. Return orderAction
    M->>U: 3. Redirect user
    U->>W: 4. User completes payment
    W-->>M: 5. Webhook notification
    W->>U: 6. Redirect back to merchant
```

<Steps>
  <Step title="Create an order on your server">
    Call the payment creation API to obtain `orderAction` from the response. `orderAction` is a JSON string.
  </Step>

  <Step title="Redirect the user">
    Parse `orderAction`, then use `webUrl` or `deeplinkUrl` based on `actionType`. The user will complete the payment on the Waffo Checkout page.
  </Step>

  <Step title="Handle the result">
    * **Webhook** (recommended): Waffo sends the payment result notification to `notifyUrl`
    * **Redirect**: Successful payments redirect to `successRedirectUrl`; payment pre-verification failures or failed payments redirect to `failedRedirectUrl`; user cancellation without continuing redirects to `cancelRedirectUrl`
    * **Active query**: Call the payment query API

    <Warning>
      A redirect only indicates the user returned to your website—it does not mean the payment succeeded. Always rely on the Webhook or the active query result.
    </Warning>
  </Step>
</Steps>

### Get the Checkout URL

`orderAction` is a JSON string. Parse it first, then choose the URL based on `actionType`:

Different values for `payMethodType` and `payMethodName` affect whether the user enters the Waffo payment-method selection page first. See [Cashier integration - Customization options](/en/developer-docs/integration/checkout/customization).

```typescript theme={null}
const orderAction = JSON.parse(response.data.orderAction);
const checkoutUrl = orderAction.actionType === 'DEEPLINK'
  ? orderAction.deeplinkUrl
  : orderAction.webUrl;
```

### Payment method prerequisites

* **WeChat Pay**: If you need WeChat Pay in production, submit the production domain to Waffo in advance. Waffo will file it with the payment channel.

***

## iframe Embedding Considerations

If you embed the Waffo Checkout inside an iframe, pay attention to the following:

### Required Configuration

* **`allow="payment"` attribute**: The iframe tag must include `allow="payment"`, otherwise payment methods such as Google Pay will not work on Android devices.
* **Referrer Policy**: Must be set to `strict-origin-when-cross-origin`, otherwise WeChat Pay will fail.

```html theme={null}
<head>
  <meta name="referrer" content="strict-origin-when-cross-origin">
</head>

<iframe src="https://cashier.waffo.com/..." allow="payment"></iframe>
```

### Responsive Width

Do not use a fixed width (e.g. `width: 700px`), as content will be clipped on different devices. Use a responsive layout instead:

```css theme={null}
.checkout-container {
  overflow: scroll;
  height: calc(100vh - 40px);
}
```

### Known Limitations

<Warning>
  * **Apple Pay**: Native Apple Pay cannot be used inside an iframe because of same-origin policy restrictions. This affects both H5 and PC iframe embeds. **Waffo provides a JS SDK solution for this scenario; report the domain to Waffo in advance before using it.** App WebViews are not affected by this iframe limitation.
  * **JKOPAY**: Does not support iframe loading.
  * **Mobile**: Check that the iframe does not have a fixed size that causes it to render as a landscape PC page on mobile.
  * For more limitations that apply by payment method or payment method type, see [Payment method integration notes](/en/developer-docs/tools-and-references/references/payment-method-integration-notes).
</Warning>

***

## `window.open` Embedding Considerations

When opening the Checkout with `window.open`:

* **Synchronous calls are fine**: Calling `window.open()` directly inside a click event handler works without issues.
* **Async calls will be blocked**: If `window.open()` is called after an `await`, the browser will block the popup. Workaround: open a blank window with `window.open()` first, then assign the URL once retrieved asynchronously; or show a confirmation dialog so the user can click to open it manually.
* **Apple mobile**: User gesture detection is strict—async opens are almost always blocked.

***

## App WebView Integration Considerations

When a merchant App loads the Checkout inside a WebView:

* **External launch capability**: Confirm that the App and WebView allow opening external Apps or external browser pages. Some wallets complete authorization through deeplinks or external pages. Blocking this will stop the payment flow.
* **Download and copy capability**: WebViews may not support file downloads, copy actions, or long-press save behavior by default. QR, OTC, and bank-transfer style payment methods may depend on these capabilities.
* **Redirect URL integrity**: When passing URLs between the native App and WebView, do not rewrite the URL or drop query parameters. Some payment methods append required parameters to the redirect URL.
* **`userTerminal`**: Pass `APP` instead of `WEB` to receive redirect links optimised for the App environment.
* **Payment method-specific limitations**: For PayPay Smart Payment, Google Pay, Apple Pay, JKOPAY, and other environment-specific limitations, see [Payment method integration notes](/en/developer-docs/tools-and-references/references/payment-method-integration-notes).
