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 Account → Webhooks
  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 Account → Webhooks
  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