Enterprise Feature: Authorization webhooks are an enterprise-only feature. Please reach out to sales@slash.com to get set up with this functionality.

Overview

Authorization webhooks allow you to implement real-time transaction approval logic by receiving authorization requests before transactions are processed. When a card transaction is initiated, Slash will send a webhook to your configured endpoint, allowing you to approve or decline the transaction based on your custom business logic.

Setup

To begin receiving authorization webhook requests, you’ll need to configure an authorization webhook URL for your account using the account authorization webhook endpoints.

Webhook Headers

Every authorization webhook request includes three important headers for security and validation:

  • x-webhook-id: A unique identifier for the webhook request
  • x-webhook-timestamp: The timestamp when the webhook was sent (Unix timestamp)
  • x-webhook-signature: HMAC signature for request validation

Request Validation

Timestamp Validation

The x-webhook-timestamp should be within 2 minutes of receiving the request to prevent replay attacks.

Signature Validation

To verify that the webhook request actually came from Slash, you should validate the x-webhook-signature header using HMAC SHA256. The signature is created by:

  1. Removing the whsec_ prefix from your signing secret and base64 decoding it
  2. Creating a payload string: {webhookId}.{webhookTimestamp}.{requestBody}
  3. Generating an HMAC SHA256 signature using the decoded secret
  4. Base64 encoding the signature and prefixing with v1=

Here’s a complete example of signature validation:

import crypto from 'crypto';

function validateWebhookSignature(webhookId, webhookTimestamp, signature, body, signingSecret) {
  // Remove whsec_ prefix from signing secret if present
  const secretBase64 = signingSecret.replace('whsec_', '');
  
  // Decode the base64 secret to get the actual signing key
  const decodedSecret = Buffer.from(secretBase64, 'base64');
  
  // Create the payload to sign: webhookId.webhookTimestamp.body
  const payload = `${webhookId}.${webhookTimestamp}.${body}`;
  
  // Generate HMAC SHA256 signature using the decoded secret
  const expectedSignature = crypto
    .createHmac('sha256', decodedSecret)
    .update(payload)
    .digest('base64');
  
  // Extract signature from header (remove 'v1=' prefix)
  const receivedSignature = signature.replace('v1=', '');
  
  // Compare signatures using timing-safe comparison
  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature, 'base64'),
    Buffer.from(receivedSignature, 'base64')
  );
}

Request Timeout

Authorization webhook requests have a default timeout of 1.5 seconds. Your endpoint must respond within this timeframe, or the transaction will be automatically decisioned based on your fallbackBehavior.

Response Format

Your webhook endpoint must return a 2xx HTTP status code to indicate successful processing. Any non-2xx response will be treated as a failed request.

The response body must contain your authorization decision. See the Authorization Webhook Response schema for the complete response format.

Example approval response:

{
  "approved": true,
  "reason": "Transaction approved"
}

Example decline response:

{
  "approved": false,
  "reason": "Insufficient funds"
}

Event Schema

The webhook request body contains detailed information about the authorization request. See the Authorization Request Event schema for the complete structure of the event data sent to your webhook.

Debugging and Monitoring

When debugging your authorization webhook behavior, you can view the approval or decline reason directly in the transaction details. This helps you understand how your webhook responses are being processed and troubleshoot any issues.

Error Handling

If your webhook endpoint is unreachable, returns a non-2xx status code, or times out, the transaction will be automatically handled based on your fallbackBehavior.

  • default: Your transaction will continue to go through our authorization flow, and will be treated as if you approved it.
  • reject: Your transaction will be declined.