HOCO B2B
SRSAPI reference

Reseller orders

The reseller's orders — list, status counters, detail with live tracking, cancellation, assisted-order confirmation or rejection, reorder, documents — and V1 return requests on delivered orders.

These operations power the « Commandes » tab of the reseller app (Imad, MRA-05, returns in MRA-10) and the orders pages of the reseller web (Anis, WEB-04); they are built in SRV-16 and SRV-20.

  • Only my orders. Every operation is scoped to the caller's reseller (cahier §5.4 « Le revendeur ne voit que ses commandes »); another reseller's order is 404 NOT_FOUND. DRAFT orders (assisted orders still being prepared by the delegate) are never visible.
  • The status is the back-office's status (ORD-07): the apps show the exact OrderStatus label, a five-step tracker and the dated history. Every order waits for an explicit back-office confirmation (ORD-14); awaitingConfirmation says who is expected to act.
  • Live. While the app or page is open, events.stream pushes order.status_changed, order.modified, assisted_order.awaiting_confirmation and return.status_changed; every change is also a push and an inbox notification (ORD-15).
  • The server decides what is allowed. allowedActions lists the buttons to show; the apps never re-implement the rules of the order lifecycle.
  • Returns are V1 (ORD-13): a return is requested on a delivered order within returns.windowDays (default 7). After-sales claims under warranty are support tickets of type AFTER_SALES (support).
MethodPathOperationAccessAppsRelease
GET/ordersorders.list
My orders with status filter and search (cursor pagination)
selfRA · RWV1
GET/orders/summaryorders.summary
Counters by status for the tracking header
selfRA · RWV1
GET/orders/{orderId}orders.get
Order detail: lines, totals, status timeline, delivery, documents, allowed actions
selfRA · RWV1
POST/orders/{orderId}/cancelorders.cancel
Cancel my order while the rules allow it
self
Idempotency-Key
RA · RWV1
POST/orders/{orderId}/confirmorders.confirmAssisted
Confirm an assisted order prepared by my delegate
self
Idempotency-Key
RA · RWV1
POST/orders/{orderId}/rejectorders.rejectAssisted
Reject an assisted order with a reason
self
Idempotency-Key
RA · RWV1
POST/orders/{orderId}/reorderorders.reorder
Copy the order's available lines into my cart
self
Idempotency-Key
RA · RWV1
GET/orders/{orderId}/documents/{type}orders.document
Signed URL of the invoice or delivery note PDF
selfRA · RWV1
POST/orders/{orderId}/returnsreturns.create
Request a return of delivered items (lines, quantities, reason, photos)
self
Idempotency-Key
RA · RWV1
GET/returnsreturns.list
My return requests with status
selfRA · RWV1
GET/returns/{returnId}returns.get
Return detail with lines, status history and credit note
selfRA · RWV1

Every operation can also answer 401 UNAUTHENTICATED, 403 ACCOUNT_SUSPENDED, 403 PERMISSION_DENIED (caller is not a reseller), 426 UPGRADE_REQUIRED, 429 RATE_LIMITED, 500 INTERNAL_ERROR and 503 MAINTENANCE; operations with Idempotency-Key required also 400 IDEMPOTENCY_KEY_REQUIRED, 409 IDEMPOTENCY_KEY_REUSED and 409 IDEMPOTENCY_IN_PROGRESS. See the error registry.

Reference screen 6 — counters per tracker step, search, history with progress tracker, invoice download and reorder.
Reference screen 6 — counters per tracker step, search, history with progress tracker, invoice download and reorder. — client reference (cahier des charges)

Tracker and allowed actions

progressStepTracker labelOrder statuses
0En attenteSUBMITTED, PENDING
1ValidéeVALIDATED
2En préparationPREPARING, READY
3ExpédiéeSHIPPED
4LivréeDELIVERED
nulloff the tracker, with the reasonREFUSED, CANCELLED, RETURNED
allowedActions valuePresent whenCalls
CANCELStatus in orders.cancelAllowedStatuses (default SUBMITTED, PENDING) and not an assisted order awaiting my confirmationorders.cancel
CONFIRM, REJECTAssisted order PENDING with confirmation AWAITING_RESELLER, before assisted.expiresAtorders.confirmAssisted, orders.rejectAssisted
REORDERDELIVERED, CANCELLED, REFUSED, RETURNEDorders.reorder
REQUEST_RETURNDELIVERED, now ≤ returnableUntil, at least one line with returnableQty above 0returns.create
OPEN_CLAIMDELIVERED, now ≤ claimableUntil, something left to claimtickets.create with type: AFTER_SALES
DOWNLOAD_INVOICE, DOWNLOAD_DELIVERY_NOTEThe document exists (documents[].available)orders.document
CONTACT_SUPPORTAlwaystickets.create with orderId (cahier §5.4 « Contacter le support »)

Schemas

PromotionApplied, LineTotals, AppliedPromotion and DisplayTotals are defined on the cart page; Totals, Address, StatusChange, FileRef and Price in the shared schemas.

type OrderAction = "CANCEL" | "CONFIRM" | "REJECT" | "REORDER" | "REQUEST_RETURN" | "OPEN_CLAIM"
                 | "DOWNLOAD_INVOICE" | "DOWNLOAD_DELIVERY_NOTE" | "CONTACT_SUPPORT";
type PendingReason = "AWAITING_RESELLER" | "CREDIT_OVER_LIMIT" | "RESELLER_NOT_VALIDATED" | "ON_HOLD";

interface OrderSummary {
  id: Uuid;
  number: string;                     // CMD-2026-000158
  status: OrderStatus;
  progressStep: number | null;        // 0–4, null off the tracker
  createdAt: Iso;                     // placed (checkout) or sent for my confirmation (assisted)
  itemsCount: number;                 // lines — « 3 articles »
  unitsCount: number;
  firstItem: { name: string; imageUrl: string | null };
  totals: { totalTtc: Money; currency: "DZD" };
  paymentMethod: PaymentMethod;
  isAssisted: boolean;
  awaitingMyConfirmation: boolean;    // pinned « À confirmer »
  assistedExpiresAt: Iso | null;
  hasInvoice: boolean;
}

interface OrderDetail {
  id: Uuid;
  number: string;
  version: number;                    // +1 on every change; compare with live events
  status: OrderStatus;
  progressStep: number | null;
  awaitingConfirmation: "BACK_OFFICE" | "RESELLER" | null;   // who must act before preparation
  pendingReasons: PendingReason[];    // non-empty only when PENDING
  channel: OrderChannel;
  isFirstOrder: boolean;
  createdAt: Iso;
  submittedAt: Iso | null;
  validatedAt: Iso | null;            // back-office confirmation
  updatedAt: Iso;
  currency: "DZD";
  itemsCount: number;
  unitsCount: number;
  lines: OrderLine[];
  totals: Totals;
  displayTotals: DisplayTotals;
  appliedPromotions: AppliedPromotion[];
  address: Address;                   // snapshot taken at checkout
  note: string | null;
  paymentMethod: PaymentMethod;
  paymentStatus: {
    invoiced: boolean;
    invoiceId: Uuid | null;
    invoiceNumber: string | null;     // FAC-2026-000124
    invoiceStatus: InvoiceStatus | null;
    dueDate: string | null;           // YYYY-MM-DD
    amountPaid: Money;                // confirmed payments allocated to this order or its invoice
    creditNotesTotal: Money;
    balance: Money;
    pendingVerificationAmount: Money; // declared, not yet verified
  };
  delivery: {
    status: DeliveryStatus | null;    // null before the back-office confirmation
    mode: DeliveryMode | null;
    carrierName: string | null;
    trackingNumber: string | null;
    trackingUrl: string | null;
    driverName: string | null;        // OWN_FLEET
    driverPhone: string | null;
    deliveryNoteNumber: string | null;   // BL-2026-000141, from READY
    shippedAt: Iso | null;
    deliveredAt: Iso | null;
    recipientName: string | null;
  };
  statusHistory: StatusChange[];      // oldest first, public reasons only
  changes: { at: Iso; reason: string; lines: { sku: string; name: string; fromQty: number; toQty: number }[] }[];
  documents: { type: "INVOICE" | "DELIVERY_NOTE"; number: string | null; available: boolean; generatedAt: Iso | null }[];
  assisted: {
    isAssisted: boolean;
    delegate: { id: Uuid; displayName: string; phone: string } | null;
    confirmation: AssistedConfirmation | null;
    expiresAt: Iso | null;
    confirmedAt: Iso | null;
    rejectionReason: string | null;
  };
  cancellation: { reasonCode: string; reasonLabel: string; comment: string | null; at: Iso; by: "RESELLER" | "HOCO" | "SYSTEM" } | null;
  refusal: { reasonCode: string; reasonLabel: string; comment: string | null; at: Iso } | null;
  returns: { id: Uuid; number: string; status: ReturnStatus }[];
  claims: { id: Uuid; number: string; status: TicketStatus }[];   // AFTER_SALES tickets on this order
  returnableUntil: Iso | null;        // deliveredAt + returns.windowDays
  claimableUntil: Iso | null;         // deliveredAt + after-sales window (BR-81)
  allowedActions: OrderAction[];
}

interface OrderLine {
  id: Uuid;                           // OrderItem id — used as orderItemId by returns and claims
  product: { id: Uuid; name: string; brandName: string; imageUrl: string | null };   // snapshot
  variant: { id: Uuid; sku: string; label: string };
  qty: number;
  price: Price;                       // snapshot unit price (customer type) before promotion
  promotionApplied: PromotionApplied | null;
  lineTotals: LineTotals;
  originalQty: number | null;         // set when the back-office changed the quantity (ORD-06)
  returnedQty: number;                // in returns not REJECTED
  claimedQty: number;                 // in after-sales claims not REJECTED
  returnableQty: number;              // delivered − returned − claimed, 0 before delivery
}

interface ReturnView {
  id: Uuid;
  number: string;                     // RET-2026-000012
  status: ReturnStatus;               // REQUESTED, APPROVED, IN_TRANSIT, RECEIVED, REFUNDED, REJECTED
  origin: "RESELLER" | "AFTER_SALES";
  order: { id: Uuid; number: string; deliveredAt: Iso };
  ticket: { id: Uuid; number: string } | null;   // when created by an after-sales resolution
  reason: string;
  items: {
    id: Uuid;
    orderItemId: Uuid;
    product: { id: Uuid; name: string; imageUrl: string | null };
    variant: { id: Uuid; sku: string; label: string };
    qty: number;                      // requested
    unitPrice: Price;                 // the order line's net unit price (after promotion)
    amountTtc: Money;
    photos: FileRef[];                // TICKET_ATTACHMENT, signed URLs
    receivedQty: number | null;       // after reception
    acceptedQty: number | null;       // credited
    refusalReason: string | null;     // for units not accepted at inspection
  }[];
  amountTtc: Money;                   // value of the requested items
  instructions: string | null;        // how to send the goods back, set at approval
  transport: { mode: "RESELLER_DROP_OFF" | "CARRIER" | "DELEGATE_PICKUP"; scheduledFor: string | null; trackingNumber: string | null } | null;
  rejectionReason: string | null;
  creditNote: { id: Uuid; number: string; amountTtc: Money; issuedAt: Iso; file: FileRef | null } | null;
  statusHistory: StatusChange[];
  requestedAt: Iso;
  updatedAt: Iso;
}

Actors in histories. For the reseller, statusHistory[].actor is the reseller's own user, the assisted-order delegate, { displayName: "Équipe HOCO" } for any back-office user (staff names are not shown to resellers), or null for the system (expiry, automatic moves). reason is the public text of the reason (ReferenceItem label plus the comment written for the reseller), never an internal note.

Operations

GET /orders

orders.list · Access session — reseller (self) · Apps RA, RW · Idempotency-Key — · Release V1 · Requirements ORD-07

Contract 1.1.0 (SRV-41): every OrderSummary carries invoiceStatus (UNPAID, PARTIALLY_PAID, PAID, OVERDUE, CANCELLED; null before invoicing) next to hasInvoice.

Purpose. « Historique des commandes »: my orders, newest first, with the tracker step of each, filterable by status and searchable.

Request

QueryTypeRequiredDefaultNotes
statusOrderStatus, repeatablenoall but DRAFTA counter tap sends its statuses: status=SUBMITTED&status=PENDING
qstring 2–60no—Order number (158 or CMD-2026-000158), product name or SKU
from, toYYYY-MM-DDno—On createdAt, Africa/Algiers days
awaitingMyConfirmationtrueno—Only assisted orders waiting for me
cursor, limit—nolimit 20Max 100

Response — 200 OK: { items: OrderSummary[], nextCursor }.

{
  "items": [
    {
      "id": "01a1a0de-84e0-79ad-9ae7-a8167cc6fcaa",
      "number": "CMD-2026-000159",
      "status": "PENDING",
      "progressStep": 0,
      "createdAt": "2026-11-03T10:05:00Z",
      "itemsCount": 2,
      "unitsCount": 15,
      "firstItem": { "name": "HOCO N32 Chargeur rapide 30W (USB-C + USB-A)", "imageUrl": "https://cdn.hoco.dz/products/n32/n32-black-1-240.webp" },
      "totals": { "totalTtc": 2495000, "currency": "DZD" },
      "paymentMethod": "CASH_ON_DELIVERY",
      "isAssisted": true,
      "awaitingMyConfirmation": true,
      "assistedExpiresAt": "2026-11-06T10:05:00Z",
      "hasInvoice": false
    },
    {
      "id": "01a1a0c0-4e80-7095-bb23-dcbea2c9e1e5",
      "number": "CMD-2026-000158",
      "status": "SUBMITTED",
      "progressStep": 0,
      "createdAt": "2026-11-03T09:32:00Z",
      "itemsCount": 4,
      "unitsCount": 41,
      "firstItem": { "name": "BOROFONE BW06 Écouteurs TWS", "imageUrl": "https://cdn.hoco.dz/products/bw06/bw06-white-1-240.webp" },
      "totals": { "totalTtc": 8038000, "currency": "DZD" },
      "paymentMethod": "CASH_ON_DELIVERY",
      "isAssisted": false,
      "awaitingMyConfirmation": false,
      "assistedExpiresAt": null,
      "hasInvoice": false
    },
    {
      "id": "01a19cef-7060-7886-83ab-24329f8f21b0",
      "number": "CMD-2026-000157",
      "status": "VALIDATED",
      "progressStep": 1,
      "createdAt": "2026-11-02T15:45:00Z",
      "itemsCount": 4,
      "unitsCount": 52,
      "firstItem": { "name": "ACEFAST A45 Chargeur rapide", "imageUrl": "https://cdn.hoco.dz/products/a45/a45-black-1-240.webp" },
      "totals": { "totalTtc": 18500000, "currency": "DZD" },
      "paymentMethod": "CASH_ON_DELIVERY",
      "isAssisted": false,
      "awaitingMyConfirmation": false,
      "assistedExpiresAt": null,
      "hasInvoice": false
    },
    {
      "id": "01a1910c-39e0-71c4-81d8-f9f786e70645",
      "number": "CMD-2026-000156",
      "status": "PREPARING",
      "progressStep": 2,
      "createdAt": "2026-10-31T08:21:00Z",
      "itemsCount": 2,
      "unitsCount": 8,
      "firstItem": { "name": "HOCO J86A Power Bank 10000mAh", "imageUrl": "https://cdn.hoco.dz/products/j86a/j86a-black-1-240.webp" },
      "totals": { "totalTtc": 2460000, "currency": "DZD" },
      "paymentMethod": "CREDIT",
      "isAssisted": false,
      "awaitingMyConfirmation": false,
      "assistedExpiresAt": null,
      "hasInvoice": false
    },
    {
      "id": "01a187cf-6b40-7c6f-894d-b1f256947da9",
      "number": "CMD-2026-000155",
      "status": "SHIPPED",
      "progressStep": 3,
      "createdAt": "2026-10-29T13:18:00Z",
      "itemsCount": 2,
      "unitsCount": 23,
      "firstItem": { "name": "HOCO X89 Câble USB-C", "imageUrl": "https://cdn.hoco.dz/products/x89/x89-black-1-240.webp" },
      "totals": { "totalTtc": 3685000, "currency": "DZD" },
      "paymentMethod": "CASH_ON_DELIVERY",
      "isAssisted": false,
      "awaitingMyConfirmation": false,
      "assistedExpiresAt": null,
      "hasInvoice": true
    }
  ],
  "nextCursor": "eyJjIjoiMjAyNi0xMC0yOVQxMzoxODowMFoiLCJpIjoiMDFhMTg3Y2YifQ"
}

Errors

StatusCodeWhen
400VALIDATION_FAILEDUnknown status, DRAFT requested, q under 2 characters, from after to.

Rules & side effects — read-only, sorted by createdAt descending. The list updates live: on order.status_changed the client patches the item's status and progressStep from the event and refreshes the counters.

Used by — RA-21 (« Commandes »), RW-08, the « Commandes » quick tile of RA-09.

GET /orders/summary

orders.summary · Access session — reseller (self) · Apps RA, RW · Idempotency-Key — · Release V1 · Requirements ORD-07

Purpose. The five counters of « Statut des commandes » (reference screen 6) and the assisted order waiting for my confirmation, in one small call.

Request

QueryTypeRequiredNotes
fromYYYY-MM-DDnoCount only orders created since that day (default: all)

Response — 200 OK.

{
  "tracker": [
    { "step": "AWAITING", "progressStep": 0, "statuses": ["SUBMITTED", "PENDING"], "count": 2 },
    { "step": "VALIDATED", "progressStep": 1, "statuses": ["VALIDATED"], "count": 4 },
    { "step": "PREPARING", "progressStep": 2, "statuses": ["PREPARING", "READY"], "count": 3 },
    { "step": "SHIPPED", "progressStep": 3, "statuses": ["SHIPPED"], "count": 2 },
    { "step": "DELIVERED", "progressStep": 4, "statuses": ["DELIVERED"], "count": 6 }
  ],
  "byStatus": {
    "SUBMITTED": 1, "PENDING": 1, "VALIDATED": 4, "PREPARING": 2, "READY": 1,
    "SHIPPED": 2, "DELIVERED": 6, "REFUSED": 0, "CANCELLED": 1, "RETURNED": 0
  },
  "total": 18,
  "toConfirm": {
    "orderId": "01a1a0de-84e0-79ad-9ae7-a8167cc6fcaa",
    "number": "CMD-2026-000159",
    "totalTtc": 2495000,
    "delegateName": "Yacine Belkacem",
    "expiresAt": "2026-11-06T10:05:00Z"
  },
  "openReturns": 0
}
FieldNotes
tracker[].stepAWAITING, VALIDATED, PREPARING, SHIPPED, DELIVERED — the client shows En attente, Validées, En préparation, Expédiées, Livrées; a tap lists statuses.
toConfirmThe assisted order awaiting my confirmation (at most one per reseller — lifecycle rule), pinned « À confirmer »; null when none.
openReturnsReturn requests not yet REFUNDED or REJECTED.

