Webhooks are one of the most important parts of a payment integration because they address an unavoidable problem: not everything finishes in the same request that started the transaction.
A charge can be created now and confirmed later. A payment can enter review. A capture can happen at another time. A refund can be processed asynchronously. A timeout can conceal an outcome that only appears a few seconds later.
Without webhooks, the application must repeatedly ask the provider whether something changed. With webhooks, the provider sends a notification when the state evolves. The idea seems simple, but correct implementation requires care with authentication, duplicates, ordering, retries, idempotency, state, and observability.
The most common mistake is treating a webhook as an ordinary HTTP call that always arrives once, in the right order, and at the perfect time. Distributed systems do not work that way.
What is a payment webhook?
A webhook is an HTTP notification sent from one system to another when a particular event occurs.
In payments, it generally reports state changes relevant to charges, payouts, refunds, subscriptions, or other financial objects.
Instead of the merchant querying the provider every second, the provider sends a request to a URL configured by the integration.
AZPay documentation allows a webhook_url to be configured for charge status changes and includes specific references for charge and payout webhooks.
This asynchronous communication is essential because a transaction's final state is not always known at creation time.
Is a webhook the same as an API response?
No.
A synchronous API response represents what the system knows at the time of the request. A webhook represents a subsequent event or relevant update that must be communicated to the integrator.
A charge may return as created or pending and receive confirmation later. Even when the initial response looks conclusive, later events can change the lifecycle: capture, reversal, cancellation, or dispute.
Mature integrations therefore do not rely on just one channel.
The synchronous response guides the immediate journey. Webhooks keep state synchronized over time.
Why might a webhook arrive twice?
Because reliable delivery generally depends on retries.
The provider sends the event and expects a successful response. If the connection fails, the server takes too long, or it returns an error, the sender may try again.
There are also cases where the merchant sent a response, but it was lost in the network. To the provider, delivery appears to have failed; to the merchant, the event has already been processed.
The result: the same event may arrive again.
This is not necessarily a bug. It is a normal consequence of distributed systems that prefer repeating a message to silently losing it.
The application must be ready to handle duplicates without repeating financial or business effects.
What does idempotent webhook processing mean?
It means receiving the same event more than once produces the same final state as receiving it only once.
If a webhook reports that a charge was paid, its first delivery may update the order, release the product, and record the event. The second should not release the product again, issue another invoice, credit a balance twice, or trigger a second delivery.
Implementation generally requires a stable event identity or a combination of data that identifies a change as already processed.
Idempotency does not mean blindly ignoring all repeats. It means controlling effects.
The application may record that the event arrived again for observability purposes without repeating an irreversible business action.
Can I deduplicate using status alone?
Usually, that is not enough.
A charge may go through several legitimate events related to the same status or receive different updates over time. There may also be multiple financial objects associated with one business intent.
Ideally, use an event identifier when the provider offers one and also retain the affected resource's identity.
The combination answers two different questions: have I processed this event before? And which object is it updating?
Without an explicit event ID, the deduplication strategy must be designed more carefully to avoid discarding legitimate changes.
Can webhooks arrive out of order?
Yes.
The network does not guarantee that two asynchronous requests sent sequentially will arrive in the same order. Retries can also make an old event reappear after a new one.
Imagine a charge moving from pending to paid. The paid webhook arrives first and the system updates the order. A few seconds later, a delayed delivery attempt for the pending event arrives again.
If the application simply replaces the current state with the content of the most recently received webhook, it may regress from paid to pending.
This is one of the most dangerous errors in event-driven integrations.
How do you prevent state regression?
The application must understand the object's lifecycle.
One strategy is validating allowed transitions. Another is comparing a version, reliable timestamp, or sequence when the provider supplies such metadata. In critical cases, the application can query the current state directly through the API before applying an ambiguous update.
The principle is simple: arrival order should not be confused with business order.
Receiving a request later does not mean it represents a newer state.
Explicitly modeling the state machine helps prevent impossible regressions.
Should I respond to a webhook before or after processing everything?
In most robust architectures, separating receipt from processing is useful.
The endpoint validates the request, durably records or queues the event, and responds quickly. Heavy work happens afterward.
This reduces the chance that the provider treats delivery as failed merely because an internal routine took too long.
If a handler tries to update several databases, call external services, send email, and execute complex logic before responding, any slowdown increases the chance of timeouts and duplicates.
A quick response does not mean accepting invalid events. Authenticity and integrity must be verified before acknowledging processing when the protocol requires it.
Do webhooks need authentication?
Yes.
A public endpoint accepting financial updates without verifying their origin creates an obvious surface for abuse.
The mechanism varies: HMAC signature, shared key, certificate, token, asymmetric signature, or another provider-defined method.
The application must follow the integration's official mechanism and also validate elements such as timestamps when available.
Verification secrets must also stay out of logs, public code, and error messages.
Authenticating events protects the boundary between the public internet and internal financial state.
Does an IP allowlist replace a signature?
Not necessarily.
An allowlist can add protection, but addresses may change, infrastructure may use shared networks, and operational control may become fragile.
A cryptographic signature binds received content to a trusted key or identity and can detect payload modification.
When the provider offers an official signature, it is usually a more appropriate foundation for event authenticity.
Defenses can be combined, but inventing a parallel mechanism that complicates maintenance is not recommended.
Should the payload be the final source of truth?
That depends on the API contract.
Some webhooks send the full object. Others send only an identifier and new state. In some integrations, the recommended pattern is to receive the notification and query the updated resource through the API.
AZPay charge webhook documentation describes the event structure and how to retrieve full charge details.
This design can be useful because it reduces event size and lets the merchant confirm the resource's current state when necessary.
The integration should understand its specific contract rather than assuming every webhook contains all required data.
When should polling be used alongside webhooks?
Webhooks and polling are not necessarily competing approaches.
Webhooks are efficient for asynchronous updates. Polling can serve as a recovery, reconciliation, or confirmation mechanism in specific scenarios.
Imagine a merchant was unavailable for several hours and missed events after the provider's retry window expired. A reconciliation job can query recent transactions and correct discrepancies.
Querying a resource can also make sense when a timeout leaves the outcome ambiguous.
The most resilient architecture generally treats webhooks as the primary change channel and includes a recovery mechanism for inconsistencies.
What if the endpoint is down?
The sender should have a retry policy, but the merchant should not rely on that alone.
Monitoring availability and delivery rate is essential. A silent endpoint outage can leave orders stuck in an incorrect state even while financial processing works normally.
Operations need alerts when webhook volume drops unexpectedly, 5xx responses increase, or the processing queue grows.
AZPay go-live documentation specifically includes webhook delivery monitoring and alerts among operational concerns.
How do webhook retries work?
The policy depends on the provider.
Generally, temporary failures trigger new attempts over time. Backoff avoids overloading an already unavailable endpoint.
The merchant must know which HTTP codes mean success, how long the provider retries, and whether events can be manually reprocessed.
This knowledge should be part of the production runbook.
During an incident, the team must know whether events will still arrive automatically or manual reconciliation will be required.
What is webhook replay?
Replay is resending a previously valid message.
It may occur legitimately through retries or maliciously if someone captures a request and tries to repeat it.
Signature mechanisms therefore often include a timestamp or another time-related element.
The application may reject overly old messages when the protocol provides for it while also maintaining event ID deduplication.
Authenticity without time-based protection may not be sufficient for every threat model.
Do webhooks and idempotency keys solve the same problem?
No.
An idempotency key generally protects an operation initiated by the customer or merchant, such as creating a charge. It helps the server recognize repeats of the same intent.
An idempotent webhook handler protects processing of events arriving from the provider.
The mechanisms operate in opposite communication directions and complement each other.
A payment architecture may need idempotency when creating a charge and deduplication when receiving events related to that charge.
What happens during a payment timeout?
Timeouts illustrate why webhooks are so important.
The application sends a charge but gets no response. This does not prove the provider failed to process the request.
If operations simply create another charge, a duplicate may result.
The safe path depends on the integration contract: query status, reuse the idempotency key, wait for an asynchronous event, or combine these strategies.
A late webhook may reveal that the first attempt completed even though the synchronous response failed.
How do webhooks relate to failover?
Failover between providers increases state complexity.
If an attempt at PSP A times out and the infrastructure sends another to PSP B, PSP A's result may still arrive later through a webhook.
The orchestration layer must know that both events belong to the same business intent and decide how to represent the result.
Without this correlation, an alternative route may create conflicting states or duplicate charges.
Safe failover therefore requires attempt identity, idempotency, and well-modeled asynchronous processing.
Should a webhook update an order directly?
It may trigger the transition, but domain boundaries are worth preserving.
The financial event says something about payment. The order system decides what that outcome means for fulfillment, inventory, or access.
Separating these domains avoids coupling the entire operation to the PSP's specific format.
An adapter can translate the provider webhook into a normalized internal event, such as payment_paid or payment_failed. Business services consume this common language.
This is especially useful in multi-PSP operations.
How do you normalize webhooks from several PSPs?
Each provider may use different event names, structures, and codes.
An integration layer can validate and translate them into a consistent internal model.
The goal is not to erase every difference, but to prevent order, subscription, and support systems from needing to understand every external payload.
Normalization can represent entities such as payments, attempts, authorizations, captures, and refunds with domain-specific states.
Provider-specific details remain available for investigation when needed.
How should webhook events be stored?
It is useful to keep enough technical records for auditing without unnecessarily exposing sensitive data.
These records may include event ID, type, resource, receipt time, validation result, processing state, and correlation references.
Keeping raw payloads indefinitely is not always necessary and may increase security or privacy risks.
The strategy should consider which fields are genuinely useful for support, reconciliation, and auditing.
Editorial and operational security follow the same principle: store only what is necessary.
What should you monitor in webhooks?
Endpoint availability is only the beginning.
Also track event volume, 2xx rate, response latency, retry rate, duplicates, queue backlog, processing delay, and failures by event type.
Another important signal is the difference between expected transaction volume and received event volume.
If payments continue but webhooks suddenly drop, there is a problem even if the endpoint passes a health check.
Observability must examine flow behavior, not just infrastructure.
How do you test webhooks before production?
The test environment must cover more than the happy path.
Simulate duplicates, delays, reversed ordering, 500 responses, endpoint timeouts, and temporary unavailability.
Also check what happens when an event arrives after the application has queried and updated the state through another path.
Webhook inspection tools can help during development, and AZPay documentation recommends such resources alongside the sandbox.
The test's goal is to prove the integration stays consistent when the network does not behave perfectly.
What does AZPay document about webhooks?
AZPay documentation includes a webhook overview, charge event reference, payout webhooks, and use of webhook_url in requests.
This allows merchants to receive lifecycle updates and synchronize their systems without relying solely on periodic queries.
The integration should follow the contracts and security mechanisms documented for each flow.
For a company already working with orchestration, observability, and multiple methods, webhooks act as part of the operation's nervous system.
A mental checklist for a robust integration
An implementation should clearly answer: how do we verify authenticity? How do we identify the event? How do we deduplicate? Which state transitions are allowed? What happens if ordering is reversed? How quickly do we respond? Does processing use a durable queue? How do we recover lost events? How do we monitor failures? How do we correlate the event with the payment, attempt, and order?
If some of these questions have no answer, the integration may work in testing yet fail in ways that are difficult to diagnose in production.
A webhook is a consistency boundary
A webhook's value goes beyond notifying that something changed.
It connects systems with their own states that must remain consistent despite network failures, retries, and asynchronous processing.
The endpoint should therefore be small, fast, and predictable. Processing should be idempotent. The domain should reject impossible regressions. Operations should monitor the entire flow.
With these principles in place, webhooks stop being fragile callbacks and become reliable pieces of payment infrastructure.