HOCO B2B
DesignScreen specificationsReseller app

Finance

Screen specifications RA-29 to RA-31 of the reseller app — balance and credit, invoices and credit notes with PDFs, payments and the declaration of a transfer, CCP or BaridiMob payment with proof.

Cahier §4.7: invoices, receipts, credit notes and payment history; payment on delivery, transfer, CCP, BaridiMob or credit; credit ceiling, available credit, due dates and blocking. The reseller app shows the reseller's own figures (FIN-10) and lets them declare a payment with proof for HOCO's finance team to verify (FIN-03). Designed on day 9, built in MRA-07; server side in SRV-18. Financial data is strictly limited to its owner (ACL-04).

IDScreenUI titleSectionReleaseDesignBuild
RA-29Balance & creditSolde et créditFinanceV1Day 9MRA-07
RA-30InvoicesFacturesFinanceV1Day 9MRA-07
RA-31Payments & payment declarationPaiementsFinanceV1Day 9MRA-07

Who sees what. Guests: nothing (the Compte tab shows the sign-up prompt). PENDING_VALIDATION: the screens open read-only (they are usually empty) and payment declaration is refused (403 ACCOUNT_PENDING_VALIDATION). Active resellers: everything — including a reseller whose lifecycle status is Suspendu, who must still be able to pay.

How money moves (for the copy). HOCO issues the invoice when the order ships (default). Cash on delivery is collected by the driver and recorded by HOCO. Transfer, CCP and BaridiMob payments are made by the reseller after HOCO confirms the order, then declared in the app with a proof; finance verifies each declaration in BO-45 and allocates it to invoices. A declaration changes nothing to the balance until it is Confirmé. Credit notes (avoirs) from returns and after-sales reduce what is due (FIN-08).

RA-29 — Balance & credit

FieldValue
ScreenBalance & credit · Finance
French titleSolde et crédit
ReleaseV1
Design dayDay 9 — DES-09
Build taskMRA-07
RequirementsFIN-05 · FIN-10
Reference screenNone — follow the design system

Purpose — Answer « how much do I owe, by when, and how much can I still order on credit? » in one screen (FIN-05, FIN-10).

Entry points & exits — Account tiles of RA-09, the finance section of RA-27, /finance. Exits to RA-30, RA-31 (list and « Déclarer un paiement »).

Layout

  1. AppBar « Solde et crédit ».
  2. Balance card: « Solde à payer » with the amount, large; under it, in danger tone, « dont en retard : 12 000,00 DA » when overdue invoices exist; « Prochaine échéance : 30 nov. 2026 — 25 000,00 DA ».
  3. Credit card (only with a credit account): « Plafond de crédit 300 000,00 DA », « Utilisé 50 000,00 DA », « Disponible 250 000,00 DA », and a progress bar (used / ceiling). Blocked: danger state « Crédit bloqué — contactez le service finance. »
  4. Declarations line: « 2 paiements en cours de vérification — 35 000,00 DA » → RA-31 filtered À vérifier.
  5. Credit notes line, when available: « Avoirs disponibles : 4 500,00 DA » → RA-30 tab Avoirs.
  6. Actions: primary « Déclarer un paiement »; ListRow « Mes factures », « Mes paiements ».
  7. Help text: « Le crédit disponible diminue avec chaque commande payée à crédit et se libère quand vos paiements sont confirmés par HOCO. »

Data

ShownSource
Balance, overdue, next due datefinance.summary → balanceDue, overdueAmount, nextDue.date, nextDue.amount
Creditfinance.summary → creditLimit, creditUsed, creditAvailable, blocked (a limit of 0 means no credit line)
Declarations under verificationfinance.summary → pendingDeclarations.count, pendingDeclarations.amount
Credit notesfinance.summary → creditNotesAvailable (Assumption — field to add with V1 credit notes)

Actions — Pull-to-refresh; « Déclarer un paiement » → RA-31 form (pending accounts: hidden).

Rules — Available credit = ceiling − used (FIN-05); used credit counts unpaid credit orders and invoices; it is checked at checkout (RA-18). Overdue is set by the daily job when a due date passes with a balance (En retard (OVERDUE)). Detailed credit terms and automatic blocking are V2 (FIN-06).

States — Loading: card skeletons. No credit account: the credit card becomes « Paiement à crédit non activé. Contactez HOCO pour en bénéficier. » (muted). Nothing due: success state « Vous êtes à jour ». Offline: cached figures with « données du … ». Error: ErrorState.

