Expo SDK

Official Expo SDK for Shika Creators - Accept Mobile Money payments with WebView or Browser mode.

Expo SDK

The official Expo SDK for Shika Creators enables you to accept Mobile Money payments in your Expo app with two modes: WebView (embedded) or Browser (system browser).

Requirements: Expo SDK 49+, react-native-webview. Optional: expo-web-browser for browser mode.

Features

  • WebView Mode: Embedded checkout in a modal (default)
  • Browser Mode: Open checkout in system browser (optional)
  • Deep Linking: Return to app after browser checkout

Installation

npx expo install @shikacreators/expo react-native-webview

# Optional: For browser mode
npx expo install expo-web-browser expo-linking

Quick Start

Wrap your app with Shika CreatorsProvider

import { Shika CreatorsProvider, Shika CreatorsAutoModal } from '@shikacreators/expo'

export default function App() {
  return (
    <Shika CreatorsProvider
      publicKey="pk_test_your_public_key"
      baseUrl="https://shikacreators.com"
      urlScheme="myapp" // Required for browser mode
    >
      <NavigationContainer>
        <AppNavigator />
      </NavigationContainer>
      <Shika CreatorsAutoModal />
    </Shika CreatorsProvider>
  )
}

Configure deep linking (for browser mode)

In your app.json:

{
  "expo": {
    "scheme": "myapp"
  }
}

Trigger payments

import { useShika Creators } from '@shikacreators/expo'
import { Button, Alert, View } from 'react-native'

function CheckoutScreen() {
  const { checkout, openCheckoutInBrowser, browserAvailable, isVisible } = useShika Creators()

  const handlePayWithWebView = async () => {
    const { sessionId } = await api.createCheckoutSession()

    checkout({
      sessionId,
      onSuccess: (data) => {
        Alert.alert('Success', 'Payment completed!')
      },
      onCancel: () => {
        console.log('Cancelled')
      },
    })
  }

  const handlePayWithBrowser = async () => {
    const { sessionId } = await api.createCheckoutSession()

    await openCheckoutInBrowser({
      sessionId,
      onSuccess: (data) => {
        Alert.alert('Success', 'Payment completed!')
      },
    })
  }

  return (
    <View style={{ padding: 20 }}>
      <Button
        title="Pay with WebView"
        onPress={handlePayWithWebView}
        disabled={isVisible}
      />
      {browserAvailable && (
        <Button
          title="Pay with Browser"
          onPress={handlePayWithBrowser}
        />
      )}
    </View>
  )
}

Components

Shika CreatorsProvider

<Shika CreatorsProvider
  publicKey="pk_test_xxx"       // Required
  baseUrl="https://shikacreators.com"  // Optional
  urlScheme="myapp"              // Required for browser mode
  defaultMode="webview"          // 'webview' | 'browser'
>
  {children}
</Shika CreatorsProvider>
PropTypeRequiredDescription
publicKeystringYesYour Shika Creators public key
baseUrlstringNoBase URL for checkout pages
urlSchemestringNo*URL scheme for deep linking (*required for browser mode)
defaultModestringNoDefault payment mode

Shika CreatorsAutoModal

Auto-managed modal that responds to checkout() and payWithLink() calls.

<Shika CreatorsAutoModal />

Shika CreatorsModal

Manually controlled modal.

<Shika CreatorsModal
  visible={visible}
  sessionId="cs_xxx"
  onSuccess={(data) => {}}
  onCancel={() => {}}
  onClose={() => setVisible(false)}
/>

Shika Creators

Low-level WebView component.

<Shika Creators
  sessionId="cs_xxx"
  onSuccess={(data) => {}}
  onCancel={() => {}}
  onError={(error) => {}}
  style={{ flex: 1 }}
/>

Hooks

useShika Creators

import { useShika Creators } from '@shikacreators/expo'

const {
  // WebView mode
  checkout,                  // (params) => void
  payWithLink,               // (params) => void

  // Browser mode
  openCheckoutInBrowser,     // (params) => Promise<void>
  openPaymentLinkInBrowser,  // (params) => Promise<void>

  // State
  close,                     // () => void
  isVisible,                 // boolean
  mode,                      // 'webview' | 'browser'
  setMode,                   // (mode) => void
  browserAvailable,          // boolean
  publicKey,                 // string
  baseUrl,                   // string
} = useShika Creators()

Payment Modes

WebView Mode (Default)

Opens checkout in an embedded WebView modal. Best for most apps.

const { checkout } = useShika Creators()

checkout({
  sessionId: 'cs_xxx',
  onSuccess: (data) => console.log('Paid!', data),
})

Browser Mode

Opens checkout in system browser. Requires expo-web-browser and expo-linking.

