React SDK
React web SDK for Elebne Pay checkout — render the hosted embed, re-verify the result server-side, and show a success screen. Three integration flows.
React SDK
@elebne/pay-react is the client SDK for Elebne Pay on the web. It wraps the hosted /embed surface: you supply (or mint) a clientSecret, the SDK renders the payment iframe, re-verifies the result server-side, and shows a success screen. It never handles a secret key.
Install
npm install @elebne/pay-reactreact and react-dom (18 or 19) are peer dependencies.
@elebne/pay-react is at 0.1.0. While it is being published to npm it is also available via the Elebne private registry — request access from dev@elebne.ai.
The three flows
Merchant backend (recommended). Your server creates the intent with its sk_ key (PHP / Java) and returns the clientSecret. The SDK never sees a secret key.
import { ElebneCheckoutProvider, EmbedCheckout } from '@elebne/pay-react';
<ElebneCheckoutProvider
config={{ env: 'production' }}
options={{ fetchClientSecret: async () => (await createIntentOnMyServer()).clientSecret }}
>
<EmbedCheckout
presentation="modal"
onPaid={(session) => console.log('paid', session.referenceNumber)}
onCancelled={(session) => console.log('cancelled', session.referenceNumber)}
onError={(error) => console.error(error.code)}
/>
</ElebneCheckoutProvider>If you already have the clientSecret at render time, pass it directly instead:
<ElebneCheckoutProvider config={{ env: 'production' }} options={{ clientSecret: 'cs_live_…' }}>
<EmbedCheckout onPaid={handlePaid} />
</ElebneCheckoutProvider>No backend (stored price). Define a price in the Elebne dashboard; the SDK mints the intent with a publishable key.
<ElebneCheckoutProvider
config={{ env: 'production' }}
options={{ publishableKey: 'pk_live_…', priceId: 'abc123', quantity: 2 }}
>
<EmbedCheckout presentation="inline" onPaid={handlePaid} />
</ElebneCheckoutProvider>Optional price fields: merchantOrderId, returnUrl, cancelUrl, label.
Verify callback (legacy). Verify an out-of-band payment against your own order reference.
<ElebneCheckoutProvider
config={{ env: 'production' }}
options={{ publishableKey: 'pk_live_…', merchantOrderId: 'ORDER-1', flow: 'verify' }}
>
<EmbedCheckout onPaid={handlePaid} />
</ElebneCheckoutProvider>ElebneCheckoutProvider props
| Prop | Type | Description |
|---|---|---|
config | ProviderConfig (optional) | env, baseUrl, embedUrl |
options | CheckoutOptions (required) | One of the flows above |
children | ReactNode | Tree that can include <EmbedCheckout> |
EmbedCheckout props
The most common props — see the package README for the exhaustive list.
| Prop | Type | Default | Description |
|---|---|---|---|
presentation | 'inline' | 'modal' | 'inline' | Modal adds a centered overlay with a close button |
onPaid | (session) => void | — | Fires after server re-verification confirms PAID |
onCancelled | (session) => void | — | Fires after re-verification confirms CANCELLED |
onExpired / onFailed | (session) => void | — | Fire on the corresponding terminal status |
onError | (error: ElebnePayError) => void | — | Non-recoverable errors |
onDone | (session) => void | — | User clicked "Continuer" on the success screen |
showSuccess | boolean | true | Show the built-in terminal success screen |
renderSuccess | (session) => ReactNode | — | Replace the default success screen |
poll | boolean | true | Polling fallback (disable in tests) |
cancelOnClose | boolean | false | In modal mode, cancel the intent when closed |
Guarantees
- Server re-verification — the iframe
postMessageis only a hint; the SDK callsGET /checkout/sessionand firesonPaid/onCancelled/onExpired/onFailedonly when the server confirms a terminal status. - Origin-checked — messages from any origin other than the embed base URL are silently ignored.
- No secret leakage — the
clientSecrettravels only in the URL fragment; nosk_key ever touches the SDK. - Idempotent minting — when the SDK mints an intent (Flow B / C), one idempotency key is generated per Provider mount, so React re-renders never create duplicates.
Imperative control
useElebneCheckout() (inside the Provider tree) returns { status, session, error, cancel }. Call cancel() to programmatically cancel the current intent.
Error handling
All SDK errors are ElebnePayError instances with a .code string:
import { ElebnePayError } from '@elebne/pay-react';
<EmbedCheckout
onError={(e) => {
if (e instanceof ElebnePayError) console.error(e.code, e.message);
}}
/>Environments & sandbox
config={{ env: 'production' }} // https://api.elebne.ai/api/v1 + https://elebne.ai/embed
config={{ env: 'staging' }} // https://api.staging.elebne.ai/api/v1 + https://pay.staging.elebne.ai/embed
// Local dev only — override both endpoints
config={{ baseUrl: 'http://localhost:3000/api/v1', embedUrl: 'http://localhost:3100/embed' }}Sandbox vs live is decided by the key: a pk_test_ / sk_test_ key yields a sandbox intent (surfaced as session.sandbox). There is no separate sandbox hostname. The http://localhost:3100/embed override is for local development only.
Next steps
- React Native SDK — the same API in a WebView
- PHP SDK / Java SDK — mint the
clientSecretfor Flow A - Webhooks — confirm payments server-side
- Pay API — the underlying REST API
Was this page helpful?
Java SDK
Server-side Java SDK for Elebne Pay — mint client secrets, retrieve/cancel/refund intents, and verify webhooks. Java 17, zero runtime dependencies.
React Native SDK
React Native SDK for Elebne Pay checkout — render the hosted embed in a WebView, re-verify server-side, and show a native success screen.