Guide to Worldpay Webhooks Features and Best Practices
Worldpay is one of the world's largest payment processors, handling billions of transactions annually for businesses across 146 countries in over 120 currencies. Following its spin-off from FIS in 2024 and subsequent acquisition by Global Payments in January 2026, Worldpay remains a dominant force in global payments infrastructure.
Beyond payment processing, Worldpay's event notification system enables merchants to receive real-time updates about payment lifecycle changes via webhooks. This guide covers everything you need to know about Worldpay webhooks: their features, how to configure them, best practices for production deployments, and the common pain points developers face along with solutions to address them.
What are Worldpay webhooks?
Worldpay webhooks are HTTP callbacks that deliver event notifications to your endpoints whenever a payment, payout, or chargeback changes status. When a transaction is authorized, settled, refunded, or encounters an error, Worldpay sends a JSON payload containing the event details to a URL you configure. This enables real-time integration with order management systems, accounting platforms, fraud detection tools, and any service that can receive HTTP requests.
Webhooks in Worldpay exist across several product contexts:
- Access Worldpay Events Webhook — The primary webhook integration for payment and payout status updates across Access Worldpay APIs.
- Hosted Payment Pages (HPP) Webhooks — Webhooks triggered by payment events originating from Worldpay's hosted checkout experience.
- Account Payout Event Webhooks — Webhooks specifically for tracking disbursement and payout lifecycle events.
This guide covers all three contexts, with a primary focus on the Access Worldpay Events Webhook, as it's the most widely used integration.
Worldpay webhook features
| Feature | Details |
|---|---|
| Webhook configuration | Implementation Manager, dashboard (HPP only), or provisioning |
| Hashing algorithm | HMAC-SHA256 via Event-Signature header |
| Timeout | 10-second acknowledgment window |
| Retry logic | Automatic retries with escalating intervals (30s to 2h), up to 1 week |
| Alert logic | Configurable event types per webhook endpoint |
| Manual retry | Not available |
| Browsable log | Not available |
| Event ordering | Not guaranteed |
| Security | HMAC signatures, mTLS with client certificates, IP whitelisting |
| Content type | application/vnd.worldpay.events-v1.hal+json |
Supported event types
Worldpay webhooks can notify you of status changes across three event classifications: payment, payout, and chargeback.
Payment events
| Event | Description |
|---|---|
sentForAuthorization | Authorization request sent to the card issuer |
authorized | Payment approved; funds reserved in the customer's account |
sentForSettlement | Request to transfer reserved funds to your Worldpay account |
settled | Funds successfully transferred |
settlementFailed | Settlement attempt failed |
settlementInstructed | Settlement instruction sent to the acquiring bank |
settlementRejected | Settlement rejected by the bank |
cancelled | Payment cancelled |
cancelledByCustomer | Payment cancelled by the customer |
error | An error occurred during payment processing |
expired | Payment authorization expired |
requestExpired | Payment request expired |
refused | Payment refused by the card issuer |
sentForRefund | Refund request initiated |
refunded | Refund successfully processed |
refundFailed | Refund attempt failed |
chargedBack | A chargeback was initiated against the payment |
informationRequested | Additional information requested as part of a chargeback dispute |
tokenCreated | A payment token was created for future use |
Payout events
| Event | Description |
|---|---|
requested | Payout request has been submitted |
pending | Payout sent to the payment network; response pending |
approved | Payout approved by the payment network |
refused | Payout refused by the payment network |
disbursed | Payout successfully disbursed |
topUpAccepted | Top-up request accepted |
topUpRejected | Top-up request rejected |
Webhook payload structure
When Worldpay sends a webhook notification, it delivers a JSON payload using the HAL (Hypertext Application Language) format. The content type is application/vnd.worldpay.events-v1.hal+json. Here's the standard structure for a payment event:
{
"eventId": "bb55ca5a-e05c-47e1-8e94-e88bac1a0a17",
"eventTimestamp": "2025-06-13T14:18:13.407",
"eventDetails": {
"classification": "payment",
"downstreamReference": "3378792436",
"transactionReference": "AuthOrder001",
"type": "sentForAuthorization",
"date": "2025-06-13",
"amount": {
"value": 2500,
"currencyCode": "GBP"
},
"_links": {
"payment": {
"href": "https://try.access.worldpay.com/payments/authorizations/..."
}
}
}
}
Key payload fields
| Field | Description |
|---|---|
eventId | Unique identifier for this specific event notification |
eventTimestamp | ISO 8601 timestamp of when the event was generated |
eventDetails.classification | Event category: payment, payout, or chargeback |
eventDetails.transactionReference | Your original transaction reference from the payment request |
eventDetails.downstreamReference | Worldpay's internal reference for the transaction |
eventDetails.type | The specific event type (e.g., authorized, settled, refused) |
eventDetails.date | The date the payment was first submitted |
eventDetails.amount | Object containing value (integer, in minor units) and currencyCode |
eventDetails._links | HAL hypermedia links back to the related payment or payout resource |
Token created payload
The tokenCreated event uses a slightly different structure that includes token-specific details:
{
"eventType": "tokenCreated",
"notificationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"createdAt": "2025-06-13T14:20:00.000Z",
"eventTimestamp": "2025-06-13T14:19:59.000Z",
"eventId": "unique-event-id",
"eventDetails": {
"transactionReference": "Order-12345",
"tokenCreatedAt": "2025-06-13T14:19:59.000Z",
"tokenId": "token-id-here",
"description": "Customer card token",
"tokenExpiryDateTime": "2026-06-13T14:19:59.000Z",
"paymentInstrument": {
"cardNumber": "4444********1111",
"cardHolderName": "J. Smith",
"cardExpiryDate": {
"month": 12,
"year": 2027
},
"brand": "visa",
"fundingType": "credit",
"countryCode": "GB"
}
}
}
Security with HMAC signatures
Worldpay supports HMAC-SHA256 signatures to verify that webhook payloads have not been tampered with in transit. When enabled, Worldpay signs each webhook body using a shared secret and includes the signature in the Event-Signature header.
The Event-Signature header follows a structured format:
Event-Signature: {keyId}/{hashFunction}/{signature}
For example: Event-Signature: 1/SHA256/a3f2b8c9d1e4f6a7b8c9d0e1f2a3b4c5.
The header can contain multiple signatures (comma-separated), and the order may change between deliveries, so always match signatures using the keyId.
You must contact your Implementation Manager to enable the
Event-Signatureheader and receive the shared secret. This is not a self-service configuration.
Authentication and security options
Worldpay webhooks support multiple layers of security:
| Method | Description |
|---|---|
| HMAC Signature | SHA256-based signature in the Event-Signature header for payload integrity verification |
| mTLS (Mutual TLS) | Worldpay attaches a client certificate (issued by Sectigo CA, CN: webhooks.worldpay.com) to every webhook by default |
| IP Whitelisting | Webhooks originate from a specific set of IP addresses on port 443 that can be whitelisted in your WAF |
| HTTPS Required | All webhook endpoints must use HTTPS with a certificate signed by a trusted CA (SHA-256 or better) |
For mTLS, configure your reverse proxy to validate the client certificate Worldpay sends against the Worldpay Client Certificate chain. Do not pin certificates to a specific version or fingerprint, as Worldpay rotates certificates periodically. Instead, validate based on the Subject Common Name (webhooks.worldpay.com) and the issuing CA (Sectigo).
Setting up Worldpay webhooks
Via Implementation Manager (Access Worldpay Events)
For the core Access Worldpay Events Webhook, configuration is not self-service. You'll need to:
- Contact your assigned Worldpay Implementation Manager.
- Provide your webhook endpoint URL (must be HTTPS with a trusted CA certificate).
- Specify which event types you want to receive (
payment,payout,chargeback, or specific event types within each). - Request the
Event-Signatureheader be enabled and receive your shared secret for HMAC verification. - Whitelist Worldpay's outbound IP addresses in your WAF for each environment (test and production).
- Optionally configure mTLS by setting up your web server to request and validate Worldpay's client certificate during the TLS handshake.
Via the Dashboard (Hosted Payment Pages)
For HPP webhooks, Worldpay offers a self-service option:
- Log in to your Worldpay dashboard.
- Navigate to the webhook settings.
- Enter your HTTPS endpoint URL.
- Enable or disable specific event types based on your requirements.
- Ensure your endpoint's SSL certificate is signed by a trusted CA using SHA-256 or better.
Acknowledging webhooks
For all webhook types, you must respond with an HTTP 200 status code to confirm receipt. This is critical because Worldpay uses a sequential queue model — failing to acknowledge an event can delay or block delivery of subsequent events in the queue.
Best practices when working with Worldpay webhooks
Verifying HMAC signatures
When processing webhooks from Worldpay, verify the HMAC signature to ensure the request originated from Worldpay and wasn't tampered with in transit.
Node.js
const crypto = require('crypto');
const express = require('express');
const app = express();
// Capture raw body for signature verification
app.use(express.json({
verify: (req, res, buf) => {
req.rawBody = buf.toString('utf8');
}
}));
function verifyWorldpaySignature(rawBody, eventSignatureHeader, secret) {
// Parse the Event-Signature header: keyId/hashFunction/signature
const signatures = eventSignatureHeader.split(',').map(s => s.trim());
for (const sig of signatures) {
const [keyId, hashFunction, signature] = sig.split('/');
if (hashFunction.toUpperCase() === 'SHA256') {
const computed = crypto
.createHmac('sha256', secret)
.update(rawBody, 'utf8')
.digest('hex');
if (crypto.timingSafeEqual(
Buffer.from(computed),
Buffer.from(signature)
)) {
return true;
}
}
}
return false;
}
app.post('/webhooks/worldpay', (req, res) => {
const eventSignature = req.headers['event-signature'];
if (!eventSignature || !verifyWorldpaySignature(
req.rawBody,
eventSignature,
process.env.WORLDPAY_WEBHOOK_SECRET
)) {
return res.status(400).send('Invalid signature');
}
// Acknowledge immediately to avoid 10-second timeout
res.status(200).send('OK');
// Process the webhook asynchronously
processWebhookAsync(req.body).catch(console.error);
});
Python
import hmac
import hashlib
import os
from flask import Flask, request, abort
app = Flask(__name__)
def verify_worldpay_signature(payload, event_signature_header, secret):
"""Verify the Worldpay Event-Signature header."""
signatures = [s.strip() for s in event_signature_header.split(',')]
for sig in signatures:
parts = sig.split('/')
if len(parts) != 3:
continue
key_id, hash_function, signature = parts
if hash_function.upper() == 'SHA256':
computed = hmac.new(
secret.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256
).hexdigest()
if hmac.compare_digest(computed, signature):
return True
return False
@app.route('/webhooks/worldpay', methods=['POST'])
def handle_worldpay_webhook():
event_signature = request.headers.get('Event-Signature')
if not event_signature or not verify_worldpay_signature(
request.get_data(as_text=True),
event_signature,
os.environ['WORLDPAY_WEBHOOK_SECRET']
):
abort(400)
# Acknowledge immediately
# Process asynchronously via a task queue
enqueue_webhook_processing(request.json)
return 'OK', 200
Respond within 10 seconds to avoid queue blocking
Worldpay has a strict 10-second timeout for webhook acknowledgment. If your endpoint doesn't respond with a 200 status code within this window, Worldpay considers the delivery failed and begins retrying. Crucially, Worldpay uses a sequential queue model, so a stuck event blocks all subsequent events for your account. Always acknowledge immediately and process asynchronously.
Use the eventId for idempotency
Each event includes a unique eventId. Use this to implement idempotent processing and guard against duplicate deliveries, which Worldpay's documentation explicitly warns can occur:
async function processWorldpayEvent(payload) {
const { eventId, eventDetails } = payload;
const idempotencyKey = eventId;
// Check if already processed
const exists = await redis.get(`processed:${idempotencyKey}`);
if (exists) {
console.log(`Event ${eventId} already processed, skipping`);
return;
}
// Process the event
await handleEvent(eventDetails);
// Mark as processed with TTL
await redis.setex(`processed:${idempotencyKey}`, 604800, '1'); // 7-day TTL
}
Handle out-of-order events
Worldpay does not guarantee event ordering. Events that follow a logical lifecycle sequence (e.g., sentForAuthorization → authorized → sentForSettlement → settled) may arrive out of order, particularly when retries are involved. Design your handler to be resilient to this:
const EVENT_PRIORITY = {
'sentForAuthorization': 1,
'authorized': 2,
'sentForSettlement': 3,
'settlementInstructed': 4,
'settled': 5,
'refused': 10,
'cancelled': 10,
'error': 10
};
async function handlePaymentEvent(eventDetails) {
const { transactionReference, type } = eventDetails;
const currentState = await getTransactionState(transactionReference);
// Only process if this event moves the transaction forward
// or represents a terminal state
const currentPriority = EVENT_PRIORITY[currentState] || 0;
const newPriority = EVENT_PRIORITY[type] || 0;
if (newPriority > currentPriority) {
await updateTransactionState(transactionReference, type, eventDetails);
} else {
console.log(`Ignoring out-of-order event ${type} for ${transactionReference}`);
}
}
Validate mTLS client certificates
If you've configured mTLS, validate the client certificate Worldpay attaches to every webhook. Verify against stable attributes rather than pinning to a specific certificate:
# Nginx configuration for mTLS validation
server {
listen 443 ssl;
ssl_client_certificate /path/to/sectigo-root-ca.pem;
ssl_verify_client on;
ssl_verify_depth 3;
location /webhooks/worldpay {
# Verify the CN matches webhooks.worldpay.com
if ($ssl_client_s_dn !~ "CN=webhooks.worldpay.com") {
return 403;
}
proxy_pass http://your-app:3000;
}
}
Worldpay webhook limitations and pain points
No self-service webhook configuration
The Problem: For the core Access Worldpay Events Webhook, there is no self-service dashboard, API, or CLI to register, update, or remove webhook URLs. You must contact your assigned Implementation Manager to make any configuration changes, including adding a URL, changing which events you subscribe to, or enabling HMAC signatures.
Why It Happens: Worldpay is an enterprise-grade payment processor that historically relies on relationship-managed onboarding. Webhook configuration is treated as part of the merchant provisioning process rather than a developer-facing feature. Only the Hosted Payment Pages product offers dashboard-based self-service.
Workarounds:
- Plan webhook configuration changes well in advance and batch requests to your Implementation Manager.
- For HPP integrations, use the self-service dashboard where available.
- Maintain thorough internal documentation of your webhook configuration, since there's no API to query it programmatically.
How Hookdeck Can Help: Hookdeck provides a single, stable ingestion URL that you configure once with Worldpay. All routing, filtering, and destination management is then handled through Hookdeck's self-service dashboard or API, so you never need to contact your Implementation Manager to make changes to how webhooks are processed or where they're delivered.
Strict 10-second acknowledgment timeout with queue blocking
The Problem: Worldpay requires your endpoint to respond with an HTTP 200 within 10 seconds. If it doesn't, the delivery is considered failed and retries begin. More critically, Worldpay uses a sequential queue model where unacknowledged events block the delivery of all subsequent events in the queue. A single slow or failed endpoint can cascade into delayed or lost notifications for your entire account.
Why It Happens: The sequential queue ensures events for the same merchant are delivered in order, but the tight timeout combined with blocking behavior means any processing delay at your endpoint has outsized consequences.
Workarounds:
- Always acknowledge webhooks immediately before any processing.
- Use a task queue (Redis, SQS, RabbitMQ) to decouple receipt from processing.
- Monitor endpoint response times closely and set alerts for anything approaching 10 seconds.
How Hookdeck Can Help: Hookdeck acknowledges webhooks on your behalf within milliseconds and then delivers them to your endpoint with configurable timeouts, retry policies, and concurrency controls. This eliminates the risk of queue blocking at the Worldpay level entirely.
No delivery logs or debugging dashboard
The Problem: Worldpay does not provide a self-service dashboard for viewing webhook delivery attempts, failures, response codes, or event history. If a webhook fails to reach your endpoint, there's no way to inspect what happened, what the payload was, or whether retries were attempted from Worldpay's side.
Why It Happens: Worldpay's webhook system was designed primarily for reliable delivery rather than developer debugging. Visibility into delivery status requires contacting Worldpay support or your Implementation Manager.
Workarounds:
- Implement comprehensive logging on your receiving endpoint, recording every incoming request with headers, body, and timestamps.
- Use a request inspection tool during development to capture and analyze payloads.
- Build health-check monitoring for your webhook endpoint and alert on any downtime.
How Hookdeck Can Help: Hookdeck's dashboard provides complete visibility into every webhook delivery: request and response payloads, HTTP status codes, latency, retry attempts, and error details. You can search, filter, and inspect events in real time without relying on Worldpay for debugging information.
No manual retry or event replay
The Problem: Once a webhook event exhausts its retry window (up to one week), it is permanently lost. There is no API, dashboard button, or mechanism to manually replay missed events. If your endpoint was down for an extended period, you have no way to recover those notifications.
Why It Happens: Worldpay's retry mechanism is designed to handle transient failures, not extended outages. After one week, events are dropped from the queue with no dead-letter queue or archive.
Workarounds:
- Use Worldpay's payment query APIs to poll for the current status of transactions you suspect you missed notifications for.
- Contact your Implementation Manager to discuss whether event replay is possible for specific time windows.
- Build reconciliation jobs that periodically compare your transaction records against Worldpay's API responses to detect gaps.
How Hookdeck Can Help: Hookdeck automatically stores all webhook events and provides one-click manual retry and bulk replay capabilities. Failed events are preserved indefinitely, so you can inspect, debug, and replay them once your endpoint issues are resolved — no events are ever permanently lost.
IP whitelisting maintenance burden
The Problem: Worldpay requires you to whitelist specific IP address ranges in your Web Application Firewall (WAF) for each environment (test and production). These IPs can change, and Worldpay has noted that for Access Worldpay endpoints specifically, outbound IPs are subject to future change, making static whitelisting fragile.
Why It Happens: Worldpay's webhook infrastructure uses a defined set of outbound IPs for security, but as their infrastructure evolves, these ranges may change, requiring you to update your firewall rules.
Workarounds:
- Subscribe to Worldpay release notes and developer communications to stay informed of IP changes.
- Automate WAF rule updates where possible.
- Use mTLS certificate validation as an additional (or alternative) authentication layer that doesn't depend on static IPs.
How Hookdeck Can Help: When using Hookdeck as your webhook ingestion point, you only need to whitelist Hookdeck's stable, well-documented IP ranges. Hookdeck handles the connection with Worldpay, removing the need to track and update Worldpay-specific IP whitelists.
Event ordering not guaranteed
The Problem: Worldpay does not guarantee that events will arrive in the order they occurred. A settled event could arrive before an authorized event, particularly when retries are involved. Since a single failed delivery blocks the queue and triggers retries with escalating intervals, events that succeed on first delivery may arrive before earlier events that required retries.
Why It Happens: The interaction between the sequential queue, retry logic, and potential network variability means that while events are generally in order, there are documented scenarios where they won't be.
Workarounds:
- Implement state machine logic in your webhook handler that validates transitions based on the event type.
- Use the
eventTimestampfield to determine the true chronological order of events. - Design your system to handle any event at any time, rather than assuming a specific sequence.
How Hookdeck Can Help: Hookdeck's event ordering capabilities can buffer and reorder events before delivering them to your endpoint, ensuring your handler receives events in the correct sequence even when Worldpay delivers them out of order.
SHA-1 certificate deprecation (March 2026)
The Problem: Worldpay is ending support for certificate chains that include any certificates using the SHA-1 signing algorithm as of March 2026. If your endpoint or any intermediate certificate in your chain uses SHA-1, webhooks will stop being delivered.
Why It Happens: SHA-1 has known cryptographic weaknesses and is being phased out industry-wide. Worldpay requires SHA-256 or better across the entire certificate chain, including root certificates.
Workarounds:
- Audit your entire SSL/TLS certificate chain (including intermediates and root certificates) to ensure all use SHA-256 or better.
- Work with your certificate authority to reissue any certificates still using SHA-1.
- Test your endpoint against Worldpay's test environment well before the March 2026 deadline.
How Hookdeck Can Help: Hookdeck's ingestion endpoints use modern TLS configurations with SHA-256+ certificates by default, ensuring compatibility with Worldpay's requirements without any certificate management on your part.
Testing Worldpay webhooks
No built-in test button for most products
Unlike some webhook providers, the core Access Worldpay Events Webhook does not offer a "send test event" button in a dashboard. To test your webhook handler, you need to trigger real events in Worldpay's test environment by making actual API calls that change transaction states.
Use a request inspector
Before building your handler, inspect real Worldpay payloads using a request inspection tool like Hookdeck Console:
- Create a temporary ingestion URL.
- Provide this URL to your Implementation Manager (or configure it in the HPP dashboard).
- Trigger real events in the test environment by processing test payments.
- Inspect the payload structure, headers, and
Event-Signatureformat.
Build a reconciliation safety net
Given the limitations around delivery visibility and event replay, build reconciliation into your integration from the start:
- Log every received webhook with its
eventIdandeventTimestamp. - Run periodic reconciliation jobs that query Worldpay's payment APIs to detect any transactions whose webhook notifications you may have missed.
- Alert on gaps between expected and received events.
Validate in staging
Test your webhook integration with realistic scenarios:
- Full payment lifecycle: authorization → settlement → completion.
- Refund and cancellation flows.
- Failed payments and error events.
- Token creation events (if using Worldpay tokenization).
- High-volume bursts to verify your endpoint responds within the 10-second window under load.
Conclusion
Worldpay webhooks provide a comprehensive event notification system for one of the world's largest payment processors. The rich set of payment, payout, and chargeback event types, combined with strong security options including HMAC signatures and mTLS, make it possible to build robust, real-time integrations with your payment infrastructure.
However, the lack of self-service configuration, strict 10-second timeouts with queue-blocking behavior, absence of delivery logs, and no manual retry capabilities mean that production deployments require careful engineering. Implementing proper signature verification, immediate acknowledgment with asynchronous processing, idempotency guards, and out-of-order event handling will address most common issues.
For most integrations with reliable endpoints and moderate transaction volumes, Worldpay's built-in webhook system combined with proper error handling works well. For high-volume payment operations, multi-destination routing, or mission-critical scenarios where delivery guarantees and visibility matter, webhook infrastructure like Hookdeck can address Worldpay's limitations by providing configurable timeouts, comprehensive delivery logs, automatic retry with manual replay, and self-service routing management without needing to contact your Worldpay Implementation Manager for every change.