Webhooks
Webhooks notify your application when events occur in your Gravv integration. When an event happens, Gravv sends an HTTPS POST request to your webhook endpoint with the event details.
When to use webhooks
Use webhooks to track the status of operations in real time. For example:
- Monitor transfer completion
- Receive notifications when funds arrive in accounts
Webhook payload structure
All webhook events in Gravv share a common base structure:
{
"event_id": "53373f52-2b15-469a-822f-69625a2632b9",
"tenant_id": "dfa96ede-fc13-43cf-8328-8b910d1cd1d2",
"timestamp": "2025-10-27T10:11:05Z",
"event_data": {
"status": "pending",
"kyc_type": "basic",
"tenant_id": "dfa96ede-fc13-43cf-8328-8b910d1cd1d2",
"customer_id": "0ff6cf9a-8da0-466d-a71c-714eb4bde248",
"customer_type": "individual",
"customer_email": "marielle@yopmail.com"
},
"event_type": "customer.kyc.status.pending",
"event_category": "customer",
"event_group_id": "0ff6cf9a-8da0-466d-a71c-714eb4bde248"
}
Every webhook request includes these fields:
| Field | Type | Description |
|---|---|---|
| event_id | string | unique identifier for this webhook event |
| tenant_id | string | your account identifier |
| timestamp | string | ISO 8601 timestamp when the event occurred |
| event_data | object | event-specific data, which varies by event type |
| event_type | string | type of event, for example, when the transfer status is completed |
| event_category | string | category of the event, for example, customer |
| event_group_id | string | groups related events together |
Verify webhook signatures
Gravv signs all webhook requests with HMAC-SHA256 to verify authenticity and prevent tampering. You should verify the signature before processing webhook events.
How signature verification works
Gravv generates a signature using:
- Your webhook secret key from the Dashboard
- The webhook payload
- HMAC-SHA256 algorithm
The signature appears in the X-Gravv-Signature header of each webhook request.
Verification steps
To verify a webhook signature:
- Extract the signature from the
X-Gravv-Signatureheader - Generate a signature using your secret key and the raw request body
- Compare the generated signature with the received signature
- Process the webhook only if the signatures match
Signature generation
The following code sample in Go shows how to generate webhook signatures for verification:
func generateSignature(secretKey string, payload []byte) (string, error) {
// 1. Initialize HMAC with SHA-256 and the Secret Key
mac := hmac.New(sha256.New, []byte(secretKey))
// 2. Hash the Payload
_, err := mac.Write(payload)
if err != nil {
return "", fmt.Errorf("failed to write to hmac: %w", err)
}
// 3. Compute the signature (HMAC digest) and encode it as a hexadecimal string
return hex.EncodeToString(mac.Sum(nil)), nil
}
Collections events
Collection events notify you when the status of a payment collection changes. These events help you track incoming payments in real time as customers complete transactions through card, mobile money, or bank transfer methods.
When collection events are sent
Gravv sends collection events when:
- A collection transaction is initiated and processing begins.
- The transaction fails due to payment issues or validation errors.
- The transaction completes successfully and funds are received.
Collection event types
The following event types are available for collections:
| Event type | Description |
|---|---|
| collection.status.pending | collection initiated and processing |
| collection.status.failed | collection failed |
| collection.status.completed | collection completed successfully |
Onramp status values
The onramp_status field in collection events indicates the payment processor status:
| Onramp status | Collection status | Description |
|---|---|---|
| initialize | pending | payment initialization started |
| transfer_queued | pending | payment queued for processing |
| transfer_initialized | pending | payment processing in progress |
| transfer_failed | failed | payment processing failed |
| transfer_completed | completed | payment successfully processed |
Collection event structure
The event_data object for collection events contains the following fields:
| Field | Type | Description |
|---|---|---|
| card_bin | string | first six digits of card number, only present for card payments |
| card_exp_month | string | card expiration month, only present for card payments |
| card_exp_year | string | card expiration year, only present for card payments |
| card_name | string | card product name, only present for card payments |
| card_type | string | card type: debit or credit, only present for card payments |
| card_segment | string | card segment: consumer or commercial, only present for card payments |
| card_brand | string | card brand: VISA, MASTERCARD, etc., only present for card payments |
| transaction_id | string | unique identifier for the collection transaction |
| onramp_status | string | payment processor status |
| transaction_status | string | current status: pending, failed, or completed |
| amount | string | amount collected |
| asset | string | stablecoin received, either USDC or USDT |
| network | string | blockchain network where funds were received |
| reference | string | client reference identifier from the collection request |
| metadata | object | custom data attached to the collection request |
| tx_hash | string | blockchain transaction hash, only present when status is completed |
| remark | string | failure reason, only present when status is failed |
The following is a sample payload for a completed collection event:
{
"event_data": {
"card_bin": "411111",
"card_exp_month": "09",
"card_exp_year": "45",
"card_name": "Visa Classic",
"card_type": "debit",
"card_segment": "consumer",
"card_brand": "VISA",
"transaction_id": "90950347-d40b-4ab9-aa77-f1882750477c",
"onramp_status": "completed",
"transaction_status": "completed",
"amount": "1.20",
"asset": "USDC",
"network": "polygon",
"reference": "trasdfjausdaa",
"tx_hash": "0x56713ddd7478bbe69925a4aa477d9cb74b56c4c041a304ca3160b2289b6e3a44",
"metadata": {
"order_id": "12345",
}
},
"tenant_id": "89fa0d5e-3acf-4834-968f-6a9f0186ab59",
"event_category": "collection",
"event_type": "collection.status.completed",
"event_group_id": "90950347-d40b-4ab9-aa77-f1882750477c"
}