Errors — none specific.

Rules & side effects — read-only; counts by status of the reseller's non-draft orders. The app recomputes the counters locally from order.status_changed events and re-reads this call on resume.

Used by — header of RA-21, RW-08; the ORDERS badge of the home quick tiles.

GET /orders/{orderId}

orders.get · Access session — reseller (self) · Apps RA, RW · Idempotency-Key — · Release V1 · Requirements ORD-06, ORD-07, ORD-15

Purpose. Order detail and tracking: lines, totals, address, payment and invoice state, delivery and tracking number, dated status history, documents, assisted-order block, returns and claims, and the actions allowed now.

Request — path orderId. If-None-Match with the last ETag ("v{version}") returns 304 when nothing changed.

Response — 200 OK, ETag: "v6": an OrderDetail. Example: an order shipped by carrier, invoiced, not yet delivered.

{
  "id": "01a187cf-6b40-7c6f-894d-b1f256947da9",
  "number": "CMD-2026-000155",
  "version": 6,
  "status": "SHIPPED",
  "progressStep": 3,
  "awaitingConfirmation": null,
  "pendingReasons": [],
  "channel": "RESELLER_APP",
  "isFirstOrder": false,
  "createdAt": "2026-10-29T13:18:00Z",
  "submittedAt": "2026-10-29T13:18:00Z",
  "validatedAt": "2026-10-29T14:02:00Z",
  "updatedAt": "2026-10-30T15:05:10Z",
  "currency": "DZD",
  "itemsCount": 2,
  "unitsCount": 23,
  "lines": [
    {
      "id": "01a187cf-6b40-7ed2-a90c-470faa12c942",
      "product": { "id": "01a08ac7-1ce0-7b52-8b6a-3ec2aaccb8fb", "name": "HOCO X89 Câble USB-C", "brandName": "HOCO", "imageUrl": "https://cdn.hoco.dz/products/x89/x89-black-1-240.webp" },
      "variant": { "id": "01a08ac7-20c8-70bf-b753-d181dfe71ff6", "sku": "X89_BLACK_1M", "label": "Noir · 1 m" },
      "qty": 20,
      "price": { "ht": 105042, "ttc": 125000, "vatRate": 1900 },
      "promotionApplied": null,
      "lineTotals": { "subtotalHt": 2100840, "discountHt": 0, "totalHt": 2100840, "vat": 399160, "totalTtc": 2500000 },
      "originalQty": null,
      "returnedQty": 0,
      "claimedQty": 0,
      "returnableQty": 0
    },
    {
      "id": "01a187cf-6b40-70a2-8f15-fa52ec7fed43",
      "product": { "id": "01a08fe8-e500-7017-b062-03c53547a2be", "name": "ACEFAST A45 Chargeur rapide", "brandName": "ACEFAST", "imageUrl": "https://cdn.hoco.dz/products/a45/a45-black-1-240.webp" },
      "variant": { "id": "01a08fe8-e8e8-762d-81d1-ab0daa011e53", "sku": "A45_BLACK_EU", "label": "Noir" },
      "qty": 3,
      "price": { "ht": 331933, "ttc": 395000, "vatRate": 1900 },
      "promotionApplied": null,
      "lineTotals": { "subtotalHt": 995799, "discountHt": 0, "totalHt": 995799, "vat": 189201, "totalTtc": 1185000 },
      "originalQty": null,
      "returnedQty": 0,
      "claimedQty": 0,
      "returnableQty": 0
    }
  ],
  "totals": { "subtotalHt": 3096639, "discountTotal": 0, "deliveryFee": 0, "vatTotal": 588361, "totalTtc": 3685000, "currency": "DZD" },
  "displayTotals": { "itemsTtc": 3685000, "discountTtc": 0, "deliveryFeeTtc": 0, "totalTtc": 3685000 },
  "appliedPromotions": [],
  "address": {
    "id": "01a12f63-efa8-7f36-87fc-e386a4e58a22",
    "label": "Magasin",
    "recipientName": "Mohamed Benali",
    "phone": "+213555123456",
    "wilayaCode": "31",
    "wilayaName": "Oran",
    "communeId": "01a0c3e1-5d20-7a10-8b31-310300000003",
    "communeName": "Bir El Djir",
    "addressLine": "Cité USTO, local n° 14",
    "landmark": "En face de la pharmacie Benyahia",
    "isDefault": true
  },
  "note": null,
  "paymentMethod": "CASH_ON_DELIVERY",
  "paymentStatus": {
    "invoiced": true,
    "invoiceId": "01a18d53-2980-79c5-a4cd-4c9ba7aef490",
    "invoiceNumber": "FAC-2026-000124",
    "invoiceStatus": "UNPAID",
    "dueDate": "2026-11-29",
    "amountPaid": 0,
    "creditNotesTotal": 0,
    "balance": 3685000,
    "pendingVerificationAmount": 0
  },
  "delivery": {
    "status": "SHIPPED",
    "mode": "CARRIER",
    "carrierName": "Rapid Express DZ",
    "trackingNumber": "RX-31-884215",
    "trackingUrl": "https://suivi.rapidexpress.dz/RX-31-884215",
    "driverName": null,
    "driverPhone": null,
    "deliveryNoteNumber": "BL-2026-000141",
    "shippedAt": "2026-10-30T15:05:00Z",
    "deliveredAt": null,
    "recipientName": null
  },
  "statusHistory": [
    { "from": null, "to": "SUBMITTED", "at": "2026-10-29T13:18:00Z", "actor": { "id": "01a19c3e-5a10-7b21-8f4e-2c6d9a1b3e57", "displayName": "Mohamed Benali" } },
    { "from": "SUBMITTED", "to": "VALIDATED", "at": "2026-10-29T14:02:00Z", "actor": { "id": "01a05bfb-7000-7d71-b777-8df1872390e6", "displayName": "Équipe HOCO" } },
    { "from": "VALIDATED", "to": "PREPARING", "at": "2026-10-30T08:10:00Z", "actor": { "id": "01a05bfb-77d0-76d5-a064-865b3b84647b", "displayName": "Équipe HOCO" } },
    { "from": "PREPARING", "to": "READY", "at": "2026-10-30T11:40:00Z", "actor": { "id": "01a05bfb-77d0-76d5-a064-865b3b84647b", "displayName": "Équipe HOCO" } },
    { "from": "READY", "to": "SHIPPED", "at": "2026-10-30T15:05:00Z", "actor": { "id": "01a05bfb-77d0-76d5-a064-865b3b84647b", "displayName": "Équipe HOCO" } }
  ],
  "changes": [],
  "documents": [
    { "type": "INVOICE", "number": "FAC-2026-000124", "available": true, "generatedAt": "2026-10-30T15:05:10Z" },
    { "type": "DELIVERY_NOTE", "number": "BL-2026-000141", "available": true, "generatedAt": "2026-10-30T11:40:05Z" }
  ],
  "assisted": { "isAssisted": false, "delegate": null, "confirmation": null, "expiresAt": null, "confirmedAt": null, "rejectionReason": null },
  "cancellation": null,
  "refusal": null,
  "returns": [],
  "claims": [],
  "returnableUntil": null,
  "claimableUntil": null,
  "allowedActions": ["DOWNLOAD_INVOICE", "DOWNLOAD_DELIVERY_NOTE", "CONTACT_SUPPORT"]
}
FieldNotes
awaitingConfirmationBACK_OFFICE while SUBMITTED or PENDING waiting for HOCO (« En attente de confirmation par HOCO »); RESELLER for an assisted order waiting for me (« À confirmer »); null afterwards.
pendingReasonsWhy a PENDING order is on hold: AWAITING_RESELLER, CREDIT_OVER_LIMIT, RESELLER_NOT_VALIDATED, ON_HOLD (put on hold by HOCO; the public reason is in the last statusHistory entry).
paymentStatusBefore invoicing (invoiced: false) balance is the order total minus confirmed prepayments. The invoice is issued at billing.invoiceOn (default SHIPPED).
deliverytrackingUrl comes from the carrier's template; for OWN_FLEET the driver's name and phone replace the carrier (cahier §4.4 « suivi de livraison »).
changesControlled modifications by HOCO (ORD-06): each with the reason shown to the reseller and the old and new quantities; lines[].originalQty marks modified lines.
returnableQtyDrives the return form: delivered quantity minus what is already in a return or a claim (not rejected).

Errors

StatusCodeWhen
404NOT_FOUNDUnknown order, another reseller's order, or a DRAFT.

Rules & side effects

  1. Read-only. The reseller sees prices and totals as snapshotted at checkout (or as re-priced at an assisted confirmation, or after a controlled modification) — never today's prices.
  2. Live updates. The detail screen relies on events.stream: on order.status_changed or order.modified for this orderId, the client refetches orders.get (with If-None-Match); on return.status_changed it refreshes the returns block. When the stream is not connected (background, network loss) the push notification opens the screen, which then refetches. Nothing is polled.
  3. Internal data never appears: purchase prices, control results, override reasons, internal notes and staff names are back-office only (admin.orders.get).

Used by — RA-22 (« Suivi de commande »), RA-23, RW-09, deep links of order notifications.

POST /orders/{orderId}/cancel

orders.cancel · Access session — reseller (self) · Apps RA, RW · Idempotency-Key required · Release V1 · Requirements ORD-10

Purpose. « Annuler la commande » while the back-office has not confirmed it yet.

Request

