Agent skill

GOV.UK Pay Webhooks Skill

Receive and verify GOV.UK Pay webhooks. Use when configuring GOV.UK Pay webhook endpoints, debugging pay-signature signatures, or handling card_payment_captured, card_payment_succeeded, card_payment_refunded.

Install this skill

npx skills add hookdeck/webhook-skills --skill govuk-pay-webhooks


Receive GOV.UK Pay card-payment updates.

When to Use This Skill

  • Configure a receiver for GOV.UK Pay webhook deliveries.
  • Diagnose pay-signature verification failures.
  • Handle card_payment_captured, card_payment_succeeded, card_payment_refunded.

Setup

In the GOV.UK Pay admin tool, open Settings > Developers > Webhooks, configure the endpoint and events, and use View to reveal this webhook's signing secret. Live callbacks require HTTPS with TLS 1.2 and a .gov.uk domain. Exceptions require support approval and a domain owned by your service or parent organisation. Use public tunnel URLs only for sandbox or not-live-yet testing; confirm an approved callback domain before live Hookdeck routing.

Set GOVUK_PAY_WEBHOOK_SECRET in the server environment. Read setup before enabling delivery.

Verification (core)

pay-signature contains a bare hex digest over the raw body. Use HMAC-SHA256 with the secret's UTF-8 bytes. Verify the original bytes before parsing JSON. Validate the digest format, then compare equal-length buffers in constant time.

After extracting the documented digest and constructing message as described in verification, the comparison is:

const expected = crypto.createHmac('sha256', secret).update(message).digest();
if (digest.length !== 64 || !/^[0-9a-fA-F]{64}$/.test(digest)) return false;
const received = Buffer.from(digest, 'hex');
return received.length === expected.length && crypto.timingSafeEqual(received, expected);

No timestamp is included in the signed message. These examples do not invent an age check from unsigned fields.

Complete handlers and tests: Express, Next.js, FastAPI.

Event Handling

Read event_type from the body. webhook_message_id identifies the message. Verify Pay-Signature with the signing secret as UTF-8 bytes, preserving the body bytes exactly without adding a BOM.

Return 2xx promptly. Messages may arrive more than once and out of order; deduplicate using webhook_message_id and reconcile payment state before applying updates.

Local Development

npx hookdeck-cli listen 3000 govuk-pay --path /webhooks/govuk-pay

Use port 8000 for FastAPI. The CLI provides a local tunnel and inspection UI; no account is required to start.

Resources

Repository

hookdeck/webhook-skills

v0.1.0 · MIT · Updated Nov 12, 2026

View on GitHub →