Copy — « Solde et crédit » · « Solde à payer » · « dont en retard : {amount} » · « Prochaine échéance : {date} — {amount} » · « Plafond de crédit » · « Utilisé » · « Disponible » · « Crédit bloqué — contactez le service finance. » · « {count} paiements en cours de vérification — {amount} » · « Avoirs disponibles : {amount} » · « Déclarer un paiement » · « Mes factures » · « Mes paiements » · « Vous êtes à jour ».

Analytics — finance_viewed with hasCredit, hasOverdue.

Acceptance criteria

  • Balance, ceiling, used and available credit equal the back-office credit account (BO-46) at the same moment.
  • A confirmed payment lowers the balance (and frees credit) at the next refresh; a declaration under verification does not.
  • Without a credit account, no credit figure is shown.

RA-30 — Invoices

FieldValue
ScreenInvoices · Finance
French titleFactures
ReleaseV1
Design dayDay 9 — DES-09
Build taskMRA-07
RequirementsFIN-01 · FIN-10
Reference screenNone — follow the design system

Purpose — List the reseller's invoices and credit notes, show what is paid and what remains, and give the PDFs (FIN-01, FIN-08, FIN-10).

Entry points & exits — « Mes factures » on RA-29 and RA-27, the invoice row of RA-22, notification invoice.issued, /finance/invoices/{invoiceId}. Exits to the invoice detail (same screen, pushed view), RA-22 (linked order), RA-31 (declare for this invoice), the PDF viewer.

Layout — list

  1. AppBar « Factures ».
  2. Tabs « Factures » · « Avoirs ».
  3. Status chips (invoices): « Toutes », Impayée, Partiellement payée, En retard, Payée, Annulée.
  4. Invoice rows: number « FAC-2026-000123 », issue date, order « CMD-2026-000158 », total TTC, « Reste 10 350,00 DA », StatusBadge, due date « Échéance 30 nov. » (danger when overdue).
  5. Credit-note rows: number, date, origin (« Retour RET-2026-000012 », « SAV TKT-2026-000045 »), amount, PDF icon.

Layout — invoice detail

  1. Header: number, StatusBadge, « Émise le 14 nov. 2026 », « Échéance le 30 nov. 2026 ».
  2. Amounts: « Total HT », « TVA », « Total TTC », « Déjà payé », « Reste à payer » (large).
  3. « Paiements affectés »: rows « PAY-2026-000077 — 15 nov. — Virement bancaire — 5 000,00 DA » with the payment status.
  4. « Commande »: link to RA-22.
  5. Buttons: « Télécharger la facture (PDF) »; « Déclarer un paiement » (when something remains and the account is active) → RA-31 prefilled with this invoice and the remaining amount.

Data

ShownSource
Invoicesinvoices.list ?status=&cursor= → items[].id, number, issuedAt, dueDate, order.id, order.number, totalTtc, amountPaid, amountDue, status
Invoice detailinvoices.get → totals (ht, vat, ttc), payments[] (paymentId, number, paidAt, method, amountAllocated, status), pdf.url, pdf.expiresAt
Credit notesAssumption — a reseller list of credit notes (creditNotes.list, or invoices.list?kind=CREDIT_NOTE) is needed for the Avoirs tab; until it exists, credit notes are reached from their return (RA-40) or claim (RA-34)

Actions — Row → detail. PDF → signed URL valid 5 minutes (requested at every tap, never cached), downloaded and opened in the PDF viewer with « Partager ». Pull-to-refresh.

Rules — Invoices carry the legal mentions (NIF, NIS, RC, AI, VAT) in the PDF (FIN-01, template DQA-09). An issued invoice is never edited; a correction is a cancellation or a credit note. Cancelled invoices stay visible.

States — Loading: row skeletons. Empty: « Aucune facture pour le moment. Les factures sont émises à l'expédition de vos commandes. » Error: ErrorState. PDF failure: snackbar « Téléchargement impossible. Réessayez. » Offline: cached list; PDFs unavailable.

Copy — « Factures » · « Avoirs » · « Toutes » · « Échéance {date} » · « Reste {amount} » · « Émise le {date} » · « Total HT » · « TVA » · « Total TTC » · « Déjà payé » · « Reste à payer » · « Paiements affectés » · « Télécharger la facture (PDF) » · « Déclarer un paiement » · « Aucune facture pour le moment. Les factures sont émises à l'expédition de vos commandes. »