const { openCheckoutInBrowser, browserAvailable } = useShika Creators()

if (browserAvailable) {
  await openCheckoutInBrowser({
    sessionId: 'cs_xxx',
    onSuccess: (data) => console.log('Paid!', data),
  })
}

Comparison

FeatureWebView ModeBrowser Mode
User ExperienceIn-app modalSystem browser
SetupSimplerRequires deep linking
Dependenciesreact-native-webview+ expo-web-browser, expo-linking
Best forMost appsApps needing browser features
const { payWithLink, openPaymentLinkInBrowser } = useShika Creators()

// WebView mode
payWithLink({
  linkId: 'pl_xxx',
  amount: 50.00,  // For dynamic amount
  email: 'customer@example.com',
  onSuccess: (data) => console.log('Paid!', data),
})

// Browser mode
await openPaymentLinkInBrowser({
  linkId: 'pl_xxx',
  amount: 50.00,
  onSuccess: (data) => console.log('Paid!', data),
})

TypeScript

import type {
  Shika CreatorsConfig,
  CheckoutParams,
  PaymentLinkParams,
  PaymentResult,
  Shika CreatorsError,
  PaymentMode,
} from '@shikacreators/expo'

Test Mode

Use test keys (pk_test_xxx) during development:

<Shika CreatorsProvider publicKey="pk_test_xxx" urlScheme="myapp">
  {/* Test mode enabled */}
</Shika CreatorsProvider>

Complete Example

import React, { useState } from 'react'
import { View, Button, Text, StyleSheet, Alert } from 'react-native'
import { NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
import { Shika CreatorsProvider, Shika CreatorsAutoModal, useShika Creators } from '@shikacreators/expo'

const Stack = createNativeStackNavigator()

function CheckoutScreen() {
  const { checkout, openCheckoutInBrowser, browserAvailable, isVisible } = useShika Creators()
  const [loading, setLoading] = useState(false)

  const createSession = async () => {
    const response = await fetch('https://api.yourstore.com/create-session', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ amount: 100 }),
    })
    return response.json()
  }

  const handleWebViewCheckout = async () => {
    setLoading(true)
    try {
      const { sessionId } = await createSession()
      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 create session')
    } finally {
      setLoading(false)
    }
  }

  const handleBrowserCheckout = async () => {
    setLoading(true)
    try {
      const { sessionId } = await createSession()
      await openCheckoutInBrowser({
        sessionId,
        onSuccess: (data) => {
          Alert.alert('Success', 'Payment completed!')
        },
        onCancel: () => {
          Alert.alert('Cancelled', 'Payment was cancelled')
        },
      })
    } catch (error) {
      Alert.alert('Error', 'Failed to open browser')
    } finally {
      setLoading(false)
    }
  }

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Checkout</Text>
      <Text style={styles.price}>Total: GHS 100.00</Text>

      <View style={styles.buttons}>
        <Button
          title={loading ? 'Loading...' : 'Pay with WebView'}
          onPress={handleWebViewCheckout}
          disabled={loading || isVisible}
        />

        {browserAvailable && (
          <View style={styles.buttonSpacing}>
            <Button
              title="Pay with Browser"
              onPress={handleBrowserCheckout}
              disabled={loading}
            />
          </View>
        )}
      </View>
    </View>
  )
}

export default function App() {
  return (
    <Shika CreatorsProvider
      publicKey="pk_test_xxx"
      baseUrl="https://shikacreators.com"
      urlScheme="myapp"
    >
      <NavigationContainer>
        <Stack.Navigator>
          <Stack.Screen name="Checkout" component={CheckoutScreen} />
        </Stack.Navigator>
      </NavigationContainer>
      <Shika CreatorsAutoModal />
    </Shika CreatorsProvider>
  )
}

const styles = StyleSheet.create({
  container: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 },
  title: { fontSize: 24, fontWeight: 'bold', marginBottom: 10 },
  price: { fontSize: 18, marginBottom: 30 },
  buttons: { width: '100%' },
  buttonSpacing: { marginTop: 10 },
})

Troubleshooting

WebView not loading

npx expo install react-native-webview

Browser mode not working

  1. Install dependencies:
npx expo install expo-web-browser expo-linking
  1. Configure URL scheme in app.json:
{
  "expo": {
    "scheme": "myapp"
  }
}
  1. Pass urlScheme to provider:
<Shika CreatorsProvider publicKey="..." urlScheme="myapp">

Make sure your URL scheme matches in:

  • app.jsonexpo.scheme
  • Shika CreatorsProviderurlScheme prop

browserAvailable is false

Install the optional dependencies:

npx expo install expo-web-browser expo-linking