React SDK
The coal-react package provides a <CoalCheckoutButton> component and a useCoalCheckout hook for integrating Coal payments into React applications. The SDK is redirect-based — it navigates users to the Coal-hosted checkout page. Full TypeScript support is included.
Installation
1npm install coal-react2# or3yarn add coal-react4# or5pnpm add coal-react
Peer dependencies: React 18+ and React DOM 18+.
How it works
Coal uses a redirect-based checkout flow:
- Your server creates a checkout session via the Coal API
- Your server returns a
checkoutUrlto the client - The SDK button redirects the user to that URL
- The user pays on the Coal-hosted page
- After payment, Coal redirects the user to your
redirectUrl
No iframe, no postMessage events — just a clean redirect flow.
<CoalCheckoutButton>
Renders a styled button that redirects to the Coal checkout page.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
checkoutUrl | string | — | Full checkout URL returned by your session endpoint. Preferred. |
sessionId | string | — | Alternative to checkoutUrl — URL is constructed from this. |
baseUrl | string | 'https://usecoal.xyz' | Override the Coal base URL (for local dev). |
target | '_self' | '_blank' | '_self' | '_self' redirects in the current tab, '_blank' opens a new tab. |
onBeforeRedirect | () => void | — | Callback fired just before the redirect. Use for analytics. |
children | React.ReactNode | "Pay with Coal" | Override button content. |
className | string | — | CSS class names on the button element. |
style | React.CSSProperties | — | Inline styles on the button element. |
Basic usage
1import { CoalCheckoutButton } from 'coal-react';23export default function BuyButton({ checkoutUrl }: { checkoutUrl: string }) {4 return (5 <CoalCheckoutButton6 checkoutUrl={checkoutUrl}7 onBeforeRedirect={() => console.log('Redirecting to checkout…')}8 />9 );10}
With session ID
If your backend returns only a sessionId, you can pass that instead:
1<CoalCheckoutButton2 sessionId={sessionId}3 baseUrl="https://usecoal.xyz"4/>
Open in a new tab
Useful for demo pages or when you want to keep your page visible:
1<CoalCheckoutButton2 checkoutUrl={checkoutUrl}3 target="_blank"4>5 Pay with Crypto ↗6</CoalCheckoutButton>
useCoalCheckout hook
A lower-level hook that gives you the resolved URL and programmatic redirect/open methods.
Signature
1function useCoalCheckout(options: UseCoalCheckoutOptions): UseCoalCheckoutReturn
UseCoalCheckoutOptions
| Option | Type | Description |
|---|---|---|
checkoutUrl | string | Full checkout URL. Preferred. |
sessionId | string | Alternative — URL is constructed as {baseUrl}/pay/checkout/{id}. |
baseUrl | string | Override the Coal base URL. Defaults to 'https://usecoal.xyz'. |
UseCoalCheckoutReturn
| Property | Type | Description |
|---|---|---|
checkoutUrl | string | null | Resolved checkout URL, or null if not ready. |
redirectToCheckout | () => void | Redirect in the current tab. |
openCheckout | () => void | Open checkout in a new tab. |
Example
1'use client';23import { useState } from 'react';4import { useCoalCheckout } from 'coal-react';56export default function CheckoutButton({ amount, productName }: { amount: number; productName: string }) {7 const [checkoutUrl, setCheckoutUrl] = useState<string | null>(null);8 const [loading, setLoading] = useState(false);910 const { redirectToCheckout } = useCoalCheckout({ checkoutUrl: checkoutUrl ?? undefined });1112 const handleCheckout = async () => {13 setLoading(true);14 const res = await fetch('/api/create-session', {15 method: 'POST',16 headers: { 'Content-Type': 'application/json' },17 body: JSON.stringify({ amount, productName }),18 });19 const data = await res.json();20 setCheckoutUrl(data.checkoutUrl);21 // Redirect immediately22 window.location.href = data.checkoutUrl;23 };2425 return (26 <button onClick={handleCheckout} disabled={loading}>27 {loading ? 'Creating session…' : `Pay $${amount}`}28 </button>29 );30}
Full Next.js example
1. Create a session on your server
1// app/api/create-session/route.ts2import { NextRequest, NextResponse } from 'next/server';34export async function POST(req: NextRequest) {5 const { amount, productName } = await req.json();67 const res = await fetch('https://api.usecoal.xyz/api/checkouts', {8 method: 'POST',9 headers: {10 'Content-Type': 'application/json',11 'x-api-key': process.env.COAL_API_KEY!,12 },13 body: JSON.stringify({14 amount,15 productName,16 redirectUrl: `${req.nextUrl.origin}/success`,17 }),18 });1920 const data = await res.json();21 const sessionId = data.data?.id ?? data.id;22 const checkoutUrl = `https://usecoal.xyz/pay/checkout/${sessionId}`;2324 return NextResponse.json({ sessionId, checkoutUrl });25}
2. Render the checkout button
1// app/checkout/page.tsx2'use client';34import { useState } from 'react';5import { CoalCheckoutButton } from 'coal-react';67export default function CheckoutPage() {8 const [checkoutUrl, setCheckoutUrl] = useState<string | null>(null);9 const [loading, setLoading] = useState(false);1011 const createSession = async () => {12 setLoading(true);13 const res = await fetch('/api/create-session', {14 method: 'POST',15 headers: { 'Content-Type': 'application/json' },16 body: JSON.stringify({ amount: 29.99, productName: 'Pro Plan' }),17 });18 const data = await res.json();19 setCheckoutUrl(data.checkoutUrl);20 setLoading(false);21 };2223 if (!checkoutUrl) {24 return (25 <button onClick={createSession} disabled={loading}>26 {loading ? 'Loading…' : 'Buy Pro Plan – $29.99'}27 </button>28 );29 }3031 return (32 <CoalCheckoutButton33 checkoutUrl={checkoutUrl}34 onBeforeRedirect={() => console.log('Checkout started')}35 />36 );37}
3. Handle the success redirect
After payment, Coal redirects the user to your redirectUrl with ?session_id=... appended:
1// app/success/page.tsx2import { Suspense } from 'react';3import { useSearchParams } from 'next/navigation';45function SuccessContent() {6 const params = useSearchParams();7 const sessionId = params.get('session_id');8 return <p>Payment confirmed! Session: {sessionId}</p>;9}1011export default function SuccessPage() {12 return (13 <Suspense>14 <SuccessContent />15 </Suspense>16 );17}
TypeScript types
All types are exported from coal-react:
1import type {2 CoalCheckoutButtonProps,3 UseCoalCheckoutOptions,4 UseCoalCheckoutReturn,5} from 'coal-react';
Backwards-compatible aliases
CoalWidget and CoalCheckout are exported as aliases for CoalCheckoutButton for backwards compatibility. They are deprecated — use CoalCheckoutButton in new code.
1// These still work but are deprecated:2import { CoalWidget, CoalCheckout } from 'coal-react';
Next steps
- Quickstart — full integration walkthrough
- Authentication — API keys and security
- Webhooks — confirm payments server-side
