# CheckoutForm

The `CheckoutForm` component is the primary entry point for handling payment links and checkout sessions. It serves as a high-level wrapper that automatically fetches the necessary data based on a provided ID and renders the appropriate payment or donation interface. This component provides the most straightforward method for integrating a complete checkout flow into your application.

For the `CheckoutForm` to function correctly, it must be nested within a `PaymentProvider`. This provider supplies the necessary context, such as session information and API configuration. For detailed setup instructions, please refer to the [PaymentProvider documentation](./providers-payment-provider.md).

## How It Works

The component manages the entire checkout process through a clear, sequential flow:

1.  **Initialization**: The component is mounted with an `id` prop, which must be either a `paymentLink` ID (prefixed with `plink_`) or a `checkoutSession` ID (prefixed with `cs_`).
2.  **Data Fetching**: It sends a request to the payment backend to retrieve the complete checkout context, which includes available payment methods, line items, and customer details.
3.  **UI Rendering**: Based on the `formType` prop, it internally renders either the standard `Payment` component for purchases or the specialized `DonationForm` for contributions.
4.  **State Management**: It handles the full lifecycle of the transaction, managing loading states, completion status, and any potential errors.

## Props

The `CheckoutForm` component is configured using the following properties.

<x-field-group>
  <x-field data-name="id" data-type="string" data-required="true">
    <x-field-desc markdown>The unique identifier for the payment link (`plink_...`) or checkout session (`cs_...`).</x-field-desc>
  </x-field>
  <x-field data-name="mode" data-type="'standalone' | 'inline' | 'popup' | 'inline-minimal' | 'popup-minimal'" data-required="false" data-default="inline">
    <x-field-desc markdown>Defines the rendering mode. `'standalone'` creates a full-page view, while `'inline'` embeds the form within an existing container. The `-minimal` variants hide the order summary.</x-field-desc>
  </x-field>
  <x-field data-name="formType" data-type="'payment' | 'donation'" data-required="false" data-default="payment">
    <x-field-desc markdown>Specifies the type of form to render. Use `'donation'` to activate the specialized donation user interface.</x-field-desc>
  </x-field>
  <x-field data-name="onPaid" data-type="(res: CheckoutContext) => void" data-required="false">
    <x-field-desc markdown>A callback function that is executed upon successful payment completion. It receives the final checkout context as an argument.</x-field-desc>
  </x-field>
  <x-field data-name="onError" data-type="(err: Error) => void" data-required="false" data-default="console.error">
    <x-field-desc markdown>A callback function that is executed if an error occurs during the checkout process.</x-field-desc>
  </x-field>
  <x-field data-name="onChange" data-type="(data: CheckoutFormData) => void" data-required="false">
    <x-field-desc markdown>A callback function that fires whenever a value in the payment form changes.</x-field-desc>
  </x-field>
  <x-field data-name="goBack" data-type="() => void" data-required="false">
    <x-field-desc markdown>If provided, a back button is rendered. This function is called when the button is clicked.</x-field-desc>
  </x-field>
  <x-field data-name="extraParams" data-type="Record<string, any>" data-required="false" data-default="{}">
    <x-field-desc markdown>An object containing extra parameters to be appended to the URL when initiating a checkout session from a payment link.</x-field-desc>
  </x-field>
  <x-field data-name="theme" data-type="'default' | 'inherit' | PaymentThemeOptions" data-required="false" data-default="default">
    <x-field-desc markdown>Controls the component's theme. `'inherit'` uses the parent theme, while `'default'` applies the library's standard theme. A custom theme object can also be provided.</x-field-desc>
  </x-field>
  <x-field data-name="action" data-type="string" data-required="false" data-default="''">
    <x-field-desc markdown>A string identifier used for customizing UI elements, such as button text, or for tracking specific analytics events.</x-field-desc>
  </x-field>
</x-field-group>

## Usage Examples

### Basic Inline Payment Form

This is the most common use case, where the payment form is embedded directly into a page of your application. The component handles all data fetching and state management internally.

```javascript MyStorePage.jsx icon=logos:react
import { PaymentProvider, CheckoutForm } from '@blocklet/payment-react';
import { useSessionContext } from './hooks/session-context'; // This is an example hook from your application

export default function MyStorePage() {
  const { session, connectApi } = useSessionContext();

  const handlePaymentSuccess = (result) => {
    console.log('Payment successful!', result);
    alert('Thank you for your purchase!');
  };

  const handlePaymentError = (error) => {
    console.error('Payment failed:', error);
    alert('Sorry, your payment could not be processed.');
  };

  return (
    <PaymentProvider session={session} connectApi={connectApi}>
      <div style={{ maxWidth: '960px', margin: '0 auto' }}>
        <h1>Checkout</h1>
        <CheckoutForm
          id="plink_xxxxxxxxxxxxxx" // Replace with your Payment Link ID
          mode="inline"
          onPaid={handlePaymentSuccess}
          onError={handlePaymentError}
        />
      </div>
    </PaymentProvider>
  );
}
```

### Standalone Full-Page Checkout

Use `mode="standalone"` to render a dedicated, full-page checkout experience. This mode is ideal for redirecting the user to a separate URL to complete their payment without distractions.

```javascript CheckoutPage.jsx icon=logos:react
import { PaymentProvider, CheckoutForm } from '@blocklet/payment-react';
import { useSessionContext } from './hooks/session-context';

export default function CheckoutPage() {
  const { session, connectApi } = useSessionContext();

  // In a real application, you would get this ID from the URL parameters
  const paymentLinkId = 'plink_xxxxxxxxxxxxxx';

  return (
    <PaymentProvider session={session} connectApi={connectApi}>
      <CheckoutForm
        id={paymentLinkId}
        mode="standalone"
        onPaid={() => {
          // Redirect to a success page
          window.location.href = '/payment-success';
        }}
      />
    </PaymentProvider>
  );
}
```

### Donation Form

By setting `formType="donation"`, the component renders a specialized UI tailored for donation campaigns. This form includes features such as amount presets and can display information about the benefits of donating.

```javascript DonationPage.jsx icon=lucide:gift
import { PaymentProvider, CheckoutForm } from '@blocklet/payment-react';
import { useSessionContext } from './hooks/session-context';

export default function DonationPage() {
  const { session, connectApi } = useSessionContext();

  return (
    <PaymentProvider session={session} connectApi={connectApi}>
      <div style={{ padding: '2rem', textAlign: 'center' }}>
        <h2>Support Our Cause</h2>
        <CheckoutForm
          id="plink_yyyyyyyyyyyyyy" // Replace with your Donation Link ID
          formType="donation"
          onPaid={() => alert('Thank you for your generous donation!')}
        />
      </div>
    </PaymentProvider>
  );
}
```