# Fiat-to-crypto onramp # Set up an embeddable onramp integration Build a full, working Stripe [fiat-to-crypto onramp](https://docs.stripe.com/crypto/onramp.md) integration with your test API key. To customize the look and feel, go to the [branding settings](https://dashboard.stripe.com/account/branding) of the Dashboard. In the Dashboard, make sure you’ve added domains to the [domain allowlist](https://dashboard.stripe.com/crypto-onramp/allowlist-domains) for the domains you’ll use to host the onramp page. // This is a public sample test API key. // Don’t submit any personally identifiable information in requests made with this key. // Sign in to see your own test API key embedded in code samples. const Stripe = require("stripe"); const stripe = Stripe('<>'); const OnrampSessionResource = Stripe.StripeResource.extend({ create: Stripe.StripeResource.method({ method: 'POST', path: 'crypto/onramp_sessions', }), }); // Create an OnrampSession with the order amount and currency const onrampSession = await new OnrampSessionResource(stripe).create({ transaction_details: { destination_currency: transaction_details["destination_currency"], destination_exchange_amount: transaction_details["destination_exchange_amount"], destination_network: transaction_details["destination_network"], }, customer_ip_address: req.socket.remoteAddress, }); res.send({ clientSecret: onrampSession.client_secret, }); require 'stripe' \# This is a public sample test API key. # Don’t submit any personally identifiable information in requests made with this key. # Sign in to see your own test API key embedded in code samples. Stripe.api_key = '<>' \# Create an OnrampSession with amount and currency onramp_session = Stripe::APIResource.request( :post, '/v1/crypto/onramp_sessions', { transaction_details: { destination_currency: data['transaction_details']['destination_currency'], destination_exchange_amount: data['transaction_details']['destination_exchange_amount'], destination_network: data['transaction_details']['destination_network'] }, customer_ip_address: request.ip } )[0].data { clientSecret: onramp_session[:client_secret] }.to_json import stripe \# This is a public sample test API key. # Don’t submit any personally identifiable information in requests made with this key. # Sign in to see your own test API key embedded in code samples. stripe.api_key = '<>' try: data = json.loads(request.data) \# Create an OnrampSession with the order amount and currency onramp_session = stripe.stripe_object.StripeObject().request( "post", "/v1/crypto/onramp_sessions", { "transaction_details": { "destination_currency": data["transaction_details"]["destination_currency"], "destination_exchange_amount": data["transaction_details"]["destination_exchange_amount"], "destination_network": data["transaction_details"]["destination_network"], }, "customer_ip_address": request.remote_addr, }) return jsonify({ 'clientSecret': onramp_session['client_secret'] }) except Exception as e: return jsonify(error=str(e)), 403 $stripe = new \Stripe\StripeClient($stripeSecretKey); // Create an OnrampSession with amount and currency $params = [ 'transaction_details' => [ 'destination_currency' => $jsonObj->transaction_details->destination_currency, 'destination_exchange_amount' => $jsonObj->transaction_details->destination_exchange_amount, 'destination_network' => $jsonObj->transaction_details->destination_network, ], 'customer_ip_address' => $_SERVER['REMOTE_ADDR'] ]; $onrampSession = $stripe->request('post', '/v1/crypto/onramp_sessions', $params, []); $output = [ 'clientSecret' => $onrampSession->client_secret, ]; $stripeSecretKey = '<>'; "github.com/stripe/stripe-go/v84" // This is a public sample test API key. // Don’t submit any personally identifiable information in requests made with this key. // Sign in to see your own test API key embedded in code samples. stripe.Key = "<>" // Create an OnrampSession with amount and currency clientIp, _, _ := net.SplitHostPort(r.RemoteAddr) params := &OnrampSessionParam{ TransactionDetails: &req.TransactionDetails, CustomerIpAddress: &clientIp, } os, err := NewOnrampSession(params) log.Printf("pi.New: %v", os.ClientSecret) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Printf("pi.New: %v", err) return } writeJSON(w, struct { ClientSecret string `json:"clientSecret"` }{ ClientSecret: os.ClientSecret, }) // This test secret API key is a placeholder. Don't include personal details in requests with this key. // To see your test secret API key embedded in code samples, sign in to your Stripe account. // You can also find your test secret API key at https://dashboard.stripe.com/test/apikeys. services.AddSingleton(new StripeClient("<>")); var onrampSessionService = new OnrampSessionService(_client); var onrampSession = onrampSessionService.Create(new OnrampSessionCreateOptions { TransactionDetails = request.TransactionDetails, CustomerIpAddress = HttpContext.Connection.RemoteIpAddress.ToString(), }); return Json(new { clientSecret = onrampSession.ClientSecret }); // This is a public sample test API key. // Don’t submit any personally identifiable information in requests made with this key. // Sign in to see your own test API key embedded in code samples. Stripe.apiKey = "<>"; CreateOnrampSession postBody = gson.fromJson(request.body(), CreateOnrampSession.class); OnrampSessionCreateParams params = OnrampSessionCreateParams.builder() .setCustomerIpAddress(request.ip().replaceAll("^\\[|\\]$", "")) .setTransactionDetails( OnrampSessionCreateParams.TransactionDetails.builder() .setDestinationCurrency(OnrampSessionCreateParams.TransactionDetails.DestinationCurrency .valueOf(postBody.transactionDetails.destinationCurrency.toUpperCase())) .setDestinationExchangeAmount(postBody.transactionDetails.destinationExchangeAmount) .setDestinationNetwork(OnrampSessionCreateParams.TransactionDetails.DestinationNetwork .valueOf(postBody.transactionDetails.destinationNetwork.toUpperCase())) .build()) .build(); // Create an OnrampSession with the order amount and currency OnrampSession onrampSession = OnrampSession.create(params); CreateOnrampSessionResponse onrampSessionResponse = new CreateOnrampSessionResponse( onrampSession.getClientSecret()); return gson.toJson(onrampSessionResponse); import React, { useState, useEffect } from "react"; import { loadStripeOnramp } from "@stripe/crypto"; // Make sure to call loadStripeOnramp outside of a component’s render to avoid // recreating the StripeOnramp object on every render. // This is a public sample test API key. // Don’t submit any personally identifiable information in requests made with this key. // Sign in to see your own test API key embedded in code samples. const stripeOnrampPromise = loadStripeOnramp("<>"); useEffect(() => { // Fetches an onramp session and captures the client secret fetch( "/create-onramp-session", "/create.php", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ transaction_details: { destination_currency: "usdc", destination_exchange_amount: "13.37", destination_network: "ethereum", } }), }) .then((res) => res.json()) .then((data) => setClientSecret(data.clientSecret)); }, []); const onChange = React.useCallback(({ session }) => { setMessage(`OnrampSession is now in ${session.status} state.`); }, []); {clientSecret && ( )} // ReactContext to simplify access of StripeOnramp object const CryptoElementsContext = React.createContext(null); CryptoElementsContext.displayName = 'CryptoElementsContext'; export const CryptoElements = ({ stripeOnramp, children, }) => { const [ctx, setContext] = React.useState(() => ({ onramp: null, })); React.useEffect(() => { let isMounted = true; Promise.resolve(stripeOnramp).then((onramp) => { if (onramp && isMounted) { setContext((ctx) => (ctx.onramp ? ctx : { onramp })); } }); return () => { isMounted = false; }; }, [stripeOnramp]); return ( {children} ); }; // React hook to get StripeOnramp from context export const useStripeOnramp = () => { const context = React.useContext(CryptoElementsContext); return context?.onramp; }; // React element to render Onramp UI const useOnrampSessionListener = ( type, session, callback ) => { React.useEffect(() => { if (session && callback) { const listener = (e) => callback(e.payload); session.addEventListener(type, listener); return () => { session.removeEventListener(type, listener); }; } return () => {}; }, [session, callback, type]); }; export const OnrampElement = ({ clientSecret, appearance, onReady, onChange, ...props }) => { const stripeOnramp = useStripeOnramp(); const onrampElementRef = React.useRef(null); const [session, setSession] = React.useState(); const appearanceJSON = JSON.stringify(appearance); React.useEffect(() => { const containerRef = onrampElementRef.current; if (containerRef) { // NB: ideally we want to be able to hot swap/update onramp iframe // This currently results a flash if one needs to mint a new session when they need to update fixed transaction details containerRef.innerHTML = ''; if (clientSecret && stripeOnramp) { setSession( stripeOnramp .createSession({ clientSecret, appearance: appearanceJSON ? JSON.parse(appearanceJSON) : {} }) .mount(containerRef) ); } } }, [appearanceJSON, clientSecret, stripeOnramp]); useOnrampSessionListener('onramp_ui_loaded', session, onReady); useOnrampSessionListener('onramp_session_updated', session, onChange); return
; };
const stripeOnramp = StripeOnramp("<>"); // Fetches an onramp session and captures the client secret const response = await fetch( "/create-onramp-session", "/create.php", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ transaction_details: { destination_currency: "usdc", destination_exchange_amount: "13.37", destination_network: "ethereum", } }), }); const { clientSecret } = await response.json(); session = stripeOnramp .createSession({ clientSecret, appearance: { theme: "dark", } }) .addEventListener('onramp_session_updated', (e) => { showMessage(`OnrampSession is now in ${e.payload.session.status} state.`) }) .mount("#onramp-element"); { "name": "stripe-sample", "version": "1.0.0", "description": "A sample Stripe implementation", "main": "server.js", "scripts": { "start": "node server.js" }, "author": "stripe-samples", "license": "ISC", "dependencies": { "express": "^4.17.1", "stripe": "^20.4.0" } } { "name": "stripe-sample", "version": "0.1.0", "dependencies": { "@stripe/react-stripe-js": "^3.7.0", "@stripe/stripe-js": "^7.3.0", "express": "^4.17.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "^3.4.0", "stripe": "20.4.0" }, "devDependencies": { "concurrently": "4.1.2" }, "homepage": "http://localhost:3000/checkout", "proxy": "http://localhost:4242", "scripts": { "start-client": "react-scripts start", "start-server": "node server.js", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "start": "concurrently \"yarn start-client\" \"yarn start-server\"" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } } require github.com/stripe/stripe-go/v84 v84.4.0 certifi==2026.1.4 chardet==5.2.0 click==8.3.1 Flask==3.1.2 idna==3.11 itsdangerous==2.2.0 Jinja2==3.1.6 MarkupSafe==3.0.3 requests==2.32.5 stripe==14.4.0 toml==0.10.2 Werkzeug==3.1.5 { "name": "stripe-sample", "version": "0.1.0", "dependencies": { "@stripe/crypto": "^0.0.2", "@stripe/stripe-js": "^7.3.0", "express": "^4.17.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "^3.4.0", "stripe": "^8.202.0" }, "devDependencies": { "concurrently": "4.1.2" }, "homepage": "http://localhost:3000", "proxy": "http://localhost:4242", "scripts": { "start-client": "react-scripts start", "start-server": "node server.js", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject", "start": "concurrently \"yarn start-client\" \"yarn start-server\"" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } } { "name": "client", "version": "0.1.0", "private": true, "dependencies": { "@stripe/stripe-js": "^7.3.0", "@stripe/crypto": "^0.0.2", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "^3.4.0" }, "homepage": "http://localhost:3000", "proxy": "http://localhost:4242", "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } } 1. Build the server ~~~ pip3 install -r requirements.txt ~~~ 1. Build the server ~~~ bundle install ~~~ 1. Build the server ~~~ composer install ~~~ 1. Build the server ~~~ dotnet restore ~~~ 1. Build the server ~~~ mvn package ~~~ 2. Run the server ~~~ export FLASK_APP=server.py python3 -m flask run --port=4242 ~~~ 2. Run the server ~~~ ruby server.rb -o 0.0.0.0 ~~~ 2. Run the server ~~~ php -S 127.0.0.1:4242 --docroot=public ~~~ 2. Run the server ~~~ dotnet run ~~~ 2. Run the server ~~~ java -cp target/sample-jar-with-dependencies.jar com.stripe.sample.Server ~~~ 3. Build the client app ~~~ npm install ~~~ 4. Run the client app ~~~ npm start ~~~ 5. Go to [http://localhost:3000](http://localhost:3000) 3. Go to [http://localhost:4242/onramp.html](http://localhost:4242/onramp.html) 3. Build the client app ~~~ npm install ~~~ 4. Run the client app ~~~ npm start ~~~ 5. Go to [http://localhost:3000](http://localhost:3000) 3. Go to [http://localhost:4242/onramp.html](http://localhost:4242/onramp.html) 3. Build the client app ~~~ npm install ~~~ 4. Run the client app ~~~ npm start ~~~ 5. Go to [http://localhost:3000](http://localhost:3000) 3. Go to [http://localhost:4242/onramp.html](http://localhost:4242/onramp.html) 3. Build the client app ~~~ npm install ~~~ 4. Run the client app ~~~ npm start ~~~ 5. Go to [http://localhost:3000](http://localhost:3000) 3. Go to [http://localhost:4242/onramp.html](http://localhost:4242/onramp.html) 3. Build the client app ~~~ npm install ~~~ 4. Run the client app ~~~ npm start ~~~ 5. Go to [http://localhost:3000](http://localhost:3000) 3. Go to [http://localhost:4242/onramp.html](http://localhost:4242/onramp.html) 1. Run the server ~~~ go run server.go ~~~ 2. Build the client app ~~~ npm install ~~~ 3. Run the client app ~~~ npm start ~~~ 4. Go to [http://localhost:3000](http://localhost:3000) 1. Run the server ~~~ go run server.go ~~~ 2. Go to [http://localhost:4242/onramp.html](http://localhost:4242/onramp.html) 1. Build the application ~~~ npm install ~~~ 2. Run the application ~~~ npm start ~~~ 3. Go to [http://localhost:3000](http://localhost:3000) 1. Build the server ~~~ npm install ~~~ 2. Run the server ~~~ npm start ~~~ 3. Go to [http://localhost:4242/onramp.html](http://localhost:4242/onramp.html) \### Development 1. Build the application ~~~shell $ npm install ~~~ 2. _Optional_: download and run the [Stripe CLI](https://stripe.com/docs/stripe-cli) ~~~shell $ stripe listen --forward-to localhost:3000/api/webhooks ~~~ 3. Run the application ~~~shell $ STRIPE_WEBHOOK_SECRET=$(stripe listen --print-secret) npm run dev ~~~ 4. Go to [localhost:3000](http://localhost:3000) ### Production 1. Build the application ~~~shell $ npm install $ npm build ~~~ 2. Run the application ~~~shell $ npm start ~~~ ### Install the Stripe Node library Install the package and import it in your code. Alternatively, if you’re starting from scratch and need a package.json file, download the project files using the Download link in the code editor. #### npm Install the library: ```bash npm install --save stripe ``` #### GitHub Or download the stripe-node library source code directly [from GitHub](https://github.com/stripe/stripe-node). ### Install the Stripe Ruby library Install the Stripe ruby gem and require it in your code. Alternatively, if you’re starting from scratch and need a Gemfile, download the project files using the link in the code editor. #### Terminal Install the gem: ```bash gem install stripe ``` #### Bundler Add this line to your Gemfile: ```bash gem 'stripe' ``` #### GitHub Or download the stripe-ruby gem source code directly [from GitHub](https://github.com/stripe/stripe-ruby). ### Install the Stripe Java library Add the dependency to your build and import the library. Alternatively, if you’re starting from scratch and need a sample pom.xml file (for Maven), download the project files using the link in the code editor. #### Maven Add the following dependency to your POM and replace {VERSION} with the version number you want to use. ```bash \ncom.stripe\nstripe-java\n{VERSION}\n ``` #### Gradle Add the dependency to your build.gradle file and replace {VERSION} with the version number you want to use. ```bash implementation "com.stripe:stripe-java:{VERSION}" ``` #### GitHub Download the JAR directly [from GitHub](https://github.com/stripe/stripe-java/releases/latest). ### Install the Stripe Python package Install the Stripe package and import it in your code. Alternatively, if you’re starting from scratch and need a requirements.txt file, download the project files using the link in the code editor. #### pip Install the package through pip: ```bash pip3 install stripe ``` #### GitHub Download the stripe-python library source code directly [from GitHub](https://github.com/stripe/stripe-python). ### Install the Stripe PHP library Install the library with composer and initialize with your secret API key. Alternatively, if you’re starting from scratch and need a composer.json file, download the files using the link in the code editor. #### Composer Install the library: ```bash composer require stripe/stripe-php ``` #### GitHub Or download the stripe-php library source code directly [from GitHub](https://github.com/stripe/stripe-php). ### Set up your server Add the dependency to your build and import the library. Alternatively, if you’re starting from scratch and need a go.mod file, download the project files using the link in the code editor. #### Go Make sure to initialize with Go Modules: ```bash go get -u github.com/stripe/stripe-go/v84 ``` #### GitHub Or download the stripe-go module source code directly [from GitHub](https://github.com/stripe/stripe-go). ### Install the Stripe.net library Install the package with .NET or NuGet. Alternatively, if you’re starting from scratch, download the files which contains a configured .csproj file. #### dotnet Install the library: ```bash dotnet add package Stripe.net ``` #### NuGet Install the library: ```bash Install-Package Stripe.net ``` #### GitHub Or download the Stripe.net library source code directly [from GitHub](https://github.com/stripe/stripe-dotnet). ### Install the Stripe libraries Install the packages and import them in your code. Alternatively, if you’re starting from scratch and need a `package.json` file, download the project files using the link in the code editor. Install the libraries: ```bash npm install --save stripe @stripe/stripe-js next ``` ### Create a OnrampSession Add an endpoint on your server that creates an [OnrampSession](https://docs.stripe.com/api/crypto/onramp_sessions.md) object. An `OnrampSession` object tracks the customer’s onramp lifecycle, keeping track of order details and ensuring the customer is only charged once. Return the `OnrampSession` object’s *client secret* (A client secret is used with your publishable key to authenticate a request for a single object. Each client secret is unique to the object it's associated with) in the response to finish the onramp on the client. > Our official libraries don’t contain built-in support for the API endpoints because the onramp API is in limited beta. This guide includes custom extension to the official Stripe libraries for minting onramp sessions. You can find them in the downloadable sample code on the right. ### Add Stripe to your React app Use the *Stripe.js* (Use Stripe.js’ APIs to tokenize customer information, collect sensitive card data, and accept payments with browser payment APIs) and the [Stripe crypto SDK](https://www.npmjs.com/@stripe/crypto) to remain *PCI compliant* (Any party involved in processing, transmitting, or storing credit card data must comply with the rules specified in the Payment Card Industry (PCI) Data Security Standards. PCI compliance is a shared responsibility and applies to both Stripe and your business). The crypto SDK includes Typescript type definitions. ```bash npm install --save @stripe/crypto @stripe/stripe-js ``` ### Initialize the Stripe crypto SDK Call `loadStripeOnramp()` with your Stripe publishable API key to configure the Stripe library. ### Load Stripe Crypto SDK Use *Stripe.js* (Use Stripe.js’ APIs to tokenize customer information, collect sensitive card data, and accept payments with browser payment APIs) and the [Stripe crypto SDK](https://www.npmjs.com/package/@stripe/crypto) to remain *PCI compliant* (Any party involved in processing, transmitting, or storing credit card data must comply with the rules specified in the Payment Card Industry (PCI) Data Security Standards. PCI compliance is a shared responsibility and applies to both Stripe and your business). These scripts must always load directly from Stripe’s domains (https://js.stripe.com and https://crypto-js.stripe.com) for compatibility. Don’t include the scripts in a bundle or host a copy yourself. If you do, your integration might break without warning. ### Define the onramp container Add one empty placeholder `div` to your page to host the onramp widget. Stripe inserts an iframe to securely collect the customer’s payment and other sensitive information. ### Initialize Stripe crypto SDK Initialize Stripe crypto SDK with your publishable API keys. You’ll use it to retrieve the `OnrampSession` object and complete the onramp on the client. ### Fetch an OnrampSession Immediately make a request to the endpoint on your server to create a new `OnrampSession` object as soon as your page loads. The *clientSecret* (A client secret is used with your publishable key to authenticate a request for a single object. Each client secret is unique to the object it's associated with) returned by your endpoint is used to complete the onramp. ### Define Stripe Elements Define components in your code to simplify the access of the `StripeOnramp` object and rendering of the onramp widget. > These components will be released as an ES module in the future similar to `@stripe/react-stripe-js`. ### Initialize Stripe Elements Pass the resulting promise from the `loadStripeOnramp` call to the Elements provider. This allows the child components to access the Stripe service through the Elements consumer. ### Add the OnrampElement Add an `OnrampElement` component to your page. It embeds an iframe with a dynamic UI that collects necessary order, identity, and payment details to complete the purchase and delivery of crypto. > Use the [values provided here](https://docs.stripe.com/crypto/onramp/embedded.md#sandbox-values) to complete an onramp transaction in *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). ### Create the OnrampElement Create an `OnrampSession` instance and mount it to the placeholder `
` on your page. It embeds an iframe with a dynamic UI that collects necessary order, identity, and payment details to complete the purchase and delivery of crypto. > Use the [values provided here](https://docs.stripe.com/crypto/onramp/embedded.md#sandbox-values) to complete an onramp transaction in *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). ## Enhance your integration You’re ready to let users securely purchase cryptocurrencies directly from your platform or Dapp at checkout. Continue with the steps below to add more features. ### Style the onramp widget Customize the Onramp UI with [brand settings](https://dashboard.stripe.com/settings/branding) in your dashboard. Use your company’s color scheme to make it match with the rest of your onramp page. ### Dark mode Apply dark mode to the onramp widget with the `theme` parameter. ### Set up OnrampSession state callbacks Initialize callbacks to create a responsive interface when an onramp session completes. For example, you can direct users to resume their previous task or return to their intended destination. ### Set up OnrampSession state listeners Initialize listeners to provide a responsive user interface when an onramp session completes. For example, you can direct users to resume their previous task or return to their intended destination. ## Next steps #### [Customize appearance](https://docs.stripe.com/crypto/onramp/embedded.md#customize-onramp) Customize the appearance of the onramp. #### [Pre-populate parameters](https://docs.stripe.com/crypto/onramp/embedded.md#prepopulate-onramp) Customze the `OnrampSession`, such as pre-populating customer information and setting default cryptocurrencies. #### [Configure conversion quotes](https://docs.stripe.com/crypto/onramp/embedded.md#quotes) Use the Onramp Quotes API to fetch estimated quotes for onramp conversions into various cryptocurrencies on different networks. #### [Back-end integration best practices](https://docs.stripe.com/crypto/onramp/embedded.md#use-case) Review the suggested `OnrampSession` parameters to set based on your product use case.