A Clojure webhook handler for processing and validating payment events with SQLite persistence and HTTP callbacks for confirmation/cancellation.
- Validates a secure token from incoming webhooks
- Checks for duplicate or malformed payloads
- Confirms or cancels transactions via internal HTTP APIs
- Persists transaction IDs in an SQLite database
- Supports both HTTP (port 5000) and HTTPS (port 5443)
git clone https://github.com/victorlga/payment-webhook-handler.git
cd payment-webhook-handlerThis project will run a HTTPS server locally. To make this possible, you need to generate a self-signed certificate. Run the following command in the root of the repository to create a keystore.p12 file:
keytool -genkeypair -alias server-key \
-keyalg RSA -keysize 2048 -storetype PKCS12 \
-keystore keystore.p12 -validity 365 \
-storepass changeit -keypass changeit \
-dname "CN=localhost, OU=Dev, O=MyCompany, L=City, S=State, C=BR"This creates a self-signed certificate valid for 365 days, with both the store and key passwords set to
changeit.
Make sure Docker is running:
docker build -t clojure-webhook-handler -f .devcontainer/Dockerfile .If ports 5000 (HTTP) or 5443 (HTTPS) are in use, change the exposed ports.
docker run -p 5000:5000 -p 5443:5443 clojure-webhook-handlerFor example, if port 5000 is busy and you want to use port 5050 instead:
docker run -p 5050:5000 -p 5443:5443 clojure-webhook-handlerYou should see something like:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
...
cd pythonpython3 -m venv venv
source venv/bin/activate
pip install -r requirements.txtpython3 test_webhook.py
⚠️ If you changed the port during Docker run, make sure to update it intest_webhook.py.
Once the server is running with HTTPS (on port 5443 by default), test it using curl:
curl -k -X POST https://localhost:5443/webhook \
-H "Content-Type: application/json" \
-H "x-webhook-token: meu-token-secreto" \
-d '{"transaction_id": "test-123", "event": "payment", "amount": "49.90", "currency": "BRL", "timestamp": "2025-06-08T12:00:00Z"}'- The
-kflag allowscurlto skip certificate verification (necessary for self-signed certs). - You should receive a response like
"OK"if the request is accepted.
- This
curlrequest only validates the HTTPS interface. - The internal HTTP requests to confirm or cancel the transaction will fail, because
curldoesn't run the backend services required to handle those endpoints (/confirmar,/cancelar). - This is expected during basic HTTPS testing.
.
├── core.clj ; Main handler logic
├── project.clj ; Leiningen config
├── .devcontainer/
│ └── Dockerfile ; Docker setup
├── data/ ; SQLite database
└── python/
├── test_webhook.py ; Test client for webhook
└── requirements.txt ; Python dependencies