django_program.registration.webhooks

Stripe webhook handling for the registration app.

Provides a registry-based dispatch system for processing Stripe webhook events. Each event kind (e.g. payment_intent.succeeded) maps to a handler class that encapsulates idempotent processing, signal dispatch, and error capture.

The stripe_webhook view verifies event signatures per-conference, deduplicates by Stripe event ID, and delegates to the appropriate handler.

Usage in URL configuration:

from django_program.registration.webhooks import stripe_webhook

urlpatterns = [
    path("webhooks/stripe/", stripe_webhook),
]

Functions

stripe_webhook(request, conference_slug)

Receive and process Stripe webhook events for a specific conference.

Classes

ChargeDisputeCreatedWebhook

Handles charge.dispute.created events.

ChargeRefundedWebhook

Handles charge.refunded events.

PaymentIntentPaymentFailedWebhook

Handles payment_intent.payment_failed events.

PaymentIntentSucceededWebhook

Handles payment_intent.succeeded events.

Webhook

Abstract base class for Stripe webhook event handlers.

WebhookRegistry

Singleton registry mapping Stripe event kinds to handler classes.

class django_program.registration.webhooks.WebhookRegistry[source]

Bases: object

Singleton registry mapping Stripe event kinds to handler classes.

Handlers are registered at module load time and looked up by the webhook view when an event arrives.

__init__()[source]

Initialize an empty handler registry.

register(kind, handler_class)[source]

Register a handler class for a Stripe event kind.

Parameters:
  • kind (str) – The Stripe event type string (e.g. "payment_intent.succeeded").

  • handler_class (type[Webhook]) – A Webhook subclass that handles this event kind.

Return type:

None

get(kind)[source]

Return the handler class for a given event kind, or None.

Parameters:

kind (str) – The Stripe event type string.

Return type:

type[Webhook] | None

Returns:

The registered handler class, or None if no handler exists.

keys()[source]

Return all registered event kinds.

Return type:

list[str]

Returns:

A list of Stripe event type strings that have registered handlers.

class django_program.registration.webhooks.Webhook[source]

Bases: object

Abstract base class for Stripe webhook event handlers.

Subclasses must set name to the Stripe event kind they handle and implement process_webhook() with the actual business logic. The base process() method wraps execution in idempotency checks and exception capture.

name

The Stripe event kind this handler processes.

event

The StripeEvent model instance being handled.

Parameters:

event (StripeEvent)

name: str = ''
__init__(event)[source]

Bind the handler to a specific Stripe event record.

Parameters:

event (StripeEvent) – The persisted StripeEvent to process.

process()[source]

Run the handler with idempotency and error capture.

Skips events that have already been processed. On success, marks the event as processed and fires any associated Django signal. On failure, captures the traceback to EventProcessingException and re-raises.

Return type:

None

process_webhook()[source]

Implement event-specific processing logic.

Raises:

NotImplementedError – Subclasses must override this method.

Return type:

None

send_signal()[source]

Send a Django signal after successful processing.

The default implementation is a no-op. Subclasses that need to fire signals should override this method.

Return type:

None

log_exception()[source]

Capture the current exception to EventProcessingException.

Return type:

None

class django_program.registration.webhooks.PaymentIntentSucceededWebhook[source]

Bases: Webhook

Handles payment_intent.succeeded events.

Creates a Payment record, transitions the Order from PENDING to PAID, clears the inventory hold, and fires the order_paid signal.

Parameters:

event (StripeEvent)

name: str = 'payment_intent.succeeded'
process_webhook()[source]

Create a payment and mark the order as paid.

Return type:

None

send_signal()[source]

Fire the order_paid signal for downstream listeners.

Return type:

None

class django_program.registration.webhooks.PaymentIntentPaymentFailedWebhook[source]

Bases: Webhook

Handles payment_intent.payment_failed events.

Locates the PENDING payment record for the failed intent and updates its status to FAILED with the error reason from Stripe.

Parameters:

event (StripeEvent)

name: str = 'payment_intent.payment_failed'
process_webhook()[source]

Mark the matching payment as failed and log the reason.

Return type:

None

class django_program.registration.webhooks.ChargeRefundedWebhook[source]

Bases: Webhook

Handles charge.refunded events.

Determines whether the refund is full or partial by comparing amount_refunded to amount, then updates Payment and Order statuses accordingly.

Parameters:

event (StripeEvent)

name: str = 'charge.refunded'
process_webhook()[source]

Update payment and order status based on refund amount.

Return type:

None

class django_program.registration.webhooks.ChargeDisputeCreatedWebhook[source]

Bases: Webhook

Handles charge.dispute.created events.

Logs the dispute for manual review. No automated actions are taken; the event is simply recorded and marked as processed.

Parameters:

event (StripeEvent)

name: str = 'charge.dispute.created'
process_webhook()[source]

Log the dispute details.

Return type:

None

django_program.registration.webhooks.stripe_webhook(request, conference_slug)[source]

Receive and process Stripe webhook events for a specific conference.

Verifies the event signature against the conference’s webhook secret, deduplicates by Stripe event ID, persists the raw event, and dispatches to the registered handler.

Always returns HTTP 200 to acknowledge receipt, even when processing fails. Errors are logged and captured to EventProcessingException.

Parameters:
  • request (HttpRequest) – The incoming HTTP request from Stripe.

  • conference_slug (str) – URL slug identifying which conference this webhook is for.

Return type:

HttpResponse

Returns:

An HttpResponse with status 200.