Skip to main content

Echezona React Native SDK

React Native SDK for Echezona Payment Gateway.

Features​

  • Secure Handling: Encrypted card details using RSA.
  • Multiple Payment Methods: Card, Transfer, USSD, OPay.
  • Ready-to-use UI: CheckoutModal and CheckoutView components for quick integration.
  • Hooks-based: useInitializePayment for triggering the checkout flow.

Installation​

npm install echezona-react-native-sdk

Peer Dependencies​

Ensure you have react and react-native installed. You will also need a storage adapter (like expo-secure-store for Expor projects).

Usage​

1. Wrap your app in EchezonaProvider​

The EchezonaProvider requires a configuration object. You should provide a storage adapter to persist session data.

import {
EchezonaProvider,
EchezonaErrorResponse,
CheckoutModal,
} from "echezona-react-native-sdk";
import * as SecureStore from "expo-secure-store";

// If you are using Expo, you should provide a storage adapter to persist session data.
const expoStorage = {
getItem: async (key: string) => await SecureStore.getItemAsync(key),
setItem: async (key: string, value: string) =>
await SecureStore.setItemAsync(key, value),
removeItem: async (key: string) => await SecureStore.deleteItemAsync(key),
};

const config = {
apiKey: "YOUR_API_KEY", // not required if you are using accessCode
storage: expoStorage, // Required for persistence
onSuccess: () => {
console.log("Payment successful");
},
onClose: () => {
console.log("Checkout closed");
},
onError: (error: EchezonaErrorResponse) => {
console.error("Payment Error:", error.responseMessage);
},
};

export default function App() {
return (
<EchezonaProvider config={config}>
<MainContent />
{/* Add the Modal component to your root */}
<CheckoutModal />
</EchezonaProvider>
);
}

It is highly recommended to initialize payments on your backend. Once your backend returns an accessCode, pass it to the startCheckout function.

See our API Documentation for more information on how to initialize a payment and generate an access code.

import { useInitializePayment } from "echezona-react-native-sdk";

const MainContent = () => {
const { startCheckout } = useInitializePayment();

const handlePay = async () => {
// 1. Fetch access code from your backend
const { accessCode } = await myApi.createPayment({ amount: 1000 });

// 2. Start checkout
startCheckout(accessCode);
};

return <Button title="Pay Now" onPress={handlePay} />;
};

3. Alternative: Client-side Initialization​

You can also initialize payments directly from the client, but this means you must pass your API key to the client, which is less secure.

const { initializePayment } = useInitializePayment();

const handlePay = async () => {
const payload = {
email: "emino@yopmail.com",
amount: 0.1,
currency: "NGN",
isLive: true,
phone: "08182426598",
firstName: "Emino",
lastName: "Minamino",
transactionId: `ECHY-RXT-NTV-${Date.now()}`,
// ... other payload fields
};

await initializePayment(payload);
};

Advanced Usage (Headless Hooks)​

Relevant Licenses & Compliance Certifications Required

These headless hooks (useCardCheckout, useTransferCheckout, useUssdCheckout) call the Core API directly and put your app in control of raw cardholder data, just like Core API Integration on the web. You must hold the relevant licenses and compliance certifications before using them in production. Contact hello@echezona.com to begin the approval process.

For custom checkout experiences, you can use our specific hooks for different payment methods.

1. Card Payments (useCardCheckout)​

Includes support for encryption, 3DS, and OTP validation.

import { useCardCheckout } from "echezona-react-native-sdk";

const CardPayment = () => {
const { makeCardPayment, validateCardOtp, cardPage } = useCardCheckout();

const handlePay = async () => {
// 1. Initiate payment
await makeCardPayment({
cardNumber: "5399...",
expiryMonth: "12",
expiryYear: "25",
cvv: "123",
pin: "1234"
});
};

const handleOtp = async (otp: string) => {
// 2. Validate OTP if cardPage is "otp"
await validateCardOtp(otp);
};

return (
// Your custom UI here
// Show OTP input if cardPage === "otp"
);
};

2. Bank Transfers (useTransferCheckout)​

Handles virtual account creation and automatic polling for confirmation.

import { useTransferCheckout, PaymentTypes } from "echezona-react-native-sdk";

const TransferPayment = () => {
const { makeTransferPayment, verifyTransferPayment, validationTimer } = useTransferCheckout();

const handlePay = async () => {
const res = await makeTransferPayment({
paymentType: PaymentTypes.TRANSFER
});

if (res?.data) {
// Start polling for payment confirmation
verifyTransferPayment();
}
};

return (
// Display transfer details (bankName, accountNumber)
// Show remaining time from validationTimer
);
};

3. USSD Payments (useUssdCheckout)​

Handles USSD string generation and confirmation polling.

import { useUssdCheckout } from "echezona-react-native-sdk";

const UssdPayment = () => {
const { makeUssdPayment, verifyUssdPayment, validationTimer } = useUssdCheckout();

const handlePay = async () => {
const ussdString = "*737*...";
const res = await makeUssdPayment(ussdString);

if (res) {
// Start polling for payment confirmation
verifyUssdPayment();
}
};

return (
// Display USSD string to user
// Show remaining time from validationTimer
);
};

