Guide to Payrix Pro Webhooks: Features and Best Practices
Payrix Pro webhooks tell your platform when something changes in your payments portfolio. The example Payrix Pro gives is a new merchant's onboarding status moving from Not Ready to Boarded, which means the merchant can start processing payments. Webhooks let your software react to changes like that without polling the API.
This guide covers how a Payrix Pro webhook is put together, how to authenticate it with a header on each action, and how to work around the parts the portal documentation doesn't cover.
What are Payrix Pro webhooks?
Payrix Pro is Worldpay's PayFac-as-a-service platform. A webhook in the Payrix Pro portal has three parts:
- Webhook Details: who owns the webhook and what it monitors, with a Login ID and one scope: For Login (one user's activity), Team or Division.
- Webhook Triggers: a Resource and an Event that fire the webhook.
- Webhook Actions: where the notification goes, with an Endpoint, an optional Header Name and Header Value, and a Content-Type format.
A webhook can have several triggers and several actions, so one webhook can notify more than one endpoint.
Payrix Pro doesn't sign webhooks. The Header Name and Header Value on each action are the authentication: Payrix Pro describes the value as "any value displayed in the webhook header, including authentication or other security flags". An action without them sends nothing you can check.
Payrix Pro webhook features
| Feature | Details |
|---|---|
| Configuration | Payrix Pro portal, Admin > Webhooks > ADD WEBHOOK |
| API | The Alerts API in the Worldpay Developer Hub |
| Scope | One of For Login, Team or Division per webhook |
| Triggers | A Resource and an Event, chosen from dropdowns |
| Actions | Endpoint, optional Header Name and Header Value, Content-Type |
| Authentication | The optional header on each action |
| Signature and timestamp | None |
| Event list | Not published on the portal pages |
| HTTP method and payload | Not documented on the portal pages |
| Retries and timeout | Actions have retry settings, but their values aren't documented |
| Source IPs | Not published |
Payrix Pro's setup guide says it doesn't break down the available resources "due to the number of resources available". Choose the Resource and Event that match what you need to know, and capture a delivery before you write the parser.
Inspect Payrix Pro webhooks as they arrive. Add a webhook action with a Hookdeck Inspect URL as its Endpoint to see the exact method, headers and body Payrix Pro sends for your trigger, with no account or setup required.
Setting up Payrix Pro webhooks
Pick a header name, such as X-Webhook-Secret, and generate a long random value, for example with openssl rand -hex 32.
- In the Payrix Pro portal, under Admin in the left navigation, select Webhooks.
- Click ADD WEBHOOK, and enter a Name and, optionally, a Description.
- Optionally, open Advanced Options to set the Login ID and the Team, Division or For Login scope. The Division is filled in by default.
- Click Next and enter your endpoint URL in Endpoint.
- Enter your header name and value in the fields under Endpoint.
- Click Next, choose a Resource and the Event that should trigger the webhook, and click Add.
To deliver to another endpoint, open the webhook's details page, click ADD WEBHOOK ACTION, and enter the endpoint, header name and header value. Set the header on every action.
With Hookdeck. Payrix Pro is a supported source in Hookdeck. Its setup note reads: "Set a Header Name and Header Value on each Payrix Pro webhook action. Actions without one send nothing to verify." Create a source with the Payrix Pro type and use its URL as the action's Endpoint. Enter the header name in API Key Header and its exact value in API Key. Header names match case-insensitively; the value must match exactly.
Payrix Pro's portal pages don't name the HTTP method, so the source pre-selects POST without managing it. Trigger the event once and look at the request in Hookdeck. If its method isn't POST, allow that method on the source as well, or requests with it won't be accepted. A request with a missing or wrong header still gets a 200 from Hookdeck, but Hookdeck marks it as failed verification and doesn't deliver it to your service.
For local development, hookdeck listen 3000 payrix-pro --path /webhooks/payrix gives you a public URL that forwards to your machine.
Securing Payrix Pro webhooks
Read the header you set on the action and compare its whole value with the one you stored, in constant time. Check it before you read the body, whatever the method.
const crypto = require('crypto');
const express = require('express');
const HEADER_NAME = (process.env.PAYRIX_WEBHOOK_HEADER || 'x-webhook-secret').toLowerCase();
const SECRET = process.env.PAYRIX_WEBHOOK_SECRET;
function safeEqual(received, expected) {
const a = Buffer.from(received, 'utf8');
const b = Buffer.from(expected, 'utf8');
// timingSafeEqual throws on unequal lengths, so check first.
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
const app = express();
// The method isn't documented, so accept any and check the header first.
app.all('/webhooks/payrix', express.raw({ type: '*/*' }), (req, res) => {
const received = req.get(HEADER_NAME); // case-insensitive lookup
if (!SECRET || typeof received !== 'string' || !safeEqual(received, SECRET)) {
return res.sendStatus(401);
}
// The format depends on the action's Content-Type: store req.body
// with req.get('content-type') and parse it in a background job.
res.sendStatus(200);
});
The same check in Python:
import hmac
import os
HEADER_NAME = os.environ.get("PAYRIX_WEBHOOK_HEADER", "X-Webhook-Secret")
SECRET = os.environ.get("PAYRIX_WEBHOOK_SECRET", "")
def verify_payrix_request(headers) -> bool:
if not SECRET:
return False # never accept when unconfigured
received = headers.get(HEADER_NAME) # Starlette and Flask headers are case-insensitive
if not received:
return False
# Compare bytes: compare_digest raises TypeError on a non-ASCII str.
return hmac.compare_digest(received.encode("utf-8"), SECRET.encode("utf-8"))
A static header proves the sender knows the value and nothing more. It doesn't cover the body, so a modified payload still passes, and with no timestamp a captured request can be replayed. The portal's Webhook Actions table also has a Header Value column, so assume anyone with access to the webhook can read it. Use HTTPS only, use a long random value, and change it if someone who could see it leaves.
Make Payrix Pro webhooks production-ready. Hookdeck Event Gateway checks the header on every action, stores each notification durably, and gives you retries and replay you control.
Payrix Pro webhook limitations and pain points
Most of the contract is undocumented
The Problem: You can't tell from the portal docs which events exist, what the body looks like, which method is used, or how failures are retried.
Why It Happens: The portal pages describe the configuration screens. The resource and event vocabulary and the API side live in the Alerts API documentation in the Worldpay Developer Hub.
Workarounds:
- Read the Alerts API reference for the resources and events you use.
- Capture a real delivery for each trigger before you write its handler, and parse defensively.
How Hookdeck Can Help: Hookdeck stores every request with its method, headers and body, so you can capture a delivery once and replay it against your handler while you build it.
The secret is visible in the portal
The Problem: Your webhook header value may be readable by anyone who can open the webhook.
Why It Happens: The Webhook Actions table on the webhook's details page includes a Header Value column, and the docs don't say it's masked.
Workarounds:
- Limit who can manage webhooks in the portal.
- Rotate the value when portal access changes.
How Hookdeck Can Help: Hookdeck records failed-verification requests, so you can see quickly when a rotation has left one side behind.
Each action has its own header
The Problem: A second endpoint added later arrives without authentication.
Why It Happens: Header Name and Header Value are optional fields on each action, not settings on the webhook.
Workarounds:
- Set the header every time you add an action, and check new actions with a test trigger.
How Hookdeck Can Help: A Hookdeck source keeps requests without the header away from your service, so an action you forgot to configure shows up as failed verification rather than as silent unauthenticated traffic.
Best practices
Use one webhook per purpose
Group triggers that a single handler processes, and keep unrelated resources in separate webhooks with separate endpoints. It keeps parsing simple when the body isn't documented.
Make handlers idempotent
Assume a notification can arrive more than once. Key on the resource ID and the state it reports, and skip repeats. See our guide to webhook idempotency.
Acknowledge fast and process asynchronously
Return 200 once the header checks out and the body is stored. Do the work, such as enabling a merchant in your platform, in a background job. See why to process webhooks asynchronously.
Conclusion
A Payrix Pro webhook combines a monitoring scope, triggers made of a Resource and an Event, and actions that deliver to an endpoint with an optional header. There's no signature, so set a Header Name and a long random Header Value on every action, compare it in full and in constant time, and capture real deliveries to fill in the method, body and retry behaviour that the portal docs leave out.
Hookdeck Event Gateway checks the header, stores every notification, and lets you retry and replay delivery to your platform.
Get started with Hookdeck for free and handle Payrix Pro webhooks reliably in minutes.