Getting Started
Get up and running with the Oobit Plug & Pay SDK in your React Native or Expo app
The Oobit React Native SDK embeds the Plug & Pay widget in your mobile app, enabling crypto-to-card payment experiences for your users.
Installation
Latest version: 3.3.3
npm install @oobit/react-native-sdkOr with yarn:
yarn add @oobit/react-native-sdkPeer Dependencies
npm install react-native-webviewChoose Your Integration
Plug & Pay supports two integration modes for funding the card. Which one you use is configured on your partner account — if you're not sure, check with your Oobit account manager.
| Widget-Managed Flow (default) | Standalone Flow | |
|---|---|---|
| Who builds the deposit transaction | The widget — your app receives a ready-to-sign TransactionRequest and broadcasts it | Your app — using Oobit's Partner API to fetch the user's deposit address |
| What you pass the SDK | userWalletAddress + onTransactionRequested | onDepositRequested (+ optional email / externalUserId) |
| Deep dive | Widget-Managed Deposits | API-Managed Deposits |
Basic Usage
import { WidgetSDK } from "@oobit/react-native-sdk";
function MyScreen() {
return (
<WidgetSDK
accessToken={accessToken}
userWalletAddress="0x1234567890abcdef..."
onTransactionRequested={(transaction) => {
// Navigate to your transaction confirmation screen
navigation.navigate("ConfirmTransaction", { transaction });
}}
/>
);
}import { WidgetSDK, type StandaloneConfig } from "@oobit/react-native-sdk";
function MyScreen() {
return (
<WidgetSDK
accessToken={accessToken}
email="[email protected]" // optional - prefills onboarding
externalUserId="your-internal-user-id" // optional
onDepositRequested={(email) => {
// `email` is the user's verified email — pass it to your backend
// so it can call Oobit's Partner API on their behalf.
navigation.navigate("Deposit", { email });
}}
/>
);
}Props Reference
Shared
| Prop | Type | Required | Description |
|---|---|---|---|
accessToken | string | Yes | JWT token from your backend (Authentication Guide) |
onClose | () => void | No | Called when the user requests to close the widget. Required to show back/close buttons — if omitted, the widget's navigation buttons are hidden and users have no in-widget way to dismiss it. |
Widget-Managed Flow (WidgetSDKConfig)
WidgetSDKConfig)| Prop | Type | Required | Description |
|---|---|---|---|
userWalletAddress | string | Yes | The user's crypto wallet address — the widget uses it to build the deposit transaction |
onTransactionRequested | (transaction: ``TransactionRequest``) => void | Yes | Called when the user initiates a transaction. See Widget-Managed Deposits |
Standalone Flow (StandaloneConfig)
StandaloneConfig)| Prop | Type | Required | Description |
|---|---|---|---|
email | string | No | The user's email. If provided, the widget skips email entry. If omitted, the user enters and verifies it inside the widget's onboarding flow |
externalUserId | string | No | Your internal user ID. Alternative identifier for Partner API calls |
onDepositRequested | (email: string) => void | Yes | Called when the user taps "Add Funds". Receives the user's verified email so your backend can identify them (API-Managed Deposits) |
Styling & Customization
| Prop | Type | Required | Description |
|---|---|---|---|
style | StyleProp<ViewStyle> | No | Style applied to the SDK's outer container View. Useful for setting background color, border radius, etc. |
webViewProps | Omit<WebViewProps, …managed> | No | Escape hatch: extra props forwarded to the underlying WebView. source, ref, onMessage, onShouldStartLoadWithRequest and onOpenWindow are managed by the SDK and cannot be overridden. Passing your own onLoadEnd suppresses the SDK's built-in loading overlay so you can render your own. |
<WidgetSDK
accessToken={accessToken}
userWalletAddress={walletAddress}
onTransactionRequested={handleTransaction}
style={{ backgroundColor: "#fff" }}
webViewProps={{
showsVerticalScrollIndicator: false,
showsHorizontalScrollIndicator: false,
}}
/>Custom loading indicator
Pass onLoadEnd through webViewProps to drive your own loader. The SDK's built-in ActivityIndicator is suppressed whenever this callback is present.
const [isLoading, setIsLoading] = useState(true);
<View style={{ flex: 1 }}>
<WidgetSDK
accessToken={accessToken}
onTransactionRequested={handleTransaction}
webViewProps={{
onLoadEnd: () => setIsLoading(false),
}}
/>
{isLoading && (
<View style={StyleSheet.absoluteFill} pointerEvents="none">
<ActivityIndicator size="large" color="#FF6B35" />
</View>
)}
</View>Reset isLoading to true each time you open the widget so the loader appears again on reopen.
See Also
- Deposit Flow — Overview of both integration modes
- Widget-Managed Deposits — Handling
onTransactionRequested - API-Managed Deposits — Deep dive on the standalone flow