API Reference​

Components​

EchezonaProvider​

The root provider component that wraps your application and provides the payment context.

Props:

  • config (object): Configuration object containing:
    • apiKey (string, optional): Your Echezona API key
    • storage (object, required): Storage adapter for persistence
    • onSuccess (function): Callback for successful payments
    • onClose (function): Callback when checkout is closed
    • onError (function): Callback for payment errors

CheckoutModal​

A ready-to-use modal component that displays the checkout interface.

Usage:

<CheckoutModal />

CheckoutView​

A view component for embedding checkout directly in your layout.

Usage:

<CheckoutView />

Hooks​

useInitializePayment​

Main hook for initializing payments using access codes or direct API calls.

Returns:

  • startCheckout (function): Start checkout with access code
  • initializePayment (function): Initialize payment with payload
  • isLoading (boolean): Loading state
  • error (object): Error state

useCardCheckout​

Hook for handling card payments with encryption and validation.

Returns:

  • makeCardPayment (function): Process card payment
  • validateCardOtp (function): Validate OTP for card
  • cardPage (string): Current page state ("form", "otp", "success", "error")
  • isLoading (boolean): Loading state
  • error (object): Error state

useTransferCheckout​

Hook for handling bank transfer payments.

Returns:

  • makeTransferPayment (function): Initiate transfer payment
  • verifyTransferPayment (function): Start verification polling
  • validationTimer (number): Remaining time for payment
  • transferDetails (object): Virtual account information

useUssdCheckout​

Hook for handling USSD payments.

Returns:

  • makeUssdPayment (function): Initiate USSD payment
  • verifyUssdPayment (function): Start verification polling
  • validationTimer (number): Remaining time for payment

Types​

PaymentTypes​

Enum for payment method types:

  • CARD
  • TRANSFER
  • USSD
  • OPAY

EchezonaErrorResponse​

Error response interface:

  • responseCode (string): Error code
  • responseMessage (string): Error message
  • transactionId (string, optional): Transaction identifier

Configuration​

Storage Adapter​

The SDK requires a storage adapter to persist session data. Here's how to implement one:

// For Expo
import * as SecureStore from "expo-secure-store";

const expoStorage = {
getItem: async (key: string) => await SecureStore.getItemAsync(key),
setItem: async (key: string, value: string) =>
await SecureStore.setItemAsync(key, value),
removeItem: async (key: string) => await SecureStore.deleteItemAsync(key),
};

// For React Native (using AsyncStorage)
import AsyncStorage from "@react-native-async-storage/async-storage";

const nativeStorage = {
getItem: async (key: string) => await AsyncStorage.getItem(key),
setItem: async (key: string, value: string) =>
await AsyncStorage.setItem(key, value),
removeItem: async (key: string) => await AsyncStorage.removeItem(key),
};

Security Best Practices​

  1. Use Access Codes: Always initialize payments from your backend when possible
  2. Environment Variables: Store API keys in environment variables
  3. HTTPS: Ensure all API calls are made over HTTPS
  4. Validation: Validate all user inputs before processing payments

Troubleshooting​

Common Issues​

Storage Errors​

Ensure your storage adapter is properly configured and permissions are granted.

Network Errors​

Check your internet connection and API endpoints.

Payment Failures​

Verify your API key and transaction parameters are correct.

Response Codes​

See Our response code mappings

Platform Support​

  • iOS 13+
  • Android API 24+
  • Expo / Bare React Native

Examples​

Complete Example​

import React from "react";
import { Button, View, Text } from "react-native";
import {
EchezonaProvider,
CheckoutModal,
useInitializePayment,
} from "echezona-react-native-sdk";
import * as SecureStore from "expo-secure-store";

const storage = {
getItem: async (key: string) => await SecureStore.getItemAsync(key),
setItem: async (key: string, value: string) =>
await SecureStore.setItemAsync(key, value),
removeItem: async (key: string) => await SecureStore.deleteItemAsync(key),
};

const config = {
apiKey: process.env.EXPO_PUBLIC_ECHEZONA_API_KEY,
storage,
onSuccess: () => alert("Payment successful!"),
onClose: () => console.log("Checkout closed"),
onError: (error) => alert(`Payment failed: ${error.responseMessage}`),
};

const PaymentButton = () => {
const { startCheckout, isLoading } = useInitializePayment();

const handlePayment = async () => {
try {
// Get access code from your backend
const response = await fetch("https://your-api.com/create-payment", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ amount: 1000 }),
});

const { accessCode } = await response.json();
startCheckout(accessCode);
} catch (error) {
console.error("Payment initialization failed:", error);
}
};

return (
<Button
title={isLoading ? "Processing..." : "Pay Now"}
onPress={handlePayment}
disabled={isLoading}
/>
);
};

export default function App() {
return (
<EchezonaProvider config={config}>
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Echezona Payment Demo</Text>
<PaymentButton />
</View>
<CheckoutModal />
</EchezonaProvider>
);
}