PayGate

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-webview
yarn add @paygate/react-native react-native-webview

iOS Setup

cd ios && pod install

Android 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 app

Use 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>
PropTypeRequiredDescription
publicKeystringYesYour PayGate public key
baseUrlstringNoBase 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}
/>
PropTypeDefaultDescription
visibleboolean-Whether modal is visible
sessionIdstring-Checkout session ID
paymentLinkIdstring-Payment link ID
onSuccessfunction-Called on success
onCancelfunction-Called on cancel
onClosefunction-Called when modal closes
animationTypestring"slide"Animation type
showCloseButtonbooleantrueShow close button
safeAreaColorstring"#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()

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 install

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 */ },
})