Skip to content

React

Terminal window
npm i @sanwohq/react @sanwohq/paystack
import { SanwoReactProvider } from "@sanwohq/react";
import { paystack } from "@sanwohq/paystack";
export default function App() {
return (
<SanwoReactProvider provider={paystack} publicKey="pk_test_xxxxxxxxxxxx">
<CheckoutPage />
</SanwoReactProvider>
);
}
import { useSanwoCheckout } from "@sanwohq/react";
function CheckoutPage() {
const { checkout, isLoading, error, result, reset } = useSanwoCheckout();
async function pay() {
const res = await checkout({
amount: 500000,
currency: "NGN",
customer: { email: "customer@example.com" },
});
if (res.status === "successful") {
console.log("Paid!", res.reference);
}
}
return (
<button onClick={pay} disabled={isLoading}>
{isLoading ? "Processing…" : "Pay ₦5,000"}
</button>
);
}

Wraps your app (or a subtree) and initializes the Sanwo instance.

<SanwoReactProvider
provider={paystack}
publicKey="pk_test_xxxxxxxxxxxx"
debug={false}
timeout={120}
containerId="checkout-container"
>
{children}
</SanwoReactProvider>
Prop Type Required Default Description
provider SanwoProvider Yes Imported provider
publicKey string Yes Your provider public key
debug boolean No false Enable debug logging
timeout number No 120 Checkout timeout in seconds
containerId string No Render checkout into a specific DOM element

The primary hook for triggering payments.

const { checkout, isLoading, error, result, reset } = useSanwoCheckout();
Value Type Description
checkout (options: CheckoutOptions) => Promise<CheckoutResult> Start a checkout
isLoading boolean true while checkout is in progress
error Error | null Set if checkout threw
result CheckoutResult | null Last checkout result
reset () => void Clear error and result

Low-level hook for direct access to the Sanwo instance.

const { sanwo, providerId, state } = useSanwo();
Value Type Description
sanwo SanwoInstance The raw callable instance
providerId string Current provider identifier
state string Current checkout state

Use this when you need event listeners or manual control:

const { sanwo } = useSanwo();
useEffect(() => {
const unsub = sanwo.on("success", (data) => {
analytics.track("payment_success", { ref: data.reference });
});
return unsub;
}, [sanwo]);

A ready-made button component that handles checkout state for you.

import { SanwoButton } from "@sanwohq/react";
<SanwoButton
checkoutOptions={{
amount: 500000,
currency: "NGN",
customer: { email: "customer@example.com" },
}}
onSuccess={(result) => console.log("Paid!", result.reference)}
onError={(err) => console.error(err)}
loadingText="Processing…"
>
Pay ₦5,000
</SanwoButton>
Prop Type Required Description
checkoutOptions CheckoutOptions Yes What to charge
onSuccess (result) => void No Called on successful payment
onError (error) => void No Called on failure
loadingText string No Button text while loading
children ReactNode No Button content

All other props are forwarded to the underlying <button> element.

import { SanwoReactProvider, SanwoButton } from "@sanwohq/react";
import { paystack } from "@sanwohq/paystack";
function App() {
return (
<SanwoReactProvider provider={paystack} publicKey="pk_test_xxxxxxxxxxxx">
<h1>My Store</h1>
<SanwoButton
checkoutOptions={{
amount: 500000,
currency: "NGN",
customer: { email: "customer@example.com" },
reference: `order_${Date.now()}`,
}}
onSuccess={(result) => {
window.location.href = `/receipt?ref=${result.reference}`;
}}
onError={(err) => alert(err.message)}
loadingText="Processing…"
className="pay-btn"
>
Pay ₦5,000
</SanwoButton>
</SanwoReactProvider>
);
}

SanwoReactProvider uses React context, so it must live in a client component.

"use client";
import { SanwoReactProvider } from "@sanwohq/react";
import { paystack } from "@sanwohq/paystack";
export function Providers({ children }: { children: React.ReactNode }) {
return (
<SanwoReactProvider provider={paystack} publicKey="pk_test_xxxxxxxxxxxx">
{children}
</SanwoReactProvider>
);
}