Integrations
Ready-made packages for Laravel, Symfony, WordPress and WoltLab Suite — plus the guide for one of your own.
On this page
Laravel integration
1. Add the repository
Add the CaptchaCore repository to your composer.json:
{
"repositories": [
{
"type": "composer",
"url": "https://captchacore.eu/packages"
}
]
}
2. Install the package
composer require captchacore/laravel
3. Configure .env
CAPTCHACORE_URL=https://captchacore.eu CAPTCHACORE_SITE_KEY=cc_pub_dein_key CAPTCHACORE_SECRET_KEY=cc_sec_dein_secret CAPTCHACORE_WIDGET_MODE=interactive # interactive | visible | invisible CAPTCHACORE_WIDGET_THEME=auto # auto | light | dark CAPTCHACORE_WIDGET_COLOR=#4ade80 CAPTCHACORE_WIDGET_LABEL=Ich bin kein Bot CAPTCHACORE_WIDGET_BRAND=CaptchaCore
Blade component
<form method="post" data-captchacore="interactive"> @csrf <!-- Formularfelder --> <x-captchacore::widget /> <button type="submit">Absenden</button> </form>
Middleware
// Route schützen Route::post('/register', RegisterController::class) ->middleware('captchacore:register'); // Oder als Validation Rule 'captchacore_token' => ['required', new CaptchaCoreToken('contact')] // Tests: fake() mockt alle Verifikationen CaptchaCore::fake();
Symfony Bundle
For Symfony 6.4 LTS and 7.x. Four integration paths: FormType, validator constraint, controller attributes and security badge.
1. Install
composer require captchacore/captchacore-bundle
Symfony Flex registers the bundle and creates config/packages/captchacore.yaml automatically.
2. Configure .env
CAPTCHACORE_URL=https://api.captchacore.eu CAPTCHACORE_SITE_KEY=cc_pub_xxxxxxxxxxxxxxxxxxxxxxxxxxxx CAPTCHACORE_SECRET_KEY=cc_sec_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
FormType (recommended)
use CaptchaCore\SymfonyBundle\Form\Type\CaptchaCoreType; $builder ->add('email', EmailType::class) ->add('message', TextareaType::class) ->add('captcha', CaptchaCoreType::class, [ 'form_type' => 'contact', ]);
Controller attributes
use CaptchaCore\SymfonyBundle\Security\Attribute\RequiresCaptcha; #[Route('/contact', methods: ['POST'])] #[RequiresCaptcha(formType: 'contact')] public function submit(Request $request): Response { /* ... */ }
Validator constraint (DTOs)
use CaptchaCore\SymfonyBundle\Validator\CaptchaCoreToken; final class ContactDto { public function __construct( #[Assert\NotBlank] public string $email, #[CaptchaCoreToken(formType: 'contact')] public string $captchaToken, ) {} }
Programmatic
use CaptchaCore\SymfonyBundle\Client\CaptchaCoreClient; $result = $this->captcha->verify($token, 'login'); if ($result->blocked()) { throw new AccessDeniedHttpException(); } // Properties: valid, riskScore, action, confidence, reasons, stepUp
Twig (standalone)
{{ captchacore_widget(mode: 'interactive') }}
Tests
CaptchaCoreClient::fake(VerificationResult::allow()); $this->client->request('POST', '/contact', [...]); self::assertResponseIsSuccessful();
WordPress Plugin
- Install the plugin — in WordPress, go to
Plugins → Add Newand search for “CaptchaCore” (entry in the WordPress directory). Updates then come from WordPress itself. Alternatively upload the ZIP from your account. - Activate it under Plugins
- Open Settings > CaptchaCore
- Enter the service URL, site key and secret key
- Choose widget mode, theme and color
- Enable the forms you want (login, registration, comments, etc.)
No code required. The plugin automatically embeds the widget in all enabled WordPress forms and verifies tokens server-side.
WoltLab Suite
The package is distributed through the official WoltLab plugin store. Installation and every future update run through it — there is no separate download in your account.
- Buy the package in the plugin store and install it in the ACP under
Packages → Install package - Enter your credentials under
Options → Security → Anti-Spam → CaptchaCore: service URL, site key and secret key - Choose the appearance: mode, theme, accent colour and language — “auto” follows the language of your forum.
- Select CaptchaCore as the captcha under
Options → Security → Anti-Spam → Captcha— it then applies to registration, the contact form and every other system form
| Setting | Meaning |
|---|---|
| Endpoint | EU standard or worldwide endpoint. EU keeps all verification data inside the EU; the global endpoint speeds things up for distant visitors. |
| Mode | interactive, visible or invisible — the same three modes as everywhere else, see widget modes. |
| Behaviour during an outage | If CaptchaCore cannot be reached, the plugin lets the form through by default and logs the error. Switch it off if you would rather block in case of doubt. |
One package for 6.1 and 6.2. The handler verifies every token server-side against the V2 API; the extra check (“step_up”) is handled by the widget itself, and the visitor gets a message of its own instead of an error.
Build your own integration
Do you want to bring CaptchaCore into a system with no package yet, such as Shopware, Joomla or your own framework? It takes a few hours. This order has proven itself.
Deliver the script
Include captchacore-v2.min.js from the EU endpoint and pass the site key and service URL as data attributes. In a CMS this belongs in the hook that registers frontend scripts. Only load the script on pages that actually contain a protected form.
Mark the forms
Put data-captchacore on the form and insert an empty container with data-captchacore-widget. data-form-type decides which policy applies. Several forms on one page are no problem, each gets its own widget.
Check the token server side
Read the captchacore_token field from the request and send it with your secret key to /api/v2/verify. Check decision, and do not treat step_up like block.
Handle outages
Set a timeout of about three seconds and decide deliberately whether an outage lets traffic through or blocks it. Make it configurable in the plugin, the answer differs from form to form.
Account for late loading
If your system swaps forms via AJAX, call CaptchaCoreV2.attach() afterwards.
Offer settings
Site key, secret key, choice of protected forms, appearance and the behaviour on outage belong in your plugin's configuration screen.
Templates to copy from
All supplied integrations follow the same pattern. For a Symfony-based system such as Shopware 6 the Symfony bundle is the closest template, for a classic CMS the WordPress plugin.
Check before release
- Form submitted without JavaScript — does your fail rule apply?
- Token used twice — the second check must fail, the nonce is single use.
- Token submitted after more than five minutes — the widget renews it by itself, verify that in a long-running test.
- Two protected forms on one page — both must work independently.
- Form loaded in via AJAX — does the widget appear?
- The secret key appears nowhere in the HTML or in JavaScript.
- A response with decision=step_up — the user must not end up in a dead end.
Building an integration and want us to list it here or help maintain it? Get in touch — we provide test accounts and a contact person.