Analytics — invoices_viewed with filter; invoice_viewed with status; invoice_pdf_downloaded; credit_note_pdf_downloaded.

Acceptance criteria

  • Each invoice's remaining amount equals total TTC minus confirmed allocated payments.
  • The PDF opens with the same number and amounts as the screen.
  • Overdue invoices are marked in danger tone with their due date.

RA-31 — Payments & payment declaration

FieldValue
ScreenPayments & payment declaration · Finance
French titlePaiements
ReleaseV1
Design dayDay 9 — DES-09
Build taskMRA-07
RequirementsFIN-02 · FIN-03
Reference screenNone — follow the design system

Purpose — Show every payment of the shop — declared by the reseller or recorded by HOCO — with its verification status, and let the reseller declare a transfer, CCP or BaridiMob payment with its proof so that HOCO can confirm and allocate it (FIN-02, FIN-03).

Entry points & exits — « Mes paiements » and « Déclarer un paiement » on RA-29; « Déclarer un paiement » on RA-22 and the invoice detail of RA-30; pushes payment.confirmed (also when HOCO records a payment) and payment.rejected; /finance/payments, /finance/payments/declare?invoiceId=&orderId=. Exits to the payment detail, the declaration form, RA-30, back.

Layout — list

  1. AppBar « Paiements » and the primary button « Déclarer un paiement » (top of the list, full width).
  2. Status chips: « Tous », À vérifier, Confirmé, Rejeté.
  3. Payment rows: number « PAY-2026-000077 », date paid, method label, amount, StatusBadge, source (« Déclaré par vous » or « Enregistré par HOCO » — cash collected at delivery), allocation (« FAC-2026-000123 » or « Non affecté »). Rejected rows show the reason in one line.

Layout — payment detail (BottomSheet, full height): every field above, the reference, the comment, the proof thumbnail (tap to open), a small timeline (« Déclaré le … », « Confirmé par HOCO le … » or « Rejeté le … — Motif : … »), and for a rejected declaration « Déclarer à nouveau » (form prefilled from it, without the proof).

Layout — declaration form (full screen, bottom navigation hidden):

  1. AppBar « Déclarer un paiement ».
  2. « Mode de paiement » — three RadioCard: Virement bancaire, CCP, BaridiMob (cash on delivery and credit are never declared).
  3. « Coordonnées HOCO » card for the chosen method, each value with a copy icon: account holder and bank RIB (transfer); CCP account number and key (CCP); RIP (BaridiMob).
  4. TextField « Montant (DA) » — numeric keyboard, formatted as typed (« 25 000,00 »).
  5. Date picker « Date du paiement » — default today.
  6. TextField « Référence de l'opération (facultatif) » — helper « Numéro de virement, de reçu CCP ou de transaction BaridiMob ».
  7. « Factures concernées (facultatif) » — multi-select list of unpaid invoices with their remaining amounts (prefilled when coming from an invoice); the sum of the selected remainders is shown; when coming from an order without invoice yet, the order number is shown instead.
  8. « Justificatif » — Uploader with two buttons « Prendre une photo » and « Choisir un fichier » (image or PDF); preview with « Remplacer » and « Supprimer »; upload progress bar.
  9. TextField « Commentaire (facultatif) », 300 characters.
  10. StickyFooter: primary « Envoyer la déclaration ».

Data

Shown or usedSource
Paymentspayments.list ?status=&cursor= → items[].id, number, method, amount, paidAt, declaredAt, status (PaymentStatus), source (RESELLER, BACK_OFFICE), reference, comment, invoices[] (id, number, amountAllocated), rejectionReason, proof (FileRef)
HOCO's payment detailsfinance.summary → paymentInstructions[] (method, beneficiary, bankName, rib, ccpNumber, ccpKey, rip) — Assumption, field to add; values set in the back-office settings
Unpaid invoicesinvoices.list ?status=UNPAID&status=PARTIALLY_PAID&status=OVERDUE → items[].id, number, amountDue, dueDate
Uploadfiles.createUpload → fileId, uploadUrl, headers, expiresAt; files.completeUpload → FileRef
Resultpayments.declare → id, number, status

