I have spent 18 years building software across SaaS, fintech and payments, much of it in regulated, audited and security-sensitive environments. Today most of my open-source time goes into PandaWard, a local application security assessment engine that keeps evidence for every finding and says plainly what it did not test. Alongside it I build payment infrastructure at Payshen, maintain tooling for payment developers and review payment, webhook and auth code in other projects.
| Venture | Role and focus |
|---|---|
| PandaWard | Maintainer, main open-source project. Local, evidence-based application security assessment as a Go CLI and a Claude Code plugin. |
| Payshen | Founder and Managing Director. Payment orchestration: every provider through one integration, each payment routed to the provider most likely to approve it, retried elsewhere only when that is safe, with the reason recorded. |
| PandaPayLens | Maintainer. Open-source, local-first payment error decoder and transaction timeline visualizer. |
| afend | Founder. Guided ISO/IEC 27001:2022 readiness, from risk register to an auditor-ready handoff. |
| Nanotesting | Founder. Automated security assessment for websites, APIs and repositories. |
| SodaSoft | Founder. Venture studio for software products: design, engineering and launch. |
Application security assessment for your own repositories that also tells you what it did not test. Most scanners print alerts and stop; PandaWard keeps a ledger of every control it could check, how it checked it and the redacted evidence, and lists every control it could not decide. Passive by default, network tests only after a person approves the scope. Formerly PenSec, renamed in 0.2.0.
- Honest coverage: only PASS and FAIL are decisive; blocked, unsupported or suspected controls never count as secure.
- Evidence, not opinions: each finding links to a redacted, SHA-256 addressed evidence record and is fingerprinted across runs, so a fix counts only when the check runs again.
- No AI-confirmed findings: review agents can only record hypotheses, and the engine reads and redacts the cited lines itself.
- Wide static coverage: secrets, injection sinks, CI/CD, containers, Terraform, Android and iOS manifests, webhooks, MCP and LLM output reaching exec sinks.
- Reports and CI: HTML, Markdown, JSON, SARIF 2.1.0 and CSV, with a
--fail-ongate. Release binaries are reproducible, with checksums, an SBOM and signed provenance.
/plugin marketplace add ratomirjovanovic/pandaward
/plugin install pandaward@pandaward # macOS and Linux
/plugin install pandaward-windows@pandaward # Windows
/pandaward:scan
Live demo · Website · Docs · Quick start · Releases · Roadmap
Paste an API response, webhook or postback and see what the provider reported, what the code means, which events belong together and what looks wrong. Nothing leaves the browser.
- Deterministic analysis: structural provider detection, documented error catalogs, correlation by explicit identifiers and explainable diagnostic rules.
- Wide coverage: card processors, wallets, pay-by-bank, crypto and high-risk billing providers, each with an honest capability manifest.
- Privacy by design: sensitive data redacted from everything shown or exported, identifiers masked, strict Content Security Policy, no server-side processing.
- Three ways to run it: a static demo, an offline CLI and a Next.js app with a passkey-protected admin area.
Live demo · Demo video (1 min) · Docs · Releases · Roadmap · Good first issues
Official client libraries for the Payshen payment orchestration API: payments, captures, voids, refunds, events and webhook verification. Published and maintained on four registries.
PHP · Python · WooCommerce
Recent public reviews, mostly payment, webhook and security changes. The last column shows what GitHub recorded after the review: whether the author pushed changes, whether I approved, and whether the pull request was merged.
20 pull requests in 16 projects · 9 revised by their authors after the review · 7 merged
| Project | Pull request reviewed | Since the review |
|---|---|---|
| better-auth/better-auth | #12049 fix(account): share and guard concurrent provider token refreshes | Revised after review |
| better-auth/better-auth | #12014 fix(stripe): refetch subscription in subscription webhooks | Closed |
| DataDog/dd-trace-js | #10932 fix(appsec): wrap shared Stripe webhooks methods only once | Closed |
| paypal/paypal-js | #1100 fix(paypal-js): only reuse a pending v6 script for the same namespace | Revised after review |
| standard-webhooks/standard-webhooks | #348 Sign binary payloads byte for byte (JavaScript, Python) | Merged after revision |
| modelcontextprotocol/go-sdk | #1451 auth/extauth: send resource in client credentials token requests | Merged after revision |
| juspay/hyperswitch-web | #1829 fix: preserve 3DS messages before closing fullscreen frames | Merged |
| medusajs/medusa | #17538 fix(medusa): reject webhooks for nonexistent providers | Merged |
| payloadcms/payload | #19024 fix(plugin-ecommerce): drop cart items from Stripe payment intent metadata | Closed |
| Adyen/adyen-web | #4273 Fix/prevent duplicate 3DS2 challenge completion | Merged after revision |
| anthropics/anthropic-sdk-typescript | #1284 fix(client): keep the abort listener while the Response is held | Open |
| mark3labs/mcp-go | #1123 fix(oauth): refresh an access token shortly before it expires | Open |
Problems I found while integrating or reviewing other projects, reported upstream.
| Project | Issue | Status |
|---|---|---|
| go-pay/gopay | #558 Is there a private way to report a security issue? | Open |
| payloadcms/payload | #19055 plugin-ecommerce: restore the Stripe cart drift check with a metadata digest,... | Open |
| getlago/lago | #842 [BUG]: No private way to report a security issue on GitHub | Open |
| svix/svix-webhooks | #2763 php: Webhook accepts an empty or non-base64 secret and verifies with an empty... | Fixed |
| Adyen/adyen-node-api-library | #1816 [Bug]: HmacValidator accepts a malformed HMAC key as an empty key | Open |
| golang/go | #82658 x/oauth2: DeviceAccessToken panics on a negative or very large interval | Open |
| medusajs/medusa | #17544 [Bug]: Payment providers removed from config are never disabled in payment_pr... | Fixed |
| supabase/ssr | #209 tsconfig.json: outDir without rootDir triggers TS6059 / migration warning whe... | Fixed |
Fixes I wrote for other projects that their maintainers merged.
| Project | Pull request | Merged |
|---|---|---|
| Adyen/adyen-node-api-library | #1817 fix(hmac): reject malformed HMAC keys and compare signatures exactly | 2026-11-03 |
| Adyen/adyen-dotnet-api-library | #1899 fix(hmac): reject an empty HMAC key | 2026-11-03 |
| Adyen/adyen-java-api-library | #2100 fix(hmac): don't include the HMAC key in the invalid key exception | 2026-11-03 |
| svix/svix-webhooks | #2768 php: fix Webhook::fromRaw | 2026-10-30 |
| svix/svix-webhooks | #2765 php: reject an empty or non-base64 webhook secret | 2026-10-29 |
The Adyen fixes follow #1816, an HMAC validation issue I reported and Adyen confirmed. Related fixes for the PHP, Python, Go and Ruby libraries are in review.
This card and the review list above are generated daily from public GitHub data. My contribution activity is GitHub's own overview, below this README.
| Area | Focus |
|---|---|
| Payments and fintech | PSP integrations, orchestration and routing, decline and error semantics, webhooks, settlement and reconciliation |
| Application security | Static analysis and evidence-based assessment, secrets handling, CI/CD and supply chain, webhook and auth review |
| GRC | ISO/IEC 27001 readiness, risk and supplier management, control evidence, secure design |
| Engineering | TypeScript, Go and Python services, API clients and SDKs, testing and CI, documentation that matches the code |
| Area | Tools |
|---|---|
| Languages | |
| Frameworks | |
| Data and cloud | |
| Delivery |




