Clarification on Stripe Live IDs

I’m deploying my Bubble app with Stripe live payments. I updated the Stripe plugin with live keys (sk_live and pk_live) and created live products/prices in Stripe. I also added the live price_id and product_id into my Bubble Option Sets. However, when I save the Option Set values and come back, Bubble reverts them back to the old test IDs. Also, my checkout page still generates cs_test_ sessions and shows “Sandbox,” even though the app is deployed to my custom live domain. I’m trying to understand whether:

  1. Bubble Option Sets behave differently between Development and Live,

  2. I should store both test/live Stripe IDs separately,

  3. My workflows are still referencing development data,

  4. Or whether Stripe plugin/workflows cache old IDs somewhere.

Would appreciate guidance from anyone who has moved a Bubble + Stripe subscription app from test to live successfully.

Option Sets do not have live or dev values. They have just one value that is set for both Live + Dev. You need to set them in dev and then push live to have updates appear in your live app.

For Stripe, most Devs add 2 data points in their option sets. Live ID and Test ID

You can then use the expression Isn't live version:formatted as text to use the proper key when in live and dev.

This allows your testing app to use the Stripe sandbox so you can test payment flows without actually paying.

This usually means the checkout session is still being created from a test-mode Stripe configuration somewhere in the app.

A custom live domain alone does not make Stripe live. If Stripe is returning cs_test_ and the Checkout page shows “Sandbox,” then the request that created that Checkout Session is still using test credentials, a test price, a test Payment Link, or a workflow/API call that is still pointing to test mode.

A few things I’d check:

  1. Option Sets are static app data, not normal database records
    Bubble Option Sets are part of the app structure/source, not the live database. So they don’t behave like normal Development/Live database records. If you change an Option Set in Development, you still need to deploy that version to Live before the Live app uses those new values.

Also make sure you are editing the correct branch/version. If the value appears to “revert,” it may be because you are switching between branches, looking at Live vs Development, or the change wasn’t saved/deployed from the version that your live app is actually running.

  1. Store test and live Stripe IDs separately
    For Stripe, I usually recommend storing both IDs separately instead of overwriting one field.

  2. Check every workflow that creates checkout
    The main thing to inspect is the exact workflow/action/API call that creates the Checkout Session.

If the session ID starts with cs_test_, Stripe is definitely receiving a test-mode request.

  1. Plugin settings may not be the only Stripe connection
    If you use the official Stripe plugin plus API Connector, check both.

A common issue is updating the Bubble Stripe plugin to live keys but forgetting that the Checkout Session is actually being created through an API Connector call with:

  1. Deploy after changing Option Sets, plugin settings, and workflows
    After updating Option Sets/workflows/plugin settings, create a save point and deploy Development to Live. Then test from the live app URL without /version-test.

I’d also clear the browser cache or test in an incognito window, especially because Option Sets/static app data can be cached until a new deployed version is loaded.

My recommended setup would be:

  • Keep test and live Stripe products/prices separate

  • Store both test/live price IDs in Option Sets or a private admin settings data type

  • Use conditional logic to select the right ID

  • Make sure all checkout creation happens through one clean workflow

  • Confirm no API Connector call still uses test keys

  • Deploy the updated version to Live

  • Create a brand-new checkout session and confirm it starts with cs_live_