Getting Started with Webhooks

Simply put, a webhook is a notification from one website to another website about an event that just happened. Rather than having to pull information via polling jobs or carrier pigeons and API requests, ConnexPay's Eventing Services (CXP Eventing) push information to your destination when important events occur. We support rich eventing across all aspects of the payment lifecycle. When a new event is ready, CXP Eventing POSTs an HTTP request to a destination URL (endpoint) that you specify. Click here for information about supported event types and their payloads.

To create a webhook, you'll need to:

  • Create a destination URL on your server that will receive event data
    -- Optionally you may choose to secure your endpoint via a method listed under Endpoint Security below
  • Configure your endpoint to capture incoming HTTP POST requests and parse the JSON data provided in the request body
  • Provide the endpoint URL and optional security details to your ConnexPay implementations contact
  • Look for a validation event to be submitted to your endpoint to confirm your endpoint subscription has been configured successfully
  • Rejoice!

IMPORTANT: Endpoint Validation

CXP Eventing requires you to prove ownership of your Webhook endpoint before it starts delivering events to it. This requirement prevents a malicious user from flooding your endpoint with events.

We support two ways of validating your subscription:

  • Synchronous handshake: At the time of event subscription creation, we will send a subscription validation event to your endpoint. The schema of this event is similar to any other event you will receive from CXP Eventing. The data portion of this event includes a validationCode property. Your application verifies that the validation request is for an expected event subscription, and returns the validation code in the response synchronously.
  • Asynchronous handshake: In certain cases, you can't return the ValidationCode in response synchronously. For example, if you use a third-party service (like Zapier or IFTTT), you can't programmatically respond with the validation code.

For these cases, we offer a manual validation handshake option. In addition to the aforementioned valiationCode, we also provide a validationUrl property in the data portion of the subscription validation event. To complete the handshake, find that URL in the event data and do a GET request to it. You can use either a REST client or navigate to the URL from your favorite web browser.

📘

Validation URL Lifetime

The provided validationURL is valid for 5 minutes after event delivery. If you don't complete the manual validation within 5 minutes, the subscription will fail and we'll have to create the event subscription again before restarting the manual validation.

Both of these authentication mechanisms also require the webhook endpoint to return an HTTP status code of 200 so that it knows that the POST for the validation event was accepted. In other words, if the endpoint returns 200 but doesn't return back a validation response synchronously, the mode is transitioned to the manual validation mode. If there's a GET on the validation URL within 10 minutes, the validation handshake is considered to be successful. YAAY!

An example SubscriptionValidationEvent is shown in the following example:

[
    {
        "id": "8a4ffa31-b0ae-4d8b-b204-6a089ce80bd8",
        "topic": "/subscriptions/.../topics/ConnexPay-PurchaseEvents",
        "subject": "",
        "data": {
            "validationCode": "E573FFFC-38AB-4053-B31C-17FA58123456",
            "validationUrl": "https://rp-eastus.eventgrid.azure.net:553/eventsubscriptions/requestinsp/validate?id=E573FFFC-38AB-4053-B31C-17FA58123456&t=2021-05-06T21:17:48.5649700Z&apiVersion=2020-10-15-preview&token=L1fRvAnmbt1lD5z1t%2fzyCV1icmmPF1h1ZCDc1MtEQVA%3d"
        },
        "eventType": "Microsoft.EventGrid.SubscriptionValidationEvent",
        "eventTime": "2021-05-06T21:17:48.56497Z",
        "metadataVersion": "1",
        "dataVersion": "2"
    }
]

Endpoint Security

You can secure your webhook endpoint by specifying data elements (tokens, keys, secrets, etc...) to be passed with every event posted to your endpoint. CXP Eventing supports data passed via query parameters or request headers. We allow up to 10 headers per endpoint subscription, with each header value not exceeding 4,096 (4K) bytes.
Setting the Authorization header with a bearer token (non-normative example)
Set a value to an Authorization header to identify the request with your Webhook handler. An Authorization header can be set if you aren't protecting your Webhook with Azure Active Directory.

SETTING THE AUTHORIZATION HEADER WITH A BEARER TOKEN (NON-NORMATIVE EXAMPLE)

Header name

Header type

Header value

Authorization

Static string

BEARER SlAV32hkKG...

Retry schedule and duration

CXP Eventing provides durable delivery. It delivers each message at least once for each subscription. Events are sent to the registered endpoint of each subscription immediately. If an endpoint doesn't acknowledge receipt of an event, CXP Eventing retries delivery of the event.

📘

Note

ConnexPay Eventing does not guarantee events will always be posted in order. This means that when events occur close together they may be delivered to your endpoint out of order due to the nature of asynchronous delivery and delayed retry.

When CXP Eventing receives an error for an event delivery attempt, it decides whether it should retry the delivery, dead-letter the event, or drop the event based on the type of the error.

If the error returned by the subscribed endpoint is a configuration-related error that can't be fixed with retries (for example, if the endpoint is deleted), CXP Eventing will either perform dead-lettering on the event or drop the event if dead-letter isn't configured.

The following table describes the types of endpoints and errors for which retry doesn't happen:

Endpoint Type

ErrorCodes

Webhook

400 Bad Request, 413 Request Entity Too Large, 403 Forbidden, 404 Not Found, 401 Unauthorized

If Dead-Letter isn't configured for an endpoint, events will be dropped when the above errors happen. Consider configuring Dead-Letter if you don't want these kinds of events to be dropped.

If the error returned by the subscribed endpoint isn't among the above list, CXP Eventing performs the retry using the policies described below.

We wait 30 seconds for a response after delivering a message. After 30 seconds, if the endpoint hasn’t responded, the message is queued for retry. CXP Eventing uses an exponential backoff retry policy for event delivery with the following schedule on a best effort basis:

  • 10 seconds
  • 30 seconds
  • 1 minute
  • 5 minutes
  • 10 minutes
  • 30 minutes
  • 1 hour
  • 3 hours
  • 6 hours
  • Every 12 hours up to 24 hours

If the endpoint responds within 3 minutes, we will attempt to remove the event from the retry queue on a best effort basis but duplicates may still be received.

CXP Eventing adds small randomization to all retry steps and may opportunistically skip certain retries if an endpoint is consistently unhealthy, down for a long period, or appears to be overwhelmed.

By default, we expire all events that aren't delivered within 24 hours.

Message Delivery Status

CXP Eventing uses HTTP response codes to acknowledge receipt of events.

Success codes
We consider only the following HTTP response codes as successful deliveries. All other status codes are considered failed deliveries and will be retried or dead-lettered as appropriate. Upon receiving a successful status code, CXP Eventing considers delivery complete.

  • 200 OK
  • 201 Created
  • 202 Accepted
  • 203 Non-Authoritative Information
  • 204 No Content

Failure Codes
All other codes not in the above set (200-204) are considered failures and will be retried (if needed). Some have specific retry policies tied to them outlined below, all others follow the standard exponential back-off model. It's important to keep in mind that due to the highly parallelized nature of this architecture, the retry behavior is non-deterministic.

Status Code

Retry behavior

400 Bad Request

Not retried

401 Unauthorized

Retry after 5 minutes or more

403 Forbidden

Not retried

404 Not Found

Retry after 4 minutes or more

408 Request Timeout

Retry after 2 minutes or more

413 Request Entity Too Large

Not retried

503 Service Unavailable

Retry after 30 seconds or more

All others

Retry after 10 seconds or more


What’s Next
Did this page help you?