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

# Checkout Widget

> Embed crypto payments in your website or app with a few lines of code

Integrate the MoonPay Commerce Checkout Widget with just a few lines of code to accept USDC, 100+ digital currencies and card payments via a seamless on-ramp flow.

* Embed a `paylinkId` as a Checkout Widget in your application for a seamless payment experience. Explore the configurations below
* Embed a `depositId` as a Deposit Widget in your app. [Learn more about deposit widget configuration options](https://docs.hel.io/docs/deposits.md#3-serve-the-deposit-ui-in-your-app)

Test and customise your configurations with our easy-to-use widget builder

> [!NOTE]
>
> [Checkout Widget Builder](https://demo.hel.io/)

# Get started

* Log into [MoonPay Commerce](https://app.hel.io/) to setup your `paylinkId` and generate the code snippet on the final step of our payment creation flow. Use [https://demo.hel.io/](https://demo.hel.io/) to customise your theme & config
* Our standard way to embed our checkout is with our JS/HTML embed - simply paste into your code builder as follows
* If you want to set the price in your widget programmatically, set the price to `dynamic` in the dashboard and pass the `amount`

# MoonPay Commerce Checkout (React)

If you have a React based app, then the easiest way to embed MoonPay Commerce Checkout is with our React component.

* [NPM Package](https://www.npmjs.com/package/@heliofi/checkout-react)

Install the dependency:

```bash Shell theme={null}
yarn add @heliofi/checkout-react
# or npm install @heliofi/checkout-react
# or pnpm add @heliofi/checkout-react
```

Then in your React components import it in (simply grab the example code snippet for our React component on step 4 when creating your Pay Link).

```bash JavaScript theme={null}
import {HelioCheckout} from '@heliofi/checkout-react'

const helioConfig = {
    paylinkId: "6571e7cd4a2bee8095ee84da",
    amount: "5.99",
};

function YourCheckoutComponent() {
  return <HelioCheckout config={helioConfig} />;
}
```

**Note:** if you are dynamically generating the config object, we recommend wrapping it in `useMemo()`

## Config Options

The configuration options object is the same for our Vanilla JS and React version.

### Common config options:

* One of the following must be set (but not both)
* `paylinkId`
  * **This is the ID for the Pay Link you would like to embed**
    * \*\*example: \*\*`paylinkId: "6571e7cd4a2bee1095ee84da"`
* `chargeToken`
  * [**A charge token (you can create charges via our API).**](/reference/charge/create.md#/)
    * **example:** `chargeToken: "05adc323-0450-4ef8-b127-18949b9ff485"`
* `network` (optional - default is `main`)
  * **values:** `main`
  * **example:** `network: "main"`
* `paymentType` (optional - default is `paylink`)
  * **values:** `paylink` or `paystream`
  * **example:** paymentType: "paystream"
  * **This is only required if you set up a recurring paystream embed.**
  * If your Pay Link is recurring, the code snippet on step 4 will already include `paymentType: "paystream"`
* `platform` only if you are embedding from presale.magiceden.io
  * [**If you are embedding our checkout for a Pay link created from moonpay.hel.io you should not set this value.**](https://moonpay.hel.io/)
  * **values:** `magic_eden`
  * **example:** platform: `magic_eden`

## Customising the look of the embed:

* `display` (optional - default is `inline`)
  * **values:** `button` `inline` or `new-tab`
  * **example:** `display: "button"` Use this to display a button that opens up a modal with our checkout flow
  * [**`example:display: "new-tab" Use this to display a button that opens up a unique, single use checkout page in a new tab. The "charge pages" are optimal for mobile payment flows, deep-linking, QR codes, embedded pay buttons on simple websites like Wix, or other custom payment flows. Learn more about Charges`**](https://docs.hel.io/docs/charges)
* `primaryPaymentMethod` (optional - default is `crypto`)
  * values: `crypto` or `fiat`
  * example: `primaryPaymentMethod: "fiat"`
  * **`If set tofiat, then 'pay with card' will be the default button option.`**
* `customTexts` (optional)
* **Use this to override some texts/copy within the embed.**
* Current options are as follows:

```text theme={null}
{
  customTexts: {
    mainButtonTitle: "Purchase via Helio",
    payButtonTitle: "Click to pay",
  }
}
```

* `themeMode` (optional — **recommended**)
* **values:** `light` or `dark`

Use the **top-level** `themeMode` to force a light or dark appearance:

> [!NOTE]
>
> `themeMode` controls **light vs dark** only — set it to force a mode, or omit it to follow the buyer's **system preference**. It is independent of the theme's colors: an assigned theme (`themeId`) or your **company default theme** (Settings → Themes) supplies both the light and dark palettes, and `themeMode` selects which one renders. So `themeMode: "dark"` with a custom theme shows that theme's dark palette. See [Themes](/docs/themes.md) for saving and assigning themes.

**Example usage:**

```text theme={null}
{
    paylinkId: "6571e7cd4a2bee1095ee84da",
    themeMode: "dark", // or "light" — omit to follow the buyer's system preference
}
```

* `theme` (optional — **legacy**)

The nested `theme` object (`theme.themeMode`, `theme.colors`) is the older,
pre-Themes-V2 customisation surface. It still works, but for Themes V2 use the
**top-level `themeMode`** above. `theme.themeMode` (nested) and `themeMode`
(top-level) are **separate fields** — don't confuse them.

```text theme={null}
{
    paylinkId: "6571e7cd4a2bee1095ee84da",
    theme: {
        themeMode: "dark", // legacy — prefer the top-level themeMode
    }
}
```

* `primaryColor` (optional, required when `neutralColor` is defined)
  * Use this to customise main colours within the embed
* `neutralColor` (optional, required when `primaryColor` is defined)
  * Use this to customise neutral colours such as border and text colours within the embed

**Example usage:**

```text theme={null}
{
    paylinkId: "6571e7cd4a2bee1095ee84da",
    primaryColor: "#E60000",
    neutralColor: "#5A6578"
}
```

* `backgroundColor` (optional, use this to change the background color)
  * values: Provide a `hex code` (e.g., #FFFFFF for white or #000000 for black)

**Example usage:**

```text theme={null}
{
    paylinkId: "6571e7cd4a2bee1095ee84da",
    backgroundColor: "#4bbe7c"
}
```

* showPayWithCard (optional - default is `true`)
  * Use this to remove the 'Pay with card' button from the embed.
  * values: `true`or `false`

**Example usage:**

```text theme={null}
{
    paylinkId: "6571e7cd4a2bee1095ee84da",
    showPayWithCard: false
}
```

## Dynamic config options

If you have a dynamic payment (to programatically set the amount a) then you will need to use these options:

* Log in to MoonPay Commerce and select CREATE PAYMENT -> Dynamic pricing -> paylinkId
* `amount` (required for dynamic payments)
  * values: a string value
  * example: `amount: "5.99"`
  * This will be the amount **of the payment currency**
* Use step 2 of the Pay link creation process on [moonpay.hel.io](https://moonpay.hel.io/) to set the currencies you will receive in.

## Autofill config options

Use the `autofillConfig` option to pre-populate customer and shipping fields in the checkout form.

All fields are optional strings.

**Customer details:**

* `fullName` — customer's full name
* `email` — customer's email address
* `phoneNumber` — phone number
* `areaCode` — phone area/country code

**Shipping address:**

* `deliveryAddress` — full delivery address (freeform)
* `street` — street name
* `streetNumber` — street/house number
* `city` — city
* `state` — state or region
* `country` — ISO 3166-1 alpha-2 country code (e.g. `"US"`, `"GB"`)
* `areaCode` — postal/area code

**Product:**

* `productValue` — pre-fill the product value
* `additionalProductValue` — additional product value

**Social handles:**

* `discordUsername` — Discord username
* `telegramUsername` — Telegram username
* `twitterUsername` — Twitter/X username

**Example:**

```text theme={null}
{
  paylinkId: "6571e7cd4a2bee1095ee84da",
  autofillConfig: {
    fullName: "Jane Doe",
    email: "jane@example.com",
    country: "US",
    city: "New York",
    street: "Broadway",
    streetNumber: "123",
    state: "NY",
  }
}
```

## Callback config options

Use our callbacks to run Javascript code when certain actions occur.

You can use these to trigger changes in your application.

* `onSuccess`
* `onError`
* `onPending`
* `onCancel`
* `onStartPayment`

**Example:**

```text theme={null}
{
  // ... (your other config options) ...
  onSuccess: event => console.log(event),
  onError: event => console.log(event),
  onPending: event => console.log(event),
  onCancel: () => console.log("Cancelled payment"),
  onStartPayment: () => console.log("Starting payment"),
}
```

In addition, we recommend using [our Pay Link webhooks](/reference/webhook/paylink-transaction/overview.md) to verify transaction on your backend. You can find an end-to-end developer example here including the Checkout Widget and webhooks here:

> [!NOTE]
>
> ### [MoonPay Commerce Checkout Embed Widget](https://embed.hel.io/)

## Advanced Config Options:

* `debug`(optional - default is `false`)
  * `true` or `false`
  * example: `debug: true`
  * if true then it will output some helpful debug information

### AdditionalJSON

* `additionalJSON` (optional)
  * values can be any valid JSON data.
  * example: `additionalJSON: {customerId: "customer1", product: "T-shirt"}`
  * Anything you pass in here will get stored when a customer makes a transaction.
  * You can retrieve this on transactions by listening for our [Pay Link webhooks](/reference/webhook/paylink-transaction/overview.md), which include all relevant values

> [!NOTE]
>
> **IMPORTANT:** Phantom requires domain allowlisting for the checkout widget to avoid transaction safety warnings. Fill this [form](https://docs.google.com/forms/d/e/1FAIpQLSeoSDtQc9CEHG-dC2EUO6ZkDCaFQXq3M92M1csH4WrdCCW-QQ/viewform) for allowlisting.

# React Native

Accept crypto payments in your React Native app with the `@heliofi/checkout-react-native` package.

It provides a drop-in provider, payment hook, and composable UI components for building a mobile checkout flow.

### Install

```text Bash theme={null}
npm install @heliofi/checkout-react-native
```

### Peer dependencies

```text Bash theme={null}
npm install react-native-gesture-handler react-native-reanimated react-native-safe-area-context react-native-svg lucide-react-native
```

### Quick start

Create a charge on your backend using the Charges API, then pass the returned `token` to the provider.

```text TypeScript theme={null}
import {
  MoonpayCommerceProvider,
  usePayWithCrypto,
} from '@heliofi/checkout-react-native';

export default function App() {
  return (
    <MoonpayCommerceProvider chargeToken="your-charge-token" network="main">
      <Checkout />
    </MoonpayCommerceProvider>
  );
}

function Checkout() {
  const { payWithCrypto } = usePayWithCrypto();

  return (
    <Button
      title="Pay with Crypto"
      onPress={() => payWithCrypto()}
    />
  );
}
```

### Notes

* `chargeToken` is required and should be created on your backend.
* Do not expose your API key in the client.
* Use `network="main"` for production.
* The SDK handles wallet selection, deeplinking, payment polling, and success/error states.

For the full API reference, props, and composable components, see the npm package:

> **Full reference**\
> For API reference, props, composable components, and package updates, see the `@heliofi/checkout-react-native`[ npm package](https://www.npmjs.com/package/@heliofi/checkout-react-native).
