# Payments Setup (Hyperswitch + Mollie) This guide explains how to configure Hyperswitch and Mollie for payment processing in Veza. ## Overview - **Hyperswitch**: Payment orchestration layer (self-hosted or cloud) - **Mollie**: Payment processor (cards, iDEAL, etc.) configured in Hyperswitch - **Flow**: Backend creates order → Hyperswitch creates payment → Frontend shows payment form → User pays via Mollie → Webhook updates order ## Prerequisites - Docker and Docker Compose - Mollie account (https://www.mollie.com/dashboard) - Hyperswitch API keys (from Control Center or self-hosted) ## 1. Start Hyperswitch (Local Development) Hyperswitch runs as an optional Docker profile. Start it with: ```bash docker compose --profile payments up -d ``` This starts: - `hyperswitch_postgres` – Hyperswitch database - `hyperswitch` – Hyperswitch router on port 18081 Verify: ```bash curl http://localhost:18081/health ``` ## 2. Hyperswitch Control Center ### Option A: Hyperswitch Cloud (app.hyperswitch.io) 1. Sign up at https://app.hyperswitch.io 2. Create a merchant account 3. Obtain **API Key** and **Publishable Key** from Settings → Developers 4. Configure webhook URL: `https://your-domain.com/api/v1/webhooks/hyperswitch` ### Option B: Self-Hosted Control Center If using a self-hosted Control Center, follow the Hyperswitch documentation to obtain API keys and configure webhooks. ## 3. Configure Mollie in Hyperswitch 1. In Hyperswitch Control Center, go to **Connectors** 2. Add **Mollie** 3. Enter your Mollie API key: - **Test**: `test_xxx` from https://www.mollie.com/dashboard/developers/api-keys - **Live**: `live_xxx` for production Mollie test cards: https://docs.mollie.com/overview/testing ## 4. Backend Environment Variables Add to `veza-backend-api/.env`: ```bash # Hyperswitch HYPERSWITCH_ENABLED=true HYPERSWITCH_URL=http://localhost:18081 HYPERSWITCH_API_KEY=your_api_key_from_control_center HYPERSWITCH_WEBHOOK_SECRET=whsec_xxx # Checkout success redirect (used in return_url) CHECKOUT_SUCCESS_URL=http://localhost:5173/purchases ``` For Docker, use `http://hyperswitch:8080` as `HYPERSWITCH_URL`. ## 5. Frontend Environment Variables Add to `apps/web/.env.local`: ```bash VITE_HYPERSWITCH_PUBLISHABLE_KEY=pk_test_xxx ``` Use the publishable key from Hyperswitch Control Center (Settings → Developers). ## 6. Webhook Configuration Hyperswitch must be able to reach your webhook endpoint: - **Local dev**: Use a tunnel (ngrok, etc.) and set webhook URL to `https://your-tunnel.ngrok.io/api/v1/webhooks/hyperswitch` - **Production**: `https://your-domain.com/api/v1/webhooks/hyperswitch` The webhook is **public** (no auth). Signature verification is done via `HYPERSWITCH_WEBHOOK_SECRET`. ## 7. Test Flow 1. Start backend and frontend 2. Add items to cart 3. Go to checkout 4. Fill billing details and click "Proceed to payment" 5. Backend creates order and returns `client_secret` 6. Hyperswitch payment form appears 7. Use Mollie test card or iDEAL 8. On success, webhook updates order and creates licenses 9. User is redirected to `/purchases` ## 8. Simulated Payments (No Hyperswitch) When `HYPERSWITCH_ENABLED=false` or Hyperswitch is not configured: - Orders are completed immediately (simulated payment) - Licenses are created without real payment - **Useful for local development only** — never use in production ## 9. Production Checklist **CRITICAL**: Real payments require `HYPERSWITCH_ENABLED=true`. With `false`, orders complete without payment (dev/simulated only). - [ ] Set `HYPERSWITCH_ENABLED=true` in production - [ ] Use Mollie live API key - [ ] Use Hyperswitch production keys (`pk_prd_`, `sk_prd_`) - [ ] Set `CHECKOUT_SUCCESS_URL` to production domain - [ ] Configure webhook with production URL - [ ] Verify webhook signature in handler (Phase 7) - [ ] Ensure `HYPERSWITCH_WEBHOOK_SECRET` is set and kept secret - [ ] Set `VITE_HYPERSWITCH_PUBLISHABLE_KEY` at build time for frontend ## Troubleshooting ### Hyperswitch not starting - Check `hyperswitch_postgres` is healthy - Ensure port 18081 is free - See Hyperswitch logs: `docker compose logs hyperswitch` ### Payment form not showing - Verify `VITE_HYPERSWITCH_PUBLISHABLE_KEY` is set - Check backend returns `client_secret` in CreateOrder response - Ensure `HYPERSWITCH_ENABLED=true` and API key are set ### Webhook not received - Ensure Hyperswitch can reach your webhook URL (no localhost in production) - Check webhook secret matches - Inspect backend logs for webhook errors