All configuration for the web app lives in apps/web/.env.local. Copy from apps/web/.env.example and adjust values for your machine.
Restart npm run dev after changing environment variables.
Auth
| Variable | Required | Description |
|---|
AUTH_SECRET | Yes | Session encryption secret. Generate with openssl rand -base64 32 |
AUTH_URL | Yes | Public app URL. Local: http://localhost:3000 |
AUTH_GOOGLE_ID | For Google sign-in | Google OAuth client ID |
AUTH_GOOGLE_SECRET | For Google sign-in | Google OAuth client secret |
Users can register with email and password, or sign in with Google when OAuth is configured.
Database
| Variable | Required | Default (local) |
|---|
DATABASE_URL | Yes | postgresql://payoes:payoes@localhost:5432/payoes |
Must match the credentials in docker-compose.yml.
Object storage (MinIO)
| Variable | Required | Default (local) |
|---|
S3_ENDPOINT | Yes | http://localhost:9000 |
S3_PUBLIC_URL | Yes | http://localhost:9000/payoes-uploads |
S3_ACCESS_KEY | Yes | payoes |
S3_SECRET_KEY | Yes | payoessecret |
S3_BUCKET | Yes | payoes-uploads |
S3_REGION | Yes | us-east-1 |
Used for organization logo uploads.
Stellar
| Variable | Required | Description |
|---|
STELLAR_TESTNET_USDC_ISSUER | For USDC sandbox | Testnet USDC issuer public key |
STELLAR_MAINNET_USDC_ISSUER | For USDC production | Mainnet USDC issuer public key |
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID | No | Enables WalletConnect in Stellar Wallet Kit |
XLM payments work without USDC issuer variables. Set the issuer for the network you test when accepting USDC.
Email (SMTP)
| Variable | Required | Description |
|---|
SMTP_HOST | For invites | SMTP server hostname |
SMTP_PORT | For invites | Usually 587 |
SMTP_USER | For invites | SMTP username |
SMTP_PASSWORD | For invites | SMTP password |
SMTP_FROM | For invites | From header, e.g. Payoes <noreply@yourdomain.com> |
Team invitation emails are sent only when SMTP is configured. Without SMTP, you can still test invites by copying the invite URL from the database or API response.
KYC (Persona)
| Variable | Required | Description |
|---|
PERSONA_API_KEY | For production gate | Server-side Persona API key (persona_sandbox_...) |
PERSONA_WEBHOOK_SECRET | For webhooks | Webhook signing secret from Persona dashboard |
PERSONA_INQUIRY_TEMPLATE_ID | For production gate | KYC inquiry template ID (itmpl_...) |
NEXT_PUBLIC_PERSONA_ENVIRONMENT_ID | For production gate | Persona environment ID (env_...) |
NEXT_PUBLIC_PERSONA_INQUIRY_TEMPLATE_ID | SDK only | Client-side template ID for the Persona SDK |
See KYC verification for Persona sandbox setup.
Background jobs
Self-hosted deployments only.
| Variable | When to set | Description |
|---|
CRON_SECRET | Running cron workers | Bearer token for protected cron endpoints |
See Webhook retry worker for scheduling setup.
Soroban escrow (required for payments)
Payments and checkout require a deployed and initialized Payoes Soroban contract.
| Variable | Required | Description |
|---|
STELLAR_TESTNET_OPERATOR_SECRET | Yes (sandbox) | Operator secret (S...). Printed by the deploy script |
SOROBAN_TESTNET_RPC_URL | Yes (sandbox) | Soroban RPC URL. Default: https://soroban-testnet.stellar.org |
SOROBAN_TESTNET_CONTRACT_ID | Yes (sandbox) | Contract ID (C...). Printed by the deploy script |
STELLAR_MAINNET_OPERATOR_SECRET | Production only | Mainnet operator account |
SOROBAN_MAINNET_RPC_URL | Production only | Mainnet Soroban RPC URL |
SOROBAN_MAINNET_CONTRACT_ID | Production only | Mainnet Payoes contract ID |
Deploy and initialize with one command:
./scripts/soroban-deploy-contract.sh \
--operator-account payoes-operator \
--source-account payoes-operator
See Soroban escrow setup for the full walkthrough.
Docs
| Variable | Required | Description |
|---|
NEXT_PUBLIC_DOCS_URL | Recommended | URL opened by dashboard documentation links. Local: http://localhost:3001 |
Example: minimal local file
AUTH_SECRET=<openssl rand -base64 32>
AUTH_URL=http://localhost:3000
AUTH_GOOGLE_ID=your-client-id.apps.googleusercontent.com
AUTH_GOOGLE_SECRET=your-client-secret
DATABASE_URL=postgresql://payoes:payoes@localhost:5432/payoes
S3_ENDPOINT=http://localhost:9000
S3_PUBLIC_URL=http://localhost:9000/payoes-uploads
S3_ACCESS_KEY=payoes
S3_SECRET_KEY=payoessecret
S3_BUCKET=payoes-uploads
S3_REGION=us-east-1
NEXT_PUBLIC_DOCS_URL=http://localhost:3001
Example: with Google OAuth
Set AUTH_GOOGLE_ID and AUTH_GOOGLE_SECRET in .env.local. In Google Cloud Console, set the authorized redirect URI to:
http://localhost:3000/api/auth/callback/google