Skip to main content

Getting Started

Learn how to integrate Odus Checkout SDK into your application. This guide walks you through the complete setup process with code examples in React.

Prerequisites

Before you begin, make sure you have:

  1. A publishable key from your Odus Dashboard — this is required to initialize the checkout on the frontend and is safe to expose publicly.
  2. A backend endpoint that creates payments via the Odus API — see Making Payments for details.

How It Works

Odus Checkout uses a two-step initialization process:

  1. Mount — Renders the checkout form UI (card inputs, pay button) into your page
  2. Associate — Links the checkout to a payment created on your backend, enabling the pay button and loading available payment methods

The checkout is interactive immediately after mounting, but the pay button remains disabled until a payment is associated. You should both mount and associate as early as possible in your checkout flow to minimize wait times for customers.

Step 1: Install and Mount the Checkout

First, install the Checkout SDK via NPM:

npm install @odus/checkout

Then we'll create a React component that mounts the checkout form. At this stage, we'll set up the basic structure — the checkout UI will render, but the pay button won't be functional yet.

src/components/CheckoutForm.tsx
import { useEffect, useRef } from 'react';
import { OdusCheckout } from '@odus/checkout';
import '@odus/checkout/styles'; // Required for proper styling

export function CheckoutForm() {
const checkoutRef = useRef<OdusCheckout | null>(null);

useEffect(() => {
const checkout = new OdusCheckout({
environment: 'test', // Use 'live' for production
apiKey: 'pk_test_your_publishable_key',
returnUrl: 'https://your-website.com/checkout/return',
});

checkout.mount('#checkout-container');
checkoutRef.current = checkout;

return () => {
checkoutRef.current?.unmount();
};
}, []);

return <div id="checkout-container" />;
}

After this step, you'll see the card input form rendered on the page. The pay button appears but is disabled — that's expected. Let's fix that in the next step.

important

Don't forget to import the styles with import '@odus/checkout/styles'. Without this, the checkout form won't render correctly.

Step 2: Associate a Payment

For the checkout to accept payments, you need to link it to a payment created on your backend. Your backend should call the Odus API to create a payment and return two values: paymentId and checkoutKey.

info

Learn how to create payments on your backend in the Making Payments guide.

Here's the complete component with payment association and proper error handling:

src/components/CheckoutForm.tsx
import { useEffect, useRef, useState } from 'react';
import { OdusCheckout } from '@odus/checkout';
import '@odus/checkout/styles';

export function CheckoutForm() {
const checkoutRef = useRef<OdusCheckout | null>(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);

useEffect(() => {
const checkout = new OdusCheckout({
environment: 'test',
apiKey: 'pk_test_your_publishable_key',
returnUrl: 'https://your-website.com/checkout/return',
callbacks: {
onPaymentSucceeded: () => {
window.location.href = '/checkout/success';
},
onPaymentFailed: (errorMessage) => {
setError(`Payment failed: ${errorMessage}`);
},
},
});

checkout.mount('#checkout-container');
checkoutRef.current = checkout;

// Fetch payment details from your backend and associate
async function setupPayment() {
try {
const response = await fetch('/api/create-payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
});

if (!response.ok) {
throw new Error('Failed to create payment');
}

const { paymentId, checkoutKey } = await response.json();
await checkout.associatePayment(paymentId, checkoutKey);
} catch (err) {
setError('Failed to initialize payment. Please refresh the page.');
} finally {
setIsLoading(false);
}
}

setupPayment();

return () => {
checkoutRef.current?.unmount();
};
}, []);

return (
<div>
{isLoading && <div className="loading-spinner">Loading checkout...</div>}
{error && <div className="error-message">{error}</div>}
<div id="checkout-container" />
</div>
);
}

Once associatePayment() completes successfully:

  • The pay button becomes active
  • Alternative payment methods (PayPal, Apple Pay) appear if configured
  • Customers can complete their purchase
tip

Call associatePayment() as early as possible in your checkout flow. This minimizes the time customers spend waiting for the checkout to become ready.

Next Steps

Now that you have the basics set up, there are only a few steps left to get your checkout flow production-ready: