Webhooks allow your application to receive real-time notifications when events occur in Sign Customiser. This guide will walk you through setting up webhook subscriptions and verifying webhook signatures for security.
Setting Up Your Webhook Subscription
Step 1: Access Your Account
Log into your Sign Customiser account using your credentials.
Step 2: Navigate to Webhooks
From your home page dashboard, click on the "Webhooks" option to access the webhooks management area.
Step 3: Create a New Webhook
Click the "New Webhook" button to start creating your webhook subscription.
Step 4: Configure Your Webhook
Select your topic: Choose the event type you want to receive notifications for (e.g., product created, order updated, etc.)
Enter your URL: Provide the endpoint URL where Sign Customiser should send POST requests when the event occurs
Step 5: Access Your Webhook Details
After creating the webhook, you'll be automatically redirected to the webhook detail page. This page shows:
Real-time webhook requests being made to your endpoint
Your unique webhook secret - copy this value as you'll need it to verify incoming webhooks
Verifying Webhook Signatures
For security, all webhooks from Sign Customiser include cryptographic signatures that you should verify to ensure the requests are legitimate and haven't been tampered with.
Understanding the Verification Process
Sign Customiser includes two important headers with each webhook:
x-webhook-timestamp
: The Unix timestamp when the webhook was sentx-webhook-signature
: A SHA-256 HMAC signature of the payload
Implementation Steps
Step 1: Extract Headers and Payload When your webhook endpoint receives a request, extract the timestamp and signature from the headers, plus capture the raw request body:
const timestamp = req.headers["x-webhook-timestamp"];
const signature = req.headers["x-webhook-signature"];
const rawPayload = req.body.toString("utf8"); // Raw JSON string
Step 2: Verify Timestamp (Prevent Replay Attacks) Check that the webhook timestamp is recent (within 5 minutes) to prevent replay attacks:
const currentTime = Math.floor(Date.now() / 1000);
const webhookTime = Number.parseInt(timestamp, 10);
const timeDiff = Math.abs(currentTime - webhookTime);
if (timeDiff > 300) { // 5 minutes in seconds
return false; // Reject old webhooks
}
Step 3: Create the Signature String Combine the timestamp and raw payload to create the string that was signed:
const stringToSign = `${timestamp}.${rawPayload}`;
Step 4: Calculate Expected Signature Using your webhook secret (copied from the detail page), calculate what the signature should be:
const expectedSignature = crypto.createHmac("sha256", webhookSecret).update(stringToSign).digest("hex");
Step 5: Compare Signatures Securely Use a constant-time comparison to prevent timing attacks:
const isValid = crypto.timingSafeEqual( Buffer.from(signature, "hex"), Buffer.from(expectedSignature, "hex") );
Important Implementation Notes
Raw Body Requirement: You must capture the raw request body (not parsed JSON) for signature verification.
Return appropriate HTTP status codes:
200 OK
must be returned to indicate success
Security Best Practices
Store your webhook secret securely (environment variables, not in code)
Always verify signatures before processing webhook data
Use HTTPS for your webhook URLs to encrypt data in transit
Troubleshooting
Common Issues:
Invalid signatures: Ensure you're using the raw request body, not parsed JSON
Timestamp errors: Check your server's system clock is accurate
Testing Your Implementation: Use the webhook detail page in Sign Customiser to monitor incoming requests and verify your endpoint is responding correctly with 200 OK
status codes.
Next Steps
Once your webhooks are set up and verified, you can process the webhook payload data to trigger actions in your application, such as updating databases, sending notifications, or integrating with other services.