HOCO B2B
SRS

Business rules

Numbered rules BR-01 to BR-86 grouped like cahier §8, with source, tuning setting, default and worked examples, followed by the catalogue of every business setting.

Cahier §8 lists the cross-cutting rules in nine families — identifiers, prices, stock, orders, credit, loyalty, attribution, GPS, notifications — and leaves most values to be validated. This page turns each family into numbered, testable rules, adds the families the other sections imply (catalog visibility, promotions, assisted orders, account validation, after-sales and support, data retention), and ends with the settings catalogue: every value HOCO can tune from BO-64 without a code change.

How to read a rule: the statement is binding; Source traces it; Setting names the key that tunes it and its default; Example shows it with numbers. Amounts are integer centimes of DZD (125000 = 1 250,00 DA) and rates are basis points (1900 = 19 %), as on the API reference. Where a value is still an open question, the rule gives the default the team builds with and the decision id of the decision register.

Product decisions of 17 October 2026

Three prices per variant selected by the reseller's customer type (no segment price lists, no quantity tiers in V1); prices hidden from guests; stock shown to resellers only as En stock / En rupture; no automatic order confirmation; automatic restock on cancellation and return reception; returns, credit notes and after-sales claims in V1; regional WhatsApp support. The rules below apply them.

Identifiers

BR-01 — Technical identifiers

Every record has a UUIDv7 id. The delegate app generates the id of records it can create offline (prospects, unplanned visits, visit photos, visit reports, notes); the server upserts on it, so a replay never duplicates. Technical ids never appear to users — screens, documents, SMS and support conversations use business numbers.

  • Source: cahier §7.3 (« doublons »), §8 Identifiants.
  • Example: a prospect created at 10:02 offline and replayed three times by sync.batch exists once; the second and third replays answer REPLAYED.

BR-02 — Business numbers

Each business document gets a unique, human-readable number from a per-type sequence (NumberSequence), allocated in the same transaction as the business event, so a rolled-back transaction leaves no gap and a number is never reused, even after a cancellation.

EntityFormatAllocated whenYearly reset
ResellerREV-000123Record createdNo
OrderCMD-2026-000158Submission (assisted and back-office drafts have none)Yes
InvoiceFAC-2026-000123Invoice issuedYes
Delivery noteBL-2026-000123Order READYYes
PaymentPAY-2026-000077Payment recorded or declaredYes
Credit noteAV-2026-000012 (proposed)Credit note issuedYes
TourTRN-2026-000045Tour plannedYes
VisitVIS-2026-001234Visit planned, or unplanned visit received by the serverYes
TicketTKT-2026-000045Ticket or claim openedYes
ReturnRET-2026-000012Return request createdYes
  • Source: cahier §8 Identifiants (« Numéros uniques pour revendeurs, commandes, factures, tournées, visites, tickets et retours »), ADM-04.
  • Setting: numbering.<type>.prefix and numbering.<type>.padding (default 6 digits). The year is the Africa/Algiers year of the event; the counter restarts at 1 on 1 January. Beyond 999 999 the number grows to 7 digits, it never wraps.
  • Example: the first invoice issued at 00:10 on 1 January 2027 (Algiers time — 23:10 UTC on 31 December) is FAC-2027-000001.

BR-03 — Invitation codes

An invitation code is 8 characters from A–Z without I, L, O, plus 0–9 (33 symbols, about 1.4 × 10¹² combinations), displayed AB12-CD34, linked as https://app.hoco.dz/i/AB12CD34. Input is normalised: upper-cased, spaces and dashes removed, O read as 0, I and L read as 1. A code is valid invitations.validityDays (default 30); a reseller has one active invitation at a time. Resolving codes is rate-limited (30 per minute per IP) to prevent enumeration.

  • Source: cahier §6.6 (« Le lien doit être unique et sécurisé »), IVT-01.
  • Example: a reseller types ab12 cd3a; the server normalises to AB12CD3A and resolves it, or answers valid: false when expired.

BR-04 — Phone normalisation and uniqueness

Phones are stored in E.164. Accepted inputs: 0555 12 34 56, 0555.12.34.56, +213 555 12 34 56, 00213555123456, 213555123456, +213 (0) 555…. The main reseller phone must be an Algerian mobile number (national number of 9 digits starting with 5, 6 or 7) because it receives OTPs. It is unique across all reseller records, whatever their status (including NOT_INTERESTED and disabled accounts). The duplicate answer depends on the caller: the back-office sees the existing record; a delegate sees the record only when it is in their scope, otherwise « Ce numéro est déjà enregistré — contactez le back-office » with the number masked (05•• •• •• 56); a self sign-up is routed to the claim flow (BR-78).

  • Source: cahier §4.2 and §6.5 (« Le téléphone principal doit être unique »), §12 (« sans doublon »), CRM-03.
  • Example: 0661 23 45 67 and +213661234567 are the same number: the second creation answers 409 PHONE_ALREADY_EXISTS.

BR-05 — Duplicate hints beyond the phone

At validation the queue shows non-blocking hints: same normalised store name in the same commune, another point of sale within 30 m (GPS), same WhatsApp number, same legal identifier (RC or NIF). The validator decides; historical duplicates are merged with the V2 merge tool (CRM-13).

  • Source: cahier §4.2, §12 (« La fiche créée sur le terrain apparaît dans le CRM sans doublon »).
  • Example: « Épicerie El Wafa » in Oran centre and « EPICERIE EL-WAFA » 18 m away are flagged as a probable duplicate.

Prices

BR-06 — Price data per variant

