Saudi commerce · Salla · Webhook architecture

Salla conditional webhooks: filter events without losing control

A production guide to filtering Salla events at the source while preserving security, idempotency, audit evidence and authoritative recovery.

TOPIC HUBE-commerce Engineering
A high-speed letter sorting machine, used as a visual metaphor for Salla conditional webhooks filtering event streams into selected routes.
P

Salla conditional webhooks let an integration receive only events that satisfy a documented rule, such as an order total threshold, a payment method, a branch, a coupon code or a product attribute. They can reduce queue pressure and unnecessary processing, but they must not become the only record of store state. A production design should treat the rule as a versioned control-plane policy, verify every delivery, persist accepted events before acknowledging them, deduplicate retries, and reconcile critical entities against Salla's authoritative APIs.

This is a practical engineering explainer, not a product announcement. The supported rule fields, operators, webhook security strategies and management endpoints are documented by Salla; the versioning, inbox, rollout, reconciliation and observability model below is an engineering design derived from those contracts. Documentation was checked on 30 October 2026.

Answer first

Use conditional webhooks when a downstream workflow genuinely needs a stable subset of events. Keep the filter narrow, explicit and reviewable. Do not use it to replace authorization, to encode an entire business process, or to prove that nothing happened outside the filter.

A safe production path is:

Salla event -> server-side rule -> signed webhook -> durable inbox
            -> idempotent worker -> domain projection -> downstream action

Salla API -> bounded reconciliation --------------------^ 

The webhook path gives low latency. Reconciliation detects rule drift, missed deliveries, schema changes and operational mistakes. Both paths should converge on the same idempotent domain update.

What Salla documents

Salla's conditional webhook guide describes rules that filter supported events by documented attributes. Examples include an order rule such as total > 100, a special-offer rule using OR, and a customer rule combining city and location with AND. The guide lists supported order attributes including IDs, totals, branch, coupon, payment method, shipment information and currency. It separately lists attributes for products, customers, offers, categories, brands, carts and reviews.

The webhook overview documents fields such as event, version, rule, url, headers, security strategy and secret. It says new registrations default to webhook version 2 and to the Signature strategy when no security strategy is supplied. The same page documents Signature and Token strategies and warns that a failed delivery may be retried three times at roughly five-minute intervals.

Salla also exposes management endpoints to register, update, list active webhooks, list supported events and deactivate a webhook. These endpoints form a control plane. They are not a substitute for a durable data plane that processes deliveries.

Decide whether to filter at the source

SituationRecommended subscriptionReason
ERP needs every order state transitionUnfiltered critical event setMissing an event can break the ledger or fulfilment state
A high-value-order alert only needs orders above a stable thresholdConditional webhookThe excluded events are intentionally irrelevant to this workflow
A payment service routes only one documented payment methodConditional webhook plus payment reconciliationThe rule reduces traffic while reconciliation protects money state
Analytics may change its segment definition frequentlyBroad event ingestion, filter downstreamHistorical reclassification is impossible if excluded events were never received
A fraud rule changes rapidly or uses many signalsFilter downstreamComplex policy belongs in a tested decision service, not a webhook string
A merchant-specific automation depends on one branchConditional webhook plus configuration auditBranch identity is stable enough, but policy drift must remain visible

The key question is not whether filtering saves requests. Ask whether an excluded event could later be required for money, inventory, fulfilment, customer rights, audit or model retraining. If yes, keep the authoritative stream broader or maintain an independent recovery path.

Original engineering diagram: a Salla event passes through a versioned rule, signature verification, durable inbox and idempotent worker, while authoritative reconciliation detects gaps. Cover photo by Mike Peel, CC BY-SA 2.0 UK via Wikimedia Commons; resized or cropped for responsive delivery.
Original engineering diagram: a Salla event passes through a versioned rule, signature verification, durable inbox and idempotent worker, while authoritative reconciliation detects gaps. Cover photo by Mike Peel, CC BY-SA 2.0 UK via Wikimedia Commons; resized or cropped for responsive delivery. Open for a larger view

Model rules as versioned policy

Store desired webhook configuration in your own control-plane table rather than editing registrations ad hoc:

{
  "merchant_id": "m_123",
  "event": "order.created",
  "rule": "total > 100 AND branch_id = 827301",
  "webhook_version": 2,
  "destination": "https://events.example.com/salla/v3",
  "security_strategy": "signature",
  "policy_version": 7,
  "status": "active"
}

The example uses attributes and operators shown by Salla, but every production rule must be checked against the current attribute list for its event. Do not assume that a field present in a webhook payload is automatically valid in a rule.

For each desired registration, keep:

  • merchant and app identities;
  • exact event and webhook version;
  • normalized rule text and a configuration hash;
  • destination generation and secret identifier, never the secret value in logs;
  • remote webhook ID returned by Salla;
  • desired and observed state;
  • last successful read-back time;
  • approver, change reason and rollback target.

This makes a rule reviewable, reproducible and reversible. The configuration hash also lets a reconciler compare desired state with the result returned by List Active Webhooks without relying on human memory.

Keep business logic out of the rule string

A webhook rule is a routing predicate. It should answer a small question: should this event enter this workflow? It should not calculate refunds, allocate stock, decide fraud outcomes or manage a multi-step order lifecycle.

Good rule candidates have stable documented fields, simple comparisons and a clear owner. Examples are a fixed branch ID, a documented payment method, or a high-value threshold owned by operations. Poor candidates combine frequently changing thresholds, customer scoring, external data and exceptions. Put those in an application service with tests, versioned inputs and explainable decisions.

When AND and OR appear together, do not guess precedence. Split the policy into separate subscriptions or verify the exact expression in a non-production store. A shorter rule is easier to audit than a clever one.

Verify before parsing or acting

Treat the public webhook endpoint as an untrusted Internet boundary.

  1. Enforce HTTPS and a strict request-size limit.
  2. Read the security-strategy header and reject unexpected strategies.
  3. Verify the Salla signature or token using the configured secret and a constant-time comparison.
  4. Preserve the exact request bytes if the framework can reserialize JSON differently before verification.
  5. Parse JSON only after authenticity checks pass.
  6. Validate the event name, merchant identity, required data fields and expected schema version.
  7. Record an immutable inbox row and commit it.
  8. Return a successful response quickly; perform domain work asynchronously.

Salla's guide presents signature verification with X-Salla-Signature and a shared secret. Your implementation should follow the current contract and test it with real signed fixtures from an isolated store. Never accept security_strategy: none in production merely because the field exists.

Design the durable inbox for retries

The documented retry behavior means duplicates are normal, not exceptional. Generate an idempotency key from the most stable identifiers available for that event. If no platform delivery ID exists, use a reviewed composite such as merchant, event, entity ID, source timestamp and a canonical payload hash. Store the original payload digest and processing result.

insert into webhook_inbox
  (provider, merchant_id, event_name, entity_id, payload_hash, received_at, body)
values
  ('salla', :merchant, :event, :entity, :hash, now(), :body)
on conflict (provider, merchant_id, event_name, entity_id, payload_hash)
do nothing;

The uniqueness constraint prevents repeated effects. The worker should also make downstream writes idempotent: use an order projection version, an outbox command key, or a compare-and-set transition instead of assuming that the inbox alone protects every dependency.

Return 2xx only after the inbox transaction commits. Returning success before durable storage creates silent loss. Performing slow ERP, email, shipping or payment calls before responding increases retries and couples endpoint availability to every downstream service.

Reconcile what the filter cannot prove

Conditional webhooks tell you which matching events arrived. They cannot prove that no nonmatching event was relevant, that the rule is still installed, or that every matching delivery reached you.

Run two reconciliation loops:

### Control-plane reconciliation

Periodically list active webhooks and compare remote event, rule, version, destination and security strategy with desired state. Alert on missing registrations, unexpected destinations, weakened security, disabled hooks, duplicate subscriptions and configuration drift. Do not repair automatically until the diff is classified; a blind repair loop can overwrite an emergency change.

### Data-plane reconciliation

For critical orders, payments, refunds, shipments and inventory, query the authoritative resource API in bounded time windows. Upsert through the same domain function used by webhook workers. Move the checkpoint only after every page commits, and overlap windows slightly to tolerate clock differences and late updates. The webhook optimizes latency; the API establishes completeness.