interface CancelOrderRequest {
  reasonCode: string;                 // ORDER_CANCEL_REASON item open to resellers (reference.lists)
  comment?: string;                   // ≤ 300 characters; required when reasonCode is OTHER
}
{ "reasonCode": "DUPLICATE_ORDER", "comment": "Commande passée deux fois, je garde CMD-2026-000157." }

Response — 200 OK: the OrderDetail after cancellation.

{
  "id": "01a1a0c0-4e80-7095-bb23-dcbea2c9e1e5",
  "number": "CMD-2026-000158",
  "version": 2,
  "status": "CANCELLED",
  "progressStep": null,
  "awaitingConfirmation": null,
  "pendingReasons": [],
  "channel": "RESELLER_APP",
  "isFirstOrder": false,
  "createdAt": "2026-11-03T09:32:00Z",
  "submittedAt": "2026-11-03T09:32:00Z",
  "validatedAt": null,
  "updatedAt": "2026-11-03T09:41:00Z",
  "currency": "DZD",
  "itemsCount": 4,
  "unitsCount": 41,
  "lines": [
    {
      "id": "01a1a0c0-4e80-71dd-aedc-7a6b01b8a49d",
      "product": { "id": "01a0901f-d380-7a88-9746-4ec8936c3d68", "name": "BOROFONE BW06 Écouteurs TWS", "brandName": "BOROFONE", "imageUrl": "https://cdn.hoco.dz/products/bw06/bw06-white-1-240.webp" },
      "variant": { "id": "01a0901f-d768-77a1-94f2-1bca2251bdcd", "sku": "BW06_WHITE", "label": "Blanc" },
      "qty": 6,
      "price": { "ht": 250420, "ttc": 298000, "vatRate": 1900 },
      "promotionApplied": null,
      "lineTotals": { "subtotalHt": 1502520, "discountHt": 0, "totalHt": 1502520, "vat": 285480, "totalTtc": 1788000 },
      "originalQty": null,
      "returnedQty": 0,
      "claimedQty": 0,
      "returnableQty": 0
    },
    {
      "id": "01a1a0c0-4e80-7c52-8789-bdc2d7ba3b57",
      "product": { "id": "01a08ac2-8900-7f6d-937c-c81b37e89a5b", "name": "HOCO N32 Chargeur rapide 30W (USB-C + USB-A)", "brandName": "HOCO", "imageUrl": "https://cdn.hoco.dz/products/n32/n32-black-1-240.webp" },
      "variant": { "id": "01a08ac2-8ce8-7069-8328-28fd7158a572", "sku": "N32_BLACK_EU", "label": "Noir" },
      "qty": 10,
      "price": { "ht": 209244, "ttc": 249000, "vatRate": 1900 },
      "promotionApplied": null,
      "lineTotals": { "subtotalHt": 2092440, "discountHt": 0, "totalHt": 2092440, "vat": 397560, "totalTtc": 2490000 },
      "originalQty": null,
      "returnedQty": 0,
      "claimedQty": 0,
      "returnableQty": 0
    },
    {
      "id": "01a1a0c0-4e80-7e8e-8f06-3842302674ed",
      "product": { "id": "01a08ac7-1ce0-7b52-8b6a-3ec2aaccb8fb", "name": "HOCO X89 Câble USB-C", "brandName": "HOCO", "imageUrl": "https://cdn.hoco.dz/products/x89/x89-black-1-240.webp" },
      "variant": { "id": "01a08ac7-20c8-70bf-b753-d181dfe71ff6", "sku": "X89_BLACK_1M", "label": "Noir · 1 m" },
      "qty": 20,
      "price": { "ht": 105042, "ttc": 125000, "vatRate": 1900 },
      "promotionApplied": null,
      "lineTotals": { "subtotalHt": 2100840, "discountHt": 0, "totalHt": 2100840, "vat": 399160, "totalTtc": 2500000 },
      "originalQty": null,
      "returnedQty": 0,
      "claimedQty": 0,
      "returnableQty": 0
    },
    {
      "id": "01a1a0c0-4e80-75c9-a6c9-7ca88b6f19f9",
      "product": { "id": "01a15889-fa80-7ff3-b294-f863a2ee34a6", "name": "HOCO J86A Power Bank 10000mAh", "brandName": "HOCO", "imageUrl": "https://cdn.hoco.dz/products/j86a/j86a-black-1-240.webp" },
      "variant": { "id": "01a15889-fe68-733d-8056-75eec8b226f5", "sku": "J86A_BLACK", "label": "Noir" },
      "qty": 5,
      "price": { "ht": 302521, "ttc": 360000, "vatRate": 1900 },
      "promotionApplied": {
        "promotionId": "01a19cfd-2c00-78b5-80c8-b4b9fb167f17",
        "label": "Offre flash -30 %",
        "type": "PERCENT_OFF",
        "value": 3000,
        "unitPrice": { "ht": 211765, "ttc": 252000, "vatRate": 1900 },
        "endsAt": "2026-11-03T22:59:59Z"
      },
      "lineTotals": { "subtotalHt": 1512605, "discountHt": 453780, "totalHt": 1058825, "vat": 201175, "totalTtc": 1260000 },
      "originalQty": null,
      "returnedQty": 0,
      "claimedQty": 0,
      "returnableQty": 0
    }
  ],
  "totals": { "subtotalHt": 7208405, "discountTotal": 453780, "deliveryFee": 0, "vatTotal": 1283375, "totalTtc": 8038000, "currency": "DZD" },
  "displayTotals": { "itemsTtc": 8578000, "discountTtc": 540000, "deliveryFeeTtc": 0, "totalTtc": 8038000 },
  "appliedPromotions": [
    { "promotionId": "01a19cfd-2c00-78b5-80c8-b4b9fb167f17", "label": "Offre flash -30 %", "type": "PERCENT_OFF", "lineIds": ["01a1a0c0-4e80-75c9-a6c9-7ca88b6f19f9"], "discountHt": 453780, "discountTtc": 540000 }
  ],
  "address": {
    "id": "01a12f63-efa8-7f36-87fc-e386a4e58a22",
    "label": "Magasin",
    "recipientName": "Mohamed Benali",
    "phone": "+213555123456",
    "wilayaCode": "31",
    "wilayaName": "Oran",
    "communeId": "01a0c3e1-5d20-7a10-8b31-310300000003",
    "communeName": "Bir El Djir",
    "addressLine": "Cité USTO, local n° 14",
    "landmark": "En face de la pharmacie Benyahia",
    "isDefault": true
  },
  "note": "Merci d'appeler avant la livraison, le magasin ferme à 13h le vendredi.",
  "paymentMethod": "CASH_ON_DELIVERY",
  "paymentStatus": { "invoiced": false, "invoiceId": null, "invoiceNumber": null, "invoiceStatus": null, "dueDate": null, "amountPaid": 0, "creditNotesTotal": 0, "balance": 0, "pendingVerificationAmount": 0 },
  "delivery": { "status": null, "mode": null, "carrierName": null, "trackingNumber": null, "trackingUrl": null, "driverName": null, "driverPhone": null, "deliveryNoteNumber": null, "shippedAt": null, "deliveredAt": null, "recipientName": null },
  "statusHistory": [
    { "from": null, "to": "SUBMITTED", "at": "2026-11-03T09:32:00Z", "actor": { "id": "01a19c3e-5a10-7b21-8f4e-2c6d9a1b3e57", "displayName": "Mohamed Benali" } },
    { "from": "SUBMITTED", "to": "CANCELLED", "at": "2026-11-03T09:41:00Z", "actor": { "id": "01a19c3e-5a10-7b21-8f4e-2c6d9a1b3e57", "displayName": "Mohamed Benali" }, "reason": "Commande en double — Commande passée deux fois, je garde CMD-2026-000157." }
  ],
  "changes": [],
  "documents": [
    { "type": "INVOICE", "number": null, "available": false, "generatedAt": null },
    { "type": "DELIVERY_NOTE", "number": null, "available": false, "generatedAt": null }
  ],
  "assisted": { "isAssisted": false, "delegate": null, "confirmation": null, "expiresAt": null, "confirmedAt": null, "rejectionReason": null },
  "cancellation": { "reasonCode": "DUPLICATE_ORDER", "reasonLabel": "Commande en double", "comment": "Commande passée deux fois, je garde CMD-2026-000157.", "at": "2026-11-03T09:41:00Z", "by": "RESELLER" },
  "refusal": null,
  "returns": [],
  "claims": [],
  "returnableUntil": null,
  "claimableUntil": null,
  "allowedActions": ["REORDER", "CONTACT_SUPPORT"]
}

Errors

StatusCodeWhen
400VALIDATION_FAILEDreasonCode unknown, inactive or not open to resellers.
404NOT_FOUNDNot my order.
409ORDER_TRANSITION_NOT_ALLOWEDStatus not in orders.cancelAllowedStatuses — typically already confirmed (« Commande déjà confirmée : contactez le support »), or an assisted order awaiting my confirmation (use reject). details: { from, to: "CANCELLED", allowed }.
422REASON_REQUIREDOTHER without comment.

Rules & side effects

  1. Allowed only before the back-office confirmation: orders.cancelAllowedStatuses accepts SUBMITTED and PENDING only (exposed to the apps by appConfig.get). After confirmation the reseller contacts support; HOCO can still cancel until shipping (admin.orders.cancel).
  2. In one transaction: status CANCELLED, OrderStatusChange with the reason, reservations released automatically if any (stock.reserveOn = SUBMITTED), promotion caps given back, credit exposure released, first-order flag moved to the next order if this was the first (lifecycle).
  3. Outbox order.cancelled: the order leaves the confirmation queue, orders.validate holders get an in-app alert, the assigned delegate is informed; the reseller gets no push (own action) but the live event updates their other open screens.

Used by — « Annuler la commande » on RA-22 and RW-09.

POST /orders/{orderId}/confirm

orders.confirmAssisted · Access session — reseller (self), AccountStatus ACTIVE · Apps RA, RW · Idempotency-Key required · Release V1 · Requirements ORD-08

Contract 1.1.0 (SRV-41) — RA-23: the body also accepts paymentMethod, addressId (one of my addresses; 404 NOT_FOUND otherwise, 422 ADDRESS_MISSING without an address line) and note (≤ 500, replaces the delegate's). They are written with the confirmation; the order is re-priced for the chosen address (delivery fee) and method (credit checks), so expectedTotalTtc is the total shown for them — a different total answers 409 CART_CHANGED with the re-priced order.

Purpose. The reseller confirms the order their delegate prepared for them (cahier §4.4 « Une commande assistée doit être confirmée par le revendeur ou validée par l'administration », §6.7). The order is then submitted to the back-office like any order.

Request

interface ConfirmAssistedRequest {
  expectedTotalTtc: Money;            // total shown on RA-23
}
{ "expectedTotalTtc": 2495000 }

Response — 200 OK: the OrderDetail, now SUBMITTED and waiting for the back-office.

{
  "id": "01a1a0de-84e0-79ad-9ae7-a8167cc6fcaa",
  "number": "CMD-2026-000159",
  "version": 3,
  "status": "SUBMITTED",
  "progressStep": 0,
  "awaitingConfirmation": "BACK_OFFICE",
  "pendingReasons": [],
  "channel": "DELEGATE_ASSISTED",
  "isFirstOrder": false,
  "createdAt": "2026-11-03T10:05:00Z",
  "submittedAt": "2026-11-03T18:20:00Z",
  "validatedAt": null,
  "updatedAt": "2026-11-03T18:20:00Z",
  "currency": "DZD",
  "itemsCount": 2,
  "unitsCount": 15,
  "lines": [
    {
      "id": "01a1a0de-84e0-75c9-8cd5-80f3fe61a689",
      "product": { "id": "01a08ac2-8900-7f6d-937c-c81b37e89a5b", "name": "HOCO N32 Chargeur rapide 30W (USB-C + USB-A)", "brandName": "HOCO", "imageUrl": "https://cdn.hoco.dz/products/n32/n32-black-1-240.webp" },
      "variant": { "id": "01a08ac2-8ce8-7069-8328-28fd7158a572", "sku": "N32_BLACK_EU", "label": "Noir" },
      "qty": 5,
      "price": { "ht": 209244, "ttc": 249000, "vatRate": 1900 },
      "promotionApplied": null,
      "lineTotals": { "subtotalHt": 1046220, "discountHt": 0, "totalHt": 1046220, "vat": 198780, "totalTtc": 1245000 },
      "originalQty": null,
      "returnedQty": 0,
      "claimedQty": 0,
      "returnableQty": 0
    },
    {
      "id": "01a1a0de-84e0-721a-acd6-1f49ea0f9f86",
      "product": { "id": "01a08ac7-1ce0-7b52-8b6a-3ec2aaccb8fb", "name": "HOCO X89 Câble USB-C", "brandName": "HOCO", "imageUrl": "https://cdn.hoco.dz/products/x89/x89-black-1-240.webp" },
      "variant": { "id": "01a08ac7-20c8-70bf-b753-d181dfe71ff6", "sku": "X89_BLACK_1M", "label": "Noir · 1 m" },
      "qty": 10,
      "price": { "ht": 105042, "ttc": 125000, "vatRate": 1900 },
      "promotionApplied": null,
      "lineTotals": { "subtotalHt": 1050420, "discountHt": 0, "totalHt": 1050420, "vat": 199580, "totalTtc": 1250000 },
      "originalQty": null,
      "returnedQty": 0,
      "claimedQty": 0,
      "returnableQty": 0
    }
  ],
  "totals": { "subtotalHt": 2096640, "discountTotal": 0, "deliveryFee": 0, "vatTotal": 398360, "totalTtc": 2495000, "currency": "DZD" },
  "displayTotals": { "itemsTtc": 2495000, "discountTtc": 0, "deliveryFeeTtc": 0, "totalTtc": 2495000 },
  "appliedPromotions": [],
  "address": {
    "id": "01a12f63-efa8-7f36-87fc-e386a4e58a22",
    "label": "Magasin",
    "recipientName": "Mohamed Benali",
    "phone": "+213555123456",
    "wilayaCode": "31",
    "wilayaName": "Oran",
    "communeId": "01a0c3e1-5d20-7a10-8b31-310300000003",
    "communeName": "Bir El Djir",
    "addressLine": "Cité USTO, local n° 14",
    "landmark": "En face de la pharmacie Benyahia",
    "isDefault": true
  },
  "note": "Préparée avec Yacine lors de la visite du 3 novembre.",
  "paymentMethod": "CASH_ON_DELIVERY",
  "paymentStatus": { "invoiced": false, "invoiceId": null, "invoiceNumber": null, "invoiceStatus": null, "dueDate": null, "amountPaid": 0, "creditNotesTotal": 0, "balance": 2495000, "pendingVerificationAmount": 0 },
  "delivery": { "status": null, "mode": null, "carrierName": null, "trackingNumber": null, "trackingUrl": null, "driverName": null, "driverPhone": null, "deliveryNoteNumber": null, "shippedAt": null, "deliveredAt": null, "recipientName": null },
  "statusHistory": [
    { "from": "DRAFT", "to": "PENDING", "at": "2026-11-03T10:05:00Z", "actor": { "id": "01a0f2b1-7d3c-7a45-9e61-0b2c3d4e5f60", "displayName": "Yacine Belkacem" }, "reason": "En attente de votre confirmation" },
    { "from": "PENDING", "to": "SUBMITTED", "at": "2026-11-03T18:20:00Z", "actor": { "id": "01a19c3e-5a10-7b21-8f4e-2c6d9a1b3e57", "displayName": "Mohamed Benali" } }
  ],
  "changes": [],
  "documents": [
    { "type": "INVOICE", "number": null, "available": false, "generatedAt": null },
    { "type": "DELIVERY_NOTE", "number": null, "available": false, "generatedAt": null }
  ],
  "assisted": {
    "isAssisted": true,
    "delegate": { "id": "01a0f2b1-7d3c-7a45-9e61-0b2c3d4e5f60", "displayName": "Yacine Belkacem", "phone": "+213770123456" },
    "confirmation": "CONFIRMED_BY_RESELLER",
    "expiresAt": "2026-11-06T10:05:00Z",
    "confirmedAt": "2026-11-03T18:20:00Z",
    "rejectionReason": null
  },
  "cancellation": null,
  "refusal": null,
  "returns": [],
  "claims": [],
  "returnableUntil": null,
  "claimableUntil": null,
  "allowedActions": ["CANCEL", "CONTACT_SUPPORT"]
}

Errors

StatusCodeWhen
403ACCOUNT_PENDING_VALIDATIONMy account is not validated yet — the administration can confirm on my behalf (admin.orders.confirmAssisted).
403RESELLER_SUSPENDEDCommercial block.
404NOT_FOUNDNot my order.
409ORDER_TRANSITION_NOT_ALLOWEDNot an assisted order awaiting my confirmation (already confirmed by the administration, rejected, cancelled). A second confirmation of an order I already confirmed returns 200 with the current detail instead (double tap from two devices).
409ASSISTED_ORDER_EXPIREDassisted.expiresAt has passed, even if the expiry job has not run yet (details.expiresAt).
409CART_CHANGEDThe re-priced total differs from expectedTotalTtc. details: { expectedTotalTtc, actualTotalTtc, order: OrderDetail } — the re-priced order is saved (version +1) and shown again; the reseller confirms with the new total and a new Idempotency-Key.
422PRODUCT_UNAVAILABLE · STOCK_INSUFFICIENT · ORDER_MIN_AMOUNT_NOT_MET · CREDIT_LIMIT_EXCEEDEDSame controls as a checkout (lifecycle); details.issues. The reseller asks the delegate to adjust the order or rejects it.

Rules & side effects

  1. The order is re-priced and re-controlled at confirmation exactly as a checkout (cahier §6.7 « Le prix, le stock et le crédit sont contrôlés comme pour une commande normale »); expectedTotalTtc protects the reseller from confirming a total they did not see. Assumption — honouring the price quoted by the delegate during the 72-hour window instead of re-pricing is an open question for HOCO.
  2. In one transaction: confirmation CONFIRMED_BY_RESELLER, status PENDING → SUBMITTED (or stays PENDING with RESELLER_NOT_VALIDATED / CREDIT_OVER_LIMIT), promotion caps consumed, first-order flag and attribution to the source delegate (ORD-09) — then the same side effects as cart.checkout: the order joins the back-office confirmation queue.
  3. Outbox assisted_order.confirmed (push to the delegate) and order.submitted.

Used by — « Confirmer la commande » on RA-23 and RW-09, reached from the push or the « À confirmer » pin.

POST /orders/{orderId}/reject

orders.rejectAssisted · Access session — reseller (self) · Apps RA, RW · Idempotency-Key required · Release V1 · Requirements ORD-08

Contract 1.1.0 (SRV-41): send reasonCode (a code of the ASSISTED_REJECT_REASON reference list: WRONG_ITEMS, TOO_EXPENSIVE, NOT_REQUESTED, LATER, OTHER) and an optional comment (≤ 300, required for OTHER); the stored reason is « label — comment ». The free-text reason stays accepted; one of the two is required (400 VALIDATION_FAILED, field reasonCode).

Purpose. The reseller declines the assisted order, with a reason the delegate will read.

Request

interface RejectAssistedRequest {
  reason: string;                     // 3–300 characters
}
{ "reason": "Je préfère commander moi-même la semaine prochaine, après mon inventaire." }

Response — 200 OK: the OrderDetail with status: "CANCELLED", assisted.confirmation: "REJECTED_BY_RESELLER", assisted.rejectionReason set, cancellation: { "reasonCode": "REJECTED_BY_RESELLER", "reasonLabel": "Refusée par le revendeur", "by": "RESELLER", … } and allowedActions: ["REORDER", "CONTACT_SUPPORT"]. Excerpt of what changes from the confirmation example above:

{
  "id": "01a1a0de-84e0-79ad-9ae7-a8167cc6fcaa",
  "number": "CMD-2026-000159",
  "version": 3,
  "status": "CANCELLED",
  "progressStep": null,
  "awaitingConfirmation": null,
  "statusHistory": [
    { "from": "DRAFT", "to": "PENDING", "at": "2026-11-03T10:05:00Z", "actor": { "id": "01a0f2b1-7d3c-7a45-9e61-0b2c3d4e5f60", "displayName": "Yacine Belkacem" }, "reason": "En attente de votre confirmation" },
    { "from": "PENDING", "to": "CANCELLED", "at": "2026-11-03T18:20:00Z", "actor": { "id": "01a19c3e-5a10-7b21-8f4e-2c6d9a1b3e57", "displayName": "Mohamed Benali" }, "reason": "Refusée par le revendeur — Je préfère commander moi-même la semaine prochaine, après mon inventaire." }
  ],
  "assisted": {
    "isAssisted": true,
    "delegate": { "id": "01a0f2b1-7d3c-7a45-9e61-0b2c3d4e5f60", "displayName": "Yacine Belkacem", "phone": "+213770123456" },
    "confirmation": "REJECTED_BY_RESELLER",
    "expiresAt": "2026-11-06T10:05:00Z",
    "confirmedAt": null,
    "rejectionReason": "Je préfère commander moi-même la semaine prochaine, après mon inventaire."
  },
  "cancellation": {
    "reasonCode": "REJECTED_BY_RESELLER",
    "reasonLabel": "Refusée par le revendeur",
    "comment": "Je préfère commander moi-même la semaine prochaine, après mon inventaire.",
    "at": "2026-11-03T18:20:00Z",
    "by": "RESELLER"
  },
  "allowedActions": ["REORDER", "CONTACT_SUPPORT"]
}

All other fields keep the values shown in the confirmation example (the full OrderDetail is always returned).

Errors

StatusCodeWhen
400VALIDATION_FAILEDreason shorter than 3 or longer than 300 characters.
404NOT_FOUNDNot my order.
409ORDER_TRANSITION_NOT_ALLOWEDNot awaiting my confirmation.
409ASSISTED_ORDER_EXPIREDAlready expired (it is cancelled by the job anyway).

Rules & side effects — status CANCELLED with the system reason « Refusée par le revendeur » (locked ORDER_CANCEL_REASON item); nothing was reserved or consumed, so there is nothing to release; outbox assisted_order.rejected → push to the delegate with the reason (DA-18). The delegate may prepare a new assisted order afterwards.

Used by — « Refuser » on RA-23 and RW-09.

POST /orders/{orderId}/reorder

orders.reorder · Access session — reseller (self) · Apps RA, RW · Idempotency-Key required · Release V1 · Requirements ORD-07

Purpose. « Recommander » (cahier §5.4): copies the lines of a past order into my cart at today's prices and tells me which lines could not be copied.

Request

interface ReorderRequest {
  mode?: "MERGE" | "REPLACE";         // default MERGE: add to the current cart; REPLACE empties it first
}
{ "mode": "MERGE" }

Response — 200 OK.

interface ReorderResult {
  cart: CartView;                     // see the cart page
  addedLines: number;
  unavailableLines: { orderItemId: Uuid; sku: string; productName: string; qty: number;
                      reason: "PRODUCT_UNAVAILABLE" | "OUT_OF_STOCK" }[];
  adjustedLines: { orderItemId: Uuid; sku: string; productName: string; fromQty: number; toQty: number;
                   reason: "QUANTITY_RULES" }[];
}

Example — reordering CMD-2026-000154 (delivered: X89 × 20, A45 × 3, CA91 × 10) into an empty cart; the CA91 car holder has been archived since.

{
  "cart": {
    "id": "01a1396c-e400-70fe-bda9-3dc62fcad676",
    "updatedAt": "2026-11-05T08:10:00Z",
    "itemsCount": 2,
    "unitsCount": 23,
    "lines": [
      {
        "id": "01a1aac1-f3c0-7b47-9126-75c245282858",
        "kind": "VARIANT",
        "product": { "id": "01a08ac7-1ce0-7b52-8b6a-3ec2aaccb8fb", "name": "HOCO X89 Câble USB-C", "brandName": "HOCO", "imageUrl": "https://cdn.hoco.dz/products/x89/x89-black-1-240.webp" },
        "variant": { "id": "01a08ac7-20c8-70bf-b753-d181dfe71ff6", "sku": "X89_BLACK_1M", "label": "Noir · 1 m" },
        "qty": 20,
        "limits": { "minQty": 5, "qtyStep": 5, "maxQtyPerOrder": 200 },
        "price": { "ht": 105042, "ttc": 125000, "vatRate": 1900 },
        "promotionApplied": null,
        "lineTotals": { "subtotalHt": 2100840, "discountHt": 0, "totalHt": 2100840, "vat": 399160, "totalTtc": 2500000 },
        "availability": "IN_STOCK",
        "addedAt": "2026-11-05T08:10:00Z",
        "issues": []
      },
      {
        "id": "01a1aac1-f3c0-73a0-af10-be1da58e9e4b",
        "kind": "VARIANT",
        "product": { "id": "01a08fe8-e500-7017-b062-03c53547a2be", "name": "ACEFAST A45 Chargeur rapide", "brandName": "ACEFAST", "imageUrl": "https://cdn.hoco.dz/products/a45/a45-black-1-240.webp" },
        "variant": { "id": "01a08fe8-e8e8-762d-81d1-ab0daa011e53", "sku": "A45_BLACK_EU", "label": "Noir" },
        "qty": 3,
        "limits": { "minQty": 1, "qtyStep": 1, "maxQtyPerOrder": 30 },
        "price": { "ht": 331933, "ttc": 395000, "vatRate": 1900 },
        "promotionApplied": null,
        "lineTotals": { "subtotalHt": 995799, "discountHt": 0, "totalHt": 995799, "vat": 189201, "totalTtc": 1185000 },
        "availability": "IN_STOCK",
        "addedAt": "2026-11-05T08:10:00Z",
        "issues": []
      }
    ],
    "totals": { "subtotalHt": 3096639, "discountTotal": 0, "deliveryFee": 0, "vatTotal": 588361, "totalTtc": 3685000, "currency": "DZD" },
    "displayTotals": { "itemsTtc": 3685000, "discountTtc": 0, "deliveryFeeTtc": 0, "totalTtc": 3685000 },
    "appliedPromotions": [],
    "delivery": { "addressId": "01a12f63-efa8-7f36-87fc-e386a4e58a22", "feePolicy": "FREE", "isFree": true, "freeThresholdTtc": null },
    "minimumOrder": { "amountTtc": 1000000, "met": true, "missingTtc": 0 },
    "issues": [],
    "canCheckout": true
  },
  "addedLines": 2,
  "unavailableLines": [
    { "orderItemId": "01a17cd2-00e0-7c68-a5a6-21eea8b7a786", "sku": "CA91_BLACK", "productName": "HOCO CA91 Support voiture magnétique", "qty": 10, "reason": "PRODUCT_UNAVAILABLE" }
  ],
  "adjustedLines": []
}

Errors

StatusCodeWhen
404NOT_FOUNDNot my order.
409ORDER_TRANSITION_NOT_ALLOWEDStatus not DELIVERED, CANCELLED, REFUSED or RETURNED (details.allowed).
422CART_LINE_LIMIT_REACHEDThe merged cart would exceed 100 lines; nothing is added.
422NOTHING_TO_REORDERNo line of the order can be added (all unavailable); the cart is unchanged and details.unavailableLines lists why.

Rules & side effects

  1. Each order line is added like cart.items.add with the order's quantity, at today's price for my customer type and today's promotions.
  2. Lines whose product is no longer visible or orderable, or whose variant is out of stock, are skipped and reported in unavailableLines. A quantity that no longer fits the variant's rules (minimum, step, maximum) is moved to the nearest allowed quantity and reported in adjustedLines.
  3. A line in stock whose full quantity is not available is still added, with its quantity, and carries the blocking STOCK_INSUFFICIENT issue in the returned cart (no quantity is revealed); the reseller lowers it in the cart.
  4. The client opens the cart (RA-17) and shows the reported lines in a banner.

Used by — « Recommander » on RA-21, RA-22, RW-08, RW-09.

GET /orders/{orderId}/documents/{type}

orders.document · Access session — reseller (self) · Apps RA, RW · Idempotency-Key — · Release V1 · Requirements ORD-12, FIN-01

Purpose. « Télécharger la facture » (reference screen 6) or the delivery note: returns a short-lived signed link to the PDF.

Request

Path / queryTypeRequiredNotes
orderIdUuidyes
typeINVOICE | DELIVERY_NOTEyes
downloadbooleannotrue → Content-Disposition: attachment (web download); default false (in-app viewer)
GET /v1/orders/01a187cf-6b40-7c6f-894d-b1f256947da9/documents/INVOICE?download=true

Response — 200 OK, Cache-Control: no-store.

{
  "type": "INVOICE",
  "number": "FAC-2026-000124",
  "fileName": "FAC-2026-000124_Magasin_El_Wafa.pdf",
  "file": {
    "id": "01a18d53-40f0-7e81-8297-383013436902",
    "url": "https://storage.hoco.dz/hoco-private/generated_document/2026/10/01a18d53-40f0-7e81-8297-383013436902.pdf?X-Amz-Expires=300&response-content-disposition=attachment%3B%20filename%3D%22FAC-2026-000124_Magasin_El_Wafa.pdf%22&X-Amz-Signature=5be1…",
    "mimeType": "application/pdf",
    "size": 48213,
    "purpose": "GENERATED_DOCUMENT"
  },
  "expiresAt": "2026-11-03T09:35:00Z",
  "generatedAt": "2026-10-30T15:05:10Z"
}

Errors

StatusCodeWhen
400VALIDATION_FAILEDtype not INVOICE or DELIVERY_NOTE.
404NOT_FOUNDNot my order.
404DOCUMENT_NOT_AVAILABLENot generated yet: the delivery note exists from READY, the invoice from billing.invoiceOn (default SHIPPED); or the invoice was cancelled (details.reason: NOT_GENERATED, CANCELLED).

Rules & side effects — the URL is valid 5 minutes (files) and each issued URL is logged with user and time; the PDF is the latest version (a regeneration never changes amounts). Credit notes are reached from returns and invoices.

Used by — RA-22 (« Télécharger la facture », « Bon de livraison »), RW-09, and the invoice screens RA-30, RW-13.

POST /orders/{orderId}/returns

returns.create · Access session — reseller (self) · Apps RA, RW · Idempotency-Key required · Release V1 · Requirements ORD-13, STK-03

Contract 1.1.0 (SRV-41): send reasonCode (a code of the RETURN_REASON reference list: DAMAGED_ON_DELIVERY, DEFECTIVE, WRONG_ITEM, NOT_AS_DESCRIBED, OVERSTOCK, OTHER) and reason as an optional detail (required for OTHER), or reason alone (≥ 10 characters) as before. The return keeps the code in reasonCode (ReturnView) and « label — detail » in reason.

Purpose. « Demander un retour »: asks HOCO to take back items of a delivered order (wrong, damaged or defective items noticed after delivery), with photos.

Request

interface CreateReturnRequest {
  reason: string;                     // 10–500 characters, shown to the back-office
  items: {
    orderItemId: Uuid;                // OrderDetail.lines[].id
    qty: number;                      // 1 … returnableQty
    photoFileIds: Uuid[];             // 0–4 TICKET_ATTACHMENT files per item; at least one photo per request
  }[];                                // 1–50 items, each orderItemId once
}
{
  "reason": "Deux câbles X89 arrivés coupés dans le carton et un chargeur A45 qui ne s'allume pas.",
  "items": [
    { "orderItemId": "01a17cd2-00e0-7829-8228-5952ab20d8f4", "qty": 2, "photoFileIds": ["01a1a0f4-2b10-7c31-9d42-5e6f708192a3"] },
    { "orderItemId": "01a17cd2-00e0-7e2c-ad45-104861602e5d", "qty": 1, "photoFileIds": ["01a1a0f4-3c21-7d42-8e53-6f708192a3b4"] }
  ]
}

Response — 201 Created, Location: /v1/returns/01a1a0f6-1a00-7b5c-8d6e-7f8091a2b3c4: a ReturnView in REQUESTED.

{
  "id": "01a1a0f6-1a00-7b5c-8d6e-7f8091a2b3c4",
  "number": "RET-2026-000012",
  "status": "REQUESTED",
  "origin": "RESELLER",
  "order": { "id": "01a17cd2-00e0-7779-8e81-ceca0079d9c9", "number": "CMD-2026-000154", "deliveredAt": "2026-10-28T11:40:00Z" },
  "ticket": null,
  "reason": "Deux câbles X89 arrivés coupés dans le carton et un chargeur A45 qui ne s'allume pas.",
  "items": [
    {
      "id": "01a1a0f6-1a00-7c11-9a22-0b1c2d3e4f50",
      "orderItemId": "01a17cd2-00e0-7829-8228-5952ab20d8f4",
      "product": { "id": "01a08ac7-1ce0-7b52-8b6a-3ec2aaccb8fb", "name": "HOCO X89 Câble USB-C", "imageUrl": "https://cdn.hoco.dz/products/x89/x89-black-1-240.webp" },
      "variant": { "id": "01a08ac7-20c8-70bf-b753-d181dfe71ff6", "sku": "X89_BLACK_1M", "label": "Noir · 1 m" },
      "qty": 2,
      "unitPrice": { "ht": 105042, "ttc": 125000, "vatRate": 1900 },
      "amountTtc": 250000,
      "photos": [
        { "id": "01a1a0f4-2b10-7c31-9d42-5e6f708192a3", "url": "https://storage.hoco.dz/hoco-private/ticket_attachment/2026/11/01a1a0f4-2b10-7c31-9d42-5e6f708192a3.webp?X-Amz-Expires=300&X-Amz-Signature=91ac…", "thumbnailUrl": "https://storage.hoco.dz/hoco-private/ticket_attachment/2026/11/01a1a0f4-2b10-7c31-9d42-5e6f708192a3-thumb.webp?X-Amz-Expires=300&X-Amz-Signature=02bd…", "mimeType": "image/webp", "size": 214876, "purpose": "TICKET_ATTACHMENT" }
      ],
      "receivedQty": null,
      "acceptedQty": null,
      "refusalReason": null
    },
    {
      "id": "01a1a0f6-1a00-7d22-8b33-1c2d3e4f5061",
      "orderItemId": "01a17cd2-00e0-7e2c-ad45-104861602e5d",
      "product": { "id": "01a08fe8-e500-7017-b062-03c53547a2be", "name": "ACEFAST A45 Chargeur rapide", "imageUrl": "https://cdn.hoco.dz/products/a45/a45-black-1-240.webp" },
      "variant": { "id": "01a08fe8-e8e8-762d-81d1-ab0daa011e53", "sku": "A45_BLACK_EU", "label": "Noir" },
      "qty": 1,
      "unitPrice": { "ht": 331933, "ttc": 395000, "vatRate": 1900 },
      "amountTtc": 395000,
      "photos": [
        { "id": "01a1a0f4-3c21-7d42-8e53-6f708192a3b4", "url": "https://storage.hoco.dz/hoco-private/ticket_attachment/2026/11/01a1a0f4-3c21-7d42-8e53-6f708192a3b4.webp?X-Amz-Expires=300&X-Amz-Signature=7d10…", "thumbnailUrl": "https://storage.hoco.dz/hoco-private/ticket_attachment/2026/11/01a1a0f4-3c21-7d42-8e53-6f708192a3b4-thumb.webp?X-Amz-Expires=300&X-Amz-Signature=c4e2…", "mimeType": "image/webp", "size": 187340, "purpose": "TICKET_ATTACHMENT" }
      ],
      "receivedQty": null,
      "acceptedQty": null,
      "refusalReason": null
    }
  ],
  "amountTtc": 645000,
  "instructions": null,
  "transport": null,
  "rejectionReason": null,
  "creditNote": null,
  "statusHistory": [
    { "from": null, "to": "REQUESTED", "at": "2026-11-03T15:20:00Z", "actor": { "id": "01a19c3e-5a10-7b21-8f4e-2c6d9a1b3e57", "displayName": "Mohamed Benali" } }
  ],
  "requestedAt": "2026-11-03T15:20:00Z",
  "updatedAt": "2026-11-03T15:20:00Z"
}

Errors

StatusCodeWhen
400VALIDATION_FAILEDField codes: TOO_SHORT (reason), PHOTO_REQUIRED (no photo in the whole request), TOO_MANY (more than 4 photos on an item), DUPLICATE_ITEM, UNKNOWN_ORDER_ITEM (not a line of this order), FILE_NOT_FOUND (unknown or not uploaded by me), FILE_ALREADY_ATTACHED.
403RESELLER_SUSPENDEDCommercial block.
404NOT_FOUNDNot my order.
422FILE_NOT_READYA photo's upload was not completed (files).
422FILE_PURPOSE_MISMATCHA photo was not uploaded with purpose TICKET_ATTACHMENT.
409ORDER_NOT_DELIVEREDThe order is not DELIVERED (details.status).
422RETURN_WINDOW_EXPIREDMore than returns.windowDays (default 7) after deliveredAt (details.returnableUntil). For warranty problems the app offers an after-sales claim instead (OPEN_CLAIM).
422RETURN_QTY_EXCEEDS_DELIVEREDqty above the line's returnableQty (delivered − already returned − already claimed), details.lines: [{ orderItemId, returnableQty }].

Rules & side effects

  1. ReturnRequest + ReturnItem rows, number RET-YYYY-NNNNNN, status REQUESTED, origin RESELLER; the photos are attached (they become readable by staff with orders.view).
  2. Nothing moves in stock or finance yet: the back-office approves or rejects (admin.returns.decide), sets the transport and instructions, and at reception (admin.returns.receive) the accepted quantities re-enter stock automatically and a credit note is issued (lifecycle, FIN-08).
  3. Outbox return.requested: SSE and in-app alert to orders.validate holders (returns queue BO-69), acknowledgement in the reseller's inbox; every later status change reaches the reseller live (return.status_changed) and by push.
  4. The order keeps DELIVERED; it becomes RETURNED only when every delivered unit has come back.

Used by — RA-40 (« Demande de retour », from « Demander un retour » on RA-22), RW-14.

GET /returns

returns.list · Access session — reseller (self) · Apps RA, RW · Idempotency-Key — · Release V1 · Requirements ORD-13

Purpose. My return requests with their status, newest first.

Request

QueryTypeRequiredNotes
statusReturnStatus, repeatableno
orderIdUuidnoReturns of one order
cursor, limit—nolimit default 20, max 100

Response — 200 OK: { items: ReturnSummary[], nextCursor } where ReturnSummary = { id, number, status, origin, order { id, number }, itemsCount, unitsCount, amountTtc, creditNote { number, amountTtc } | null, requestedAt, updatedAt }.

{
  "items": [
    {
      "id": "01a1a0f6-1a00-7b5c-8d6e-7f8091a2b3c4",
      "number": "RET-2026-000012",
      "status": "REFUNDED",
      "origin": "RESELLER",
      "order": { "id": "01a17cd2-00e0-7779-8e81-ceca0079d9c9", "number": "CMD-2026-000154" },
      "itemsCount": 2,
      "unitsCount": 3,
      "amountTtc": 645000,
      "creditNote": { "number": "AV-2026-000004", "amountTtc": 645000 },
      "requestedAt": "2026-11-03T15:20:00Z",
      "updatedAt": "2026-11-06T10:30:00Z"
    },
    {
      "id": "01a10f2a-6c00-7e41-9b52-3d4e5f607182",
      "number": "RET-2026-000009",
      "status": "REJECTED",
      "origin": "RESELLER",
      "order": { "id": "01a1065b-2900-748c-88c5-976d443033f4", "number": "CMD-2026-000131" },
      "itemsCount": 1,
      "unitsCount": 8,
      "amountTtc": 2304000,
      "creditNote": null,
      "requestedAt": "2026-10-09T10:12:00Z",
      "updatedAt": "2026-10-09T15:40:00Z"
    }
  ],
  "nextCursor": null
}

Errors — 400 VALIDATION_FAILED for an unknown status.

Rules & side effects — read-only; includes returns created by an after-sales resolution (origin: AFTER_SALES).

Used by — returns section of RA-40 and of RW-14; returns block of RA-22.

GET /returns/{returnId}

returns.get · Access session — reseller (self) · Apps RA, RW · Idempotency-Key — · Release V1 · Requirements ORD-13, FIN-08

Purpose. A return with its lines, the instructions to send the goods back, the inspection result, the status history and the credit note.

Request — path returnId.

Response — 200 OK: a ReturnView. Example: RET-2026-000012 three days later — collected by the delegate, inspected, credited.

{
  "id": "01a1a0f6-1a00-7b5c-8d6e-7f8091a2b3c4",
  "number": "RET-2026-000012",
  "status": "REFUNDED",
  "origin": "RESELLER",
  "order": { "id": "01a17cd2-00e0-7779-8e81-ceca0079d9c9", "number": "CMD-2026-000154", "deliveredAt": "2026-10-28T11:40:00Z" },
  "ticket": null,
  "reason": "Deux câbles X89 arrivés coupés dans le carton et un chargeur A45 qui ne s'allume pas.",
  "items": [
    {
      "id": "01a1a0f6-1a00-7c11-9a22-0b1c2d3e4f50",
      "orderItemId": "01a17cd2-00e0-7829-8228-5952ab20d8f4",
      "product": { "id": "01a08ac7-1ce0-7b52-8b6a-3ec2aaccb8fb", "name": "HOCO X89 Câble USB-C", "imageUrl": "https://cdn.hoco.dz/products/x89/x89-black-1-240.webp" },
      "variant": { "id": "01a08ac7-20c8-70bf-b753-d181dfe71ff6", "sku": "X89_BLACK_1M", "label": "Noir · 1 m" },
      "qty": 2,
      "unitPrice": { "ht": 105042, "ttc": 125000, "vatRate": 1900 },
      "amountTtc": 250000,
      "photos": [
        { "id": "01a1a0f4-2b10-7c31-9d42-5e6f708192a3", "url": "https://storage.hoco.dz/hoco-private/ticket_attachment/2026/11/01a1a0f4-2b10-7c31-9d42-5e6f708192a3.webp?X-Amz-Expires=300&X-Amz-Signature=3f8e…", "thumbnailUrl": "https://storage.hoco.dz/hoco-private/ticket_attachment/2026/11/01a1a0f4-2b10-7c31-9d42-5e6f708192a3-thumb.webp?X-Amz-Expires=300&X-Amz-Signature=a6b0…", "mimeType": "image/webp", "size": 214876, "purpose": "TICKET_ATTACHMENT" }
      ],
      "receivedQty": 2,
      "acceptedQty": 2,
      "refusalReason": null
    },
    {
      "id": "01a1a0f6-1a00-7d22-8b33-1c2d3e4f5061",
      "orderItemId": "01a17cd2-00e0-7e2c-ad45-104861602e5d",
      "product": { "id": "01a08fe8-e500-7017-b062-03c53547a2be", "name": "ACEFAST A45 Chargeur rapide", "imageUrl": "https://cdn.hoco.dz/products/a45/a45-black-1-240.webp" },
      "variant": { "id": "01a08fe8-e8e8-762d-81d1-ab0daa011e53", "sku": "A45_BLACK_EU", "label": "Noir" },
      "qty": 1,
      "unitPrice": { "ht": 331933, "ttc": 395000, "vatRate": 1900 },
      "amountTtc": 395000,
      "photos": [
        { "id": "01a1a0f4-3c21-7d42-8e53-6f708192a3b4", "url": "https://storage.hoco.dz/hoco-private/ticket_attachment/2026/11/01a1a0f4-3c21-7d42-8e53-6f708192a3b4.webp?X-Amz-Expires=300&X-Amz-Signature=b21d…", "thumbnailUrl": "https://storage.hoco.dz/hoco-private/ticket_attachment/2026/11/01a1a0f4-3c21-7d42-8e53-6f708192a3b4-thumb.webp?X-Amz-Expires=300&X-Amz-Signature=e95c…", "mimeType": "image/webp", "size": 187340, "purpose": "TICKET_ATTACHMENT" }
      ],
      "receivedQty": 1,
      "acceptedQty": 1,
      "refusalReason": null
    }
  ],
  "amountTtc": 645000,
  "instructions": "Votre délégué Yacine récupère les articles lors de sa visite du jeudi 5 novembre. Gardez-les dans leur emballage d'origine.",
  "transport": { "mode": "DELEGATE_PICKUP", "scheduledFor": "2026-11-05", "trackingNumber": null },
  "rejectionReason": null,
  "creditNote": {
    "id": "01a1a8c2-5e00-7a61-8b72-9c0d1e2f3a4b",
    "number": "AV-2026-000004",
    "amountTtc": 645000,
    "issuedAt": "2026-11-06T10:30:00Z",
    "file": {
      "id": "01a1a8c2-6f11-7b72-9c83-0d1e2f3a4b5c",
      "url": "https://storage.hoco.dz/hoco-private/generated_document/2026/11/01a1a8c2-6f11-7b72-9c83-0d1e2f3a4b5c.pdf?X-Amz-Expires=300&X-Amz-Signature=d4a7…",
      "mimeType": "application/pdf",
      "size": 39804,
      "purpose": "GENERATED_DOCUMENT"
    }
  },
  "statusHistory": [
    { "from": null, "to": "REQUESTED", "at": "2026-11-03T15:20:00Z", "actor": { "id": "01a19c3e-5a10-7b21-8f4e-2c6d9a1b3e57", "displayName": "Mohamed Benali" } },
    { "from": "REQUESTED", "to": "APPROVED", "at": "2026-11-04T09:10:00Z", "actor": { "id": "01a05bfb-7000-7d71-b777-8df1872390e6", "displayName": "Équipe HOCO" } },
    { "from": "APPROVED", "to": "IN_TRANSIT", "at": "2026-11-05T11:25:00Z", "actor": { "id": "01a05bfb-77d0-76d5-a064-865b3b84647b", "displayName": "Équipe HOCO" } },
    { "from": "IN_TRANSIT", "to": "RECEIVED", "at": "2026-11-06T10:30:00Z", "actor": { "id": "01a05bfb-77d0-76d5-a064-865b3b84647b", "displayName": "Équipe HOCO" } },
    { "from": "RECEIVED", "to": "REFUNDED", "at": "2026-11-06T10:30:00Z", "actor": null, "reason": "Avoir AV-2026-000004 émis" }
  ],
  "requestedAt": "2026-11-03T15:20:00Z",
  "updatedAt": "2026-11-06T10:30:00Z"
}
FieldNotes
instructions, transportSet at approval: drop at the depot (RESELLER_DROP_OFF), carrier collection with a tracking number, or the delegate's next visit (DELEGATE_PICKUP).
items[].acceptedQtyUnits credited; units not accepted carry refusalReason (« Produit utilisé, emballage manquant ») and are not re-entered.
creditNoteNumber AV-YYYY-NNNNNN (assumption, format to confirm in D-21); amount = accepted units × the order line's net unit price TTC. It reduces the invoice balance, or becomes a credit balance when the invoice is already paid (finance).

Errors

StatusCodeWhen
404NOT_FOUNDNot my return.

Rules & side effects — read-only; photo and PDF URLs are signed for 5 minutes (refetch to renew). Live updates through return.status_changed.

Used by — RA-40, RW-14, deep links of return notifications.

On this page