The Moment React SDK enables seamless payment integration into any React application. Whether you need a modal overlay or an inline embedded checkout, the SDK provides a simple, declarative API with React hooks to handle the entire payment flow.Built with React and modern hooks, the SDK integrates naturally with your React workflow and state management.
Set up two providers at the root of your app: MomentProvider initializes the SDK instance (equivalent to Moment(clientKey) in vanilla JS), and MomentCheckoutProvider configures the checkout product (equivalent to moment.checkout(config)). You provide two fetch callbacks — the SDK calls them automatically at the right moments, so you never manage tokens or session IDs manually.Backend endpoints:
Node.js
Python
Go
Firebase
Supabase
Lambda
server.js
// Called by fetchClientToken when checkout.launch() is triggeredapp.post('/api/create-payment-session', async (req, res) => { const response = await fetch('https://api.momentpay.net/collect/payment_sessions', { method: 'POST', headers: { 'Authorization': 'Bearer sk_test_your_secret_key', 'Content-Type': 'application/json', }, body: JSON.stringify({ amount: 10000, // Amount in cents (e.g., R100.00) currency: 'ZAR', type: 'one_time', options: { checkout_options: { presentation_mode: { mode: 'embedded' }, success_url: 'https://yoursite.com/checkout?session_id={SESSION_ID}', // required for redirect payments }, }, }), }); const { client_token } = await response.json(); res.json({ client_token });});// Called by fetchSessionStatus after customer returns from a redirect payment.// The SDK extracts session_id from the URL (?session_id=abc123) and passes it here.app.get('/api/session-status', async (req, res) => { const sessionId = req.query.session_id; const response = await fetch( `https://api.momentpay.net/collect/payment_sessions/${sessionId}`, { headers: { 'Authorization': 'Bearer sk_test_your_secret_key' } } ); const session = await response.json(); res.json({ status: session.status, ...session });});
server.py
import requestsfrom flask import Flask, request, jsonifyapp = Flask(__name__)SECRET_KEY = 'sk_test_your_secret_key'# Called by fetchClientToken when checkout.launch() is triggered@app.route('/api/create-payment-session', methods=['POST'])def create_payment_session(): response = requests.post( 'https://api.momentpay.net/collect/payment_sessions', headers={ 'Authorization': f'Bearer {SECRET_KEY}', 'Content-Type': 'application/json', }, json={ 'amount': 10000, # Amount in cents (e.g., R100.00) 'currency': 'ZAR', 'type': 'one_time', 'options': { 'checkout_options': { 'presentation_mode': {'mode': 'embedded'}, 'success_url': 'https://yoursite.com/checkout?session_id={SESSION_ID}', # required for redirect payments }, }, }, ) data = response.json() return jsonify({'client_token': data['client_token']})# Called by fetchSessionStatus after customer returns from a redirect payment.# The SDK extracts session_id from the URL (?session_id=abc123) and passes it here.@app.route('/api/session-status', methods=['GET'])def get_session_status(): session_id = request.args.get('session_id') response = requests.get( f'https://api.momentpay.net/collect/payment_sessions/{session_id}', headers={'Authorization': f'Bearer {SECRET_KEY}'}, ) session = response.json() return jsonify({'status': session['status'], **session})
server.go
package mainimport ( "bytes" "encoding/json" "fmt" "io" "net/http")const secretKey = "sk_test_your_secret_key"const momentAPI = "https://api.momentpay.net"// Called by fetchClientToken when checkout.launch() is triggeredfunc createPaymentSession(w http.ResponseWriter, r *http.Request) { payload, _ := json.Marshal(map[string]any{ "amount": 10000, // Amount in cents (e.g., R100.00) "currency": "ZAR", "type": "one_time", "options": map[string]any{ "checkout_options": map[string]any{ "presentation_mode": map[string]string{"mode": "embedded"}, "success_url": "https://yoursite.com/checkout?session_id={SESSION_ID}", // required for redirect payments }, }, }) req, _ := http.NewRequest("POST", momentAPI+"/collect/payment_sessions", bytes.NewBuffer(payload)) req.Header.Set("Authorization", "Bearer "+secretKey) req.Header.Set("Content-Type", "application/json") resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() var result map[string]any json.NewDecoder(resp.Body).Decode(&result) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]any{"client_token": result["client_token"]})}// Called by fetchSessionStatus after customer returns from a redirect payment.// The SDK extracts session_id from the URL (?session_id=abc123) and passes it here.func getSessionStatus(w http.ResponseWriter, r *http.Request) { sessionID := r.URL.Query().Get("session_id") req, _ := http.NewRequest("GET", fmt.Sprintf("%s/collect/payment_sessions/%s", momentAPI, sessionID), nil) req.Header.Set("Authorization", "Bearer "+secretKey) resp, _ := http.DefaultClient.Do(req) defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) w.Header().Set("Content-Type", "application/json") w.Write(body)}func main() { http.HandleFunc("/api/create-payment-session", createPaymentSession) http.HandleFunc("/api/session-status", getSessionStatus) http.ListenAndServe(":8080", nil)}
Initializes the Moment SDK instance — equivalent to Moment(clientKey) in vanilla JS. Provides the SDK context to all product providers nested below it. Must be the outermost Moment wrapper in your app.
Prop
Type
Required
Description
clientKey
string
Yes
Your publishable key (pk_test_... or pk_live_...). Determines sandbox vs. production environment.
Initializes the checkout product — equivalent to moment.checkout(config) in vanilla JS. Must be a child of MomentProvider and a parent of any component using useCheckout.
Prop
Type
Required
Description
fetchClientToken
function
Yes
Async function returning Promise<string> — a fresh client token. Called by the SDK when checkout.launch() is invoked.
fetchSessionStatus
function
No
Async function receiving a sessionId string, returning Promise<{ status: string, ... }>. Called when a session_id is found in the URL after a redirect-based payment. Required only if you use redirect mode.
onSuccess
function
No
Global callback fired when payment succeeds (both embedded and redirect flows)
onFailure
function
No
Global callback fired when payment fails
onCancel
function
No
Global callback fired when user cancels
onAttemptFailed
function
No
Global callback fired when a payment attempt fails (user can retry)
onExpired
function
No
Global callback fired when the payment session expires
React hook that returns a checkout object for triggering checkout from any component. Must be used inside MomentCheckoutProvider. Callbacks defined here are component-level and fire alongside any global callbacks on MomentCheckoutProvider.
Parameter
Type
Required
Description
onSuccess
function
No
Component-level callback fired when payment succeeds
onFailure
function
No
Component-level callback fired when payment fails
onCancel
function
No
Component-level callback fired when user cancels
onAttemptFailed
function
No
Component-level callback fired when a payment attempt fails (user can retry)
onExpired
function
No
Component-level callback fired when the payment session expires
Returns a checkout object — checkout.launch(), checkout.close(), and checkout.submit().
Opens the payment checkout. Internally calls fetchClientToken from MomentCheckoutProvider to retrieve a fresh token, then opens checkout. The display variant (modal or inline) is determined from the JWT payload variant claim, which is set when creating the session on your backend.
Parameter
Type
Required
Description
options.container
string or Element
No
CSS selector or DOM element — for inline variant only
Returns a Promise that resolves with { checkoutUrl, variant } once the checkout is open.Examples:
// Open checkout — SDK fetches token via fetchClientToken from MomentCheckoutProvidercheckout.launch();// Inline checkout with custom containercheckout.launch({ container: '#checkout-container' });
Triggers payment submission from outside the checkout UI — useful when you want an external “Pay” button rather than relying on the checkout’s built-in submit. Only available for the inline variant.
// Wire up an external Pay button<button onClick={() => checkout.submit()}>Pay</button>
The Moment React SDK offers flexible callback handling at both the global (MomentCheckoutProvider) and component (useCheckout hook) levels. Understanding when to use each approach helps you write cleaner, more maintainable code.
Override or supplement global callbacks with component-specific behavior.✅ Best for:
Component-specific state updates
Different flows for different payment contexts
Local UI feedback
Context-aware error handling
ProductCheckout.jsx
function ProductCheckout({ product }) { const [status, setStatus] = useState('idle'); const checkout = useCheckout({ onSuccess: (result) => { // Component-specific behavior setStatus('success'); // This will ALSO trigger the global onSuccess from MomentCheckoutProvider }, onFailure: (result) => { setStatus('error'); // This will ALSO trigger the global onFailure from MomentCheckoutProvider } }); // ... rest of component}
Important: Component-level callbacks do not override global callbacks. Both will fire:
Component-level callback fires first (if defined)
Global callback fires second (if defined)
This allows you to handle both component-specific and app-wide logic.
// Global callback (in MomentCheckoutProvider)onSuccess: (result) => { console.log('Global: Tracking analytics'); trackEvent('payment_success', result);}// Component callback (in useCheckout)onSuccess: (result) => { console.log('Component: Updating local state'); setPaymentComplete(true);}// Both will fire when payment succeeds:// Output:// "Component: Updating local state"// "Global: Tracking analytics"