Skip to main content

Webhooks

CodeSpar's webhooks are called Triggers: signed HTTP callbacks (X-CodeSpar-Signature, HMAC-SHA256) delivered when payments settle, fail, or refund. This page maps the name you searched for to the primitive.

1 min read
View MarkdownEdit on GitHub

Webhooks

You searched for webhooks; in CodeSpar the primitive is called a Trigger. Same thing, one difference in shape: instead of wiring one webhook per payment provider, you register one endpoint and CodeSpar normalizes every provider's callback into a single signed envelope, with one signing secret, one retry policy, and one dead-letter queue.

The 60-second version

  1. Create a trigger with POST /v1/triggers, naming the event and your HTTPS endpoint. The response carries the signing secret exactly once.
  2. An event settles on any provider connection in your project: commerce.payment.succeeded, commerce.payment.failed, commerce.payment.refunded, commerce.payment.pending, commerce.payment.updated, commerce.payment.disputed.
  3. CodeSpar signs and delivers: X-CodeSpar-Signature: t=<unix>,v1=<hex> where v1 = HMAC-SHA256(secret, "<timestamp>.<raw body>").
  4. Your endpoint answers 2xx within 10 seconds; anything else is retried, and after the fifth failure the delivery lands in the trigger's DLQ for inspection or redelivery.

Verifying the signature

import { createHmac, timingSafeEqual } from "node:crypto";

function verify(rawBody: string, header: string, secret: string): boolean {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const expected = createHmac("sha256", secret)
    .update(`${parts.t}.${rawBody}`)
    .digest("hex");
  return timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}

Reject deliveries whose timestamp is outside your tolerance window before comparing, and always verify against the raw request body, not a re-serialized parse.

Push or pull: pick per flow

You needUse
"Tell my backend the moment a Pix charge settles"A trigger on commerce.payment.succeeded
A synchronous answer inside an agent conversationsession.execute and read the result
A status check on one payment you just createdpaymentStatus / paymentStatusStream in the SDK

Payment confirmation does not require polling: triggers are the push path, and they are the right primitive for billing flows that react to settlement.

  • Triggers: the full object, event catalog, retries, DLQ, secret rotation.
  • Webhook Listener cookbook: a deterministic loop that issues the NF-e, creates shipping, and sends the WhatsApp message on commerce.payment.succeeded.
  • Refunds: the outbound half, and the commerce.payment.refunded event.
Webhooks | CodeSpar