Skip to Content

Webhooks

Le bundle expose POST /cashier/webhook pour recevoir les événements Stripe.

Configuration

cashier: webhook: secret: '%env(STRIPE_WEBHOOK_SECRET)%' tolerance: 300 events: - customer.subscription.created - customer.subscription.updated - customer.subscription.deleted - customer.deleted - invoice.payment_succeeded - invoice.payment_failed - checkout.session.completed - payment_intent.succeeded - payment_intent.payment_failed

Rôle des webhooks

Ne limitez pas votre intégration au retour navigateur après paiement.

Les webhooks servent à:

  • confirmer le paiement côté serveur
  • synchroniser les subscriptions
  • archiver les factures
  • émettre les événements Symfony du bundle

Handlers intégrés

Le bundle fournit des handlers pour les événements billing principaux, notamment:

  • customer.subscription.created
  • customer.subscription.updated
  • customer.subscription.deleted
  • customer.deleted
  • invoice.payment_succeeded
  • invoice.payment_failed
  • invoice.payment_action_required
  • checkout.session.completed
  • checkout.session.expired
  • payment_method.updated
  • payment_intent.succeeded
  • payment_intent.payment_failed

Handlers placeholder

Certains handlers sont des points d’extension vides — implémenter via un handler custom:

  • InvoicePaymentActionRequiredHandler — gère invoice.payment_action_required
  • CheckoutSessionCompletedHandler — gère checkout.session.completed

Configuration production

Créer le webhook via CLI:

php bin/console cashier:webhook --url=https://monsite.com/cashier/webhook --show-secret

Copier le secret dans STRIPE_WEBHOOK_SECRET.

Vérifier que le path correspond à cashier.path dans cashier.yaml.

Idempotence

Les handlers Stripe peuvent être appelés plusieurs fois avec le même event ID.

Utilisez $event->id comme guard : stockez les IDs traités, rejetez les doublons.

Gestion des exceptions

Si un handler lance une exception, Stripe retentera le webhook (3 jours, intervalles croissants).

Capturez les exceptions métier et retournez 200 si l’événement peut être ignoré:

Handler custom

use CashierBundle\Contract\WebhookHandlerInterface; use Stripe\Event; use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag; #[AutoconfigureTag('cashier.webhook_handler')] final readonly class SyncOrderHandler implements WebhookHandlerInterface { public function handles(): array { return ['payment_intent.succeeded']; } public function handle(Event $event): void { $paymentIntent = $event->data->object; $orderId = $paymentIntent->metadata->app_order_id ?? null; // votre logique métier } }

Événements Symfony dispatchés

  • WebhookReceivedEvent
  • WebhookHandledEvent
  • SubscriptionCreatedEvent
  • SubscriptionUpdatedEvent
  • SubscriptionDeletedEvent
  • PaymentSucceededEvent
  • PaymentFailedEvent

Stripe CLI locale

php bin/console cashier:webhook:listen --forward-to=http://127.0.0.1:8000/cashier/webhook

Ou avec --base-url pour construire automatiquement l’URL :

php bin/console cashier:webhook:listen --forward-to --base-url http://localhost:8000

La commande:

  • lance stripe listen
  • récupère le whsec_...
  • peut mettre à jour vos .env*
  • colorise les entrées webhook et les statuts HTTP

Lecture de la sortie console

  • événement entrant Stripe: cyan
  • réponse 2xx: vert
  • réponse 4xx: jaune
  • réponse 5xx et erreurs CLI: rouge

Événements Symfony →

Last updated on