pending to authorised, or from authorised to waiting). Instead of polling the API, you register an endpoint and Hello Clever sends a POST request to it automatically on each status transition.
How webhooks work
When a payment status changes, Hello Clever sends aPOST request to your configured endpoint_url with a JSON payload describing the current state of the transaction. Your endpoint must return HTTP 200 to acknowledge receipt. If it does not, Hello Clever retries up to 3 times with a 15-minute delay between each attempt.
Because retries can deliver the same payload more than once, implement idempotent handling in your webhook endpoint. Deduplicate on the transaction identifier:
uuid for the standard payload, or transaction_info.uuid for the Payment Gateway 3 payload.Setting up webhooks
You can configure your webhook endpoint in two ways: SDK integration: Contact Hello Clever to register your default webhook URL. Any payment created via the SDK will send notifications to that URL. API integration: Include awebhook_notification object in your payment creation request. If provided, it overrides the default webhook URL for that payment.
object
Webhook configuration to include in a payment creation request.
Payment statuses
Hello Clever sends a webhook notification whenever a payment transitions to any of the following statuses:When a payment is in
in_dispute status, contact Hello Clever support to submit evidence for the dispute resolution process.Webhook object
Hello Clever sends two different payload shapes. Which one you receive depends on the product that created the payment, so confirm which applies to your integration before you map fields:Standard payload
Payment APIs, Multi-Currency Payment APIs, and Card APIs all send this shape. Each webhook POST body contains the following fields:Example payload: card payment
Example payload: bank transfer
For bank transfer and QR methods,pay_code carries the details the customer needs to complete the payment instead of a 3DS URL:
Payment Gateway 3 payload
Payment Gateway 3 sends a payment link object rather than a flat transaction object. The differences matter when you write your handler:- Payment status is at
transaction_info.status, not at the top level. - Amounts are JSON numbers, not strings.
- The customer arrives as
sender_info, not as top-levelnameandemail. transaction_infoisnulluntil the customer starts a payment against the link.
Example payload
Deduplicate Payment Gateway 3 deliveries on
transaction_info.uuid. The top-level uuid identifies the payment link, which can produce more than one transaction.Token for authorised cards
When a card payment reachesauthorised or waiting status, Hello Clever includes a token object in the webhook payload. Save this token securely: you can use it to create future payments for the same customer without requiring them to re-enter their card details.
Webhook security
Hello Clever supports two security mechanisms you can use independently or together.Authorization header
If you set anauthorization_header in your webhook configuration, Hello Clever will send that value in the Authorization header of every webhook request to your endpoint:
HTTP webhook signature (HMAC-SHA256)
Hello Clever also signs each webhook payload using HMAC-SHA256 and sends the signature in theHTTP-WEBHOOK-SIGNATURE header:
1
Find your Webhook Secret Key
In the Merchant Portal, go to Dashboard → Developer → Authentication → Webhook tab and copy the value from the Webhook secret key field.
2
Compute the expected signature
Use the raw request body (do not parse and re-stringify JSON) and your Webhook Secret Key:
3
Compare and accept or reject
If the signatures match, the payload is authentic and unmodified. If they differ, reject the request; it may have been tampered with or sent by an untrusted source.
Testing your signature verification
If your verification is rejecting valid requests, check your computation against the delivered signature by hand before changing your code.1
Capture the raw request body
Open your request log and copy the raw body of the webhook request exactly as it arrived. Do not reformat it, and do not parse and re-serialise the JSON: whitespace and key order are part of what was signed.
2
Compute the HMAC outside your application
Run the raw body through any HMAC-SHA256 calculator, using your Webhook Secret Key as the key. Set the input encoding to UTF-8 and the output encoding to lowercase hex.
3
Compare against the delivered header
Find the If they match, the signature is valid and the bug is in your application’s handling. If they differ, the request was either tampered with or signed with a different key: confirm you are using the Webhook Secret Key for the correct merchant.
http-webhook-signature header on the same request and compare the two values:Error handling and retries
If your endpoint does not return HTTP200, Hello Clever retries the webhook call up to 3 times with a 15-minute delay between each attempt.
To handle retries correctly:
- Return
200immediately upon receiving the webhook, before performing any heavy processing. - Process the event asynchronously (e.g. via a queue) to avoid timeouts.
- Use the transaction identifier to detect and discard duplicate deliveries:
uuid, ortransaction_info.uuidon Payment Gateway 3.
Error codes
When a payment fails, thepay_code object includes error_code and error_message. The following table lists all possible error codes:
Best practices
- Verify the
Authorizationheader orHTTP-WEBHOOK-SIGNATUREon every incoming request before processing. - Implement idempotency using the transaction identifier (
uuid, ortransaction_info.uuidon Payment Gateway 3) to prevent duplicate side effects from retried deliveries. - Return
200 OKas soon as you receive the request; process the payload asynchronously. - Keep your webhook endpoint URL private; avoid sharing it publicly.
- Use HTTPS for your webhook endpoint to protect the payload in transit.
- Test your endpoint during development using tools like webhook.site or a local tunnel such as ngrok.