This is especially important when a threshold changes. Lowering total > 100 to total > 50 does not replay older orders between 50 and 100. A bounded backfill must fill that newly included range if the business requires it.

Roll out a rule change without a blind spot

  1. Export the current active registration and store its configuration hash.
  2. Validate the proposed event, attributes and operators against current Salla documentation.
  3. Test positive, negative and boundary cases in an isolated merchant store.
  4. Deploy endpoint code that can accept both old and new policy generations.
  5. Update the remote webhook through the documented API.
  6. Read back the active registration and compare every security and routing field.
  7. Run synthetic events that should match and should not match.
  8. Start a bounded authoritative backfill for the transition interval.
  9. Watch ingest volume, duplicates, signature failures, processing lag and reconciliation differences.
  10. Close the old policy generation only after the new path and backfill are proven.

If you use two overlapping subscriptions during migration, expect duplicate deliveries and ensure the idempotency key spans both subscription IDs. Never assume that a successful update response proves that traffic is reaching the intended endpoint.

Observability that reveals false confidence

Measure more than HTTP 200 rates:

  • active-webhook drift by merchant and policy version;
  • signed deliveries received by event and merchant;
  • signature and schema rejection counts;
  • inbox insertions, duplicates and processing failures;
  • receive-to-commit and receive-to-effect latency;
  • queue age and dead-letter volume;
  • authoritative entities scanned during reconciliation;
  • missing, stale and conflicting projections;
  • rule-change backfill coverage;
  • downstream effects linked to inbox and outbox IDs.

You cannot directly count events that Salla excluded at the rule boundary. That is why reconciliation coverage and control-plane read-back are stronger signals than a quiet queue.

Best practices

  • Keep one clear business purpose per subscription.
  • Use the narrowest supported fields without hiding critical state.
  • Default to Signature and rotate secrets with overlapping verification windows.
  • Verify authenticity before JSON parsing and authorization before effects.
  • Persist first, acknowledge second, process asynchronously.
  • Treat retries as ordinary and make every downstream write idempotent.
  • Keep rules and remote IDs in version-controlled configuration.
  • Reconcile both active subscriptions and authoritative business entities.
  • Test boundary values, Unicode, empty fields and merchant-specific identifiers.
  • Minimize personal data in logs and rule-change evidence.

Anti-patterns and limits

  • Using a conditional rule as an authorization boundary.
  • Assuming every payload field is valid in a rule.
  • Mixing AND and OR without testing precedence.
  • Returning 2xx before durable storage.
  • Sending email, ERP or shipping requests inside the webhook transaction.
  • Treating no incoming events as proof that no matching activity occurred.
  • Changing a threshold without backfilling the newly included range.
  • Logging secrets, signatures or full customer payloads.
  • Automatically repairing every control-plane difference.
  • Filtering financial or inventory history so aggressively that audit reconstruction becomes impossible.

Conditional webhooks intentionally discard visibility outside the predicate. They reduce transport and compute, not the need for reconciliation, evidence or incident recovery. They also depend on the current event and attribute contracts; verify the documentation before every policy change.

Executive checklist

  1. Confirm the workflow can safely exclude nonmatching events.
  2. Select a documented event, version and rule attribute set.
  3. Store desired configuration, hash, owner and rollback target.
  4. Verify signatures or tokens before parsing.
  5. Commit to a durable inbox before returning 2xx.
  6. Deduplicate retries and make downstream effects idempotent.
  7. Read back active registrations after every change.
  8. Reconcile critical entities through bounded API windows.
  9. Backfill whenever a rule expands its matching set.
  10. Monitor drift, lag, duplicates and reconciliation gaps.

Related reading: Salla webhook endpoint rotation, Salla order backfills, Salla and Zid order states, the E-commerce Engineering hub, and backend and API engineering services.

Primary references

Prepared by: Noor Yasser

Official references

These references document the tools discussed. Examples and design decisions are illustrative and should be adapted to the project and its versions.

Prepared by: Noor Yasser

FROM DECISION TO DELIVERY

Working through a similar engineering challenge?

I help teams turn architecture decisions into a clear scope and dependable, reviewable implementation.

Book a 30-minute callRelated serviceBackend engineering & API integrationsRelevant projectLogistics at scale