Every ProductVariant carries three selling prices HT, one per customer type — priceSuperGros, priceDemiGros, priceDetail — plus the VAT rate (default pricing.defaultVatRate = 19 %; allowed 0 %, 9 %, 19 %), the recommended retail price TTC (prix conseillé, shown to resellers) and the purchase price (restricted, BR-11). The three prices are required to publish a product. Normally super-gros ≤ demi-gros ≤ détail; the editor warns, but does not block, when the order is broken.

  • Source: cahier §4.3 (« Prix d'achat, prix revendeur, prix conseillé »), §8 Prix (« Prix défini par segment, niveau, volume ou accord spécifique »), decision of 17 Oct 2026, PRC-01.
  • Example: HOCO X37 câble 1 m — super-gros 385,00 DA, demi-gros 419,90 DA, détail 459,00 DA HT, VAT 19 %, prix conseillé 650,00 DA TTC.

BR-07 — Price resolution: customer type, then promotions

The price a reseller pays is resolved in two steps:

  1. Base unit price = the variant's price for the reseller's customerType (SUPER_GROS → priceSuperGros, DEMI_GROS → priceDemiGros, DETAIL → priceDetail).
  2. Promotions eligible for that reseller and line apply on top (BR-64 to BR-67).

There are no segment price lists and no quantity tiers in V1; per-reseller agreements and level prices are V2 (PRC-03). A guest gets no price at all (price: null); an account pending validation gets the prices of its declared type when catalog.pricesVisibleBeforeValidation is true (BR-61). A delegate preparing an assisted order sees the prices of that reseller's type.

  • Source: decision of 17 Oct 2026, cahier §5.1 (« Les prix revendeur sont calculés selon le profil »), PRC-02.
  • Example — 30 × HOCO X37 câble 1 m with an active promotion « −10 % câbles HOCO »:
Customer typeBase price HTLine HT before promotionPromotion −10 %Net HTVAT 19 %Line TTC
SUPER_GROS38 5001 155 000−115 5001 039 500197 5051 237 005 (12 370,05 DA)
DEMI_GROS41 9901 259 700−125 9701 133 730215 4091 349 139 (13 491,39 DA)
DETAIL45 9001 377 000−137 7001 239 300235 4671 474 767 (14 747,67 DA)
Guest—————price hidden, « Créez un compte pour voir les prix »

BR-08 — Rounding and totals

Amounts are integers in centimes. Discounts and VAT are computed per line, on the line amount (not on the rounded unit price), rounded half-up to the centime. Order totals are sums of line totals plus the delivery fee: subtotalHt (before discounts), discountTotal, deliveryFee (HT), vatTotal, totalTtc. The unit price shown in the app is informative; documents and payments use line totals. With pricing.displayTaxMode = TTC (default, to confirm — D-17) reseller screens show TTC; invoices always show HT, VAT per rate and TTC (PRC-04).

  • Source: cahier §4.7, reference screen 5 (« Total TTC »), PRC-04.
  • Example (demi-gros line of BR-07): VAT = 1 133 730 × 19 % = 215 408,7 → 215 409. Unit net HT = 37 791; unit TTC shown = 37 791 × 1,19 = 44 971,29 → 449,71 DA. 30 × 44 971 = 1 349 130, but the line TTC is 1 349 139: the 9-centime difference is expected and the line total wins.

BR-09 — Price history and order snapshot

Every change to one of the three prices, the purchase price, the recommended price or the VAT rate writes a PriceChange row (old, new, field, actor, time, optional reason), viewable from the product editor. At submission each OrderItem snapshots the customer type, base price, discounts, promotion ids, VAT rate and line totals; later price or type changes never alter a submitted order. A controlled modification keeps the snapshot of unchanged lines; added lines take the current price of the reseller's type.

  • Source: cahier §8 Prix (« historique des modifications »), §4.4 (« Toute modification d'une commande doit être historisée »), PRC-01, AUD-02.

BR-10 — Re-validation at cart and checkout

cart.get re-prices every line at each read (current type price, active promotions, availability) and returns issues (PRICE_CHANGED, STOCK_INSUFFICIENT, PRODUCT_UNAVAILABLE, « Offre terminée »). cart.checkout re-runs everything and compares the result with the totals the reseller confirmed; any difference refuses the checkout with 409 CART_CHANGED and the re-validated cart, so the reseller always sees the final amount before it is ordered. Tolerance: zero centime.

  • Source: cahier §5.3 (« Le système revalide prix et stock avant envoi »), PRC-05.
  • Example: a promotion ends at 18:00; the reseller taps « Valider la commande » at 18:00:20 with a total computed at 17:58 → 409 CART_CHANGED; the app shows the new total and asks again.

BR-11 — Price confidentiality

A reseller only ever receives the price of their own type: the reseller and delegate APIs never return the other two prices, the purchase price or margins. In the back-office, the purchase price and margins are returned only to holders of finance.view and written only by holders of pricing.update and finance.view (permissions matrix). Exports apply the same masking.

  • Source: cahier §5 (« Les prix et stocks doivent respecter les règles de visibilité du revendeur »), §4.7 (« Les droits d'accès aux données financières sont strictement limités »), ACL-04, PRC-05.

Stock

BR-12 — Available stock

Per variant and warehouse: available = physical − reserved. The sellable availability of a variant is the sum over warehouses flagged sellable. Available is never shown below 0 outside the back-office; it can only become negative through a recorded override (BR-15).

  • Source: cahier §8 Stock (« Stock disponible = stock physique − stock réservé »), STK-02.

BR-13 — Reservation, deduction and automatic restock

Stock moves with the order status, and comes back on its own:

EventMovementEffect
Order reaches stock.reserveOn (default VALIDATED, the back-office confirmation)RESERVATIONreserved +qty
Order reaches stock.deductOn (default SHIPPED)SHIPMENTphysical −qty, reserved −qty
Order refused, cancelled or expiredRESERVATION_RELEASE for reserved quantities, RETURN for quantities already deductedautomatic
Line modified on a reserved orderRESERVATION or RESERVATION_RELEASE for the differenceautomatic
Return received (admin.returns.receive)RETURN for accepted quantitiesautomatic

A movement fires when the order reaches or passes the status, so a pickup order that goes from READY to DELIVERED is still deducted. Allowed values: stock.reserveOn ∈ SUBMITTED, VALIDATED; stock.deductOn ∈ READY, SHIPPED, DELIVERED. See the order lifecycle.

  • Source: cahier §8 Stock, §12 (« Les quantités sont réservées ou déduites selon le statut configuré »), decision of 17 Oct 2026, STK-03. Decisions D-22 (reservation and deduction statuses) and D-02 (stock rules).
  • Example: physical 100, reserved 20 (available 80). An order of 30 is confirmed → reserved 50, available 50. It ships → physical 70, reserved 20, available 50. Later 10 units come back and 8 are accepted at reception → physical 78, available 58.

BR-14 — Stock checkpoints

MomentCheckOn failure
Add to cart, change quantityrequested quantity ≤ available422 STOCK_INSUFFICIENT — the reseller is told the item cannot be added in that quantity, without the available number
Cart readevery line still availableIssue STOCK_INSUFFICIENT on the line (blocking)
Checkoutevery line available422 STOCK_INSUFFICIENT with the lines concerned
Back-office confirmationevery line available at that momentConfirmation refused unless overridden (BR-15)
  • Source: cahier §5.2 (« La quantité ne peut dépasser le maximum autorisé ni le stock disponible »), §8 Stock (« contrôle au panier et à la validation »), PRC-05.

BR-15 — Stock override

An order may be confirmed beyond available stock only by a user holding stock.validate, with a reason. The override is written to the AuditLog (OVERRIDE), the order is flagged « Dérogation stock », available may become negative and a stock alert is raised.

  • Source: cahier §4.3 (« Une commande ne peut être validée au-delà du stock disponible sauf autorisation explicite »), STK-08.
  • Example: available 4, order line 6 → the commercial admin cannot confirm; the stock manager confirms with « Arrivage confirmé demain » → available −2, alert « Stock négatif ».

BR-16 — Availability is the only stock information outside the back-office

Resellers, guests and delegates see a single availability per variant: IN_STOCK (En stock, available > 0) or OUT_OF_STOCK (En rupture, available = 0). No quantity, no « Plus que N pièces », no availableQty field ever leaves the back-office APIs. There is no display setting. Out-of-stock products stay visible and cannot be added to the cart.

  • Source: decision of 17 Oct 2026, cahier §4.3 (« La quantité exacte peut être affichée ou masquée selon le paramétrage » — HOCO's choice: always hidden), STK-07.

BR-17 — Movement ledger

Every stock variation is a StockMovement (type, signed quantity, before and after values, reason, actor, linked order, return or inventory). The ledger is append-only: corrections are compensating movements. StockLevel is a projection updated in the same transaction.

  • Source: cahier §4.3 (« Les variations de stock doivent être journalisées »), STK-04.

BR-18 — Automatic out-of-stock and alerts

When the sellable available stock of every variant of an ACTIVE product reaches 0, the product becomes OUT_OF_STOCK; it returns to ACTIVE as soon as one variant is available again (receipt, cancellation, return). A low-stock alert fires when available crosses the variant's threshold downwards (default stock.lowThresholdDefault = 20 units, per variant and warehouse — D-02) and re-arms only after it rises back above it. Alerts go to stock managers (in-app, SSE stock.alert, stock dashboard BO-07); thresholds are never shown to resellers.

  • Source: cahier §4.1 (« ruptures et alertes de stock »), §4.3 (« seuil d'alerte »), STK-05.

BR-19 — Inventory sessions

An inventory session snapshots system quantities at opening; counts are entered per line; at validation (stock.validate) the difference counted − (snapshot + movements since opening) is posted as INVENTORY movements with the session as reason. Selling continues during the count.

  • Source: cahier §3 (« inventaires »), STK-06.

Orders

BR-20 — Minimum order amount

A checkout is refused when the cart total TTC, after discounts and before the delivery fee, is below orders.minAmount (default 10 000,00 DA — decision D-19, which may also set one minimum per customer type). The cart shows the missing amount before checkout.

  • Source: cahier §5.3 (« Le montant minimum et les quantités minimales sont contrôlés »), §8 Commande, ORD-02.
  • Example: with orders.minAmount = 1000000 (10 000,00 DA) a cart of 8 450,00 DA answers 422 ORDER_MIN_AMOUNT_NOT_MET with details: { minAmount: 1000000, currentAmount: 845000, missing: 155000 }.

BR-21 — Quantity rules

Per variant: minimum quantity (minQty, default orders.minQtyPerLine = 1), step (qtyStep, default 1 — quantities must be multiples) and maximum per order (maxQty, default orders.maxQtyPerLine = 999) — defaults of decision D-19. Variant values override the global defaults. The product page and cart stepper respect them; the server refuses others with 422 QUANTITY_NOT_ALLOWED and the nearest valid quantities.

  • Source: cahier §5.2, §5.3, §8 Commande (« Montant minimum, quantités minimales, limites et conditions configurables »), ORD-02.
  • Example: a cable sold by 10 (minQty 10, qtyStep 10): 25 is refused with details: { lower: 20, higher: 30 }.

BR-22 — One cart per reseller

Each reseller has one server-side cart shared by the app and the web (ORD-01, RWA-02). Lines of products that become unavailable stay in the cart, flagged, until removed. The cart never expires in V1. Guests have no cart.

  • Source: cahier §5.3, team decision (reseller web).

BR-23 — Checkout and order snapshot

Checkout requires an Idempotency-Key; it converts the cart into an order atomically (number, snapshot of lines, prices, promotions, customer type, address and payment method), consumes promotion caps and empties the cart. A replay returns the same order. The order appears at once in the back-office queue (cahier §5.3 « apparaît immédiatement dans le back-office »).

  • Source: cahier §5.3, §12, ORD-03.

BR-24 — Every order is confirmed by a person

No order — reseller app, web, assisted or phone — is ever confirmed automatically. It waits in SUBMITTED (or PENDING when on hold) until a user with orders.validate confirms it (admin.orders.validate) from the « Commandes à confirmer » queue (BO-41, oldest first, with the results of the automatic controls). There is no setting that changes this. A proposed alert warns validators when the oldest order of the queue waits more than orders.confirmationAlertMinutes (default 120) during working hours (job orders.staleConfirmationAlert).

  • Source: decision of 17 Oct 2026, cahier §4.4 (« Validation, modification contrôlée ou refus avec motif »), ORD-14.
  • Example: an order submitted on Friday evening (weekend) stays « Envoyée » until Sunday morning's confirmation; the reseller sees the status live and receives the push when it is confirmed.

BR-25 — Cancellation rules

The reseller can cancel their own order while it is in orders.cancelAllowedStatuses (default and maximum: SUBMITTED, PENDING — before confirmation). The back-office (orders.update) can cancel up to READY with a reason from ORDER_CANCEL_REASON; after SHIPPED the only path is a return. Cancellation puts stock back automatically (BR-13), releases promotion caps and credit exposure, and cancels an issued invoice with a full credit note.

  • Source: cahier §4.4, ORD-10, decision of 17 Oct 2026.

BR-26 — Controlled modification

The back-office may modify lines (orders.update) in SUBMITTED, PENDING, VALIDATED, and in PREPARING only to decrease or remove (picking shortage). A reason is required; controls run again; reservations and caps follow the difference; the change is stored as an OrderChange; the reseller is notified live and by push with the new totals.

  • Source: cahier §4.4 (« modification contrôlée », « Toute modification d'une commande doit être historisée »), ORD-05, ORD-06.

BR-27 — First order

The reseller's first order is their first non-draft order that does not end REFUSED or CANCELLED. It is flagged isFirstOrder at submission and attributed to: the source delegate for an assisted order; otherwise the delegate of the invitation used at sign-up; otherwise the delegate assigned at submission. If it is refused or cancelled, the flag moves to the next order. Reports count a first order when it is confirmed.

  • Source: cahier §6.7 (« La première commande est correctement attribuée au revendeur et au délégué dans les rapports »), §12, ORD-09.

BR-28 — Delivery fee

delivery.feeMode decides the fee: FREE (default, as on reference screen 5 « Offerts »), FLAT (delivery.flatFee) or PER_WILAYA (delivery.wilayaFees, by delivery-address wilaya). Above delivery.freeThreshold (TTC, before fee) delivery is free; a FREE_DELIVERY promotion also makes it free. The fee is HT and bears VAT at the standard rate (to confirm with HOCO's accountant). PICKUP orders have no fee.

  • Source: reference screen 5, DLV-06. Decision D-20 (delivery fees; carriers are D-08).
  • Example: PER_WILAYA, Oran (31) 600,00 DA HT, threshold 50 000,00 DA. A cart of 13 491,39 DA TTC pays 600,00 + 114,00 VAT → total 14 205,39 DA; a cart of 52 000,00 DA pays nothing.

BR-29 — Order documents

The delivery note is generated at READY; the invoice at billing.invoiceOn (default SHIPPED), with the legal mentions (seller's RC, NIF, NIS, AI; buyer's identifiers when known; HT, VAT per rate, TTC; stamp duty for cash payments when applicable — rule of decision D-21). An issued document is immutable; regeneration reproduces the same amounts.

  • Source: cahier §4.4 (« Génération des factures, bons de livraison et documents »), ORD-12, FIN-01.

BR-30 — Real-time status for the reseller

Every change of status or content of a reseller's order (order.status_changed, order.modified, assisted_order.awaiting_confirmation, return.status_changed) reaches the reseller live on the open app or web page through events.stream, and as a push plus an inbox notification. An app that was closed resynchronises from orders.list on reopening; the stream resumes with Last-Event-ID.

  • Source: cahier §5.4 (« Chaque changement de statut doit être daté et notifié »), §12 (« Les changements du back-office sont visibles dans l'application et notifiés »), decision of 17 Oct 2026, ORD-15, SYN-07.

BR-31 — Returns

A reseller may request a return of delivered items within returns.windowDays of delivery (default 7): per line, quantity ≤ delivered − already returned or claimed; reason and photos required. The back-office approves or rejects (orders.validate); reception at the depot (stock.update) records received and accepted quantities, re-enters accepted quantities automatically and issues a credit note for them at the order's snapshot prices. A door refusal creates a full return automatically. When every delivered unit is back, the order becomes RETURNED.

  • Source: cahier §4.4 (« annulation, retour et remboursement »), decision of 17 Oct 2026, ORD-13, FIN-08.
  • Example: 30 cables delivered on 3 Nov; on 6 Nov the reseller asks to return 10; approved; 10 received, 8 accepted → RETURN +8, credit note 8 × 37 791 HT = 302 328 + VAT 57 442 = 359 770 (3 597,70 DA); the order stays DELIVERED (partial return).

Credit and payments

BR-32 — Credit account and the CREDIT method

Each reseller has a CreditAccount: limit (default credit.defaultLimit = 0, i.e. no credit until finance sets one), payment term in days (default credit.defaultTermDays = 30) and a blocked flag. The CREDIT payment method is offered only when it is enabled (payments.enabledMethods), the limit is above 0 and the account is not blocked.

  • Source: cahier §4.7 (« Plafond de crédit, crédit disponible, échéances et blocage »), §8 Crédit, FIN-05. Decision D-04 (credit ceiling).

BR-33 — Exposure and available credit

Exposure = open balances of invoices (UNPAID, PARTIALLY_PAID, OVERDUE, whatever the payment method) + totals TTC of CREDIT orders not yet invoiced (SUBMITTED, PENDING, VALIDATED, PREPARING, READY) − confirmed payments not yet allocated. Available = max(0, limit − exposure). Declarations still PENDING_VERIFICATION do not reduce exposure.

  • Source: cahier §4.7, §5.3 (« Le crédit disponible est contrôlé si le paiement sur crédit est choisi »), FIN-05.
  • Example: limit 200 000,00 DA; open invoices 120 000,00; credit orders in progress 50 000,00 → exposure 170 000,00, available 30 000,00 DA.

BR-34 — Over-limit policy

When a CREDIT order exceeds the available credit, credit.overLimitPolicy applies: BLOCK (default) refuses the checkout (422 CREDIT_LIMIT_EXCEEDED, other enabled methods remain possible); REQUIRE_APPROVAL accepts the order into PENDING with reason CREDIT_OVER_LIMIT, and only a finance.validate holder can confirm it.

  • Source: cahier §4.7 (« Le dépassement du plafond peut bloquer la commande ou exiger une validation »). Decision D-04.
  • Example: with the account of BR-33, a 45 000,00 DA cart on credit: BLOCK → refused, « Crédit disponible insuffisant (30 000,00 DA) »; REQUIRE_APPROVAL → order « En attente », finance sees « Dépassement : 15 000,00 DA ».

BR-35 — Credit limit changes

Limits, terms and blocking are changed only with finance.administer; each change writes a CreditLimitChange (old, new, reason, actor) and notifies the reseller when the available credit changes.

  • Source: cahier §4.7, §10, FIN-05.

BR-36 — Invoice due dates and overdue

dueDate = issue date + the reseller's term for CREDIT orders, + billing.dueDaysDefault (default 7) for other methods. A daily job (01:00 Africa/Algiers) sets OVERDUE on invoices with a balance past their due date. In V1 overdue invoices are shown and counted; automatic reminders and blocking are V2 (FIN-06, FIN-07).

  • Source: cahier §4.7 (« échéances », « alertes d'impayé »), FIN-01.
  • Example: invoice issued 3 Nov on a credit order (term 30) → due 3 Dec; unpaid on 4 Dec at 01:00 → OVERDUE.

BR-37 — Payment declarations, verification and allocation

A reseller declares a transfer, CCP or BaridiMob payment with amount, date, reference and a proof file; it stays PENDING_VERIFICATION until finance confirms or rejects it (reason from PAYMENT_REJECT_REASON). Confirmed amounts are allocated to invoices, by default oldest due first; a remainder stays as an advance. A declaration with the same reference and amount as one of the last 30 days is flagged as a probable duplicate. The CCP account, RIB and BaridiMob details shown to resellers come from payments.instructions.

  • Source: cahier §4.7 (« Paiement à la livraison, virement, CCP, BaridiMob ou crédit », « Paiements partiels et rapprochement »), FIN-03, FIN-04. Decision D-03 (payment methods).
  • Example: two invoices open, 40 000,00 (due 1 Nov) and 25 000,00 (due 15 Nov); a 50 000,00 DA BaridiMob declaration confirmed → first invoice PAID, second PARTIALLY_PAID with 15 000,00 DA left.

BR-38 — Cash on delivery

For CASH_ON_DELIVERY orders the proof of delivery records the cash collected; it creates a payment PENDING_VERIFICATION that finance confirms when the cash is handed over. A shortfall is visible on the delivery and the invoice.

BR-39 — Credit notes

Credit notes (CreditNote, avoirs) are V1. They are issued by the system for accepted returns, by an after-sales resolution CREDIT_NOTE, and when an issued invoice is cancelled (full amount). A credit note references its invoice, is numbered, immutable, and reduces the invoice balance; any surplus over what remains due becomes an advance usable on later invoices, or a cash refund recorded by finance.

  • Source: cahier §4.7 (« Factures, reçus, avoirs »), decision of 17 Oct 2026, FIN-08.

Loyalty (V2)

Loyalty is V2 (cahier §14.2, LOY-01 to LOY-05); the rules below are the baseline HOCO validates with the V2 scope (decision D-05, loyalty policy).

BR-40 — Earning

Points are earned on the order total TTC without delivery fee, at loyalty.pointsPerAmount (default 1 point per 100,00 DA), credited when the order reaches loyalty.earnOn (PAID by default — the invoice is paid — or DELIVERED). Bonuses come from campaigns.

  • Source: cahier §4.4 (« crédités après livraison ou paiement selon le paramétrage »), §4.6.
  • Example: an order of 13 491,39 DA whose invoice is paid → 134 points.

BR-41 — Expiry

Points expire loyalty.pointsValidityMonths (default 12) after they were earned, oldest first; the expiry job writes EXPIRE entries.

  • Source: cahier §4.6 (« expiration »).

BR-42 — Reversal and adjustments

A cancelled order, an accepted return or an after-sales credit note reverses the points earned on the amounts concerned (REVERSAL, pro rata); manual adjustments need a reason (ADJUST, loyalty.update).

  • Source: cahier §4.6 (« Les points annulés ou remboursés doivent être régularisés »).

BR-43 — Levels

Bronze, Silver, Gold and VIP are computed over a rolling loyalty.levelPeriodMonths (default 12) against thresholds validated by HOCO (reference screen 7 shows Gold at 15 000 points).

  • Source: cahier §4.6 (« Les niveaux sont calculés selon une période et des seuils validés par le client »).

BR-44 — Rewards

Rewards (voucher, free delivery, discount, gift, early access) are redeemable only when available and affordable; an unavailable reward cannot be claimed.

  • Source: cahier §4.6, §5.5 (« Les récompenses indisponibles ne doivent pas pouvoir être réclamées »).

Attribution

BR-45 — One delegate, one zone, several segments

A reseller is linked to at most one assigned delegate and one zone at a time, and to any number of segments (used for targeting and visibility, not for prices in V1). The creating delegate (createdByDelegateId) is kept for ever.

  • Source: cahier §8 Attribution (« Le revendeur peut être lié à un délégué, une zone et un segment »), §4.2, CRM-05.

BR-46 — Zone resolution

A zone is a set of whole wilayas and/or communes (ZoneArea). A commune resolves to the most specific match (an explicit commune beats its wilaya); a commune can belong to only one zone (409 ZONE_OVERLAP when saving). A reseller's zone is derived from its commune and can be overridden by the back-office.

  • Source: cahier §4.5 (« Attribution des wilayas, communes et points de vente »), GEO-02.

BR-47 — Initial assignment by creation path

PathAssigned delegate
Delegate creates the point of saleThat delegate
Back-office creates itThe delegate chosen, else the zone's primary delegate
Self sign-up with an invitationThe invitation's delegate
Self sign-up without invitationThe zone's primary delegate, else unassigned (commercial admins' queue)
ImportThe delegate in the file, else as back-office
  • Source: cahier §4.2 (« Un revendeur peut être lié au délégué qui l'a créé »), §6.5, §6.6.

BR-48 — Reassignment

Reassigning writes a ResellerAssignment row (from, to, reason, actor). Open tasks move to the new delegate; the reseller's future PLANNED visits in the former delegate's tours are cancelled; both delegates are notified.

  • Source: cahier §4.2 (« Attribution d'un délégué et d'une zone »), CRM-05.

BR-49 — Attribution of orders and KPIs

Each order stores the delegate it is attributed to at submission (source delegate for assisted orders, else the assigned delegate); revenue, orders and first orders are reported against that snapshot, so reassignments never rewrite history.

  • Source: cahier §4.1 (« Chiffre d'affaires par … délégué »), §6.7.

GPS

BR-50 — Capture standard and distance

A position is { lat, lng, accuracy, capturedAt } in WGS84 degrees (6 decimals ≈ 0,1 m), accuracy in metres, device time. Distances use the haversine formula on a 6 371 km sphere.

  • Source: cahier §6.3, §6.4, §8 GPS, GEO-03.

BR-51 — Check-in tolerance

« Arrivé » is accepted when accuracy ≤ field.gpsMaxAccuracyMeters (default 100) and distance to the point of sale ≤ field.gpsToleranceMeters (default 150). Outside tolerance the check-in is refused unless field.allowOutOfToleranceCheckIn is true (default false), in which case a justification is required and the visit is flagged « Hors tolérance » for review. A point of sale without coordinates accepts the check-in and stores the position as a candidate for validation.

  • Source: cahier §6.3 (« L'arrivée peut être soumise à une distance maximale du point de vente », « lorsque la tolérance GPS est respectée »), §12, FLD-07. Decision D-06 (GPS tolerance).
  • Examples:
DistanceAccuracyResult
92 m18 mAccepted
140 m120 m422 GPS_ACCURACY_TOO_LOW — the app waits up to 30 s for a better fix and retries
310 m12 m422 GPS_OUT_OF_TOLERANCE (default); with the option on, accepted with justification and flag
anyany, isMock = true422 GPS_MOCK_LOCATION (BR-55)

BR-52 — Location sampling

Positions are sampled only while the delegate's tour is IN_PROGRESS — never when suspended, closed, or outside a tour — every field.locationIntervalSeconds (default 300) or field.locationDistanceMeters (default 200), whichever comes first, and uploaded in batches (sync.locationPings). Android shows the foreground-service notice « Localisation active pendant la tournée » while sampling.

  • Source: cahier §8 GPS (« Tolérance, fréquence, consentement et durée de conservation à valider »), §10, FLD-15. Decision D-07 (location frequency).

BR-53 — Consent and transparency

Before the first tour the delegate reads the location notice and gives consent (DA-04); the version and time of consent are stored. Settings (DA-26) show what is collected, when, and for how long. Without location permission the delegate can still start a tour (no start position, flagged) but cannot check in.

  • Source: cahier §10 (« Consentement et transparence concernant la géolocalisation des délégués »), SEC-07.

BR-54 — Kilometres

Kilometres of a tour = sum of distances between consecutive pings with accuracy ≤ 100 m, ignoring jumps that imply more than 150 km/h, plus the legs from the start position and to the end position.

  • Source: cahier §6.9 (« kilomètres »), reference screen 10.

BR-55 — Mock locations and plausibility

A position flagged as mocked by Android is refused for check-in (422 GPS_MOCK_LOCATION) and logged. A ping or action whose occurredAt is more than 5 minutes in the future or older than 72 hours is refused (422 OCCURRED_AT_OUT_OF_RANGE).

  • Source: cahier §12 (« Le check-in respecte la tolérance et conserve les coordonnées autorisées »).

Notifications

BR-56 — Channel by event type

Every user-facing event creates an inbox notification. Time-sensitive events (order status, assisted order to confirm, return or claim decision, tour assigned) also send a push. SMS is used for OTPs and for messages that must reach someone without the app (account approved, assisted order to confirm when the reseller has no app). Email serves staff (exports ready, daily digests) and documents. WhatsApp in V1 is share links (wa.me) only; automated WhatsApp Business messages are V2. The full event × channel × recipient table is the notifications matrix.

  • Source: cahier §8 Notifications (« Push, in-app, WhatsApp, SMS ou email selon le type d'événement »), NOT-04.

BR-57 — Preferences and quiet hours

TRANSACTIONAL and SECURITY notifications cannot be disabled; FIELD, PROMOTIONAL and ANNOUNCEMENT can, per channel. Promotional and announcement pushes are held during notifications.quietHours (default 21:00–08:00 Africa/Algiers) and sent at the end of the window.

  • Source: cahier §10, NOT-06.

BR-58 — Delivery guarantees

A notification is sent at most once per event, recipient and channel (deduplication key). Push is retried 3 times, SMS twice, with backoff; a token rejected by FCM deactivates the device. Every attempt is logged (NotificationDelivery).

  • Source: cahier §2.1 (« Les événements importants génèrent des notifications et sont conservés dans un journal »), NOT-04.

BR-59 — Templates, languages and SMS length

Templates exist per event, channel and locale (fr in V1; ar, en prepared). SMS templates are written in GSM-7 without accents so that one message holds 160 characters (an accented character switches to UCS-2 and 70 characters per segment).

  • Source: cahier §9 (« Français en V1 ; arabe et anglais prévus »), §11.
  • Example: « HOCO: votre code est 482915. Valable 5 min. Ne le partagez pas. » — 63 characters, one segment.

Catalog visibility

BR-60 — Visibility evaluation

A product is visible to a reseller when its status is ACTIVE or OUT_OF_STOCK, its brand and category are active, and its visibility rules allow it: with no rule, everyone sees it; ALLOW rules restrict it to the listed segments or resellers; DENY rules exclude; a reseller-level rule beats a segment-level rule. Guests see products without any ALLOW rule.

  • Source: cahier §4.3 (« visibilité par revendeur ou segment »), §5.1 (« Seuls les produits actifs et autorisés sont visibles »), CAT-05.

BR-61 — Guests and accounts pending validation

The reseller app and web can be browsed without an account: home, catalog, search, filters (except price), product pages, promotions and the WhatsApp button work; prices are null with the lock « Créez un compte pour voir les prix »; nothing can be added to the cart. After sign-up, prices of the declared customer type appear right away when catalog.pricesVisibleBeforeValidation is true (default); ordering always waits for validation. Decision D-18 may instead show the Détail price to every account until validation.

BR-62 — Delegate catalog

Delegates browse every visible product with availability; prices appear when they work for a given reseller (assisted order) and are that reseller's type prices.

  • Source: cahier §6.7.

BR-63 — Search, filters, facets and sorting

Search matches name, reference, brand and barcode. Filters combine (AND across facets, OR inside a facet): category and sub-category, brand, attributes defined per category (power in W, connector, cable length, colour, capacity in mAh, Bluetooth version…), availability, promotion, new arrivals, and price range for signed-in resellers only. catalog.facets returns counts for the current query. Sorts: relevance, price (own type), newest (publishedAt), popularity (units sold over 30 days). Results in under 3 seconds on a normal mobile connection.

  • Source: cahier §5.1 (« Rechercher par nom, référence ou marque », « moins de 3 secondes »), decision of 17 Oct 2026, CAT-07, CAT-12, CAT-13.

Promotions application and stacking

BR-64 — Eligibility

A promotion applies to a line when it is ACTIVE, now is within its dates, the product matches its scope (products, categories, brands), the reseller matches its audience (wilaya of the store, segment, customer type, V2 level) and its volume condition (minimum quantity or amount), and its cap is not exhausted.

  • Source: cahier §4.6 (« Ciblage par wilaya, segment, niveau, marque ou volume »), §5.5 (« Une promotion doit respecter ses dates, son stock et sa cible »), PRM-02, PRM-04.

BR-65 — Mechanics per type

PERCENT_OFF reduces the line by the rate; AMOUNT_OFF reduces each unit by the amount, never below 0; FIXED_PRICE sets the unit price HT and applies only when lower than the type price; FREE_DELIVERY sets the delivery fee to 0. Line promotions apply to the customer-type price.

  • Source: cahier §4.6 (« remises temporaires »), PRM-01.

BR-66 — Stacking modes

promotions.stackingMode: BEST_ONLY (default) applies the single eligible promotion that gives the lowest line total; STACK_BY_PRIORITY applies stackable promotions in descending priority, each on the result of the previous, with FIXED_PRICE never stacked. FREE_DELIVERY combines with any line promotion.

  • Source: cahier §4.6 (« Les règles de cumul des promotions doivent être configurables »), PRM-03.
  • Example: demi-gros price 41 990 × 30 (1 259 700 HT); promotion A −10 % (priority 10), promotion B −20,00 DA per unit (priority 20, stackable). BEST_ONLY: A gives 1 133 730, B gives 1 199 700 → A applies, 1 133 730. STACK_BY_PRIORITY: B first → 1 199 700, then A −10 % → 1 079 730.

BR-67 — Quantity caps

A promotion may cap the units sold at the promotional price. Units are consumed at submission and released when the order is refused or cancelled. When fewer units remain than a line asks for, the promotion applies to the remaining units only and the rest is at the type price; when the cap is exhausted the promotion ends.

  • Source: cahier §5.5 (« son stock »), PRM-04.
  • Example: 12 units left, a line of 30 → 12 at the promotional price, 18 at the normal price; the promotion becomes ENDED.

BR-68 — Daily offers and banners

A daily offer is a promotion flagged offre du jour running from 00:00 to 23:59 Africa/Algiers, shown with a countdown. A banner is visible only while its target (promotion, product or category) is active and visible to the viewer; guests see banners and promotion badges without prices: the percentage of a PERCENT_OFF promotion is shown, never an amount or a fixed price.

  • Source: cahier §5 (« Consulter l'offre du jour »), §4.6, PRM-05.

BR-69 — Snapshot and changes during a cart's life

Carts follow promotions live (re-priced at each read); orders keep the promotions they were submitted with. An active promotion can only be extended, have its cap raised, or be paused; other changes need a new promotion.

  • Source: cahier §5.5 (« Le total du panier applique correctement l'offre »).

Assisted orders

BR-70 — Who and for whom

A delegate prepares an assisted order only for a reseller in their scope that is not suspended; a prospect pending validation is allowed (the order then waits for the account approval).

  • Source: cahier §6.7, ORD-08.

BR-71 — Same controls as a normal order

Prices (that reseller's customer type), availability, quantity rules, minimum amount and credit are checked exactly as at checkout, at every draft change, at submission and again at confirmation.

  • Source: cahier §6.7 (« Le prix, le stock et le crédit sont contrôlés comme pour une commande normale »).

BR-72 — Confirmation, reminder and expiry

The reseller confirms in the app or web, or the administration confirms on their behalf with a note, within orders.assistedConfirmationHours (default 72); a reminder goes out 24 h before expiry; then the order is cancelled automatically (delay: decision D-23). A confirmed assisted order still waits for the back-office confirmation (BR-24).

  • Source: cahier §4.4 (« Une commande assistée doit être confirmée par le revendeur ou validée par l'administration »), ORD-08.

BR-73 — Attribution to the source delegate

The order carries sourceDelegateId and channel DELEGATE_ASSISTED for ever; it counts in the delegate's orders, revenue and first-order objectives.

  • Source: cahier §6.7 (« La commande assistée doit identifier le délégué source »), ORD-09.

BR-74 — One pending assisted order per reseller

A reseller has at most one assisted order awaiting confirmation (409 ASSISTED_ORDER_ALREADY_PENDING), to avoid duplicate first orders.

  • Source: team rule derived from cahier §6.7 and §12.

Account validation

BR-75 — What requires validation

Self sign-ups, claims of unapproved records and points of sale created in the field are validated by a user with crm.validate. Records created by the back-office or imported are approved at creation.

  • Source: cahier §4.2, §6.5 (« Le compte revendeur peut rester en attente de validation »), §12, CRM-09.

BR-76 — Checks before approval

The validator reviews the duplicate hints (BR-05), the required data of cahier §15.5, the façade photo and GPS position for field creations, the documents HOCO requires (none by default — decision D-30 on who validates and what), and confirms or changes the declared customer type.

  • Source: cahier §15.5, decision of 17 Oct 2026, AUTH-11.

BR-77 — Effects of a decision

Approval activates the account (checkout unlocked), notifies the reseller by SMS and push with the confirmed customer type, and releases orders waiting for RESELLER_NOT_VALIDATED. Rejection requires a reason shown to the reseller, who can correct and resubmit.

  • Source: cahier §12 (« Une inscription valide apparaît dans le back-office et peut être approuvée »).

BR-78 — Account claim without duplicate

A sign-up whose verified phone matches an existing record claims that record: history, delegate, invitation attribution and customer type (pre-filled, editable until validation) are kept. A suspended or disabled record cannot be claimed (« Contactez le support »).

  • Source: cahier §4.2, §6.5, §6.6, AUTH-05.

BR-79 — Customer type changes

After validation only the back-office changes a customer type (crm.update), with a reason; the change is audited (before, after, actor), the reseller is notified, the cart is re-priced at its next read and submitted orders keep their prices.

  • Source: decision of 17 Oct 2026, AUTH-11.
  • Example: a détail shop that now buys in volume is moved to demi-gros on 10 Dec; its cart line at 45 900 HT becomes 41 990 HT at the next read; its order of 8 Dec keeps 45 900.

BR-80 — Validation reminders

An item waiting more than crm.validationReminderHours (default 24) triggers a reminder to validators; the target is one working day (Sunday–Thursday).

  • Source: cahier §4.2.

After-sales and support

BR-81 — After-sales claims

A reseller opens an after-sales claim (ticket type AFTER_SALES) on a delivered order with a delay that depends on the issue: DAMAGED, WRONG_ITEM and MISSING_ITEM — visible at reception — within returns.windowDays of delivery (default 7); DEFECTIVE, NOT_AS_DESCRIBED and OTHER within the product's warranty (cahier §15.4 « Garantie »), or afterSales.windowDays (default 180 days) when the product has no warranty value (decision D-35). The claim lists lines and quantities (≤ delivered − already claimed or returned), the issue (AfterSalesIssue) and at least one photo.

  • Source: cahier §2.1 (« demandes SAV et réclamations »), §4.4, decision of 17 Oct 2026, SUP-04.
  • Example: a charger delivered on 3 Nov with a 6-month warranty can be claimed as DEFECTIVE until 3 May; a MISSING_ITEM claim on the same order closes on 10 Nov.

BR-82 — After-sales resolutions

A user with support.validate resolves a claim with one resolution: REPLACEMENT (free order, confirmed and delivered like any order), RETURN (return request created APPROVED), CREDIT_NOTE (amount ≤ claimed lines at snapshot prices), REPAIR (repair note and date) or REJECTED (reason). The resolution is audited and notified live and by push.

BR-83 — Regional WhatsApp support

The fixed WhatsApp button opens the number of the user's support region: the region of the wilaya declared in the account when signed in; otherwise the region of the device location (nearest commune centroid → wilaya → region); otherwise the wilaya the user picks; failing all, support.defaultWhatsappNumber (regions and numbers: decision D-36; default one national region). Each region carries a number and opening hours; outside hours the app says when an answer can be expected.

  • Source: decision of 17 Oct 2026, SUP-05, ADM-08.
  • Example: a guest in Sétif with location allowed → region Est → wa.me/213… of the Est team.

Data retention

BR-84 — Retention periods

DataKeptThen
Location pingsfield.locationRetentionDays (default 90 days)Deleted
Check-in and visit positionsWith the visit recordAnonymised with the delegate
Idempotency records30 daysDeleted
Expired sessions, OTP codes30 days, 24 hoursDeleted
Export filesexports.retentionDays (default 7 days)Deleted, job row kept
Import files90 daysDeleted
Notification inbox12 monthsDeleted
Audit log24 months onlineArchived
Orders, invoices, credit notes, payments, proofs, delivery notes10 years (commercial and tax records)Archived
Store photos and documentsLife of the reseller recordDeleted at anonymisation

Durations other than legal ones are defaults to validate with HOCO (decision D-11, data retention).

  • Source: cahier §10 (« durée de conservation des données à valider avec le client »), « Décisions restantes », SEC-08.

BR-85 — Deactivation and anonymisation

Accounts are deactivated, never deleted, so history stays (cahier §10). On a verified deletion request the personal data of the account (name, emails, photos, documents, device tokens) is anonymised within 30 days while commercial and tax records keep the company identifiers they legally need.

  • Source: cahier §10, Law 18-07 on personal data, Google Play account-deletion policy, SEC-06, SEC-08.

BR-86 — Purge jobs

Nightly jobs purge what has passed its retention; each run logs counts per data type. A legal hold flag on a reseller suspends purges for that record.

  • Source: cahier §10.

Settings catalogue

Every business setting is a Setting row, typed and validated, changed in BO-64 through admin.settings.update by a holder of settings.administer (SUPER_ADMIN by default), each change audited with before and after values. App marks the settings the apps read through appConfig.get (public business settings); the others stay server-side. Decision ids refer to the decision register.

KeyTypeDefaultAllowed valuesOwnerAppDecision
orders.minAmountcentimes TTC1 000 000 (10 000,00 DA)≥ 0 (0 = none)Commercial✓D-19
orders.minQtyPerLineinteger11–1000 (variant overrides)Commercial✓D-19
orders.maxQtyPerLineinteger999≥ min (variant overrides)Commercial✓D-19
orders.cancelAllowedStatusesOrderStatus listSUBMITTED, PENDINGsubset of SUBMITTED, PENDINGCommercial✓—
orders.assistedConfirmationHoursinteger721–168Commercial✓ (DA)D-23
orders.confirmationAlertMinutes (proposal)integer12015–1440Commercial——
returns.windowDaysinteger70–90 (0 = no reseller-initiated returns)Commercial✓D-35
afterSales.windowDaysinteger180 (used when a product has no warranty value)1–730Commercial✓D-35
stock.reserveOnenumVALIDATEDSUBMITTED, VALIDATEDStock—D-22
stock.deductOnenumSHIPPEDREADY, SHIPPED, DELIVEREDStock—D-22
stock.lowThresholdDefaultinteger units20≥ 0Stock— (back-office only)D-02
catalog.pricesVisibleBeforeValidationbooleantruetrue, falseCommercial✓D-18
pricing.displayTaxModeenumTTCTTC, HTFinance✓D-17
pricing.defaultVatRatebasis points19000, 900, 1900Finance——
credit.overLimitPolicyenumBLOCKBLOCK, REQUIRE_APPROVALFinance—D-04
credit.defaultLimitcentimes0 (no credit)≥ 0Finance—D-04, D-29
credit.defaultTermDaysinteger300–180Finance—D-04
payments.enabledMethodsPaymentMethod listall fivenon-empty subsetFinance✓D-03
payments.instructionsobject (CCP account and key, RIB, BaridiMob RIP, beneficiary)to provide by HOCO—Finance✓D-03
billing.invoiceOnenumSHIPPEDVALIDATED, SHIPPED, DELIVEREDFinance—open — see the register
billing.dueDaysDefaultinteger70–90Finance——
billing.stampDutyobject (enabled, rate, minimum, cap)disabled until confirmedper finance lawFinance—D-21
promotions.stackingModeenumBEST_ONLYBEST_ONLY, STACK_BY_PRIORITYCommercial——
delivery.feeModeenumFREEFREE, FLAT, PER_WILAYADelivery✓D-20
delivery.flatFeecentimes HT0≥ 0Delivery✓D-20
delivery.wilayaFeesmap wilaya → centimes HTempty≥ 0 per wilayaDelivery✓D-20
delivery.freeThresholdcentimes TTC or nullnull≥ 0Delivery✓D-20
field.gpsToleranceMetersinteger15020–1000Commercial✓ (DA)D-06
field.gpsMaxAccuracyMetersinteger10010–500Commercial✓ (DA)D-06
field.allowOutOfToleranceCheckInbooleanfalse—Commercial✓ (DA)D-06
field.locationIntervalSecondsinteger30060–1800Commercial✓ (DA)D-07
field.locationDistanceMetersinteger20050–2000Commercial✓ (DA)D-07
field.locationRetentionDaysinteger907–365Direction—D-07, D-11
field.reportRequiredToEndVisitbooleantrue (default for new visit types)—Commercial✓ (DA)—
field.closingRequiresSyncbooleantrue—Commercial✓ (DA)—
field.reopenMaxDaysinteger70–30Commercial——
field.visitUnlockHoursinteger241–168Commercial——
crm.inactivityDaysinteger6015–365Commercial——
crm.validationReminderHoursinteger241–168Commercial——
invitations.validityDaysinteger301–180Commercial✓ (DA)—
auth.sessionDaysMobileinteger30 (sliding)1–90Super admin——
auth.sessionDaysBackOfficeinteger7 (sliding)1–30Super admin—D-33
auth.reauthMinutesinteger155–60Super admin—D-33
support.defaultWhatsappNumberE.164 phoneHOCO's main support numberAlgerian numberCommercial✓ (through support.whatsapp)D-36
support.autoCloseDaysinteger71–30Commercial——
notifications.quietHoursstart and end time21:00–08:00anyCommercial——
exports.retentionDaysinteger71–30Super admin——
numbering.<type>.prefix2–4 capital lettersREV, CMD, FAC, BL, PAY, AV, TRN, VIS, TKT, RETunique per type; a change applies from the next 1 JanuarySuper admin——
numbering.<type>.paddinginteger66–8Super admin——
loyalty.earnOn (V2)enumPAIDPAID, DELIVEREDCommercial—D-05
loyalty.pointsPerAmount (V2)points per centimes1 per 10 000> 0Commercial✓D-05
loyalty.pointsValidityMonths (V2)integer121–60Commercial—D-05
loyalty.levelPeriodMonths (V2)integer123–24Commercial—D-05
loyalty.levelThresholds (V2)points per levelto validateascendingCommercial✓D-05

D-01 to D-11 are the cahier's « Décisions restantes à valider » in its order; D-12 onwards were raised by the specification work. A default in this table is the value the team builds with until the decision is taken; reversing a defaulted value later is a change request.

Not settings. Some values are fixed platform constants, changed only by a release: OTP of 6 digits valid 5 minutes with 5 attempts; sign-in limited to 5 attempts per minute with a 15-minute lockout; idempotency records kept 30 days; occurredAt accepted from 72 hours in the past to 5 minutes in the future; list pages of 20 items by default (100 max), back-office tables 25 (200 max); upload sizes per FilePurpose; signed upload URLs valid 10 minutes, download URLs 5 minutes; sync.batch up to 50 mutations; visit quick note up to 300 characters. No setting confirms orders automatically (BR-24) and no setting shows stock quantities to resellers (BR-16).

On this page

IdentifiersBR-01 — Technical identifiersBR-02 — Business numbersBR-03 — Invitation codesBR-04 — Phone normalisation and uniquenessBR-05 — Duplicate hints beyond the phonePricesBR-06 — Price data per variantBR-07 — Price resolution: customer type, then promotionsBR-08 — Rounding and totalsBR-09 — Price history and order snapshotBR-10 — Re-validation at cart and checkoutBR-11 — Price confidentialityStockBR-12 — Available stockBR-13 — Reservation, deduction and automatic restockBR-14 — Stock checkpointsBR-15 — Stock overrideBR-16 — Availability is the only stock information outside the back-officeBR-17 — Movement ledgerBR-18 — Automatic out-of-stock and alertsBR-19 — Inventory sessionsOrdersBR-20 — Minimum order amountBR-21 — Quantity rulesBR-22 — One cart per resellerBR-23 — Checkout and order snapshotBR-24 — Every order is confirmed by a personBR-25 — Cancellation rulesBR-26 — Controlled modificationBR-27 — First orderBR-28 — Delivery feeBR-29 — Order documentsBR-30 — Real-time status for the resellerBR-31 — ReturnsCredit and paymentsBR-32 — Credit account and the CREDIT methodBR-33 — Exposure and available creditBR-34 — Over-limit policyBR-35 — Credit limit changesBR-36 — Invoice due dates and overdueBR-37 — Payment declarations, verification and allocationBR-38 — Cash on deliveryBR-39 — Credit notesLoyalty (V2)BR-40 — EarningBR-41 — ExpiryBR-42 — Reversal and adjustmentsBR-43 — LevelsBR-44 — RewardsAttributionBR-45 — One delegate, one zone, several segmentsBR-46 — Zone resolutionBR-47 — Initial assignment by creation pathBR-48 — ReassignmentBR-49 — Attribution of orders and KPIsGPSBR-50 — Capture standard and distanceBR-51 — Check-in toleranceBR-52 — Location samplingBR-53 — Consent and transparencyBR-54 — KilometresBR-55 — Mock locations and plausibilityNotificationsBR-56 — Channel by event typeBR-57 — Preferences and quiet hoursBR-58 — Delivery guaranteesBR-59 — Templates, languages and SMS lengthCatalog visibilityBR-60 — Visibility evaluationBR-61 — Guests and accounts pending validationBR-62 — Delegate catalogBR-63 — Search, filters, facets and sortingPromotions application and stackingBR-64 — EligibilityBR-65 — Mechanics per typeBR-66 — Stacking modesBR-67 — Quantity capsBR-68 — Daily offers and bannersBR-69 — Snapshot and changes during a cart's lifeAssisted ordersBR-70 — Who and for whomBR-71 — Same controls as a normal orderBR-72 — Confirmation, reminder and expiryBR-73 — Attribution to the source delegateBR-74 — One pending assisted order per resellerAccount validationBR-75 — What requires validationBR-76 — Checks before approvalBR-77 — Effects of a decisionBR-78 — Account claim without duplicateBR-79 — Customer type changesBR-80 — Validation remindersAfter-sales and supportBR-81 — After-sales claimsBR-82 — After-sales resolutionsBR-83 — Regional WhatsApp supportData retentionBR-84 — Retention periodsBR-85 — Deactivation and anonymisationBR-86 — Purge jobsSettings catalogue