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

# Create checkout programmatically

> Build custom checkout flows using FunnelFox APIs. Create checkout sessions, handle payments, and manage purchase completion.

Creates and opens a new checkout session for a given price and customer, and renders the payment UI on the page. This is the primary method to initiate a subscription checkout.

<Tip>
  You can customize the checkout appearance and styles. Learn more about [checkout customization](/develop/checkout-customization).
</Tip>

## Parameters

<ParamField body="orgId" type="string" required>
  Your organization ID, if not already configured globally. Useful if you did not call `configure()` or need to override it for this checkout.
</ParamField>

<ParamField body="priceId" type="string" required>
  The price identifier for the subscription or product.
</ParamField>

<ParamField body="customer" type="object" required>
  Customer information.

  <Expandable title="customer properties">
    <ParamField body="externalId" type="string" required>
      Your internal identifier for the user.
    </ParamField>

    <ParamField body="email" type="string" required>
      Customer's email address.
    </ParamField>

    <ParamField body="countryCode" type="string">
      ISO country code for the customer (if applicable).
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="container" type="string" required>
  A CSS selector for the DOM element where the checkout form will be mounted.

  <Expandable title="container styling requirements">
    When using the default skin, the container element must have the following CSS properties for proper display of the loading indicator:

    ```css theme={null}
    #checkout-container {
      position: relative;
      min-height: 200px; /* Adjust based on your layout */
    }
    ```

    * `position: relative`: Required because the loading overlay uses `position: absolute` to cover the container
    * `min-height`: Required to ensure the loader is visible during initialization. Recommended minimum is `200px`
  </Expandable>
</ParamField>

<ParamField body="clientMetadata" type="object">
  Additional metadata to associate with this checkout or customer. This data will be passed through to your backend.
</ParamField>

<ParamField body="cardSelectors" type="object">
  Custom CSS selectors for card input fields. If not provided, FunnelFox will auto-generate the payment form.

  <Expandable title="Card selector properties">
    <ParamField body="cardNumber" type="string" required>
      CSS selector for an empty `<div>` where the hosted card number input is injected.
    </ParamField>

    <ParamField body="expiryDate" type="string" required>
      CSS selector for an empty `<div>` for the hosted expiry input.
    </ParamField>

    <ParamField body="cvv" type="string" required>
      CSS selector for an empty `<div>` for the hosted CVV input.
    </ParamField>

    <ParamField body="button" type="string" required>
      CSS selector for a `<button>` element. The SDK hooks its click event for form submission.
    </ParamField>

    <ParamField body="cardholderName" type="string">
      CSS selector for an `<input>` element. The SDK reads its value directly.
    </ParamField>

    <ParamField body="emailAddress" type="string">
      CSS selector for an `<input>` element. The SDK reads its value directly.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="paymentButtonSelectors" type="object">
  Custom CSS selectors for payment buttons. Resolved relative to `document`, not the container.

  <Expandable title="Payment button selector properties">
    <ParamField body="paypal" type="string" required>
      CSS selector for a `<div>` where the PayPal button is rendered.
    </ParamField>

    <ParamField body="googlePay" type="string" required>
      CSS selector for a `<div>` where the Google Pay button is rendered.
    </ParamField>

    <ParamField body="applePay" type="string" required>
      CSS selector for a `<div>` where the Apple Pay button is rendered.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="paymentMethodOrder" type="array">
  Array of payment method identifiers to control the display order. Available values: `'PAYMENT_CARD'`, `'PAYPAL'`, `'GOOGLE_PAY'`, `'APPLE_PAY'`. Defaults to `['APPLE_PAY', 'GOOGLE_PAY', 'PAYPAL', 'PAYMENT_CARD']`.
</ParamField>

<ParamField body="onInitialized" type="function">
  Callback invoked when the checkout has been initialized and is ready.
</ParamField>

<ParamField body="onSuccess" type="function">
  Callback to execute when the payment is successful. An alternative to listening for the `'success'` event.
</ParamField>

<ParamField body="onError" type="function">
  Callback for handling errors. Alternative to the `'error'` event.
</ParamField>

<ParamField body="onStatusChange" type="function">
  Callback invoked on every status change. Alternative to the `'status-change'` event.
</ParamField>

## Returns

A `Promise<CheckoutInstance>` that resolves to a `CheckoutInstance` object representing the checkout session. You can use this object to monitor events or perform actions on the active checkout.

## Example

```javascript theme={null}
import { createCheckout } from '@funnelfox/billing';

const checkout = await createCheckout({
  // Required
  priceId: 'price_123',
  customer: {
    externalId: 'user_456',
    email: 'user@example.com',
    countryCode: 'US', // Optional
  },
  container: '#checkout-container',

  // Optional
  orgId: 'your-org-id', // If not configured globally
  clientMetadata: { source: 'web' },
  cardSelectors: {
    // Custom card input selectors (optional, defaults to auto-generated)
    cardNumber: '#cardNumberInput',
    expiryDate: '#expiryInput',
    cvv: '#cvvInput',
    cardholderName: '#cardHolderInput',
    emailAddress: '#emailInput',
    button: '#submitButton',
  },
  paymentButtonSelectors: {
    paypal: '#paypalButton',
    googlePay: '#googlePayButton',
    applePay: '#applePayButton',
  },
  paymentMethodOrder: ['APPLE_PAY', 'GOOGLE_PAY', 'PAYPAL', 'PAYMENT_CARD'], // Optional

  // Callbacks (alternative to events)
  onInitialized: () => {
    /* ... */
  },
  onSuccess: result => {
    /* ... */
  },
  onError: error => {
    /* ... */
  },
  onStatusChange: (state, oldState) => {
    /* ... */
  },
});
```
