Skip to main content

Webhook

Webhook notifications allow you to receive real-time updates about payment transaction status changes. When a payment's status changes (e.g., from pending to authorised, or from authorised to waiting), Hello Clever will send a POST request to your specified webhook endpoint.

Webhook Object

When a payment status changes, you'll receive a webhook notification with the following object structure:

FieldTypeDescription
uuidstringUnique identifier for the payment transaction
namestringCustomer's name
emailstringCustomer's email address
external_idstringYour reference ID for this payment
statusstringCurrent status of the payment
pay_codestringPayment code (if applicable)
currencystringTransaction currency code
amountstringOriginal payment amount
totalstringTotal amount including any fees
paid_amountstringAmount that has been paid
is_refundablebooleanWhether the payment can be refunded
payment_methodstringPayment method used (e.g. "card")
expired_atstringExpiration timestamp
webhook_notificationobjectWebhook configuration details
└─ endpoint_urlstringURL where webhooks will be sent
└─ authorization_headerstringAuthorization header for webhook
refund_informationobjectDetails about any refunds
└─ total_amountstringTotal amount available for refund
└─ refund_amountstringAmount that was refunded
└─ descriptionstringReason for the refund
sender_detailsobjectPayment method details
└─ cardobjectCard payment details
└─── card_typestringType of card used
└─── card_brandstringCard brand (visa, mastercard etc)
└─── card_last_4stringLast 4 digits of card number
created_atstringTimestamp when payment was created
tokenobjectCard token details
└─ idstringToken for the card
└─ typestringToken type (e.g. "card")

Example:

{
"uuid": "QVABPPC7",
"name": "Hello Clever",
"email": "[email protected]",
"external_id": "123",
"status": "authorised",
"pay_code": null,
"currency": "USD",
"amount": "100.0",
"total": "100.0",
"paid_amount": "0.0",
"is_refundable": false,
"payment_method": "card",
"expired_at": "",
"webhook_notification": {
"endpoint_url": "https://webhook.site/12da7803-c4cf-4f32-812d-aaeaecf20d9d",
"authorization_header": "****"
},
"refund_information": {
"total_amount": "250.0",
"refund_amount": "10.0",
"description": "Testing refund"
},
"sender_details": {
"card": {
"card_type": "card",
"card_brand": "visa",
"card_last_4": "1111"
}
},
"created_at": "2025-05-30T05:11:17.602+0000",
"token": {
"id": "tok_dfe1988a1ffc0d6562d3",
"type": "card"
}
}

Token for Authorised Cards

When a payment reaches the authorised status for card payment, we will additonal a token object in the webhook notification. You should be save this token and can be used it to create subsequent payments for the same customer without requiring re-authorisation of their card.

Note: For security reasons, the token object is only included in the webhook notification when the payment status changes to authorised. It will not be included in webhook notifications for other status changes.

The token object has this structure:

{
...,
"token": {
"id": "tok_773085396b86562040f4",
"type": "card"
}
}

Setting Up Webhooks

For security reasons, when using our SDK Integration, you need to contact us to provide your default webhook information to receive notifications. However, when using API Create Payment via Tokenisation, if you specify a different webhook URL, we will send notifications to that URL instead of the default webhook. You can do this by including the webhook_notification object in your payment creation request:

{
"webhook_notification": {
"endpoint_url": "https://your-domain.com/webhook",
"authorization_header": "Bearer your-secret-token" // Optional
}
}

Webhook Security

For enhanced security, you can include an authorization_header in your webhook configuration. This header will be sent with each webhook request, allowing you to verify the authenticity of the notifications.

Status Changes

Webhook notifications are sent when a payment's status changes to any of the following:

  • pending: Your customer hasn't made the requested payment yet.
  • authorised: Your customer has authorised but not yet captured.
  • waiting: Your customer has paid successfully. The funds are waiting to be settled into the merchant's available balance.
  • received: Your customer has paid successfully. the funds have been settled into the merchant's available balance.
  • expired: The payment request has expired.
  • return_pending: A full refund or partial refund request has been triggered on the payment.
  • return_expired: The refund request has expired. Expiration time is set to be 10 days.
  • partially_refunded: Payment has been refunded partially.
  • return_received: Payment has been refunded all amount.
  • return_rejected: A refund failed due to problems with the destination account. HelloClever will not retry again.
  • failed: Payment has canceled.
  • in_dispute: The payment has been in dispute or fraud.
  • dispute_lost: The dispute has been resolved. The disputed amount is not returned to the merchant.

Note: When a payment status is in_dispute, you can contact our support team to provide evidence for the dispute resolution process.

Best Practices

  1. Always verify the webhook signature or authorization header to ensure the request is legitimate
  2. Implement idempotency in your webhook handler to prevent duplicate processing
  3. Respond with a 200 OK status code as soon as you receive the webhook
  4. Process the webhook data asynchronously to avoid timeout issues
  5. Keep your webhook endpoint URL secure and private

Testing Webhooks

You can test webhook notifications using tools like webhook.site or by setting up a local endpoint using tools like ngrok.

Error Handling

If the target endpoint does not return HTTP 200, Hello Clever will retry the webhook call 3 times with 15 minutes delay per call.