# Integrate the Embedded Components onramp Step-by-step integration guide for the Embedded Components onramp. # React Native This guide provides step-by-step instructions for you to build your integration. Use this when you need full control over the onramp flow, want to understand each API, or want to customize the flow for your app. Alternatively, see the [quickstart](https://docs.stripe.com/crypto/onramp/embedded-components-quickstart.md) for a minimal example that shows the full flow, or explore the [example app](https://github.com/stripe-samples/crypto-embedded-components-onramp?platform=react-native) for a complete React Native project that demonstrates the full crypto purchase flow. ## Before you begin - The Embedded Components onramp is only available to users in the US (excluding New York). - The Embedded Components API is in private preview. No API calls succeed until onboarding is complete, including in a *sandbox* (A sandbox is an isolated test environment that allows you to test Stripe functionality in your account without affecting your live integration. Use sandboxes to safely experiment with new features and changes). To request access: 1. [Submit your application](https://docs.stripe.com/crypto/onramp.md#submit-your-application). 1. [Sign up to join the waitlist](https://docs.stripe.com/crypto/onramp.md#sign-up). 1. Work with your Stripe account executive or solutions architect to complete onboarding before you start your integration. This includes, but isn’t limited to: - Confirm that your account is enrolled in the required feature gates for the Embedded Components onramp APIs and Link OAuth APIs. - Enable Link as a payment method in your [Dashboard](https://dashboard.stripe.com/settings/payment_methods). - Obtain your OAuth client ID and client secret. Stripe provisions these credentials, and you need them for the [authentication flow](https://docs.stripe.com/crypto/onramp/embedded-components-integration-guide.md#authentication). - Confirm that your app is registered as a trusted application. We require this before you can use the SDK, including for simulator testing. - After onboarding is complete, obtain your secret key and [publishable API key](https://docs.stripe.com/keys.md#obtain-api-keys) from the [API keys page](https://dashboard.stripe.com/apikeys). ## Mobile SDK configuration ### Step 1: Install the Stripe React Native SDK For Expo projects, run the following to automatically install the version compatible with your Expo SDK: ```shell npx expo install @stripe/stripe-react-native ``` For bare React Native projects, follow the installation instructions in the [README](https://github.com/stripe/stripe-react-native?tab=readme-ov-file). See the [requirements section](https://github.com/stripe/stripe-react-native?tab=readme-ov-file#requirements) for the minimum compatible Expo SDK, React Native, iOS, and Android versions. ### Step 2: Add the onramp dependency (Client-side) By default, the onramp dependency isn’t included in the Stripe React Native SDK to reduce bundle size. Include it as follows, depending on your platform. #### Bare React Native App ```shell # android/gradle.properties StripeSdk_includeOnramp=true # ios/Podfile – add pod pod 'stripe-react-native/Onramp', path: '../node_modules/@stripe/stripe-react-native' ``` #### Expo ```javascript // [Expo] Add `"includeOnramp": true` (default false) { "expo": { ... "plugins": [ [ "@stripe/stripe-react-native", { "merchantIdentifier": string | string [], "enableGooglePay": boolean, "includeOnramp": boolean } ] ] } } ``` ```shell # Add Expo BuildProperties (https://docs.expo.dev/versions/latest/sdk/build-properties/) npx expo install expo-build-properties ``` If you’re testing on a physical device, install [expo-dev-client](https://docs.expo.dev/versions/latest/sdk/dev-client/) to avoid Metro bundler connection issues: ```shell npx expo install expo-dev-client ``` ### Step 3: Use StripeProvider (Client-side) Wrap your app with [StripeProvider](https://stripe.dev/stripe-react-native/api-reference/functions/StripeProvider.html) at a high level so Stripe functionality is available throughout your component tree. Key properties: - `publishableKey`: Your Stripe publishable key. - `merchantIdentifier`: Your Apple Merchant ID (required for Apple Pay). - `urlScheme`: Required for return URLs in authentication flows. You need this component to initialize the Stripe SDK in your React Native application before using payment-related features. ```javascript import { StripeProvider } from '@stripe/stripe-react-native'; function App() { return ( {/* Your app components */} ); } ``` ### Step 4: Configure the onramp SDK (Client-side) Before you can successfully call any onramp APIs, you need to configure the SDK using the `configure` method. It’s provided by the [useOnramp()](https://stripe.dev/stripe-react-native/api-reference/functions/useOnramp.html) hook. The `configure` method takes an instance of [Onramp.Configuration](https://stripe.dev/stripe-react-native/api-reference/types/Onramp.Configuration.html) to customize your business display name and lightly customize elements in Stripe-provided interfaces, such as the user’s wallet, one-time passcode authorization, and identity verification UI. ```javascript import { useOnramp } from '@stripe/stripe-react-native'; function OnrampComponent() { const { configure } = useOnramp(); React.useEffect(() => { const setupOnramp = async () => { const result = await configure({ merchantDisplayName: 'My Crypto App', appearance: { lightColors: { primary: '#2d22a1', contentOnPrimary: '#ffffff', borderSelected: '#07b8b8' }, darkColors: { primary: '#800080', contentOnPrimary: '#ffffff', borderSelected: '#526f3e' }, style: 'ALWAYS_DARK', primaryButton: { cornerRadius: 8, height: 48 } } }); if (result.error) { console.error('Configuration failed:', result.error.message); } }; setupOnramp(); }, [configure]); return null; } ``` ## Authentication ### Step 1: Check for a Link account (Client-side) The customer must have a [Link](https://link.com) account to use the onramp APIs. Use `hasLinkAccount` to determine if the customer’s email is associated with an existing Link account. See the [HasLinkAccountResult](https://stripe.dev/stripe-react-native/api-reference/types/Onramp.HasLinkAccountResult.html) for the return type and the [OnrampError](https://stripe.dev/stripe-react-native/api-reference/enums/OnrampError.html) for the error type. - If they have an account, proceed to [Authorize](https://docs.stripe.com/crypto/onramp/embedded-components-integration-guide.md#step-authorize). - If they don’t, use [Register a new Link user](https://docs.stripe.com/crypto/onramp/embedded-components-integration-guide.md#step-register-a-new-link-user-if-needed), then proceed to [Authorize](https://docs.stripe.com/crypto/onramp/embedded-components-integration-guide.md#step-authorize). ```jsx const { hasLinkAccount, registerLinkUser, authorize } = useOnramp(); const linkResult = await hasLinkAccount('user@example.com'); if (linkResult.error) return; if (linkResult.hasLinkAccount) { // Proceed to authorization. } else { // Register the user first (see next step). } ``` ### View example ```javascript function AuthComponent() { const { hasLinkAccount, registerLinkUser } = useOnramp(); const handleAuth = async () => { const linkResult = await hasLinkAccount('user@example.com'); if (linkResult.error) { // Lookup failed. Show linkResult.error.message and stop. return; } if (linkResult.hasLinkAccount) { // User has Link account. Proceed to authorization. } else { const userInfo = { email: 'user@example.com', phone: '+12125551234', country: 'US', fullName: 'John Smith', }; const registerResult = await registerLinkUser(userInfo); if (registerResult.error) { // Registration failed. Show registerResult.error.message and let the user fix the data. } else if (registerResult.customerId) { // User registered. Proceed to authorization. } } }; return