Webhooks

Overview

Webhooks allow you to receive real-time notifications when events occur in your Alternative Payments account. Instead of continuously polling the API to check for updates, webhooks push event data directly to your server as they happen.

Available Webhook Topics

Subscribe to the following webhook topics to receive notifications:

Topic
Description

payout_paid

Confirms that a payout was successfully settled.

payout_processing

Indicates the payout has started to be processed

payout_scheduled

Indicates the payout is scheduled to be processed

payout_failed

Indicates a failed payout attempt.

customer_created

Triggered when a new customer is onboarded.

customer_updated

Triggered when the customer has their information updated.

customer_archived

Triggered when a customer is archived.

payment_succeeded

Confirms that funds were successfully captured.

payment_refunded

Triggered when a payment refund request occurs.

payment_chargeback

Notifies when a dispute occurs. Impacts reconciliation and may require intervention.

payment_failed

Indicates a failed payment attempt.

invoice_created

Triggered when a new invoice is created.

invoice_updated

Triggered when invoice information is updated.

invoice_paid

Confirms the invoice has been fully paid. Closes the accounts receivable lifecycle and links the payment to the customer obligation.

invoice_archived

Triggered when the invoice is archived.

payment_method_added

Indicates a payment method was added. Useful for enabling Autopay.

default_payment_method_changed

Triggered when the customer default payment method change.

payment_method_deleted

Indicates a payment method was removed. Also relevant for managing Autopay.

Managing Webhook Subscriptions

Subscribe to a Webhook

Create a new webhook subscription to start receiving event notifications.

Endpoint: POST /webhooks

Request Body:

Parameters:

  • endpoint_url (required) - Your HTTPS endpoint that will receive webhook events

  • secret_key (optional) - A secret key for authentication. If provided, it will be sent as a Bearer token in the Authorization header

  • topic (required) - The event type you want to subscribe to (see available topics above)

Authentication: If you provide a secret_key, all webhook requests to your endpoint will include it in the Authorization header as a Bearer token. Use this to verify the authenticity of webhook requests.

List Webhook Subscriptions

View all your active and inactive webhook subscriptions.

Endpoint: GET /webhooks

Query Parameters:

  • limit (optional, default: 100) - Number of items to return

  • after (optional) - Cursor for forward pagination

  • before (optional) - Cursor for backward pagination

  • topic (optional) - Filter by webhook topic

  • is_active (optional) - Filter by active status (true/false)

Unsubscribe from a Webhook

Remove a webhook subscription when you no longer want to receive notifications.

Endpoint: DELETE /webhooks/{subscription_id}

Parameters:

  • subscription_id (required) - The ID of the subscription to remove

Webhook Events

List Webhook Events

View the history of webhook events sent to your endpoints.

Endpoint: GET /webhooks/events

Query Parameters:

  • limit (optional, default: 100) - Number of items to return

  • after (optional) - Cursor for forward pagination

  • before (optional) - Cursor for backward pagination

  • topic (optional) - Filter by webhook topic

  • status (optional) - Filter by status: pending, sent, or failed

  • from_date (optional) - Filter events created after this date (ISO 8601)

  • to_date (optional) - Filter events created before this date (ISO 8601)

Webhook Payload Structure

All webhooks are sent as HTTP POST requests with a JSON payload containing the following fields:

Payload Fields

  • entity_id - The ID of the primary resource related to this event

    • For invoice_paid → Invoice ID

    • For payment_method_added → Payment Method ID

    • For customer_created → Customer ID

    • For payout_paid → Payout ID

  • idempotency_key - A unique identifier for this webhook event. Use this to prevent processing duplicate webhooks

  • timestamp - ISO 8601 timestamp of when the event occurred

  • topic - The event type (see Available Webhook Topics)

  • data - Additional context about the event. The structure varies by topic but typically includes:

    • Related entity IDs (customer_id, invoice_id, etc.)

    • Current status of the resource

    • Other relevant information specific to the event type

Webhook Ordering

