Connect your own vendors
Your copy comes with no vendor accounts: every credential in it is yours.
This page goes through the settings in .env.example per vendor, and says
where each value comes from. Fill them in before your first pnpm dev.
How a service gets its settings
Section titled “How a service gets its settings”Each service declares its settings in a config class, src/config.ts, built on
envfield from
@evolve-framework/config. A missing required setting stops the service at
startup and names the setting.
- Locally, every service reads the
.envat the root of your copy. - One name for all services. A service looks for its own prefix first,
then for the plain name: purchase reads
PURCHASE_CTP_CLIENT_ID, thenCTP_CLIENT_ID. Use a prefixed name only when one service needs a different value. The prefixes arePURCHASE_,DISCOVER_, andNOTIFY_. - Deployed, Terraform in
configuration/writes the settings to each service’s configuration store, and the secrets to the cloud’s secret store. See Deployed environments.
The configuration reference lists every setting of the Evolve packages.
Commerce engine: commercetools
Section titled “Commerce engine: commercetools”Both reference sites run on commercetools. Purchase and discover each talk to
it, with these settings from
CommercetoolsConfig:
| Setting | What it is |
|---|---|
CTP_PROJECT_KEY |
Your project’s key |
CTP_API_URL |
The API host of your project’s region, such as https://api.europe-west1.gcp.commercetools.com |
CTP_AUTH_URL |
The auth host of that region, such as https://auth.europe-west1.gcp.commercetools.com |
CTP_CLIENT_ID, CTP_CLIENT_SECRET |
The service’s own API client |
CTP_SCOPES |
That client’s scopes, comma-separated |
CTP_USER_CLIENT_ID, CTP_USER_CLIENT_SECRET |
The API client that issues guest and customer tokens. Purchase needs it. |
CTP_USER_SCOPES |
The scopes of those tokens. Leave it unset to use the default. |
- Set up the project. The services expect the setup in
configuration/commercetools: custom types, product types, stores, tax categories, shipping methods, channels, and the associate roles for business units. Purchase checks at startup that its custom types exist.configuration/configs.tfapplies that module to one project; point it at yours. - Create a service client. Give it the scopes the service needs. The
reference sites list them in
configuration/purchase/commercetools.tfandconfiguration/discover/commercetools.tf. Discover only reads; purchase manages customers, carts, orders, payments, and business units. - Create a user client. Give it at least the scopes in
CTP_USER_SCOPES, or the default set when you leave that unset. commercetools refuses a token request that asks for more than the client has, and then no shopper gets a session at all. - Put the values in
.envand restart.
Moving to another engine is a bigger change. See Switch commerce engine.
Discover serves the content; the storefront only needs a secret for the preview route the CMS’s visual editor opens.
| Reference site | Service | Settings |
|---|---|---|
| B2C: Storyblok | discover | STORYBLOK_SPACE_ID, STORYBLOK_ACCESS_TOKEN, STORYBLOK_MANAGEMENT_TOKEN, STORYBLOK_CATEGORY_FOLDER_ID |
| B2C: Storyblok | site | CMS_PREVIEW_TOKEN, CMS_SECRET_TOKEN |
| B2B: Contentful | discover | CONTENTFUL_SPACE_ID, CONTENTFUL_ENVIRONMENT (default master), CONTENTFUL_ACCESS_TOKEN, CONTENTFUL_PREVIEW_TOKEN, CONTENTFUL_MANAGEMENT_API_ACCESS_TOKEN |
| B2B: Contentful | site | EVOLVE_CMS (default contentful), CMS_SECRET_TOKEN |
- Create the content model in your space first. It is Terraform, in
configuration/storyblokorconfiguration/contentful, with the space ID inconfiguration/configs.tf. - In Storyblok, discover creates a page for each new commercetools category,
with the management token.
STORYBLOK_CATEGORY_FOLDER_IDis the ID of thecategoryfolder those pages go in.
See Add a CMS for how the CMS module and its preview work.
Payment provider
Section titled “Payment provider”Payment providers run inside purchase. Each one is on when its key is set, so
set only the providers you use. The list is in
backend/purchase/src/payments/providers/index.ts.
| Reference site | Provider | Settings |
|---|---|---|
| B2C | Adyen | purchase: ADYEN_API_KEY, ADYEN_HMAC_KEY, ADYEN_MERCHANT_ACCOUNT, ADYEN_ENVIRONMENT (TEST or LIVE). Site: ADYEN_CLIENT_KEY, ADYEN_ENVIRONMENT |
| B2C, B2B | Mollie | purchase: MOLLIE_API_KEY. A test_ or live_ key picks the mode. |
| B2B | Pay on account | None. It is always on. |
Purchase also needs SERVER_URL: its own public URL. A provider sends the
shopper back and confirms the payment at SERVER_URL/payments/<provider>, so
that URL has to be reachable from the internet. Mollie does not deliver
webhooks to localhost.
See Add a payment provider for the routes each provider needs and how to add another one.
Search
Section titled “Search”- B2C serves product search from commercetools. There is nothing to connect.
- B2B serves it from commercetools by default, or from Algolia when you set
DISCOVER_SEARCH_ENGINE=algoliawithALGOLIA_APP_ID,ALGOLIA_SEARCH_API_KEY, andALGOLIA_WRITE_API_KEY. The index settings are Terraform, inconfiguration/algolia. Fill a new index withpnpm --filter @evolve-platform/discover sync algolia.
See Add search.
The notify service sends mail over SMTP. Locally it sends to Mailpit, which catches every message at localhost:8025. For a deployed environment, point it at your mail provider:
| Setting | What it is |
|---|---|
MAIL_HOST, MAIL_PORT |
Your provider’s SMTP server. Defaults to Mailpit at localhost:1025. |
MAIL_USER, MAIL_PASSWORD |
The SMTP login |
MAIL_SECURE |
true for a TLS connection. Mailpit needs false. |
MAIL_FROM |
The sender address |
MAIL_ALLOWED_DOMAINS |
The recipient domains this environment may send to. Leave it empty in production to send to everyone. |
STOREFRONT_URL |
Where links in an email point |
The names start with MAIL_, not SMTP_. An old SMTP_* value in your
.env is not read.
Other accounts in your copy
Section titled “Other accounts in your copy”The copy holds no accounts for tooling either. Fill in your own before you deploy:
- Sentry and Honeycomb for errors and traces. See Observability.
- The Hive schema registry, which checks and publishes the GraphQL schema
on each deploy, in
deploy/. - The cloud account and the Terraform state. The state backend is in
configuration/providers.tf, the project names and IDs inconfiguration/locals.tf,configuration/configs.tf, anddeploy/.
Deployed environments
Section titled “Deployed environments”Locally a setting is a line in .env. Deployed, Terraform in configuration/
owns it:
| B2C reference: Google Cloud | B2B reference: Azure | |
|---|---|---|
| Settings | One Parameter Manager parameter per service, written in configuration/<service>/config.tf |
App Configuration, with a key prefix per service |
| Secrets | Secret Manager, referenced from the parameter | Key Vault |
| commercetools clients | Created per service, with the scopes in configuration/<service>/commercetools.tf |
The same |
| Vendor secrets | configuration/tst.secrets.yaml, encrypted with SOPS |
The same |
Keep your vendor secrets for an environment in that file, encrypted with SOPS
under your own key, the same way as .env.encrypted.
Deploying covers the first release.
Next step
Section titled “Next step”Project structure: find your way around your copy, and see which parts you change.

