| 1 | --- |
| 2 | title: Setup |
| 3 | description: Connect alchemy to Stripe — secret key, profiles, CI, and how Worker bindings get their credentials. |
| 4 | --- |
| 5 | |
| 6 | ## Get a key |
| 7 | |
| 8 | Sign up at [stripe.com](https://stripe.com). Every account has a |
| 9 | **test mode** with its own keys and data — use that for everything |
| 10 | until you're ready to charge real cards. Copy the test secret key |
| 11 | (`sk_test_…`) from |
| 12 | [Developers → API keys](https://dashboard.stripe.com/test/apikeys). |
| 13 | |
| 14 | ## Register the provider |
| 15 | |
| 16 | ```typescript |
| 17 | // alchemy.run.ts |
| 18 | import * as Alchemy from "alchemy"; |
| 19 | import * as Cloudflare from "alchemy/Cloudflare"; |
| 20 | import * as Stripe from "alchemy/Stripe"; |
| 21 | import * as Effect from "effect/Effect"; |
| 22 | import * as Layer from "effect/Layer"; |
| 23 | |
| 24 | export default Alchemy.Stack( |
| 25 | "MyApp", |
| 26 | { |
| 27 | providers: Layer.mergeAll(Cloudflare.providers(), Stripe.providers()), |
| 28 | state: Alchemy.localState(), |
| 29 | }, |
| 30 | Effect.gen(function* () { |
| 31 | // resources go here |
| 32 | }), |
| 33 | ); |
| 34 | ``` |
| 35 | |
| 36 | ## Store the key |
| 37 | |
| 38 | The first `alchemy deploy` that touches a Stripe resource prompts for |
| 39 | the key and saves it under `~/.alchemy/credentials/<profile>/`. To set |
| 40 | it up ahead of time, or to add Stripe to an existing profile: |
| 41 | |
| 42 | ```sh |
| 43 | alchemy profile edit --add Stripe |
| 44 | ``` |
| 45 | |
| 46 | An optional API base URL overrides `https://api.stripe.com` (useful for |
| 47 | [stripe-mock](https://github.com/stripe/stripe-mock)). |
| 48 | |
| 49 | In CI (`CI=true`) profiles are bypassed and alchemy reads |
| 50 | `STRIPE_API_KEY` from the environment. `STRIPE_API_BASE_URL` is |
| 51 | optional. |
| 52 | |
| 53 | See [Profiles](/environments/profiles) for switching between accounts |
| 54 | and stages. |
| 55 | |
| 56 | ## Test mode is real |
| 57 | |
| 58 | A `sk_test_…` key talks to a fully working Stripe account. Products, |
| 59 | Prices, Customers, Checkout Sessions, and webhook deliveries all |
| 60 | behave exactly as in live mode; the only difference is that cards |
| 61 | like `4242 4242 4242 4242` succeed and no money moves. Deploy, destroy, |
| 62 | and redeploy freely. |
| 63 | |
| 64 | ## How Workers get credentials |
| 65 | |
| 66 | A Worker that calls Stripe at runtime needs a key on the host. You |
| 67 | never wire that up by hand. Each binding you yield — |
| 68 | `Stripe.CreateCustomer()`, `Stripe.CreateCheckoutSession()`, and so |
| 69 | on — declares the permission it needs (`customers_write`, |
| 70 | `checkout_sessions_write`, …) on a |
| 71 | [`RestrictedApiKey`](/providers/stripe/restrictedapikey) resource |
| 72 | that alchemy creates per Worker. The key's value is injected as a |
| 73 | `secret_text` binding. |
| 74 | |
| 75 | Today Stripe has no public API for minting restricted keys, so the |
| 76 | value alchemy injects is your account secret key. The permissions are |
| 77 | still recorded on the resource, which means: |
| 78 | |
| 79 | - you can see exactly which Stripe scopes each Worker uses in the plan |
| 80 | output, and |
| 81 | - if you'd rather the Worker hold a narrower key, create one in |
| 82 | [Dashboard → API keys → Restricted keys](https://dashboard.stripe.com/test/apikeys) |
| 83 | with those scopes and pass it as `value` — bindings will use it |
| 84 | unchanged. |
| 85 | |
| 86 | When Stripe ships a mint API the same declarations will drive it with |
| 87 | no code change in your Worker. |
| 88 | |
| 89 | ## Enable Connect (platforms only) |
| 90 | |
| 91 | If you're going to create connected accounts, Connect must be switched |
| 92 | on once at |
| 93 | [dashboard.stripe.com/connect](https://dashboard.stripe.com/test/connect). |
| 94 | There's no API for that step; `POST /v1/accounts` returns an error |
| 95 | until it's done. |
| 96 | |
| 97 | ## Next |
| 98 | |
| 99 | - [Sell a subscription](/stripe/guides/subscriptions) |
| 100 | - [Onboard merchants with Connect](/stripe/guides/connect) |