Skip to main content

Webhooks Setup

Configure event-driven notifications for your applications.

Overview

Webhooks allow your application to receive real-time notifications when events occur in GoValid. Instead of polling the API, GoValid sends HTTP POST requests to your configured endpoint.

How Webhooks Work

  1. You register a webhook URL in GoValid
  2. You subscribe to specific events
  3. When an event occurs, GoValid sends a POST request to your URL
  4. Your application processes the payload and responds with 200 OK

Setting Up Webhooks

Via Dashboard

  1. Log in to my.govalid.org
  2. Navigate to AccountWebhooks
  3. Click Add Webhook
  4. Enter your endpoint URL (must be HTTPS)
  5. Select events to subscribe to
  6. Set a secret for signature verification
  7. Click Save
Developer option: API setup
curl -X POST https://api.govalid.org/api/v1/webhooks/ \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhook",
"events": ["qr.scanned", "qr.created", "qr.expired"],
"secret": "your_webhook_secret"
}'

Available Events

EventDescription
qr.createdA new QR code was created
qr.scannedA QR code was scanned
qr.expiredA QR code has expired
qr.removedA QR code was removed/inactivated
qr.transferredQR code ownership was transferred
subscription.createdNew subscription started
subscription.cancelledSubscription was cancelled
payment.completedPayment was successful
payment.failedPayment failed
credit.topupCredits were added
counterfeit.detectedPotential counterfeit activity detected

Webhook Payload

{
"event": "qr.scanned",
"timestamp": "2025-01-29T12:00:00Z",
"webhook_id": "wh-001",
"data": {
"qr_id": "abc123",
"qr_title": "Product Certificate #001",
"scan_location": {
"country": "ID",
"city": "Jakarta"
},
"device": "mobile",
"platform": "iOS",
"is_first_scan": false,
"scan_count": 15
},
"signature": "sha256=a1b2c3d4..."
}

Verifying Signatures

Every webhook includes an X-GoValid-Signature header:

X-GoValid-Signature: sha256=a1b2c3d4...

Python Example

import hashlib
import hmac

def verify_webhook(payload, signature, secret):
expected = hmac.new(
secret.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)

Node.js Example

const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return `sha256=${expected}` === signature;
}

Best Practices

  1. Respond quickly: Return 200 OK within 5 seconds
  2. Verify signatures: Always verify the webhook signature
  3. Handle duplicates: Use event IDs to prevent duplicate processing
  4. Use HTTPS: Webhook URLs must use HTTPS
  5. Monitor failures: Check webhook delivery status in the dashboard

Retry Policy

GoValid retries failed webhook deliveries:

AttemptDelay
1Immediate
21 minute
35 minutes
415 minutes
51 hour

After 5 failed attempts, the webhook is disabled.

Testing

Test Your Endpoint

Use the dashboard to send a test event:

  1. Go to AccountWebhooks
  2. Click Test next to your webhook
  3. Check your server logs for the test payload

Local Development

For local testing, use tools like:

  • ngrok: Expose localhost to the internet
  • localtunnel: Alternative to ngrok
  • webhook.site: Temporary webhook URL for testing

Troubleshooting

Webhook Not Receiving Events

  1. Verify URL is accessible and uses HTTPS
  2. Check server logs for incoming requests
  3. Verify event subscriptions are correct
  4. Check webhook is active (not disabled)

Signature Verification Failing

  1. Ensure you're using the correct secret
  2. Verify you're hashing the raw request body
  3. Check encoding (UTF-8)
  4. Compare with test payload

Too Many Failures

  1. Check your server is responding within 5 seconds
  2. Ensure your endpoint returns 200 OK
  3. Review error logs for issues
  4. Re-enable webhook after fixing issues