Webhooks are delivered in order. This means:

  • All webhooks for your account are sent sequentially based on when they were created

  • A webhook will not be sent until all previous webhooks have been successfully delivered

  • This ensures you receive events in the correct chronological order

Retry Logic

If your endpoint is temporarily unavailable or returns an error, Alternative Payments will automatically retry webhook delivery.

Retry Behavior

  • Maximum attempts: 5 retries

  • Backoff strategy: Exponential backoff with a 30-second base delay

  • Retry intervals: 1:30m, 4:30m, 13:30m, 40:30m, 2:02hrs (attempts 1-5)

The retry delay is calculated using the formula:

What Happens After Max Retries

After reaching the maximum number of retry attempts:

  1. The webhook delivery is permanently paused for your account

  2. All pending and failed webhooks remain in queue but won't be automatically retried

  3. You must manually trigger a retry to resume webhook delivery

Manually Retrying Failed Webhooks

When webhooks reach max retry attempts, use this endpoint to resume delivery:

Endpoint: POST /webhooks/retry

Request: No body required

Response:

This endpoint will:

  • Reset the retry counter

  • Resume processing all pending and failed webhooks in order

  • Attempt to deliver webhooks again with the full retry logic

Processing Limits

To protect your endpoint from being overwhelmed:

  • The retry process sends a maximum of 10 webhooks per run

  • If more than 10 webhooks are pending, they will be processed in subsequent retry cycles

  • All webhooks are still delivered in order

Best Practices

Endpoint Requirements

  • Use HTTPS - Webhook endpoints must use HTTPS (not HTTP)

  • Return 2xx status codes - Your endpoint should return a 200-299 status code to indicate successful receipt

  • Respond quickly - Process webhooks asynchronously if possible. Acknowledge receipt immediately and process the event in the background

  • Handle timeouts - Implement proper timeout handling on your server

Security

  1. Verify webhook authenticity:

    • Set a secret_key when subscribing

    • Validate the Authorization header on incoming webhook requests

    • Check that the Bearer token matches your secret

  2. Use idempotency keys:

    • Store the idempotency_key from each webhook

    • Check for duplicate keys before processing to prevent double-processing

  3. Validate payload structure:

    • Always validate the JSON structure before processing

    • Check that required fields are present

    • Verify the topic matches your expected event type

Error Handling

  • Return proper status codes:

    • 200-299: Successfully received and will process

    • 300-599: Error (we will retry)

  • Monitor webhook events:

    • Use GET /webhooks/events to monitor delivery status

    • Set up alerts for failed webhooks

    • Check your webhook endpoint logs regularly

Testing

Before going live:

  1. Subscribe to a webhook topic in your staging/test environment

  2. Trigger test events (create a customer, pay an invoice, etc.)

  3. Verify your endpoint receives and processes the webhooks correctly

  4. Test your retry logic by returning error status codes temporarily

  5. Confirm your secret key validation works correctly


Example Implementation

Here's a basic example of a webhook endpoint handler:


Troubleshooting

My webhooks are not being delivered

Check the following:

  1. Verify your endpoint is publicly accessible via HTTPS

  2. Confirm your endpoint returns a 2xx status code

  3. Check GET /webhooks/events to see webhook status

  4. Ensure your subscription is active (is_active: true)

  5. Verify your server isn't blocking incoming requests

Webhooks stopped after reaching max retries
  1. Fix the issue preventing webhook delivery (check your server logs)

  2. Call POST /webhooks/retry to resume delivery

  3. Monitor the webhook events to confirm successful delivery

Receiving duplicate webhooks

This can happen during retries. Always:

  • Check the idempotency_key before processing

  • Store processed keys in your database

  • Skip processing if the key was already handled

How do I test webhooks locally?

Use a tool like ngrok to expose your local server:

  1. Run ngrok http 5000 (or your local port)

  2. Use the HTTPS URL provided by ngrok as your endpoint_url

  3. Subscribe to a webhook with the ngrok URL

  4. Trigger events in your test environment


For additional help, refer to the FAQ or contact our support team.

Last updated

Was this helpful?