This documentation always refers to the latest published release.
Live demo: Try this and other plugins live, no installation, no risk: demo.markus-michalski.net
The plugin provides two endpoints. Both are meant for internal use by the widget and the admin.
GET /altcha/challenge (route frontend.altcha.challenge, storefront scope, AJAX) gives the widget a new, signed challenge.
Response 200:
{
"parameters": {
"algorithm": "PBKDF2",
"cost": 2000,
"expiresAt": 1735999999,
"keyLength": 32,
"keyPrefix": "...",
"nonce": "...",
"salt": "..."
},
"signature": "..."
}
| Status | Meaning |
|---|---|
200 |
Challenge issued |
503 |
Spam protection or the ALTCHA widget is disabled for the sales channel ({"error": "ALTCHA is disabled"}) |
429 |
Challenge rate limit exceeded, with a Retry-After header in seconds ({"error": "Too many requests"}) |
500 |
APP_SECRET is empty, the challenge cannot be signed |
Cost, counter and expiry of the challenge come from the sales channel's settings, see Configuration.
The widget writes the solved challenge, Base64-encoded, into the form field altcha. The shop verifies it on submit: signature, expiry, algorithm (PBKDF2 only) and single use of the nonce. A payload longer than 4096 characters is rejected.
GET /api/_action/mmd-altcha/blocked-domains (route api.action.mmd-altcha.blocked-domains, API scope) feeds the "Blocked domains" view in the plugin configuration. The route requires the ACL permission system_config:read.
| Parameter | Description |
|---|---|
q |
Search term, optional, at most 253 characters (the rest is cut off) |
page |
Page, default 1 |
limit |
Entries per page, default 25, at most 100 |
salesChannelId |
Sales channel as UUID, optional. An invalid UUID returns 400 with {"error": "Invalid sales channel ID"} |
The response contains items (each with domain, source being snapshot or override, and allowed), total, page and perPage. Own entries come first, the rest alphabetically.