Skip to main content
Follow these steps in order. Each step builds on the previous one.

1. Clone and install

git clone <your-payoes-repo-url>
cd payoes
npm install
This installs dependencies for the monorepo (apps/web, packages/*).

2. Start PostgreSQL and MinIO

From the repository root:
npm run docker:up
Wait until both containers are healthy:
docker compose ps
You should see payoes-postgres and payoes-minio running. The minio-init job creates the payoes-uploads bucket automatically.
To stop services later: npm run docker:down

3. Create your environment file

cp apps/web/.env.example apps/web/.env.local
Open apps/web/.env.local and set the minimum required values below.

Minimum config for first run

# Generate a random secret:
# openssl rand -base64 32
AUTH_SECRET=your-generated-secret-here
AUTH_URL=http://localhost:3000

# Google OAuth (or register with email/password at /register)
AUTH_GOOGLE_ID=your-client-id.apps.googleusercontent.com
AUTH_GOOGLE_SECRET=your-client-secret

# Database (matches docker-compose.yml)
DATABASE_URL=postgresql://payoes:payoes@localhost:5432/payoes

# MinIO (matches docker-compose.yml)
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

# Docs link in dashboard
NEXT_PUBLIC_DOCS_URL=http://localhost:3001

# Soroban escrow (required before creating payments)
# Run: ./scripts/soroban-deploy-contract.sh --operator-account payoes-operator --source-account payoes-operator
# STELLAR_TESTNET_OPERATOR_SECRET=S...
# SOROBAN_TESTNET_RPC_URL=https://soroban-testnet.stellar.org
# SOROBAN_TESTNET_CONTRACT_ID=C...
Leave SMTP and Persona variables empty for now. You can add them later.
Payments and checkout require Soroban escrow configuration. See Soroban escrow setup before creating payments.

4. Run database migrations

npm run db:migrate
You should see migrations applied successfully. This creates all tables (organizations, payments, team invites, verification, and more).
Run migrations after every git pull that adds new files under apps/web/drizzle/.

5. Start the web app

npm run dev
Open http://localhost:3000.

6. Sign in and complete onboarding

  1. Go to http://localhost:3000/register and create an account, or sign in with Google at http://localhost:3000/login
  2. Verify your email if you registered with email/password
  3. Complete onboarding:
    • Create an organization (name + logo)
    • Connect a testnet settlement wallet (use Stellar Laboratory to generate and fund one)
You should land on the dashboard with sandbox mode enabled.

7. Deploy the Soroban escrow contract

Payments require a deployed contract. From the repository root:
stellar keys generate --global payoes-operator
curl "https://friendbot.stellar.org?addr=$(stellar keys address payoes-operator)"

./scripts/soroban-deploy-contract.sh \
  --operator-account payoes-operator \
  --source-account payoes-operator
Copy CONTRACT_ID and OPERATOR_SECRET from the output into apps/web/.env.local, then restart npm run dev. See Soroban escrow setup for separate funder accounts, other networks, and troubleshooting.

8. Verify the setup works

Run a quick smoke test:
1

Create a sandbox API key

Dashboard → Developers → API Keys → create a key with the pk_test_ prefix.
2

Create a payment

Dashboard → Payments → create a payment, or use the API:
curl -X POST http://localhost:3000/api/v1/payments \
  -H "Authorization: Bearer pk_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": "1", "asset": "XLM", "description": "Local test"}'
3

Open checkout

Open the checkout_url from the response in a browser and complete payment with a testnet wallet.
If payment status becomes completed, your local stack is working.

9. Preview the docs site

In a second terminal, from the repository root:
npm run docs:dev
Open http://localhost:3001 to preview this documentation site.

Common issues

  • Ensure Docker is running: docker compose ps
  • Restart services: npm run docker:down && npm run docker:up
  • Confirm DATABASE_URL matches docker-compose.yml credentials
  • Make sure PostgreSQL is up before running npm run db:migrate
  • If you changed schema locally, run npm run db:generate only when intentionally creating new migrations
  • Check AUTH_SECRET is set (not empty)
  • For Google sign-in, confirm AUTH_GOOGLE_ID and AUTH_GOOGLE_SECRET are set
  • For email/password, register at /register and verify your email first
  • Restart the dev server after changing .env.local
  • Confirm MinIO is running on port 9000
  • Check S3_* variables match docker-compose.yml
  • Open http://localhost:9001 and verify bucket payoes-uploads exists
  • Run the Soroban deploy script: Soroban escrow setup
  • Confirm STELLAR_TESTNET_OPERATOR_SECRET and SOROBAN_TESTNET_CONTRACT_ID are set in .env.local
  • Restart the dev server after changing env vars
npm run build
Fix TypeScript or lint errors reported in the output. Run from the repository root.

Useful commands

CommandDescription
npm run devStart web app on port 3000
npm run buildProduction build
npm run docker:upStart PostgreSQL + MinIO
npm run docker:downStop Docker services
npm run db:migrateApply database migrations
npm run db:studioOpen Drizzle Studio (database GUI)
npm run soroban:deployDeploy and initialize the Soroban escrow contract
npm run docs:devPreview Mintlify docs on port 3001
npm run lintLint apps/web

Next steps

Soroban escrow setup

Deploy the contract and configure checkout payments.

Environment variables

Full reference for OAuth, SMTP, Stellar, and Persona KYC settings.

KYC verification

Persona identity verification for production mode.