Integrate with React / Next.js
Recommended architecture for integrating Wajub in a React/Next.js app, keeping the private key server-side.
The golden rule on the frontend: the private key never leaves the server. In React/Next.js, you initialize the payment in a server route, and the client just triggers and redirects.
Architecture
- The client component calls your server route (
/api/checkout). - The server route calls Wajub with the key and returns the
authorization_url. - The client redirects to that URL.
- A webhook (server route) confirms the payment.
Server route (App Router)
Use @wajub/node on the server:
import { NextResponse } from 'next/server';
import { Wajub } from '@wajub/node';
const wajub = new Wajub({ privateKey: process.env.WAJUB_SECRET_KEY! });
export async function POST(req: Request) {
const { amount, email, orderId } = await req.json();
const payment = await wajub.payments.create(
{
amount,
currency: 'XAF',
email,
callback: `${process.env.APP_URL}/payment/return`,
metadata: { order_id: orderId },
},
{ idempotencyKey: `ORDER-${orderId}` },
);
return NextResponse.json({ authorization_url: payment.authorization_url });
}Or call the REST API directly with fetch if you prefer not to add a dependency.
Client component
'use client';
import { useState } from 'react';
export function PayButton({ amount, email, orderId }: { amount: number; email: string; orderId: string }) {
const [loading, setLoading] = useState(false);
async function pay() {
setLoading(true);
const res = await fetch('/api/checkout', {
method: 'POST',
body: JSON.stringify({ amount, email, orderId }),
});
const { authorization_url } = await res.json();
window.location.href = authorization_url; // hosted redirect
}
return <button onClick={pay} disabled={loading}>{loading ? 'Redirecting…' : 'Pay'}</button>;
}Inline embed (optional)
To keep the customer on your page instead of redirecting, use Wajub Components after creating the session server-side:
'use client';
import { WajubProvider, CheckoutEmbed } from '@wajub/react';
export function InlineCheckout({ sessionId }: { sessionId: string }) {
return (
<WajubProvider>
<CheckoutEmbed sessionId={sessionId} onSuccess={() => (window.location.href = '/thanks')} />
</WajubProvider>
);
}Never use private keys client-side
Never import the SDK with sk_… in a 'use client' component or in code
shipped to the browser. Keep initialization in a server route, a Server Action, or an API route.
Next.js environment variables
Do not prefix your keys with NEXT_PUBLIC_: this prefix would expose them to the
browser. Wajub keys remain server-only variables.
Was this page helpful?