Webhooks

Conversions enter Argus Grape exclusively through signed, idempotent webhooks — no client-side pixels, nothing a browser extension can block or forge.

Internal webhook (Zylior)

For your own checkout or back-office, post the conversion to the internal endpoint:

request
POST {API_URL}/webhooks/zylior
Content-Type: application/json
x-zylior-signature: <hex HMAC-SHA256 of the raw body, keyed with ZYLIOR_WEBHOOK_SECRET>

{
  "event_id":     "evt_2026_000042",
  "argus_cid":    "4f1d2e3c8a9b4c5d6e7f8091a2b3c4d5",
  "amount_cents": 4900
}
FieldDescription
event_idYour unique event identifier. Argus Grape is idempotent on it: replays and retries return the original result, nothing is double-counted.
argus_cidThe click id captured from the tracking-link redirect.
amount_centsOrder amount in cents (USD). Commission is computed from it.

The x-zylior-signature header is the hex HMAC-SHA256 of the raw request body, keyed with ZYLIOR_WEBHOOK_SECRET. In development, verification is skipped when the secret is unset. If the argus_cid belongs to a shadow-banned click, the conversion is recorded and automatically rejected — no commission is ever paid on flagged traffic.

curl
BODY='{"event_id":"evt_2026_000042","argus_cid":"4f1d2e3c8a9b4c5d6e7f8091a2b3c4d5","amount_cents":4900}'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$ZYLIOR_WEBHOOK_SECRET" -hex | sed 's/^.* //')

curl -X POST http://localhost:3001/webhooks/zylior \
  -H "Content-Type: application/json" \
  -H "x-zylior-signature: $SIG" \
  -d "$BODY"

Stripe webhook

Point a Stripe webhook endpoint at POST /webhooks/stripe. Argus Grape listens to checkout.session.completed and payment_intent.succeeded, reads the click id from metadata.argus_cid (falling back to client_reference_id) and the amount from amount_total.

The Stripe-Signature header (t=…,v1=… scheme) is verified against STRIPE_WEBHOOK_SECRET with a 5-minute timestamp tolerance — replayed or stale events are refused.

curl
BODY='{"type":"checkout.session.completed","data":{"object":{"metadata":{"argus_cid":"4f1d2e3c8a9b4c5d6e7f8091a2b3c4d5"},"amount_total":4900}}}'
T=$(date +%s)
V1=$(printf '%s.%s' "$T" "$BODY" | openssl dgst -sha256 -hmac "$STRIPE_WEBHOOK_SECRET" -hex | sed 's/^.* //')

curl -X POST http://localhost:3001/webhooks/stripe \
  -H "Content-Type: application/json" \
  -H "Stripe-Signature: t=$T,v1=$V1" \
  -d "$BODY"

What happens after acceptance

Once a conversion is accepted, Argus Grape walks the affiliate’s ltree ancestor chain in a single indexed query and splits the campaign commission across levels according to the campaign’s level split (e.g. 60 / 25 / 15). Stats, contest points and leaderboards update immediately.