Skip to content

Webhooks

Overview

If a partner is interested in receiving real-time callbacks from Hubble, they can share a webhook URL with us. Hubble will send POST requests to this URL for supported events.

All webhooks are signed using an HMAC signature, and partners are expected to verify the request authenticity using the X-Verify header.


Transaction Webhooks

Triggered whenever a transaction occurs via the Hubble SDK. Different webhook payloads are sent based on the order status.

JSON Payloads By Order Status

1. COMPLETED Status

Triggered by: postRedemptionSuccessActionsAsync() when redemption is successful

{
"transactionReferenceId": "01HRVY38NCAANDYPN3WVGJCDSG",
"partnerCoinTransactionId": "01HZ123EXAMPLE456789",
"partnerCoinReversalTransactionId": null,
"amount": 1000.0,
"discountAmount": 50.0,
"timestamp": "2024-01-15T14:30:22",
"userId": "01HRW71319JNKJS6D3Q85X780R",
"vouchers": [
{
"id": "01HZ46Q0P0242STC8TBV926M8C",
"brandId": "01JRSY42BBMKC2YS9TXMYSYN83",
"brandName": "Swiggy",
"cardType": "CARD_NUMBER_SECURED",
"cardNumber": "5333644476668777",
"cardPin": "123456",
"validTill": "2025-04-04",
"amount": 1000.0,
"shareImageUrl": "https://gullak-assets.s3.ap-south-1.amazonaws.com/share-wa-brand-images/Swiggy.jpg",
"brandRetailModes": ["online", "offline", "app", "website"]
}
],
"brandName": "Swiggy",
"orderStatus": "COMPLETED"
}

2. FAILED Status

Triggered when orders fail.

{
"transactionReferenceId": "01HRVY38NCAANDYPN3WVGJCDSG",
"partnerCoinTransactionId": "01HZ123EXAMPLE456789",
"partnerCoinReversalTransactionId": "01HZ456REVERSAL789012",
"amount": 1000.0,
"discountAmount": 50.0,
"timestamp": "2024-01-15T14:35:10",
"userId": "01HRW71319JNKJS6D3Q85X780R",
"vouchers": [],
"brandName": "Swiggy",
"orderStatus": "FAILED"
}

3. REVERSED Status

This is triggered during manual reversals.

{
"transactionReferenceId": "01HRVY38NCAANDYPN3WVGJCDSG",
"partnerCoinTransactionId": "01HZ123EXAMPLE456789",
"partnerCoinReversalTransactionId": "01HZ456REVERSAL789012",
"amount": 1000.0,
"discountAmount": 50.0,
"timestamp": "2024-01-15T15:00:00",
"userId": "01HRW71319JNKJS6D3Q85X780R",
"vouchers": [],
"brandName": "Swiggy",
"orderStatus": "REVERSED"
}

4. PROCESSING Status

No webhook triggered - This is an intermediate status during order processing.

5. INITIALISED Status

No webhook triggered - This is the initial status before processing begins.

Note:

  • brandRetailModes can be null and must be treated as flexible tags, not a strict enum.
  • partnerCoinReversalTransactionId and partnerCoinTransactionId will be null always if coin module is not integrated.

Brand Update Webhooks

Used to notify partners of catalog changes such as discount updates, new brand additions, or brand deactivation.

Supported Events & Sample Payloads

1. USER_DISCOUNT_UPDATED

{
"event": "USER_DISCOUNT_UPDATED",
"details": {
"id": "01GMAVS2CHXR0XP1BZSTA9A44K",
"name": "Amazon shopping",
"discountPercentage": 5
}
}

2. NEW_BRAND_CREATED

{
"event": "NEW_BRAND_CREATED",
"details": {
"id": "01GMAVS2CHXR0XP1BZSTA9A44K",
"name": "Amazon shopping",
"discountPercentage": 2
}
}

3. BRAND_DISABLED

{
"event": "BRAND_DISABLED",
"details": {
"id": "01GMAVS2CHXR0XP1BZSTA9A44K",
"name": "Amazon shopping"
}
}

Webhook Authentication & Security

All webhook requests from Hubble are secured using HMAC-SHA256 signatures. This section explains how to verify the authenticity of incoming webhook requests.

Signature Verification

Each webhook request includes an X-Verify header containing an HMAC-SHA256 signature of the request body, encoded in Base64.

Verification Process

  1. Extract the Signature

    • Get the value of the X-Verify header from the incoming request
  2. Prepare the Payload

    • Read the raw request body as a string (before any JSON parsing)
    • Ensure no whitespace modifications or formatting changes are made to the payload
  3. Generate the Expected Signature

    • Compute HMAC-SHA256 of the raw request body using your webhook secret key
    • Encode the result in Base64
  4. Compare Signatures

    • Compare the generated signature with the one in the X-Verify header
    • Only process the request if they match exactly

Example Implementation (Node.js)

import { createHmac } from "crypto";
function generateSignature(payload: string, secret: string): string {
const algorithm = "sha256";
const hmac = createHmac(algorithm, secret);
hmac.update(payload);
return hmac.digest("base64");
}
function verifyWebhook(
requestBody: string,
signatureHeader: string,
secret: string
): boolean {
const expectedSignature = generateSignature(requestBody, secret);
return expectedSignature === signatureHeader;
}

Example Implementation (Kotlin)

import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec
import java.util.Base64
private fun generateSignature(payload: String, secret: String): String {
val algorithm = "HmacSHA256"
val secretKeySpec = SecretKeySpec(secret.toByteArray(), algorithm)
val mac = Mac.getInstance(algorithm).apply { init(secretKeySpec) }
val signatureBytes = mac.doFinal(payload.toByteArray())
return Base64.getEncoder().encodeToString(signatureBytes)
}
fun verifyWebhook(requestBody: String, signatureHeader: String, secret: String): Boolean {
val expectedSignature = generateSignature(requestBody, secret)
return expectedSignature == signatureHeader
}

Important Identifiers

  • transactionReferenceId: Use this as the unique transaction identifier for all webhook callbacks. This ID remains consistent throughout the transaction lifecycle.
  • userId: This corresponds to the customer_id that was provided to Hubble during initialization, ensuring consistent user identification across all interactions.

Security Best Practices

  1. Always verify the webhook signature before processing any request
  2. Never log or expose your webhook secret key
  3. Use HTTPS for your webhook endpoint
  4. Implement rate limiting to prevent abuse
  5. Validate all incoming data before processing

IP Whitelisting (Optional)

For additional security, you can whitelist Hubble’s outbound IP addresses. Contact Hubble support to get the current list of IP addresses used for webhook notifications.