Skip to main content
The Payment Modal component and hooks let you integrate Chainrails payments into React web and React Native apps. Choose the hook pattern that best matches how you want to manage payment sessions.

Overview

Chainrails provides UI SDK packages for both supported app environments:
  • @chainrails/react: Payment modal hooks and components for React web apps
  • @chainrails/react-native: Payment modal hooks and components for React Native apps
The web and mobile SDKs follow the same session-based integration model:
  • usePaymentSession: Automatic session management with server-side URL
  • usePaymentModal: Manual session token control for advanced use cases
For both cases, the <PaymentModal /> component requires a server-generated session token to function. We’ve provided a Github repository with a curated Github template to help you get started quickly: Chainrails Demo Server

The usePaymentSession hook is ideal for React web implementations where your session URL is known upfront. The hook handles session creation automatically.

When to Use

  • You have a static session endpoint
  • You want minimal setup and automatic session management
  • You don’t need to fetch additional data before opening the modal

Parameters

  • session_url (string, required): Your server endpoint for creating payment sessions
  • onSuccess (function, optional): Callback fired when payment completes successfully
  • onCancel (function, optional): Callback fired when user cancels the payment
  • styles (object, optional): Available styling (e.g., { accentColor: "#FF6B6B", theme: "dark" })
  • excludeChains (array, optional): Array of chains to exclude from payment options (e.g., [chains.BASE_TESTNET, chains.STARKNET_TESTNET])

Example Implementation

import { PaymentModal, usePaymentSession, chains } from "@chainrails/react";

function App() {
  const cr = usePaymentSession({
    session_url: "https://your-server.com/create-session",
    onCancel: () => {
      console.log("Payment Cancelled");
    },
    onSuccess: () => {
      console.log("Payment Successful");
    },
  });

  return (
    <div>
      <button onClick={cr.open} className="border my-4 py-2 px-4 cursor-pointer">
        Open Modal
      </button>
      <PaymentModal {...cr} styles={{ accentColor: "#FF6B6B", theme: "dark" }} />
    </div>
  );
}

export default App;

Hook Return Value

The usePaymentSession hook returns an object with:
  • open(): Function to open the payment modal
  • close(): Function to close the payment modal
  • isOpen: Boolean indicating if modal is currently open
  • sessionToken: The current session token (automatically managed)

Option 2: usePaymentModal Hook (Advanced)

The usePaymentModal hook provides manual control over session token management. Use this when you need to fetch session data dynamically, set custom amounts, coordinate the modal with other operations, or integrate in React Native.

When to Use

  • You need to fetch session data from your server dynamically
  • You want to display custom amounts or user-specific information
  • You need to perform additional operations before opening the modal
  • You want explicit control over the session lifecycle
  • You are building a React Native integration

Parameters

  • sessionToken (string | null, required): Session token obtained from your server
  • onSuccess (function, optional): Callback fired when payment completes successfully
  • onCancel (function, optional): Callback fired when user cancels the payment
  • styles (object, optional): Available styling (e.g., { accentColor: "#FF6B6B", theme: "dark" })
  • excludeChains (array, optional): Array of chains to exclude from payment options

Example Implementation

import { useState } from "react";
import { PaymentModal, usePaymentModal } from "@chainrails/react";

function App() {
  const [amount, setAmount] = useState(0);
  const [sessionToken, setSessionToken] = (useState < string) | (null > null);
  const [loading, setLoading] = useState(false);

  const cr = usePaymentModal({
    sessionToken: sessionToken,
    onCancel: () => {
      console.log("Payment Cancelled");
    },
    onSuccess: () => {
      console.log("Payment Successful");
    },
  });

  async function pay() {
    setLoading(true);
    try {
      const res = await fetch("https://your-server.com/create-session");
      const data = await res.json();
      cr.updateSession(data);
      cr.open();
    } catch (error) {
      console.error("Error creating session:", error);
    } finally {
      setLoading(false);
    }
  }

  return (
    <div>
      <button onClick={pay} disabled={loading} className="border my-4 py-2 px-4 cursor-pointer">
        {loading ? "Loading..." : "Open Modal"}
      </button>
      <PaymentModal {...cr} styles={{ accentColor: "#FF6B6B", theme: "system" }} />
    </div>
  );
}

export default App;

React Native Example

import { useState } from "react";
import { Button, View } from "react-native";
import { PaymentModal, usePaymentModal } from "@chainrails/react-native";

function App() {
  const [loading, setLoading] = useState(false);

  const cr = usePaymentModal({
    sessionToken: null,
    onCancel: () => {
      console.log("Payment Cancelled");
    },
    onSuccess: () => {
      console.log("Payment Successful");
    },
  });

  async function pay() {
    setLoading(true);
    try {
      const res = await fetch("https://your-server.com/create-session");
      const data = await res.json();
      cr.updateSession(data);
      cr.open();
    } catch (error) {
      console.error("Error creating session:", error);
    } finally {
      setLoading(false);
    }
  }

  return (
    <View>
      <Button onPress={pay} title={loading ? "Loading..." : "Pay with Crypto"} />
      <PaymentModal {...cr} isPending={loading} />
    </View>
  );
}

export default App;

Hook Return Value

The usePaymentModal hook returns an object with:
  • open(): Function to open the payment modal
  • close(): Function to close the payment modal
  • isOpen: Boolean indicating if modal is currently open
  • sessionToken: The current session token (pass this to the hook)

PaymentModal Component Props

The <PaymentModal /> component accepts the following props:
PropTypeDescription
openfunctionOpens the modal
closefunctionCloses the modal
isOpenbooleanCurrent modal visibility state
sessionTokenstringActive session token for the payment
stylesobjectCustom styling object with options like accentColor, theme
amountnumber(Optional) Display amount in the modal
excludeChainsarray(Optional) Array of chains to exclude from the modal (e.g., [chains.BASE])
The same modal session flow is available in React Native through @chainrails/react-native, with platform-native presentation handled by the mobile SDK.

Styling

Both hooks accept a styles object to customize the modal appearance:
const cr = usePaymentSession({
  session_url: "https://your-server.com/create-session",
  // ... other options
});

return (
  <PaymentModal
    {...cr}
    styles={{
      accentColor: "#FF6B6B",
      theme: "dark",
    }}
  />
);
Available style options include:
  • accentColor: Primary color for buttons and highlights
  • theme: “light”, “dark”, or “system” for automatic theme switching

Callbacks

onSuccess

Fired when the payment completes successfully. Use this to:
  • Update user balance
  • Show success message
  • Redirect to confirmation page
onSuccess: () => {
  console.log("Payment processed successfully");
  // Handle successful payment
};

onCancel

Fired when the user closes or cancels the payment modal. Use this to:
  • Log analytics
  • Show informational message
  • Clean up UI state
onCancel: () => {
  console.log("User cancelled payment");
  // Handle cancellation
};

Quick Comparison

FeatureusePaymentSessionusePaymentModal
Setup ComplexitySimpleModerate
Session ManagementAutomaticManual
Dynamic Data FetchingLimitedFull Control
Best ForStandard flowsComplex workflows