A reliable delivery promise is a versioned checkout decision, not a sentence generated from the current date. Salla's Merchant API exposes delivery-promise configuration for location, delivery time, preparation time, visibility hours, working days, holidays and translations. A production integration should resolve those inputs in the store's timezone, preserve the exact promise shown to the buyer on the order, and measure the result against later fulfillment events. That separation keeps a policy change tomorrow from rewriting what the customer was told today.
This is a practical engineering guide based on Salla's official documentation, verified on 5 October 2026. It is not a claim about a new product release. The versioning, snapshot, observability and rollout patterns below are application architecture recommendations; Salla's documentation defines the API fields and access scopes.
Start with the platform contract
The List Delivery Promises endpoint returns configured promises with an activation status, type, location and a delivery-time range. Its documented examples include express, same-day, next-day, standard and international configurations. The list uses the `shipping.read` scope and is useful for discovery, but it is not the complete policy.
The Delivery Promise Details endpoint returns the fuller configuration: country, region and cities; delivery and preparation ranges; visibility hours; working days; holidays; and translations. The documented holiday object can carry a date, annual-repeat flag and title. This is the source shape a control plane should capture before calculating or changing a promise.
The Update Delivery Promise endpoint uses `shipping.read_write`. Its example includes `visible.adjust_by_preparation`, working-day values, holidays, status and location. Treat the update as a policy deployment with validation and audit, not as a casual settings patch.
Separate policy, checkout decision and shipment truth
Keep three records. The policy is the current Salla configuration plus your normalized timezone and validation metadata. The checkout decision is the resolved promise presented for a specific cart, address and instant. Shipment truth is the later sequence of preparation, handoff, carrier and delivery events. They answer different questions.
A promise such as “2–4 hours” is a configured range. It is not proof that a carrier accepted the parcel, and it is not a live tracking estimate. Conversely, a late carrier scan should not silently change the historical statement shown at checkout. The storefront may display a new operational estimate later, but it should label that as tracking or an updated estimate and preserve the original promise for audit.
Model the checkout snapshot with `promise_id`, `policy_version`, `evaluated_at`, `store_timezone`, `location_key`, `preparation_range`, `delivery_range`, `window_start`, `window_end`, `display_locale` and the rendered copy or a deterministic template version. Attach the snapshot to the cart decision and persist it with the created order.
Resolve time with a business calendar
Calendar arithmetic is the center of the design. Convert the checkout instant into the store timezone before evaluating the visibility window. Determine whether the current local day is a working day, whether it is an explicit holiday and whether the request falls before the cutoff. Then add preparation and delivery ranges over business time, not raw elapsed hours.
Do not add 48 hours to a Thursday afternoon and call the result two business days. Advance through the configured working days, skip holidays and define what happens when a cutoff is crossed. The update contract exposes preparation adjustment inside visibility rules; implement its meaning exactly as documented and verified for the store rather than inventing another hidden offset.
Keep the calendar deterministic. Given the same policy version, location, instant and locale, it should return the same window. Tests should cover daylight-saving transitions even if the main Saudi timezone does not use them, because international promises can involve other locations. Also test a holiday after cutoff, a yearly holiday, a zero-length preparation range, an inactive promise and a window that crosses midnight.
type PromiseInput = {
now: Date;
storeTimeZone: string;
countryId: number;
regionId?: number;
cityId?: number;
policyVersion: string;
};
const decision = resolveDeliveryPromise(input, policySnapshot);
await saveCheckoutPromise({
cartId,
promiseId: decision.promiseId,
policyVersion: input.policyVersion,
evaluatedAt: input.now.toISOString(),
windowStart: decision.windowStart,
windowEnd: decision.windowEnd,
locale,
renderedLabel: decision.label
});This sketch is intentionally provider-neutral. Read the actual Salla response, validate its units and IDs, and avoid copying example identifiers into production.
Make location matching explicit
Salla's documented promise payload can target country, region and cities, while the Shipping Zones API manages custom shipping zones. Normalize the address only after the platform has resolved stable location IDs. Free-form city names, Arabic spelling variants and translated labels are display data, not durable matching keys.
Use a specificity order you can explain: an exact city rule before a region rule before a country-wide rule, then a documented fallback. Reject ambiguous equal-priority matches during configuration. If no promise applies, display a conservative message or omit the promise; do not borrow the nearest city's fast window.
Store the matched location IDs in the checkout snapshot. That makes support questions answerable when a merchant later moves a city between zones or changes a broad all-cities configuration. It also lets analytics distinguish a calendar miss from incorrect address classification.
Keep shipping routes adjacent but not identical
Salla's Shipping Routes List documents route type, status, priority, combination strategy and whether a route is combinable. The documentation says routes control how shipping options appear at checkout. A route therefore affects availability and presentation, but it should not become an undocumented substitute for the delivery-promise policy.
Resolve eligible routes first, then resolve a promise that is valid for the selected location and service. Persist the chosen route or service identity beside the promise snapshot when the integration can observe it. If a carrier becomes unavailable, remove or downgrade the option through the platform's supported configuration instead of leaving a fast promise attached to a route that cannot execute it.
Do not infer a carrier SLA from route priority. Priority and combination strategy describe checkout selection behavior; delivery accuracy needs evidence from shipments. Keep configuration reads cached for a short bounded period, but invalidate them after your application updates a promise or route.
Publish configuration as a versioned change
Fetch the current detail, normalize it and compute a canonical digest. Validate location references, range order, time units, working-day coverage, holiday dates, translations and the relationship between preparation time and visibility. Show the merchant a semantic diff: “same-day disabled in Jeddah after 15:00; one annual holiday added; standard delivery unchanged.”
Write with the minimum required scope and record the actor, prior digest, proposed digest, reason and response. Read the detail again after the update and compare the observed state with the intended state. A successful HTTP response is not the same as a verified policy. If another operator changed the promise between review and write, stop and regenerate the diff.
Never update all stores from one unbounded loop. Queue per tenant, respect Salla's current rate-limit contract and preserve the last verified snapshot. A failed store must not block other merchants, and a retry must compare current state before sending the same write again.
Preserve promises across order creation
A cart can be evaluated minutes before payment and order creation. Decide how long the checkout snapshot remains valid. If the buyer changes the address, shipping method or material cart contents, recalculate. If only payment processing is slow, keep the displayed promise for a bounded hold period or ask the buyer to confirm a changed window; do not switch dates invisibly after they submit.
Persist both machine fields and customer-facing evidence. The deterministic fields support analytics and replay; the rendered label proves what the buyer saw in their language. If the platform order does not have a dedicated field for your snapshot, keep it in your application's order projection keyed by store and source order ID. Do not place private operational metadata in customer-visible notes.
Webhooks can signal order and shipment changes, but they should not recompute the original checkout promise. Use them to update fulfillment truth and to trigger reconciliation. The Salla shipment state-machine guide covers idempotent transition handling; the Salla and Zid webhook recovery guide covers gaps and duplicates.
Measure promise accuracy, not just delivery speed
The primary metric is not average delivery duration. Measure the share of eligible orders delivered within the promised window, early, late or still unresolved. Segment by promise type, city, route or carrier, warehouse, weekday and policy version. Exclude cancellations and customer-requested holds with explicit reason codes rather than deleting them from the dataset.
Track decision failures too: no matching promise, ambiguous location, inactive configuration, stale policy cache, invalid calendar and missing shipment evidence. Alert on a rise in late rate or unresolved age, but keep merchant IDs out of unbounded metric labels. Use an access-controlled trace or audit query for a single order.
Close the loop carefully. Historical accuracy may justify widening a future window, but do not let a noisy batch automatically rewrite merchant policy. Produce a recommendation with sample size, confidence and affected segment; require review; deploy a version; then compare the new cohort.
Know when not to show a precise promise
Do not offer an hour-level commitment when inventory location is unresolved, the product is made to order, the address maps ambiguously, the route has no executable carrier, or the fulfillment data is too sparse to support it. A conservative range is better than false precision. International orders may also need customs language rather than a narrow arrival date.
This architecture is useful when a merchant has location-specific delivery products, cutoffs or multiple fulfillment paths. It may be excessive for a small store that publishes one broad manual estimate and has no system acting on the promise. Even then, the distinction between the original statement and later tracking remains valuable.
The production invariant is simple: one policy version resolves one explainable promise for a cart; that promise is frozen with the order; later events update fulfillment truth without rewriting history; and measured outcomes inform reviewed changes. Salla provides the policy endpoints. The integration's job is to make their use deterministic, auditable and honest. For implementation support, see Salla and Zid integration engineering.
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
Working through a similar engineering challenge?
I help teams turn architecture decisions into a clear scope and dependable, reviewable implementation.




