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

# Embedded checkout

> Take payment inside your app with the React checkout, styled with your brand.

`@useroutr/checkout-react` is the same checkout as the hosted page, as a React component. It
opens as a modal or renders inline, shows your user what to send and follows the payment to
completion. Your API key never touches the browser: the component needs only the intent's
funding token.

<CodeGroup>
  ```bash npm theme={null}
  npm install @useroutr/sdk @useroutr/checkout-react
  ```

  ```bash pnpm theme={null}
  pnpm add @useroutr/sdk @useroutr/checkout-react
  ```

  ```bash yarn theme={null}
  yarn add @useroutr/sdk @useroutr/checkout-react
  ```
</CodeGroup>

<Steps>
  <Step title="Create the intent on your server">
    The amount is yours to decide, so decide it where your user cannot change it. Return only the
    funding token, the last segment of `hosted_funding_url`.

    ```ts app/actions.ts theme={null}
    "use server";

    import { Useroutr } from "@useroutr/sdk";

    const useroutr = new Useroutr({ apiKey: process.env.USEROUTR_API_KEY });

    export async function startCheckout(orderId: string) {
      const intent = await useroutr.fundingIntents.create(
        { amount: "25", asset: "asset_usdc_stellar", reference: orderId },
        { idempotencyKey: orderId },
      );
      const url = intent.hosted_funding_url ?? "";
      return url.slice(url.lastIndexOf("/") + 1);
    }
    ```
  </Step>

  <Step title="Render the checkout">
    ```tsx app/pay-button.tsx theme={null}
    "use client";

    import { UseroutrCheckout } from "@useroutr/checkout-react";
    import { useState } from "react";
    import { startCheckout } from "./actions";

    export function PayButton({ orderId }: { orderId: string }) {
      const [token, setToken] = useState<string | null>(null);

      return (
        <>
          <button onClick={async () => setToken(await startCheckout(orderId))}>Pay</button>
          {token === null ? null : (
            <UseroutrCheckout
              token={token}
              baseUrl="https://api.sandbox.useroutr.com/v1/public"
              mode="modal"
              onSuccess={() => console.log("paid")}
              onClose={() => setToken(null)}
            />
          )}
        </>
      );
    }
    ```

    Use `https://api.useroutr.com/v1/public` in production.
  </Step>

  <Step title="Fulfil on the webhook">
    `onSuccess` is for your interface: close the modal, show a thank-you. Fulfil the order on
    your server when the [`funding.credited` webhook](/guides/webhooks) arrives. It is signed, and
    it reaches you even if your user closes the page before the payment completes.
  </Step>
</Steps>

## Props

<ParamField path="token" type="string" required>
  The funding token from the intent's `hosted_funding_url`. It grants exactly one intent.
</ParamField>

<ParamField path="baseUrl" type="string" default="/api/public">
  Where the checkout's three public endpoints live: `https://api.sandbox.useroutr.com/v1/public`
  or `https://api.useroutr.com/v1/public`. They answer any origin, so you do not need to proxy
  them.
</ParamField>

<ParamField path="mode" type="&#x22;modal&#x22; | &#x22;inline&#x22;" default="modal">
  Open over your page, or render in place.
</ParamField>

<ParamField path="theme" type="&#x22;light&#x22; | &#x22;dark&#x22;" default="light">
  The colour scheme.
</ParamField>

<ParamField path="appearance" type="CheckoutAppearance">
  Override your saved branding for this checkout: `brandColor`, `logoUrl`, `radius` and
  `fontFamily`. See [Branding](/payments/branding).
</ParamField>

<ParamField path="onSuccess" type="(intent) => void">
  Called once, when the funding intent is credited, with the payer's view of the intent.
</ParamField>

<ParamField path="onError" type="(failure) => void">
  Called once, when the checkout cannot complete: the intent failed, expired or cannot be loaded.
</ParamField>

<ParamField path="onClose" type="() => void">
  Called when your user closes the modal.
</ParamField>

## The token is the credential

The endpoints the checkout calls take no API key, cookie or session. They are addressed by the
funding token, which is unguessable and grants one intent. Treat it like a payment link: give
it to the person paying and nobody else.

<Warning>
  If you find yourself putting an API key in the browser, the funding intent is being created in
  the wrong place. Move it to your server.
</Warning>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.