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

# React

> Use the useEscrowCheckout hook or the drop-in EscrowCheckoutButton.

The React entry point lives under the `payluk-escrow-inline-checkout/react`
subpath. It exposes the `useEscrowCheckout` hook and an
`EscrowCheckoutButton` component.

<Info>
  You still call `initEscrowCheckout()` once at your app root. The React helpers
  read from that single initialization.
</Info>

## Initialize at the root

```tsx theme={null}
// app entry (e.g. main.tsx / _app.tsx)
import { initEscrowCheckout } from 'payluk-escrow-inline-checkout';

initEscrowCheckout({ publicKey: '<YOUR_PUBLISHABLE_KEY>' });
```

## `useEscrowCheckout()`

The hook exposes the widget's readiness, an in-flight `loading` flag, the last
`error`, and a `pay` function that mirrors the core
[`pay()`](/sdk/javascript#pay-parameters) but manages loading and error state
for you.

```tsx theme={null}
import { useEscrowCheckout } from 'payluk-escrow-inline-checkout/react';

function CheckoutButton({ token }: { token: string }) {
  const { ready, loading, error, pay } = useEscrowCheckout();

  const handlePay = () =>
    pay({
      paymentToken: token,
      reference: `order_${Date.now()}`,
      redirectUrl: 'https://yourapp.com/checkout/complete',
      callback: (result) => console.log(result),
    });

  return (
    <>
      <button onClick={handlePay} disabled={!ready || loading}>
        {loading ? 'Processing…' : 'Pay with Escrow'}
      </button>
      {error && <p role="alert">{error.message}</p>}
    </>
  );
}
```

### Returns: `UseEscrowCheckoutResult`

| Field     | Type            | Description                                           |
| --------- | --------------- | ----------------------------------------------------- |
| `ready`   | `boolean`       | `true` once the widget script has loaded.             |
| `loading` | `boolean`       | `true` while a `pay()` call is in flight.             |
| `error`   | `Error \| null` | The last error encountered, normalized to an `Error`. |
| `pay`     | `typeof pay`    | Same signature as the core `pay()` function.          |

The hook takes no arguments.

## `<EscrowCheckoutButton>`

A ready-made button that calls `pay()` on click. Rendering props
(`children`, `disabled`, `className`, `title`) control the button; the rest are
forwarded to `pay()`.

```tsx theme={null}
import { EscrowCheckoutButton } from 'payluk-escrow-inline-checkout/react';

<EscrowCheckoutButton
  paymentToken="PY_8AB12C9D3045"
  reference="order_2026_0001"
  redirectUrl="https://yourapp.com/checkout/complete"
  brand="Acme Store"
  className="btn btn-primary"
  callback={(result) => console.log(result)}
  onClose={() => console.log('closed')}
>
  Pay with Escrow
</EscrowCheckoutButton>
```

### Props: `EscrowCheckoutButtonProps`

| Prop           | Type                      | Required | Description                      |
| -------------- | ------------------------- | -------- | -------------------------------- |
| `paymentToken` | `string \| string[]`      | Yes      | Token(s) to fund.                |
| `reference`    | `string`                  | Yes      | Your unique checkout reference.  |
| `redirectUrl`  | `string`                  | Yes      | Post-completion redirect URL.    |
| `children`     | `React.ReactNode`         | No       | Button label. Defaults to `Pay`. |
| `disabled`     | `boolean`                 | No       | Disables the button.             |
| `className`    | `string`                  | No       | CSS class for the button.        |
| `title`        | `string`                  | No       | Native `title` attribute.        |
| `brand`        | `string`                  | No       | Forwarded to `pay()`.            |
| `customerId`   | `string`                  | No       | Forwarded to `pay()`.            |
| `logoUrl`      | `string`                  | No       | Forwarded to `pay()`.            |
| `extra`        | `Record<string, unknown>` | No       | Forwarded to `pay()`.            |
| `callback`     | `(result: any) => void`   | No       | Forwarded to `pay()`.            |
| `onClose`      | `() => void`              | No       | Forwarded to `pay()`.            |

## Next.js & SSR

The widget runs in the browser only. Trigger `pay()` from a client component in
response to a user action (a click), never during render or on the server; a
server-side call throws `BROWSER_ONLY`. In the App Router, mark the file with
`'use client'`.
