This documentation always describes the latest published version.
Privacy-friendly spam protection for Sylius storefront forms and the Shop API, based on ALTCHA proof-of-work. No cookies, no fingerprinting, no third-party requests - the visitor's browser solves a cryptographic puzzle in the background instead of clicking tiles or reading distorted text.
Which forms are protected is decided per channel in the admin, not globally.
Privacy: Every check runs on your own server. Nothing is sent to an external service, and no cookie or fingerprint is set.
Built-in targets: registration, contact, login, forgotten password, and the checkout sign-in (rate-limit only). The support form (mmd/sylius-support-form-plugin) and the newsletter signup (mmd/sylius-newsletter-management-plugin) are detected automatically when installed and appear in the same admin list. Any other form - from a custom plugin or your own code - can be added through the admin.
| Page | Contents |
|---|---|
| Installation and Operations | Installation, update, cron jobs, uninstall |
| Configuration | Per-channel settings, admin grids, practical examples |
| Storefront Integration | Placing the widget, Twig function and hooks, theme notes |
| Shop API / Headless | Challenge endpoint, requests, error format |
| Extensibility and Compatibility | Custom targets, service tags, backward compatibility |
| Troubleshooting and FAQ | Common problems, known limitations, frequent questions |
| Technical Details | How the checks run, plugin structure, entities |
| Feature | Description |
|---|---|
| Proof-of-work challenge | PBKDF2 challenge the browser solves invisibly, signed with a per-channel HMAC secret |
| Single-use proofs | A solved challenge is accepted exactly once (replay protection) |
| Rate limiting | Per form and client address, checked before a challenge is consumed |
| Honeypot field | Invisible field that only a bot fills in |
| Minimum fill time | Signed timestamp rejects submissions sent faster than a human could type |
| Disposable-mail check | Opt-in: rejects addresses from known throwaway-inbox providers, with operator allow/deny overrides |
| Gibberish check | Opt-in: scores free-text fields and rejects keyboard mashing and nonsense text |
| Dual mode | Works identically in the Twig storefront and headless through the Shop API |
| Per-channel configuration | Every setting - targets, difficulty, rate limit, content checks - is scoped to one channel |
| Requirement | Version | Notes |
|---|---|---|
| Sylius | ^2.2 | Developed against 2.3; CI runs the full test suite on Sylius 2.2 and 2.3 |
| PHP | ^8.3 | With the sodium extension |
| Symfony | ^7.4 | Symfony 8 is not supported by Sylius 2.x and is therefore excluded |
| Database | MySQL 8 or MariaDB | PostgreSQL is not supported. The migrations are written in MySQL syntax and deliberately abort on other databases. Do not install the plugin in a PostgreSQL project, because the abort would also block all subsequent migrations of your project. Tested against MySQL 8.4, MariaDB is not verified. |
APP_SECRET |
non-empty | Channel secrets are encrypted with a key derived from it; all application servers must share the same value |
doctrine/dbal |
^3.9 or ^4.0 | Sylius 2.2 pins DBAL 3, Sylius 2.3 allows 4; both run the full test suite |
altcha-org/altcha |
~2.1.0 | Pinned - the bundled widget script and this library speak one protocol |
Commercial license: one Sylius installation (all channels, plus its development and staging environments) per license, no redistribution, updates for 12 months from purchase. The bundled ALTCHA widget scripts and the disposable-domain list keep their own licenses (MIT and CC0 respectively).
For licensing, technical questions or bug reports, contact support@markus-michalski.net.