Archived - This documentation is for React Native SDK v3.x. v3 is no longer the latest version. For the latest version, see React Native SDK v4. To upgrade, see the Migration Guide.
Official React Native SDK for integrating GlomoPay payment checkout flows into your mobile applications.
Before using this SDK, you need:
- API credentials (Public Key) from your GlomoPay dashboard
- An order ID created via the GlomoPay API (or a subscription ID for subscription payments)
| Requirement | Version |
|---|---|
| Node.js | >= 16.0.0 |
| npm | >= 8.0.0 |
| React | >= 17.0.0 |
| React Native | >= 0.68.0 |
| react-native-webview | ^13.0.0 |
| jail-monkey (optional) | ^2.6.0 |
npm install @glomopay/react-native-sdk@3.1.0 react-native-webview
cd ios && pod installnpx expo install @glomopay/react-native-sdk@3.1.0 react-native-webviewFor rooted/jailbroken device detection (strongly recommended for regulated flows):
npm install jail-monkeyThe SDK works without jail-monkey, but installing it enables automatic device security checks. Without it, the SDK logs a warning on every start() call.
import React, { useRef } from "react";
import { View, Button } from "react-native";
import {
GlomoCheckout,
type GlomoCheckoutRef,
type GlomoCheckoutPayload,
type SdkError,
} from "@glomopay/react-native-sdk";
export default function PaymentScreen() {
const checkoutRef = useRef<GlomoCheckoutRef>(null);
const handlePay = async () => {
const started = await checkoutRef.current?.start();
if (!started) {
console.log("Checkout could not start - check onSdkError for details");
}
};
return (
<View style={{ flex: 1 }}>
<Button title="Pay Now" onPress={handlePay} />
<GlomoCheckout
ref={checkoutRef}
publicKey="live_pk_abc123"
orderId="order_xyz789"
onPaymentSuccess={(payload: GlomoCheckoutPayload) => {
console.log("Payment success:", payload.paymentId);
}}
onPaymentFailure={(payload: GlomoCheckoutPayload) => {
console.log("Payment failed:", payload.paymentId);
}}
onPaymentTerminate={() => {
console.log("User dismissed checkout");
}}
onConnectionError={(error) => {
console.log("Connection error:", error);
}}
onBankTransferSubmitted={(payload) => {
console.log("Bank transfer submitted:", payload?.transactionReference);
}}
onPayViaBankCompleted={(payload) => {
console.log("Pay via bank completed:", payload.status);
}}
onPayViaBankBankConnectionSuccessful={(payload) => {
console.log("Bank connected:", payload?.bankName);
}}
onUserRefusedCameraPermissions={() => {
console.log("User refused camera - cannot proceed with bank authentication");
}}
onSdkError={(errors: SdkError[]) => {
errors.forEach((e) => console.error(e.type, e.message, e.field));
}}
/>
</View>
);
}To process subscription payments, pass a subscriptionId instead of an orderId:
<GlomoCheckout
ref={checkoutRef}
publicKey="live_pk_abc123"
subscriptionId="sub_xyz789"
onPaymentSuccess={(payload) => {
console.log("Subscription payment success:", payload.paymentId);
}}
onPaymentFailure={(payload) => {
console.log("Subscription payment failed:", payload.paymentId);
}}
onSdkError={(errors) => {
errors.forEach((e) => console.error(e.type, e.message));
}}
/>When subscriptionId is provided:
- The SDK skips order type detection (no API call)
- The
subscriptionIdmust start withsub_ - Bank transfer callbacks (
onBankTransferSubmitted,onPayViaBankCompleted) are not applicable - subscriptions are card-only - Do not pass both
orderIdandsubscriptionId- the SDK will fireonSdkError - The
detecting_order_typestatus is not emitted for subscription flows
- Cross-platform - works on both iOS and Android
- TypeScript - full type definitions for all exports
- Unified checkout - renders the correct checkout flow automatically based on your order
- Bank transfer support - callback for bank transfer submission events
- Pay via bank - bank payment flow completion and connection callbacks
- Camera permissions - built-in handling for bank authentication
- Device security - optional (but strongly recommended)
jail-monkeyintegration for rooted/jailbroken device detection - Input validation - publicKey and orderId format enforcement before checkout starts
- Mock mode - test with
test_/mock_prefixed keys without hitting production
The unified checkout component. Place it in your render tree and control it via a ref.
<GlomoCheckout ref={checkoutRef} {...props} />| Prop | Type | Required | Description |
|---|---|---|---|
publicKey | string | Yes | Your GlomoPay public key (must start with live_, mock_, or test_) |
orderId | string | No* | Order ID from the GlomoPay API (must start with order_) |
subscriptionId | string | No* | Subscription ID (must start with sub_). Bypasses order type detection. |
onPaymentSuccess | (payload: GlomoCheckoutPayload) => void | Yes | Called when payment succeeds |
onPaymentFailure | (payload: GlomoCheckoutPayload) => void | Yes | Called when payment fails |
onConnectionError | (error: unknown) => void | No | Called on network/connection errors |
onPaymentTerminate | () => void | No | Called when user dismisses checkout (back button or swipe) |
onSdkError | (errors: SdkError[]) => void | No | Called on validation errors or device compliance failures |
onBankTransferSubmitted | (payload: GlomoBankTransferPayload | null | undefined) => void | No | Called when user submits bank transfer details |
onPayViaBankCompleted | (payload: { status: string }) => void | No | Called when pay via bank flow completes |
onPayViaBankBankConnectionSuccessful | (payload: GlomoPayViaBankConnectionPayload | null | undefined) => void | No | Called when bank connection is established during pay via bank flow |
onUserRefusedCameraPermissions | () => void | No | Called when user denies camera access needed for bank authentication |
*Exactly one of orderId or subscriptionId must be provided. If both or neither are set, onSdkError fires and start() returns false.
| Method | Signature | Description |
|---|---|---|
start() | () => Promise<boolean> | Validates inputs, and opens the checkout modal. Resolves true if successful, false otherwise. |
getStatus() | () => CheckoutStatus | Returns the current checkout status. |
| Status | Description |
|---|---|
ready | Initial state - checkout can be started |
detecting_order_type | Order type detection in progress (after start(), before checkout opens) |
payment_in_progress | Checkout modal is open, user is interacting |
payment_successful | Payment completed successfully. Cannot restart with same order |
payment_failed | Payment failed. Can retry with same order |
payment_cancelled | User dismissed checkout mid-flow. Can retry |
bank_transfer_submitted | User submitted bank transfer details |
pay_via_bank_completed | Pay via bank flow completed |
interface GlomoCheckoutPayload {
orderId: string;
paymentId: string;
signature: string;
}interface GlomoBankTransferPayload {
orderId: string;
senderAccountNumber: string;
transactionReference: string;
}interface GlomoPayViaBankConnectionPayload {
bankIdentifier: string;
cooldownPeriodInMinutes: number;
bankName: string;
bankImageSrc: string;
bankImageAlt: string;
}interface SdkError {
type: "validation_error" | "device_forbidden";
message: string;
field?: "publicKey" | "orderId" | "subscriptionId" | "baseCheckoutUrl" | "generatedCheckoutUrl";
}When the checkout flow includes a bank transfer option, the user submits transfer details (account number, reference) through the checkout UI. The SDK fires onBankTransferSubmitted with a GlomoBankTransferPayload:
onBankTransferSubmitted={(payload) => {
// payload may be null/undefined if the checkout page omits it
console.log("Transfer ref:", payload?.transactionReference);
}}The checkout status transitions to bank_transfer_submitted.
The SDK fires onPayViaBankCompleted when the pay-via-bank journey completes:
onPayViaBankCompleted={(payload) => {
// payload.status - e.g. "success", "failed", "unknown"
console.log("Pay via bank status:", payload.status);
}}The checkout status transitions to pay_via_bank_completed. The SDK deduplicates this event internally - the callback fires only once per checkout session.
Additionally, onPayViaBankBankConnectionSuccessful fires when a bank account is successfully connected when initiating a pay-via-bank checkout, before the actual payment completes. This is informational only - it does not change the checkout status. Can be used to show a "bank connected" confirmation UI if desirable, while the payment continues in the background:
onPayViaBankBankConnectionSuccessful={(payload) => {
// payload may be null/undefined if the checkout page omits it
console.log("Connected to:", payload?.bankName);
console.log("Cooldown:", payload?.cooldownPeriodInMinutes, "minutes");
}}Some checkout flows may require camera access for bank authentication. The SDK handles permission prompts automatically, but you must declare the permissions in your native project config.
Add to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />Add to ios/<YourApp>/Info.plist:
<key>NSCameraUsageDescription</key>
<string>Camera access is required for identity verification during checkout</string>- Android: SDK prompts the user via a native permission dialog. If denied, checkout closes and
onUserRefusedCameraPermissionsfires. - iOS: SDK grants the WebView permission request; iOS shows its own system prompt. If the user denies at the system level, the WebView handles the denial.
- iOS: Checkout opens as a
pageSheetmodal (swipe-down to dismiss). Dismissing firesonPaymentTerminate. - Android: Checkout opens fullscreen. The hardware back button dismisses it and fires
onPaymentTerminate.
The SDK optionally integrates with jail-monkey to detect rooted (Android) or jailbroken (iOS) devices.
- If
jail-monkeyis installed and the device is compromised:start()returnsfalseandonSdkErrorfires withtype: "device_forbidden". - If
jail-monkeyis installed and the device is clean: checkout proceeds normally. - If
jail-monkeyis not installed: SDK logs a warning and proceeds without checking. This is not recommended for production deployments handling regulated transactions.
The SDK infers mock mode from the publicKey prefix:
| Prefix | Mode | Environment |
|---|---|---|
live_ | Live | Production |
test_ | Mock | Test/sandbox |
mock_ | Mock | Test/sandbox |
Mock mode keys route to the sandbox backend. No real transactions are created.
The SDK detects connection errors from the WebView and fires onConnectionError:
- iOS: NSURLErrorDomain codes (-1001 timeout, -1003 host not found, -1004 connection refused, -1009 offline)
- Android: ERR_EMPTY_RESPONSE, ERR_CONNECTION_REFUSED, ERR_NAME_NOT_RESOLVED, ERR_INTERNET_DISCONNECTED, ERR_CONNECTION_TIMED_OUT, ERR_NETWORK_CHANGED
The checkout modal is automatically dismissed on connection errors.
The SDK validates inputs before starting the checkout:
| Field | Rule |
|---|---|
publicKey | Must start with live_, mock_, or test_. Min 6 characters. |
orderId | Must start with order_. Min 7 characters. Required when subscriptionId is absent. |
subscriptionId | Must start with sub_. Trimmed and checked for emptiness. Required when orderId is absent. |
Validation failures fire onSdkError with type: "validation_error" and the relevant field name. start() returns false.
Providing both orderId and subscriptionId (or neither) also fires onSdkError.
Deprecated - Legacy hook, will be removed in a future major version.
useGlomoCheckout is a legacy placeholder from the v1.x hook-based API. In v1.x, the equivalent hook (useLrsCheckout) provided reactive WebView state and rendering primitives that merchants used to build custom checkout UIs. In v3, the inner checkout components are no longer exported, making this hook ineffective for custom rendering.
The hook's public return type (UseGlomoCheckoutReturn) exposes:
start()- identical toGlomoCheckoutRef.start(). ReturnsPromise<boolean>.getStatus()- returns a point-in-timeCheckoutStatussnapshot. Not reactive - does not trigger re-renders when status changes.
Use the GlomoCheckout component with a ref instead:
import React, { useRef } from "react";
import { GlomoCheckout, type GlomoCheckoutRef } from "@glomopay/react-native-sdk";
const checkoutRef = useRef<GlomoCheckoutRef>(null);
// Start checkout
const started = await checkoutRef.current?.start();
// Check status (point-in-time, same as hook)
const status = checkoutRef.current?.getStatus();The component-based API provides the same functionality with proper lifecycle management.
Check onSdkError for details. Common causes:
- Invalid
publicKeyformat (must start withlive_,mock_, ortest_) - Invalid
orderIdformat (must start withorder_) - Invalid
subscriptionIdformat (must start withsub_, non-empty after trimming) - Both
orderIdandsubscriptionIdprovided (or neither) - Device is rooted/jailbroken (when
jail-monkeyis installed)
- Verify network connectivity
- Check that the
publicKeyandorderIdare valid
- Ensure
AndroidManifest.xmlandInfo.plistinclude camera permission declarations - The
onUserRefusedCameraPermissionscallback will fire when the user denies
- Ensure you are passing
onPayViaBankCompletedas a prop toGlomoCheckout
// Components
export { GlomoCheckout } from "@glomopay/react-native-sdk";
// Hooks (deprecated - use GlomoCheckout component with ref instead)
export { useGlomoCheckout } from "@glomopay/react-native-sdk";
// Types
export type {
GlomoCheckoutRef,
GlomoCheckoutProps,
GlomoCheckoutPayload,
CheckoutStatus,
GlomoBankTransferPayload,
GlomoPayViaBankConnectionPayload,
UseGlomoCheckoutReturn, // deprecated
SdkError,
} from "@glomopay/react-native-sdk";The SDK loads checkout pages in an isolated WebView. No PAN, CVV, or sensitive payment data passes through the React Native bridge - all sensitive input is handled within the WebView's sandboxed context.
Device integrity checking is available via optional jail-monkey integration (see Device Security Compliance).
To report a security vulnerability, email security@glomopay.com. Do not open a public GitHub issue for security reports.
- React Native SDK v4 (Latest) - current version documentation
- Migration Guide (v1 to v4) - step-by-step upgrade instructions with before/after code
- Changelog - all release notes
- React Native SDK v1 (Archived) - previous version documentation
- Flutter SDK - GlomoPay SDK for Flutter apps
- Unified SDK (Web) - GlomoPay SDK for web apps
- Checkout overview - server-side checkout integration and signature verification