React Native SDK
Official React Native SDK for PayGate - Accept Mobile Money payments using WebView.
React Native SDK
The official React Native SDK for PayGate enables you to accept Mobile Money payments in your React Native app using WebView.
Requirements: React Native 0.60+, react-native-webview 11.0+
Installation
npm install @paygate/react-native react-native-webviewyarn add @paygate/react-native react-native-webviewiOS Setup
cd ios && pod installAndroid Setup
No additional setup required.
Quick Start
Wrap your app with PayGateProvider
import { PayGateProvider, PayGateAutoModal } from '@paygate/react-native'
function App() {
return (
<PayGateProvider
publicKey="pk_test_your_public_key"
baseUrl="https://paygate.com"
>
<NavigationContainer>
<AppNavigator />
</NavigationContainer>
{/* Add the auto modal at the root */}
<PayGateAutoModal />
</PayGateProvider>
)
}Create a checkout session on your server
// Server-side (Node.js)
import PayGate from '@paygate/node'
const paygate = new PayGate('sk_test_your_secret_key')
const session = await paygate.checkoutSessions.create({
amount: 100.00,
currency: 'GHS',
success_url: 'https://yoursite.com/success',
cancel_url: 'https://yoursite.com/cancel',
})
// Return session.id to your mobile appUse the usePayGate hook to trigger payments
import { usePayGate } from '@paygate/react-native'
import { Button, Alert, View } from 'react-native'
function CheckoutScreen() {
const { checkout, isVisible } = usePayGate()
const handlePay = async () => {
try {
// Get session ID from your server
const response = await fetch('https://your-api.com/create-session', {
method: 'POST',
body: JSON.stringify({ amount: 100 }),
})
const { sessionId } = await response.json()
// Open the payment modal
checkout({
sessionId,
onSuccess: (data) => {
console.log('Payment successful!', data)
Alert.alert('Success', 'Payment completed!')
},
onCancel: () => {
console.log('Payment cancelled')
},
onError: (error) => {
Alert.alert('Error', error.message)
},
})
} catch (error) {
Alert.alert('Error', 'Failed to create checkout session')
}
}
return (
<View style={{ padding: 20 }}>
<Button
title="Pay GHS 100.00"
onPress={handlePay}
disabled={isVisible}
/>
</View>
)
}Components
PayGateProvider
Wrap your application with PayGateProvider to enable PayGate functionality.
<PayGateProvider
publicKey="pk_test_xxx"
baseUrl="https://paygate.com"
>
{children}
</PayGateProvider>| Prop | Type | Required | Description |
|---|---|---|---|
publicKey | string | Yes | Your PayGate public key |
baseUrl | string | No | Base URL for checkout pages |
PayGateAutoModal
An auto-managed modal that responds to checkout() and payWithLink() calls. Place at the root of your app.
<PayGateAutoModal />PayGateModal
A manually controlled modal for more control.
const [visible, setVisible] = useState(false)
<PayGateModal
visible={visible}
sessionId="cs_xxx"
onSuccess={(data) => {
console.log('Paid!', data)
setVisible(false)
}}
onCancel={() => setVisible(false)}
onClose={() => setVisible(false)}
animationType="slide"
showCloseButton={true}
/>| Prop | Type | Default | Description |
|---|---|---|---|
visible | boolean | - | Whether modal is visible |
sessionId | string | - | Checkout session ID |
paymentLinkId | string | - | Payment link ID |
onSuccess | function | - | Called on success |
onCancel | function | - | Called on cancel |
onClose | function | - | Called when modal closes |
animationType | string | "slide" | Animation type |
showCloseButton | boolean | true | Show close button |
safeAreaColor | string | "#ffffff" | Safe area color |
PayGate (WebView Component)
Low-level WebView component for custom implementations.
<PayGate
sessionId="cs_xxx"
onSuccess={(data) => console.log('Paid!', data)}
onCancel={() => console.log('Cancelled')}
onError={(error) => console.error(error)}
onLoad={() => console.log('Loaded')}
style={{ flex: 1 }}
showLoader={true}
/>Hooks
usePayGate
import { usePayGate } from '@paygate/react-native'
const {
checkout, // (params: CheckoutParams) => void
payWithLink, // (params: PaymentLinkParams) => void
close, // () => void
isVisible, // boolean
publicKey, // string
baseUrl, // string
} = usePayGate()Payment Links
Accept payments using payment links:
const { payWithLink } = usePayGate()
const handleDonate = () => {
payWithLink({
linkId: 'pl_xxx',
amount: 50.00, // For dynamic amount links
email: 'customer@example.com',
phone: '0241234567',
onSuccess: (data) => {
console.log('Donation successful!', data)
},
onCancel: () => {
console.log('Donation cancelled')
},
})
}TypeScript
The SDK includes full TypeScript definitions:
import type {
PayGateConfig,
CheckoutParams,
PaymentLinkParams,
PaymentResult,
PayGateError,
} from '@paygate/react-native'Error Handling
checkout({
sessionId: 'cs_xxx',
onError: (error) => {
switch (error.type) {
case 'validation_error':
Alert.alert('Invalid Input', error.message)
break
case 'payment_error':
Alert.alert('Payment Failed', error.message)
break
case 'network_error':
Alert.alert('Network Error', error.message)
break
default:
Alert.alert('Error', error.message)
}
},
})Test Mode
Use test mode keys (pk_test_xxx) during development:
<PayGateProvider publicKey="pk_test_xxx">
{/* Test mode enabled */}
</PayGateProvider>In test mode, the checkout page shows simulation controls to test success, failure, and cancellation flows.
Complete Example
import React from 'react'
import { NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
import { View, Button, Text, StyleSheet, Alert } from 'react-native'
import { PayGateProvider, PayGateAutoModal, usePayGate } from '@paygate/react-native'
const Stack = createNativeStackNavigator()
function HomeScreen({ navigation }) {
return (
<View style={styles.container}>
<Text style={styles.title}>Welcome to My Store</Text>
<Button title="Go to Checkout" onPress={() => navigation.navigate('Checkout')} />
</View>
)
}
function CheckoutScreen() {
const { checkout, isVisible } = usePayGate()
const handlePay = async () => {
try {
const response = await fetch('https://api.yourstore.com/create-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount: 100, currency: 'GHS' }),
})
const { sessionId } = await response.json()
checkout({
sessionId,
onSuccess: (data) => {
Alert.alert('Success', `Payment ${data.id} completed!`)
},
onCancel: () => {
Alert.alert('Cancelled', 'Payment was cancelled')
},
onError: (error) => {
Alert.alert('Error', error.message)
},
})
} catch (error) {
Alert.alert('Error', 'Failed to start checkout')
}
}
return (
<View style={styles.container}>
<Text style={styles.title}>Your Cart</Text>
<Text style={styles.price}>Total: GHS 100.00</Text>
<Button
title={isVisible ? 'Processing...' : 'Pay Now'}
onPress={handlePay}
disabled={isVisible}
/>
</View>
)
}
export default function App() {
return (
<PayGateProvider publicKey="pk_test_xxx" baseUrl="https://paygate.com">
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Checkout" component={CheckoutScreen} />
</Stack.Navigator>
</NavigationContainer>
<PayGateAutoModal />
</PayGateProvider>
)
}
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 },
title: { fontSize: 24, fontWeight: 'bold', marginBottom: 20 },
price: { fontSize: 18, marginBottom: 20 },
})Troubleshooting
WebView not loading
Make sure you have installed and linked react-native-webview:
npm install react-native-webview
cd ios && pod installModal not appearing
Ensure PayGateAutoModal is placed at the root level of your app, inside PayGateProvider:
<PayGateProvider publicKey="pk_test_xxx">
<App />
<PayGateAutoModal /> {/* Must be inside provider */}
</PayGateProvider>Payment callbacks not firing
Ensure you're passing callback functions correctly:
checkout({
sessionId,
onSuccess: (data) => { /* handle success */ },
onCancel: () => { /* handle cancel */ },
onError: (error) => { /* handle error */ },
})