geekybones/fraud-defense-bundle

Symfony bundle for Google reCAPTCHA Enterprise (forms, validation, score and checkbox widgets)

Maintainers

Package info

github.com/geekybones/fraud-defense-bundle

Type:symfony-bundle

pkg:composer/geekybones/fraud-defense-bundle

Transparency log

Statistics

Installs: 29

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.1 2026-05-27 05:07 UTC

This package is auto-updated.

Last update: 2026-06-27 05:55:51 UTC


README

Symfony integration for Google reCAPTCHA Enterprise with support for standard bot protection, Transaction Defense, and SMS toll-fraud Defense. By GeekyBones.

Package geekybones/fraud-defense-bundle
PHP ^8.2
Symfony ^7.0 or ^8.0
License MIT

Installation

composer require geekybones/fraud-defense-bundle

If Symfony Flex did not register the bundle automatically, add it to config/bundles.php:

GeekyBones\FraudDefenseBundle\FraudDefenseBundle::class => ['all' => true],

Google Cloud setup

  1. Enable the reCAPTCHA Enterprise API in your GCP project.
  2. Create one or more site keys for your domain (score key for invisible checks, checkbox key for the "I'm not a robot" widget).
  3. Create an API key restricted to the reCAPTCHA Enterprise API.

For Transaction Defense and SMS Defense, additional console steps are required — see their dedicated guides.

Configuration

Add environment variables:

FRAUD_DEFENSE_PROJECT_ID=your-gcp-project-id
FRAUD_DEFENSE_API_KEY=your-api-key
FRAUD_DEFENSE_SITE_KEY=your-score-site-key
# FRAUD_DEFENSE_CHECKBOX_SITE_KEY=your-checkbox-site-key  # only if using checkbox widget

Create config/packages/fraud_defense.yaml:

fraud_defense:
    project_id: '%env(FRAUD_DEFENSE_PROJECT_ID)%'
    api_key:    '%env(FRAUD_DEFENSE_API_KEY)%'
    site_key:   '%env(FRAUD_DEFENSE_SITE_KEY)%'
    min_score:  0.5

Standard reCAPTCHA (RecaptchaType) works with this minimal config. Enable transaction_defense or sms_defense only when you need those flows.

See configuration.md for all options.

Usage

Standard form protection

use GeekyBones\FraudDefenseBundle\Form\RecaptchaType;

$builder->add('captcha', RecaptchaType::class, [
    'action' => 'login',
]);
{{ form_row(form.captcha) }}

Validation runs automatically on form submit. No controller changes needed.

Programmatic

Inject the interface and call assess() directly — useful in APIs and controllers without forms:

use GeekyBones\FraudDefenseBundle\Defense\Contract\RecaptchaAssessmentInterface;
use GeekyBones\FraudDefenseBundle\Defense\DefenseAssessmentException;

public function __construct(
    private readonly RecaptchaAssessmentInterface $recaptcha,
) {}

try {
    $result = $this->recaptcha->assess(
        token: $request->request->get('recaptcha_token'),
        action: 'login',
    );
} catch (DefenseAssessmentException $e) {
    // API error, invalid/expired token, or incomplete response
}

if (!$result->hasPassed()) {
    // score too low, action mismatch, or hostname mismatch
}

Form types

Form type When to use Requires
RecaptchaType Login, registration, contact — bot detection Default config
TransactionRecaptchaType Checkout, payment — fraud risk scoring transaction_defense.enabled: true
SmsRecaptchaType SMS OTP — toll-fraud detection sms_defense.enabled: true

All three share the same Twig widget ({{ form_row(form.captcha) }}).

Documentation

Guide Contents
configuration.md All YAML options, environment variables, per-case examples
recaptcha.md Standard reCAPTCHA: form setup, script loading, programmatic usage
transaction-defense.md Transaction Defense: GCP setup, form, context reference, troubleshooting
sms-defense.md SMS Defense: GCP setup, form, programmatic usage
architecture.md Internal code structure and request flow