# Kustom Checkout in a React Native app

Add Kustom Checkout to a React Native app with react-native-kustom-inapp-sdk — render KustomCheckoutView, set the snippet and handle onEvent and onError.

This guide adds Kustom Checkout to a React Native app with the Kustom Mobile SDK. You render
the `KustomCheckoutView` component, set the checkout snippet your server returns on it, and
handle the events it dispatches. [Kustom Checkout in a mobile app](/checkout/mobile-sdk/)
explains what's common to every platform.

## Before you start

You need:

- **A server endpoint that returns a checkout snippet.** Your backend, not the app, creates
  the order with your API credentials and returns its `html_snippet`. See [Create and update
  an order](/checkout/integrate/create-order/). This guide calls the endpoint `<YOUR-URL>`.
- **A return URL.** A custom URL scheme your app is registered for, such as `myapp://`. It
  brings the customer back after a payment method sends them to a third-party app. See [the
  return URL](/checkout/mobile-sdk/#the-return-url).

## Step by step

### 1. Add the SDK

Add
[`react-native-kustom-inapp-sdk`](https://github.com/Kustom-Checkout/react-native-kustom-inapp-sdk)
to your app. Its getting-started guide lists the available versions.

### 2. Render the checkout view

Import `KustomCheckoutView` and render it. `returnUrl` is its only required prop:

```tsx
import { KustomCheckoutView } from 'react-native-kustom-inapp-sdk';

const Checkout = () => (
  <KustomCheckoutView
    style={{ flex: 1 }}
    returnUrl={'myapp://'}
    onEvent={(event) => {
      if (event.action === 'complete') {
        // Navigate to your confirmation screen
      }
    }}
    onError={(error) => {
      // If error.isFatal is set, the checkout can't continue
    }}
  />
);
```

### 3. Set the snippet

Fetch the `html_snippet` from `<YOUR-URL>` and pass it to the component's `setSnippet`
method. This is what renders the checkout.

### 4. Handle events and errors

`onEvent` receives a `KustomProductEvent` with an `action` and its `params`. The `complete`
action means the customer has paid, and `params.uri` is the confirmation URL to load next.

`onError` receives a `KustomMobileSDKError`. If its `isFatal` is set, the checkout can't
continue, so send the customer somewhere else. [Events and
errors](/checkout/mobile-sdk/#events-and-errors) lists every action and error field.

## KustomCheckoutView props and methods

| Prop | Type | Required | Description |
| --- | --- | --- | --- |
| `returnUrl` | string | Yes | The URL third-party apps use to return the customer to your app. It must match the return URL your app is registered for. |
| `style` | `ViewStyle` | No | Styles the view. |
| `onEvent` | `(event: KustomProductEvent) => void` | No | Called when the component receives an event. The event has an `action` (string) and `params` (`{ [key: string]: any }`). |
| `onError` | `(error: KustomMobileSDKError) => void` | No | Called when an error occurs. The error has a `name`, a `message`, an `isFatal` flag and the `sessionId` it occurred in. |

| Method | Description |
| --- | --- |
| `setSnippet(snippet)` | Sets the checkout HTML snippet. Takes a string. |
| `suspend()` | Suspends the checkout and shows a loading indicator. |
| `resume()` | Resumes the checkout after `suspend()`. |

## Check that it works

Point the app at a Playground order and run the flow end to end:

1. The checkout renders in the view after `setSnippet`, rather than staying blank.
2. Paying with [Playground test data](/basics/test-data/) calls `onEvent` with a `complete` event carrying a `uri`.
3. Your confirmation screen loads from that `uri`.
4. Turning off the network mid-checkout calls `onError`, with `isFatal` telling you whether to recover or bail out.

A blank view almost always means the snippet never arrived. Check the response from
`<YOUR-URL>` before suspecting the SDK.

## Variations

**Pausing the checkout while you update the order.** Call `suspend()` before you change the
order and `resume()` afterwards, so the customer never sees stale totals. While suspended, the
view shows a loading indicator.

## Troubleshooting

**The customer is left in the bank app after BankID.** BankID may not return the customer
automatically after authentication. They might have to switch back to your app themselves.

## Related

- [Confirmation and push](/checkout/integrate/confirmation-and-push/) — what your server must do once `complete` fires
- [Create and update an order](/checkout/integrate/create-order/) — the call behind `<YOUR-URL>`
- [Kustom Checkout in a mobile app](/checkout/mobile-sdk/) — native or hybrid, the return URL and migrating from the Klarna Mobile SDK
- [iOS](/checkout/mobile-sdk/ios/) and [Android](/checkout/mobile-sdk/android/) — the same integration on the other platforms
- [Test data](/basics/test-data/) — Playground customers and cards to pay with
