Independent and educational: this site does not process payments, hold funds or offer wallets.Independent and educational. No payment processing, no custody.How we work
    Guide · standards

    Webhooks and payment events

    When a payment is detected, confirmed, under-paid or refunded, your systems need to know. Webhooks deliver those events as HTTP requests to an endpoint you control. This guide covers the design questions that decide whether an integration is reliable: what each event means, when to trust it and how to handle duplicates and delays.

    Updated October 30, 2026By the BlockchainPayments.ca editorsSources & review dates

    Mitey pointing at a simulated payment QR code

    Key points

    • A webhook is a notification, not proof: verify its signature and, for important actions, the payment itself.
    • Never release goods on a detected payment; wait for your confirmation threshold.
    • Expect every event to arrive more than once and out of order, and design for it.
    • Run a scheduled reconciliation job as a safety net for missed events.

    What a payment event is

    A payment event is a message saying that something about a payment changed. The sender might be a payment provider, or a service you run that watches the blockchain for transactions to your addresses. Either way, it sends an HTTP POST with a JSON body to your endpoint, and your endpoint replies to acknowledge it.

    Event names and fields differ between systems. The webhook explorer sandbox uses an illustrative schema to show the ideas; it is not any vendor's API, and your provider's documentation is the reference for a real integration.

    A typical event lifecycle

    The names below are illustrative. What matters is the state each event represents and what your system should do in response.

    Illustrative payment events and suggested handling
    EventMeaningWhat your system does
    payment.detectedA transaction to the invoice address has been seen but is not yet confirmedShow the payer a pending status; do not fulfil
    payment.confirmedThe transaction has reached your confirmation thresholdMark the invoice paid and release goods or services
    payment.underpaidLess than the amount due arrivedApply your tolerance rule; request the balance or hold
    payment.overpaidMore than the amount due arrivedRecord a credit or start your refund process
    payment.expiredThe quote expired before paymentClose the request; re-price if payment arrives later
    payment.convertedReceived funds were converted to CADRecord proceeds and fees for accounting
    refund.sentAn outgoing refund transaction was broadcastRecord the refund hash and notify the customer

    Choosing a confirmation threshold

    A transaction that has just been seen can still be replaced or dropped. Each additional block built on top of it makes reversal less likely. On Bitcoin, blocks are targeted about every 10 minutes and many recipients wait for several confirmations. On Ethereum's proof-of-stake network, finality typically takes about two epochs, roughly 12.8 minutes. Block times and finality vary by network and congestion.

    The right threshold is a business decision. One approach is to scale it to the amount: fewer confirmations for small digital orders, more for large or physical shipments. Whatever you choose, write it down and make it a configuration value, not a constant buried in code. On-chain settlement and finality and the transaction lifecycle sandbox show how confirmations build up.

    Verifying signatures with HMAC

    Anyone who learns your endpoint URL can send it a request. A signature lets you check that an event came from the expected sender and was not changed in transit. A common design uses an HMAC: the sender and you share a secret, the sender computes a keyed hash of the request body with that secret, and you recompute and compare it.

    1. Read the raw request body as bytes, before any JSON parsing or reformatting.
    2. Compute the HMAC, for example with SHA-256, over the exact content the sender signs, which often includes a timestamp as well as the body.
    3. Compare your result with the signature header using a constant-time comparison.
    4. Reject events whose timestamp is outside a short tolerance window, to limit replayed requests.
    5. Store the secret outside your code, restrict who can read it and rotate it on a schedule and after any suspected exposure.

    Idempotency: process each event once

    Senders usually deliver at least once, which means the same event can arrive twice or more, for example when your acknowledgement was slow. If your handler ships an order on every delivery, a duplicate becomes a double shipment.

    Give every event a unique id, store the ids you have processed and skip any you have seen. Make the actions themselves idempotent too: marking an invoice paid twice should leave it paid once. Acknowledge quickly with a success status and do slow work in a background job, so the sender does not time out and retry unnecessarily.

    A simple rule

    Key every side effect, such as an email, a shipment or a refund, on the invoice id plus the event type, so a repeat delivery finds the work already done.

    Retries and ordering

    If your endpoint fails or times out, senders typically retry with increasing delays. Events can also arrive out of order: a confirmed event might reach you before the detected event for the same payment.

    Model each invoice as a state machine that only moves forward, from open to pending to paid, and ignore events that would move it backward. When an event is ambiguous, fetch the current status from the source of truth, the provider's API or the blockchain itself, rather than trusting the order of arrival.

    Finally, assume some events will be missed. A scheduled job that compares open invoices with on-chain activity catches anything the webhooks did not; see reconciling on-chain payments.

    Checklist before going live

    The developer guide collects related material on building and testing integrations.

    • Endpoint uses HTTPS and rejects unsigned or badly signed requests.
    • Duplicate events are detected and skipped.
    • Out-of-order events cannot move an invoice backward.
    • The confirmation threshold is configurable and documented.
    • Under-payment, over-payment and expiry paths have been tested, not just the happy path.
    • Event payloads and outcomes are logged with the transaction hash for audit; FINTRAC reporting entities have specific record-keeping rules.
    • A reconciliation job runs on a schedule and alerts on mismatches.
    • Your provider's incident and retry policies are known; see questions to ask a payment provider.

    Questions people ask

    Can I fulfil an order when the payment is first detected?

    It is more prudent to wait until the transaction reaches your confirmation threshold, because an unconfirmed transaction can still be replaced or dropped.

    Why did I receive the same event twice?

    Senders typically deliver at least once and retry when they do not get a timely acknowledgement. Store processed event ids and skip duplicates.

    Is the sandbox schema the same as a real provider's?

    No. The webhook explorer uses an illustrative schema to teach the concepts. Use your provider's documentation for a real integration.

    What should I do if signature checks start failing?

    Reject the events, alert your team and check for a secret rotation or a change in how the body is read. Do not disable verification to make errors go away.

    Sources

    Reviewed October 30, 2026. Educational information only; not financial, legal, tax or investment advice. This site does not process payments or hold funds.