Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Trustkey Webhook Bundle Laravel Package

bitbirddev/trustkey-webhook-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require bitbirddev/trustkey-webhook-bundle
    

    Register the bundle in config/bundles.php:

    return [
        // ...
        BitbirdDev\TrustkeyWebhookBundle\TrustkeyWebhookBundle::class => ['all' => true],
    ];
    
  2. Configuration Publish the default config:

    php bin/console trustkey-webhook:install
    

    Update config/packages/bitbirddev_trustkey_webhook.yaml with your:

    • webhook_secret (from Trustkey dashboard)
    • trustkey_public_key (for verification)
    • endpoint (e.g., /api/webhooks/trustkey)
  3. Route Definition Add to config/routes.yaml:

    trustkey_webhook:
        path: /api/webhooks/trustkey
        controller: BitbirdDev\TrustkeyWebhookBundle\Controller\WebhookController::handle
        methods: [POST]
    
  4. First Use Case Trigger a test webhook from Trustkey’s dashboard. Verify logs (var/log/dev.log) for:

    [TRUSTKEY] Webhook received: {event_type}
    

Implementation Patterns

Core Workflow

  1. Event Handling Extend BitbirdDev\TrustkeyWebhookBundle\Event\TrustkeyWebhookEvent to create custom listeners:

    use BitbirdDev\TrustkeyWebhookBundle\Event\TrustkeyWebhookEvent;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class MyWebhookSubscriber implements EventSubscriberInterface
    {
        public static function getSubscribedEvents(): array
        {
            return [
                TrustkeyWebhookEvent::WEBHOOK_RECEIVED => 'onWebhookReceived',
            ];
        }
    
        public function onWebhookReceived(TrustkeyWebhookEvent $event)
        {
            $data = $event->getData();
            if ($data['event_type'] === 'user.created') {
                // Handle user creation (e.g., sync to your DB)
            }
        }
    }
    

    Register the subscriber in services.yaml:

    services:
        App\EventSubscriber\MyWebhookSubscriber:
            tags: ['kernel.event_subscriber']
    
  2. Data Validation Use the bundle’s validator to ensure payload integrity:

    use BitbirdDev\TrustkeyWebhookBundle\Validator\TrustkeyWebhookValidator;
    
    $validator = new TrustkeyWebhookValidator($secret, $publicKey);
    if (!$validator->validate($rawPayload)) {
        throw new \RuntimeException('Invalid webhook signature');
    }
    
  3. Async Processing Offload heavy tasks to a queue (e.g., Symfony Messenger or Laravel Queues):

    use Symfony\Component\Messenger\MessageBusInterface;
    
    class MyWebhookSubscriber
    {
        public function __construct(private MessageBusInterface $bus) {}
    
        public function onWebhookReceived(TrustkeyWebhookEvent $event)
        {
            $this->bus->dispatch(new ProcessTrustkeyEvent($event->getData()));
        }
    }
    
  4. Testing Mock webhook payloads in PHPUnit:

    $payload = json_encode(['event_type' => 'user.created', 'data' => [...]]);
    $response = $this->client->request('POST', '/api/webhooks/trustkey', [], [], [
        'HTTP_X_TRUSTKEY_SIGNATURE' => $this->generateSignature($payload),
    ]);
    $this->assertEquals(200, $response->getStatusCode());
    

Gotchas and Tips

Common Pitfalls

  1. Signature Mismatches

    • Issue: Webhook fails with 403 Forbidden due to incorrect X-Trustkey-Signature.
    • Fix: Ensure $webhook_secret in config matches Trustkey’s dashboard. Verify the signature algorithm (default: HMAC-SHA256).
    • Debug: Log the computed vs. received signature:
      $computed = hash_hmac('sha256', $payload, $secret);
      error_log("Computed: $computed | Received: {$_SERVER['HTTP_X_TRUSTKEY_SIGNATURE']}");
      
  2. Missing Headers

    • Issue: Trustkey sends X-Trustkey-Signature; ensure your middleware/route doesn’t strip headers.
    • Fix: Add to trustkey_webhook.yaml:
      allowed_headers: ['x-trustkey-signature']
      
  3. Idempotency

    • Issue: Duplicate webhooks may trigger duplicate actions.
    • Fix: Use idempotency_key in payload to deduplicate:
      if (TrustkeyWebhookEvent::getIdempotencyKey($data) === $seenKey) {
          return; // Skip duplicate
      }
      
  4. Rate Limiting

    • Issue: Trustkey may throttle requests during spikes.
    • Fix: Implement a queue (e.g., RabbitMQ) and add retries:
      # config/packages/messenger.yaml
      framework:
          messenger:
              transports:
                  async: '%env(MESSENGER_TRANSPORT_DSN)%'
              routing:
                  'App\Message\ProcessTrustkeyEvent': async
      

Pro Tips

  1. Event Mapping Pre-map Trustkey events to your domain:

    $eventMap = [
        'user.created' => UserCreatedHandler::class,
        'payment.succeeded' => PaymentHandler::class,
    ];
    $handler = new $eventMap[$data['event_type']]();
    $handler->handle($data);
    
  2. Webhook Retries Use exponential backoff for failed processing:

    use Symfony\Component\Messenger\Attribute\AsMessage;
    
    #[AsMessage]
    class ProcessTrustkeyEvent
    {
        public function __construct(
            public array $data,
            public int $retries = 0
        ) {}
    
        public function __invoke(): void
        {
            try {
                // Process logic
            } catch (\Exception $e) {
                if ($this->retries < 3) {
                    throw new RetryException($e, delay: 2 ** $this->retries);
                }
                throw $e;
            }
        }
    }
    
  3. Local Testing Use ngrok to expose a local endpoint for testing:

    ngrok http 8000
    

    Configure Trustkey to send webhooks to https://your-ngrok-url.ngrok.io/api/webhooks/trustkey.

  4. Logging Enhance logging with structured data:

    use Psr\Log\LoggerInterface;
    
    class MyWebhookSubscriber
    {
        public function __construct(private LoggerInterface $logger) {}
    
        public function onWebhookReceived(TrustkeyWebhookEvent $event)
        {
            $this->logger->info('Trustkey Webhook', [
                'event' => $event->getData()['event_type'],
                'metadata' => $event->getData()['metadata'] ?? [],
                'context' => ['ip' => $_SERVER['REMOTE_ADDR']],
            ]);
        }
    }
    
  5. Security

    • Restrict webhook endpoint to Trustkey’s IPs (check their IP ranges).
    • Use Symfony’s firewalls to add CSRF protection (if applicable):
      # config/packages/security.yaml
      firewalls:
          main:
              pattern: ^/api/webhooks/trustkey
              stateless: true
              csrf_protection: false # Disable if using signature validation
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed