DecisaDocs

Docs · Integrations

Connect a checkout platform.

Each integration ships its own webhook receiver and canonical mapper. HMAC signature verification is mandatory on every webhook route no exceptions.

HMAC verification, always

Every webhook request must pass HMAC signature verification before Decisa writes anything to the database. We don't accept the trade-off of "just disable it during setup" — a bad webhook secret will return 401 every time, and the diagnostic message tells you which header to check.

The shared secret lives in your workspace settings under Integrations → [provider] → Webhook secret. Rotate it any time; the receiver accepts the previous secret for 5 minutes after rotation so in-flight requests survive the cutover.

Replay safety

All providers retry. We assume duplicate delivery is the default. Idempotency is enforced at two layers:

  • raw_payload uniqueness on (workspace_id, provider, event_id) — the same webhook can't create two raw rows.
  • Canonical conversion uniqueness on (workspace_id, external_id) — mapping different raw payloads to the same business event never creates duplicates downstream.

Supported providers

Shopify

Generally available

POST /api/webhooks/shopify

  • orders/create
  • orders/paid
  • orders/refunded

Set the webhook in Shopify Admin → Settings → Notifications. Decisa derives external_id from order id and visitor_id from the order note attribute dcs_vid (auto-populated by the pixel on checkout).

Stripe

Generally available

POST /api/webhooks/stripe

  • checkout.session.completed
  • invoice.paid
  • customer.subscription.created

Configure a webhook endpoint in Stripe Dashboard → Developers → Webhooks. Visitor stitching uses the metadata.dcs_vid field — set it from the client during checkout creation.

Kiwify

Beta

POST /api/webhooks/kiwify

  • order.approved
  • subscription.renewed
  • order.refunded

Add the webhook URL in Kiwify → Settings → Webhooks. visitor_id is parsed from the offer URL query parameter ?_v=… that the pixel appends to outbound checkout links.

Custom backend

Always available

POST /v1/conversions

  • Any conversion type

When no canonical webhook covers your platform, call /v1/conversions directly from your backend. See the API reference for the full payload contract.

What we deliberately have not abstracted

There is no universal "checkout adapter" interface in the codebase. Each provider lives in its own namespace (App\Integrations\Checkout\Shopify, etc.) with its own mapper, its own raw payload schema, and its own HMAC verification logic. We will not extract a shared adapter until three independent providers have shipped and the patterns are obvious.

This is intentional. Premature abstraction is the most expensive mistake in integration code once you've generalized the wrong shape, every new provider becomes a puzzle.

Need a provider we haven't shipped? Email [email protected] with a sample webhook payload we typically ship in under a week. Or use the generic /v1/conversions endpoint from your backend today.