Payment Webhooks: Integration & Signature Verification Guide
Payment webhooks allow a payment provider to notify your application when a transaction changes status. For a business integrating with DeltaPay Global, webhooks can help keep order records synchronized with payment events, provided the service and event types are supported by your merchant integration.
This guide explains how webhook delivery typically works, how to approach signature verification, and how to handle duplicate events and failed deliveries securely.
Important: Obtain DeltaPay Global’s official webhook documentation before implementing these examples. The header names, signature algorithm, payload schema, event types, and retry policy below must match the provider’s actual specifications.
How Webhooks Work
When a payment event occurs, a payment provider may send an HTTP POST request containing a JSON payload to your registered webhook URL.
A typical webhook workflow looks like this:
- A payment or refund event occurs.
- The provider sends a notification to your configured endpoint.
- Your server verifies the notification’s authenticity.
- Your application checks the transaction reference, amount, currency, and order association.
- Your application records the event and updates the relevant transaction or order.
- Your endpoint returns the HTTP status code required by the provider.
The exact events and delivery behavior depend on the payment provider.
| Example event | Typical meaning |
|---|---|
payment.succeeded |
A payment was successful |
payment.failed |
A payment failed |
refund.succeeded |
A refund was completed |
refund.failed |
A refund failed |
webhook.test |
A test notification, if supported |
These are illustrative event names, not confirmed DeltaPay Global event identifiers.
The Webhook Payload
A provider may send fields such as an event ID, transaction reference, merchant order ID, payment status, amount, currency, and timestamp.
For example, a generic payload could look like this:
{
"eventId": "example-event-id",
"eventType": "payment.succeeded",
"transactionReference": "example-transaction-reference",
"merchantOrderId": "ORDER-1001",
"status": "SUCCESS",
"amount": 4250,
"currency": "PKR",
"occurredAt": "2026-10-10T12:00:00Z"
}
This JSON is illustrative only. Use the actual field names, amount format, status values, and timestamp format defined in DeltaPay Global’s documentation.
If the provider supplies a stable event identifier, store it and use it to prevent the same notification from being processed more than once.
Webhook Headers
Webhook headers may contain metadata about the event and information used to verify the request’s authenticity.
Ask DeltaPay Global to confirm:
- Which header contains the signature.
- Whether a timestamp is included.
- Whether an event ID or delivery ID is supplied.
- Which signature algorithm and encoding are used.
- How webhook secrets are issued, stored, and rotated.
Do not assume that headers from another payment provider will work with DeltaPay Global.
Verify the Signature on Every Webhook
Signature verification helps your application determine whether a webhook was generated using the expected secret and whether the signed content has been altered.
Depending on the provider’s implementation, verification may involve an HMAC signature, a timestamp, or another documented authentication mechanism.
A secure verification process should:
- Read the original request body in the format required by the provider.
- Retrieve the signature and any required timestamp from the documented headers.
- Compute or validate the expected signature using the provider’s prescribed method.
- Compare signatures using a constant-time comparison function where applicable.
- Reject invalid signatures before processing the event.
- Apply any documented timestamp tolerance to reduce replay risk.
Never invent a signature algorithm or header name. The following language-specific examples demonstrate the general structure of HMAC-based verification only. Use them only if DeltaPay Global confirms that the relevant algorithm and message format match its implementation.
Java example
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.HexFormat;
boolean verifyHmac(
String secret,
String message,
String receivedSignature
) {
try {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(
secret.getBytes(StandardCharsets.UTF_8),
"HmacSHA256"
));
byte[] digest = mac.doFinal(
message.getBytes(StandardCharsets.UTF_8)
);
byte[] received = HexFormat.of().parseHex(
receivedSignature
);
return MessageDigest.isEqual(digest, received);
} catch (Exception e) {
return false;
}
}
The message must be constructed exactly as required by the provider. Do not assume it is simply the timestamp concatenated with the request body.
PHP example
<?php
function verifyHmac(
string $secret,
string $message,
string $signature
): bool {
$expected = hash_hmac(
'sha256',
$message,
$secret
);
return hash_equals(
strtolower($expected),
strtolower($signature)
);
}
This example assumes hexadecimal HMAC-SHA256 signatures. Confirm the provider’s required encoding, capitalization, and message construction before using it.
Node.js example
const crypto = require("crypto");
function verifyHmac(secret, message, signature) {
const expected = crypto
.createHmac("sha256", secret)
.update(message)
.digest();
let received;
try {
received = Buffer.from(signature, "hex");
} catch {
return false;
}
return (
expected.length === received.length &&
crypto.timingSafeEqual(expected, received)
);
}
Capture the raw request body before JSON parsing if the provider signs the original body bytes. Construct the signed message exactly as specified in the official integration documentation.
Python example
import hmac
import hashlib
def verify_hmac(secret: str, message: bytes, signature: str) -> bool:
expected = hmac.new(
secret.encode("utf-8"),
message,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(
expected.lower(),
signature.lower()
)
The message and signature format in this example are generic. They must be adapted to the documented DeltaPay Global webhook protocol before deployment.
Configure Your Webhook Endpoint
If DeltaPay Global supports webhooks for your merchant account, ask how to register the endpoint and whether different environments require separate URLs.
A production endpoint should generally:
- Use HTTPS.
- Authenticate notifications according to the provider’s documentation.
- Validate the event against a known order or transaction.
- Reject malformed requests safely.
- Avoid exposing secrets or sensitive customer information in logs.
- Return the required acknowledgement promptly.
- Be protected against duplicate processing and unauthorized requests.
Also ask whether the provider supports a default webhook URL, transaction-specific webhook URLs, endpoint restrictions, or a dashboard for managing webhook deliveries.
Do not assume that a particular API endpoint or per-transaction webhook field exists without confirming it in the current API reference.
Retries, Idempotency, and Delivery
Webhook providers may retry deliveries if an endpoint is unavailable or returns an unsuccessful HTTP response. The exact retry schedule and maximum delivery period vary.
Your implementation should account for:
Duplicate events: Store a unique event identifier if provided and ensure repeated notifications do not trigger duplicate fulfilment, refunds, or accounting entries.
Temporary failures: Make event processing resilient to database outages, network problems, and temporary service interruptions.
Acknowledgement behavior: Follow the provider’s documented response requirements. If the provider expects a prompt acknowledgement, avoid performing slow or unnecessary work before responding.
Event history: If delivery logs or resend tools are available, use them to investigate missed or failed notifications.
Out-of-order events: Do not assume notifications will always arrive in chronological order. Check the current transaction status before applying an update.
Webhook Secret Rotation and Endpoint Security
If DeltaPay Global provides webhook secrets, keep them in a secure configuration store and restrict access to authorized services.
When rotating a secret:
- Follow the provider’s documented rotation procedure.
- Deploy the new secret according to the required migration window.
- Verify incoming notifications using the approved procedure.
- Remove the old secret when the transition is complete.
If endpoint restrictions or domain allowlists are supported, configure them according to the provider’s instructions. Also ensure that your application does not trust user-supplied callback URLs without suitable validation.
Troubleshooting
| Symptom | Possible cause or action |
|---|---|
| Signature verification fails | Check the secret, raw-body handling, encoding, and exact signed-message format |
| Timestamp validation fails | Check server clock synchronization and the provider’s allowed time window |
| No webhook arrives | Verify endpoint registration, HTTPS configuration, firewall rules, and delivery logs if available |
| The same event is processed twice | Implement idempotency using a stable event identifier or transaction-level safeguards |
| Order status does not update | Check event parsing, transaction references, database updates, and event status mapping |
| Refund status remains pending | Verify the current refund status through the documented transaction lookup or reconciliation process |
Getting Started with DeltaPay Global
Before implementing webhooks in a live application, request DeltaPay Global’s current API documentation and confirm whether webhooks are available for your integration.
Ask for the supported event types, authentication and signature-verification method, payload examples, retry behavior, sandbox testing procedure, and secret-rotation instructions.
Visit DeltaPay Global to enquire about API access, integration support, and the payment services available for your business.
A secure webhook implementation should always be based on the provider’s actual specification—not assumptions copied from another gateway.