Payments require handling sensitive data. The code examples below demonstrate the integration pattern and should not be used in production as-is. In production, store sensitive information such as API keys and private keys in a secrets manager or vault.
Stripe’s crypto on-ramp requires a US domicile (excluding Hawaii) and a registered business. Once registration is approved, the Crypto/Onramp_sessions API is enabled on your account. The examples below use Stripe’s Sandbox environment.
Prerequisites
Create an on-ramp session on the server
Create the session server-side and return only the client_secret to the frontend. Never expose your STRIPE_SECRET_KEY to the client.
Using cURL:
# SERVER-SIDE ONLY
curl https://api.stripe.com/v1/crypto/onramp_sessions \
-u sk_test_your_secret_key: \
-d "destination_currency"="usdc" \
-d "destination_network"="polygon" \
-d "wallet_addresses[0][type]"="self_custody" \
-d "wallet_addresses[0][address]"="0xYOUR_POLYGON_ADDRESS"
A successful response returns a client_secret:
{
"id": "cos_0MYvmj589O8KAxCGp14dTjiw",
"object": "crypto.onramp_session",
"client_secret": "cos_0MYvmj589O8KAxCGp14dTjiw_secret_BsxEqQLiYKANcTAoVnJ2ikH5q002b9xzouk",
"created": 1675794053,
"livemode": false,
[...]
}
}
Using the Stripe Node SDK:
import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
export async function createOnrampSession(req, res) {
const session = await stripe.crypto.onramps.sessions.create({
destination_currency: "usdc",
destination_network: "polygon",
wallet_addresses: [{
type: "self_custody",
address: "0xYOUR_POLYGON_ADDRESS"
}],
// optional: customer, email, reference, etc.
});
res.json({ client_secret: session.client_secret });
}
Pass the client_secret from your server response to the Stripe on-ramp widget:
<script src="https://js.stripe.com/v3/crypto/onramp.js"></script>
<div id="onramp"></div>
<script>
(async () => {
// Fetch client_secret from your server
const { client_secret } = await fetch("/api/create-onramp-session").then(r => r.json());
const onramp = await window.StripeOnramp.init({
clientSecret: client_secret,
appearance: { /* optional branding overrides */ },
});
onramp.mount("#onramp");
})();
</script>