Actions — declaring

  1. As soon as a proof is picked, the app compresses an image (longest side 2 000 px, JPEG quality 80, EXIF removed) and starts the upload in the background: files.createUpload { purpose: "PAYMENT_PROOF", mimeType, size, fileName } with an Idempotency-Key → PUT to the pre-signed URL (valid 10 minutes) with progress → files.completeUpload with an Idempotency-Key.
  2. « Envoyer la déclaration » (enabled when method, amount, date and a completed proof are present) → payments.declare { method, amount, paidAt, reference?, invoiceIds?, orderId?, proofFileId, comment? } with an Idempotency-Key kept until success (a retry never creates a second declaration).
  3. Success: confirmation screen « Déclaration envoyée — PAY-2026-000078. Le service finance va vérifier votre paiement. Statut : À vérifier. » with « Voir mes paiements »; the new row appears first in the list.
  4. The form is kept as a draft on the device (fields and the local file path) until it is sent, so a phone call or an app switch loses nothing.

Rules

  • Declarable methods: transfer, CCP, BaridiMob (FIN-02). The proof is required; files are private (PAYMENT_PROOF, 10 MB at most, JPEG, PNG or PDF) and read only through signed URLs (SEC-04).
  • Amount above 0; date not in the future and not older than 90 days (Assumption).
  • A declared amount above the balance due is allowed with the warning « Le montant dépasse votre solde à payer (12 000,00 DA). » (advance payment); finance decides the allocation (FIN-04).
  • A declaration cannot be edited or deleted after sending in V1; a mistake goes through support or a new declaration after rejection.
  • Verification is done by finance in BO-45: Confirmé (balance and credit updated) or Rejeté with a reason from PAYMENT_REJECT_REASON (« Justificatif illisible », « Montant différent », « Paiement introuvable »…); the reseller is notified either way.
  • Payments recorded by HOCO (cash at delivery, payment at the office) appear with the source « Enregistré par HOCO ».
  • PENDING_VALIDATION accounts cannot declare (403 ACCOUNT_PENDING_VALIDATION).

States

SituationMessage or behaviour
List loadingRow skeletons
No payment yet« Aucun paiement enregistré. » with « Déclarer un paiement »
Upload in progressProgress bar on the preview; the submit button waits (« Envoi du justificatif… »)
Upload failed or URL expired« L'envoi du justificatif a échoué. » with « Réessayer » (a new upload is requested)
422 FILE_TOO_LARGE · 422 FILE_TYPE_NOT_ALLOWED (on files.completeUpload)« Fichier trop lourd (10 Mo maximum). » · « Format non accepté : photo (JPEG, PNG) ou PDF. »
400 VALIDATION_FAILEDMessages under the fields (« Montant invalide », « La date ne peut pas être dans le futur »)
409 PAYMENT_REFERENCE_ALREADY_DECLARED (Assumption)« Cette référence a déjà été déclarée (PAY-2026-000077). »
403 ACCOUNT_PENDING_VALIDATION« Votre compte doit être validé avant de déclarer un paiement. »
OfflineList cached; the form stays fillable as a draft, « Envoyer » disabled with « Connexion requise pour envoyer la déclaration »

Copy

KeyFrench
List« Paiements » · « Déclarer un paiement » · « Tous » · « À vérifier » · « Confirmé » · « Rejeté » · « Déclaré par vous » · « Enregistré par HOCO » · « Non affecté »
Form« Mode de paiement » · « Coordonnées HOCO » · « Montant (DA) » · « Date du paiement » · « Référence de l'opération (facultatif) » · « Numéro de virement, de reçu CCP ou de transaction BaridiMob » · « Factures concernées (facultatif) » · « Justificatif » · « Prendre une photo » · « Choisir un fichier » · « Commentaire (facultatif) » · « Envoyer la déclaration »
Success« Déclaration envoyée — {number}. Le service finance va vérifier votre paiement. Statut : À vérifier. »
Rejected« Rejeté le {date} — Motif : {reason} » · « Déclarer à nouveau »

Analytics — payment_declaration_started with source; payment_proof_uploaded with sizeKb, mimeType, ms; payment_declared with method, amount, invoiceCount; payment_declaration_failed with code.

Acceptance criteria

  • A declaration with a photo proof reaches BO-45 with status À vérifier, the proof viewable, the amount, date, method and selected invoices.
  • Retrying after a network failure never creates two declarations.
  • When finance rejects it, the reseller receives a notification and sees the reason; « Déclarer à nouveau » prefills the form.
  • A confirmed payment shows its allocation to invoices and lowers the balance on RA-29.

On this page