Skip to main content
Accelebit sends HTTP POST requests to your configured endpoint whenever a payment event occurs on your account. Webhooks let you react to payment completions, failures, and refunds in real time — without polling the API. Events are guaranteed to be delivered at least once, with automatic retries if your endpoint does not respond within 15 seconds.

How webhooks work

When an event occurs — such as a payment being captured or a refund being initiated — Accelebit delivers a POST request to every endpoint you have registered for that event type. Your server receives a JSON payload alongside a set of verification headers. You confirm receipt by returning a 2xx response within 15 seconds. Because delivery is guaranteed at least once, the same event may occasionally arrive more than once. Use the X-Webhook-Id header to deduplicate events in your handler.

Setting up webhooks

1

Open the Accelebit Dashboard

Go to dashboard.accelebit.com and sign in to your account.
2

Navigate to the Webhooks section

In the left sidebar, select Developers, then click Webhooks.
3

Add your endpoint URL

Click Add endpoint and enter the URL where Accelebit should send events. Your endpoint must use HTTPS in production.
4

Select the events to receive

Choose which event types your endpoint should receive. You can subscribe to individual events or all events on your account.
5

Copy your webhook signing secret

After saving the endpoint, copy the webhook signing secret. You will use this to verify that incoming requests originate from Accelebit.

Webhook payload structure

Every webhook request includes the following HTTP headers:
HeaderDescription
Content-TypeAlways application/json
X-Webhook-SignatureHMAC-SHA256 signature of the raw request body
X-Webhook-IdUnique delivery identifier, used for deduplication
X-Webhook-TimestampISO 8601 timestamp of when Accelebit dispatched the event
The request body uses this structure:
{
  "event": "payment.captured",
  "data": {
    "transactionId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "merchantId": "merchant_abc123",
    "providerId": "everest",
    "status": "captured",
    "amount": 5500,
    "currency": "EUR"
  },
  "timestamp": "2026-04-09T12:01:01.000Z"
}
Webhook amounts are in minor units (cents). An amount of 5500 in EUR represents 55.00 EUR. This differs from the REST API, which expresses amounts as decimal strings.

Verifying signatures

Always verify the X-Webhook-Signature header before processing any webhook payload. This confirms the request originated from Accelebit and that the body has not been tampered with in transit. Compute an HMAC-SHA256 digest of the raw request body using your webhook signing secret, then compare the result to the value in X-Webhook-Signature. Use a constant-time comparison to prevent timing attacks.
import crypto from 'node:crypto';

function verifyWebhookSignature(
  body: string,
  signature: string,
  secret: string
): boolean {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// In your webhook handler:
app.post('/webhooks/accelebit', (req, res) => {
  const signature = req.headers['x-webhook-signature'] as string;
  const rawBody = req.body; // Must be the raw string, not parsed JSON

  if (!verifyWebhookSignature(rawBody, signature, process.env.WEBHOOK_SECRET!)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  const event = JSON.parse(rawBody);
  // Process the event...

  res.status(200).json({ received: true });
});

Responding to webhooks

Your endpoint must return a 2xx status code within 15 seconds of receiving a webhook request. If Accelebit does not receive a 2xx response within that window — whether due to a timeout, a network error, or a non-2xx status — the delivery is considered failed and will be retried.
Process webhooks asynchronously. Return 200 immediately, then handle your business logic in a background job or queue. Long-running synchronous processing risks exceeding the 15-second timeout, causing unnecessary retries.

Retry behavior

When a delivery fails, Accelebit retries it with exponential backoff across up to seven attempts:
AttemptDelay
1Immediate
21 minute
35 minutes
430 minutes
52 hours
612 hours
724 hours
After seven failed attempts, the delivery is marked as permanently failed. You can manually trigger a retry for any failed delivery from the Webhooks section of the Dashboard.

Idempotency

Because webhooks are delivered at least once, your handler must be idempotent — processing the same event twice should produce no unintended side effects. Use the X-Webhook-Id header to detect and skip duplicate deliveries:
const processedWebhooks = new Set<string>();

app.post('/webhooks/accelebit', (req, res) => {
  const webhookId = req.headers['x-webhook-id'] as string;

  if (processedWebhooks.has(webhookId)) {
    return res.status(200).json({ received: true }); // Already processed
  }

  // Process the event...
  processedWebhooks.add(webhookId);

  res.status(200).json({ received: true });
});
In production, store processed webhook IDs in your database or Redis rather than in memory. An in-memory set is lost on every process restart, which would allow duplicates to slip through after a deployment or crash.

Best practices

  • Always verify signatures before trusting or acting on any webhook payload.
  • Return 200 immediately and move business logic to a background job to avoid timeouts.
  • Deduplicate using X-Webhook-Id and persist the ID store across process restarts.
  • Use HTTPS for your webhook endpoint in production environments.
  • Do not rely solely on webhooks for critical flows. Before fulfilling an order, confirm payment status directly via GET /v1/payments/:id.
  • Log webhook payloads to support debugging and payment reconciliation.