Vasooli is a buildathon submission, not a production payment system. It never
moves real money: vasooli live makes real API calls, but only to a
Razorpay test-mode account, and the batch engine runs entirely on synthetic
data (vasooli/sim/).
- Webhook signature verification (
vasooli/webhook.py) useshmac.compare_digestagainstRAZORPAY_WEBHOOK_SECRETand refuses rather than trusts when that secret is unset. Seetests/test_webhook.py. - The audit ledger (
vasooli/ledger.py) is a hash-chained SQLite log. Unkeyed, it detects accidental corruption; setVASOOLI_LEDGER_KEYto make the chain HMAC-keyed, which also detects a deliberate rewrite by someone with write access to the database file. Neither mode is a substitute for an external, append-only checkpoint in a real deployment. - No customer message is ever sent.
vasooli nudgedrafts and logs customer-facing text; there is no send path in this repository. - Secrets live in
.env(gitignored) and are read viaos.environ, never hardcoded..env.exampledocuments every variable without values.
Documented in README.md §17 and the Method page:
the webhook ingestion path is not idempotent under concurrent writers, and
prior_failures() / the replay check are full-table scans that do not scale
past a demo-sized ledger. Neither is exploitable in the current deployment —
there is no publicly reachable webhook endpoint — but both would need fixing
before this became a live integration.
This is a solo hackathon project with no users and no production deployment. If you find something concerning anyway, open a GitHub issue or reach the author at the email on their GitHub profile. Please don't test against anything other than your own fork or the public demo's static pages — there is no backend to attack.