Skip to content

Platform capability

One webhook format for every provider

Every provider's callbacks come to Peneu. You receive one event format, signed the same way and retried when your endpoint is down, so your order system has one handler instead of five.

  • One event format and one signature scheme
  • Retried when your endpoint fails
  • Your reference on every event
Webhook deliveryIllustrative

Providers A, B and C send payment callbacks in three different formats. Peneu converts them into one event format, signs each event and delivers it to your endpoint. A delivery that gets a 503 response is retried and succeeds on the second attempt.

The problem

Callbacks are the least standard part of payments

Every provider notifies you differently. One sends JSON, another sends a form post, a third sends almost nothing and expects you to call back for the status. Signature schemes differ, some providers retry and some don't, and duplicate or out-of-order events are normal.

Each difference becomes code in your order system, and it has to be right, because this is the code that decides whether an order ships.

What teams end up handling

  • Three signature schemes, one of them undocumented
  • The same “success” delivered twice
  • A refund event arriving before the payment event
  • A provider that only notifies failures, not successes

How delivery works

From provider callback to your endpoint

  1. 01

    Receive and verify

    The provider's callback is verified on Peneu's side, using that provider's own signature or verification method, before anything is forwarded.

  2. 02

    Normalise

    It's mapped to a Peneu event type and status, with your reference_id and metadata attached, and it gets a unique event ID.

  3. 03

    Sign

    Each event is signed with your webhook secret (HMAC-SHA256 over the timestamp and body), so you can verify it came from Peneu and reject replays.

  4. 04

    Deliver, and retry

    Any response other than 2xx is retried with increasing gaps between attempts. Every delivery attempt and response code is logged.

Events

Core events

EventSent when
payment.authorizedA payment is approved, whichever provider processed it
payment.failedA payment reaches a final failure, with a failure category
refund.processedA refund is completed by the provider
refund.failedA refund couldn't be completed

The full event list is shared with sandbox access.

Payload and verification

What arrives, and how to check it

  • Verify against the raw request body, before parsing it
  • Header names are illustrative
Illustrative
{
  "id": "evt_91a",
  "type": "payment.authorized",
  "created_at": "2026-09-24T14:05:11Z",
  "data": {
    "id": "pay_7Hq2",
    "status": "authorized",
    "amount": 245000,
    "reference_id": "order-10234",
    "provider": "provider_b",
    "provider_ref": "9913…"
  }
}
import crypto from "node:crypto";

function verifyPeneuSignature(rawBody, headers, secret) {
  const ts = headers["peneu-timestamp"];
  const sig = headers["peneu-signature"];
  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return null; // stale
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${ts}.${rawBody}`)
    .digest("hex");
  const ok = crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
  return ok ? JSON.parse(rawBody) : null;
}

Worth knowing

Write your handler defensively

These rules hold for any webhook source. Following them makes the handler boring, which is what you want.

  • De-duplicate by event ID. The same event can arrive more than once
  • Don't assume order. If an event looks out of sequence, fetch the payment for its current state
  • Respond with 2xx quickly and do slow work asynchronously, or the delivery will time out and be retried
  • Treat the webhook as a trigger and the payment's status as the source of truth

Evaluating it

Questions to ask about this, of any provider

Use these with any platform, including Peneu. For Peneu, what's available for your business is confirmed during onboarding.

How are webhooks signed, and how do I verify them?
Acting on an unverified notice is an easy route for fraud.
What happens if my endpoint is down?
Look for retries with backoff and a way to replay missed events.
Can events arrive twice or out of order?
Usually yes; your handler must cope, and the provider should say so plainly.
Is there one event format across providers?
One format is the point of unifying webhooks; check which fields are guaranteed.

FAQ

Questions about unified webhooks

What happens if my endpoint is down?

Deliveries are retried with increasing gaps between attempts. Each attempt and its response code are logged, so you can see what was missed.

Are events delivered in order?

Not guaranteed. Payment systems can't promise ordering end to end. Use the event's created_at and the payment's current status to decide what to do.

Can I have different endpoints for sandbox and production?

Yes. Each environment has its own endpoint and its own signing secret.

Replace your per-provider handlers

Request sandbox access to get the event list, signing details and test events you can send to your own endpoint.

Last reviewed . Samples on this page are illustrative.