147 lines
4.6 KiB
Markdown
147 lines
4.6 KiB
Markdown
# 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 complete redirect (base URL; backend appends ?order_id=xxx)
|
||
# v0.402: Use /checkout/complete for success/error page (order status determines display)
|
||
CHECKOUT_SUCCESS_URL=http://localhost:5173/checkout/complete
|
||
```
|
||
|
||
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 `/checkout/complete?order_id=xxx` (success or error based on order status)
|
||
|
||
## 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
|