ElebneElebneDocs
SDKs

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-react

react 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

PropTypeDescription
configProviderConfig (optional)env, baseUrl, embedUrl
optionsCheckoutOptions (required)One of the flows above
childrenReactNodeTree that can include <EmbedCheckout>

EmbedCheckout props

The most common props — see the package README for the exhaustive list.

PropTypeDefaultDescription
presentation'inline' | 'modal''inline'Modal adds a centered overlay with a close button
onPaid(session) => voidFires after server re-verification confirms PAID
onCancelled(session) => voidFires after re-verification confirms CANCELLED
onExpired / onFailed(session) => voidFire on the corresponding terminal status
onError(error: ElebnePayError) => voidNon-recoverable errors
onDone(session) => voidUser clicked "Continuer" on the success screen
showSuccessbooleantrueShow the built-in terminal success screen
renderSuccess(session) => ReactNodeReplace the default success screen
pollbooleantruePolling fallback (disable in tests)
cancelOnClosebooleanfalseIn modal mode, cancel the intent when closed

Guarantees

  • Server re-verification — the iframe postMessage is only a hint; the SDK calls GET /checkout/session and fires onPaid / onCancelled / onExpired / onFailed only 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 clientSecret travels only in the URL fragment; no sk_ 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

Was this page helpful?

On this page