Reseller finance
The reseller's balance, credit and due dates, invoices with their allocations and PDF, payments and declarations, and the declaration of a transfer, CCP or BaridiMob payment with proof.
The reseller's money view (cahier §4.7, §5 « Consulter le solde, le crédit disponible » — FIN-10): the account tiles of the home, « Solde et crédit », « Factures » and « Paiements » of the reseller app (Imad, MRA-07) and the finance pages of the reseller web (Anis, WEB-04). Built in SRV-18; the back-office side is admin finance.
- Own data only (cahier §4.7 « Les droits d'accès aux données financières sont strictement limités »): every operation is scoped to the caller's reseller; delegates and guests have no access.
- Invoices are issued from orders at
billing.invoiceOn(defaultSHIPPED), numberedFAC-YYYY-NNNNNN; their status is derived from the balance and the due date (invoice lifecycle). - Payments: cash collected on delivery and payments recorded by finance appear here; transfers, CCP and BaridiMob are declared by the reseller with a proof and verified by finance (FIN-03, D-26). A declaration changes nothing until it is confirmed.
- Credit notes (avoirs, V1 — FIN-08) from returns and after-sales resolutions reduce invoice balances.
| Method | Path | Operation | Access | Apps | Release |
|---|---|---|---|---|---|
| GET | /finance/summary | finance.summaryBalance due, credit limit, used and available credit, next due date | self | RA · RW | V1 |
| GET | /invoices | invoices.listMy invoices with status filter | self | RA · RW | V1 |
| GET | /invoices/{invoiceId} | invoices.getInvoice detail with payments allocated and PDF link | self | RA · RW | V1 |
| GET | /payments | payments.listMy payments and declarations with their verification status | self | RA · RW | V1 |
| GET | /credit-notes | creditNotes.listMy credit notes, newest first, with their PDF | self | RA · RW | V1 |
| POST | /payments/declarations | payments.declareDeclare a transfer/CCP/BaridiMob payment with proof for verification | selfIdempotency-Key | RA · RW | V1 |
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 — see the error registry.
Definitions
| Term | Computation |
|---|---|
| Invoice balance | totalTtc − confirmed payment allocations − credit notes applied |
balanceDue (Solde) | Σ balances of my invoices UNPAID, PARTIALLY_PAID, OVERDUE |
overdueAmount | Σ balances of my OVERDUE invoices (due date before today, Africa/Algiers) |
creditUsed (exposure) | balanceDue + total of my not-yet-invoiced CREDIT orders (SUBMITTED to READY) − creditBalance (D-04) |
creditAvailable | max(0, creditLimit − creditUsed); checked at checkout for CREDIT (FIN-05) |
creditBalance | Unallocated confirmed payments (advances) and credit notes not applied to an invoice |
pendingVerificationAmount | Σ my declarations still PENDING_VERIFICATION — shown, never deducted |
Schemas
interface FinanceSummary {
currency: "DZD";
balanceDue: Money;
overdueAmount: Money;
overdueInvoicesCount: number;
openInvoicesCount: number;
pendingVerificationAmount: Money;
creditBalance: Money;
creditLimit: Money | null; // null: no credit line (limit 0)
creditUsed: Money;
creditAvailable: Money;
nextDueDate: string | null; // YYYY-MM-DD — earliest due date today or later with a balance
nextDueAmount: Money | null;
blocked: boolean; // credit account blocked by finance
blockedReason: string | null;
computedAt: Iso;
}
interface InvoiceSummary {
id: Uuid;
number: string; // FAC-2026-000124
status: InvoiceStatus;
issueDate: string; // YYYY-MM-DD
dueDate: string;
order: { id: Uuid; number: string };
totalTtc: Money;
amountPaid: Money; // confirmed allocations
creditNotesTotal: Money;
balance: Money;
daysOverdue: number | null;
}
interface InvoiceDetail extends InvoiceSummary {
currency: "DZD";
paymentMethod: PaymentMethod;
deliveryNoteNumber: string | null;
seller: LegalParty;
buyer: LegalParty;
lines: InvoiceLine[];
totals: Totals; // shared schema: HT, discounts, delivery, VAT, TTC
vatBreakdown: { vatRate: BasisPoints; baseHt: Money; vat: Money }[];
stampDuty: Money; // droit de timbre on cash payments — 0 until D-21 is decided
allocations: { paymentId: Uuid; paymentNumber: string; method: PaymentMethod; amount: Money; allocatedAt: Iso }[];
creditNotes: { id: Uuid; number: string; amountTtc: Money; issuedAt: Iso }[];
pdf: FileRef | null; // signed URL, 5 minutes
cancelledAt: Iso | null;
}
interface LegalParty {
name: string;
address: string;
rc: string | null; // registre de commerce
nif: string | null;
nis: string | null;
ai: string | null; // article d'imposition
}
interface InvoiceLine {
description: string; // product name and variant
sku: string;
qty: number;
unitPrice: Price; // net unit price (after promotion)
totalHt: Money;
vatRate: BasisPoints;
totalTtc: Money;
}
interface PaymentView {
id: Uuid;
number: string; // PAY-2026-000077
method: PaymentMethod;
amount: Money;
paidAt: Iso; // when the money was paid (declared by the reseller or recorded)
status: PaymentStatus; // PENDING_VERIFICATION | CONFIRMED | REJECTED
source: "DECLARATION" | "DELIVERY_COLLECTION" | "BACK_OFFICE";
reference: string | null; // transfer / CCP / BaridiMob transaction reference
proof: FileRef | null; // PAYMENT_PROOF, signed URL
order: { id: Uuid; number: string } | null;
requestedInvoices: { id: Uuid; number: string }[]; // what the reseller said it pays
allocations: { invoiceId: Uuid; invoiceNumber: string; amount: Money; allocatedAt: Iso }[];
unallocatedAmount: Money;
rejectionReason: string | null;
note: string | null;
declaredAt: Iso | null;
verifiedAt: Iso | null;
}Operations
GET /finance/summary
finance.summary · Access session — reseller (self) · Apps RA, RW · Idempotency-Key — · Release V1 · Requirements FIN-05, FIN-10
Contract 1.1.0 (SRV-41): the summary carries paymentInstructions { beneficiary, rib, ccpAccount, ccpKey, baridimobRip } from the setting payments.instructions (each null until HOCO provides it, D-03), shown by the declaration form for the chosen method.
Purpose. « Solde et crédit »: what I owe, what is overdue, my credit limit, used and available credit, and the next due date.
Request — no parameters.
Response — 200 OK, Cache-Control: private, no-store: a FinanceSummary.
{
"currency": "DZD",
"balanceDue": 12540000,
"overdueAmount": 1605000,
"overdueInvoicesCount": 1,
"openInvoicesCount": 3,
"pendingVerificationAmount": 1605000,
"creditBalance": 0,
"creditLimit": 40000000,
"creditUsed": 15000000,
"creditAvailable": 25000000,
"nextDueDate": "2026-11-04",
"nextDueAmount": 7250000,
"blocked": false,
"blockedReason": null,
"computedAt": "2026-11-03T09:30:00Z"
}| Field | Notes |
|---|---|
balanceDue | « Solde 125 400 DA » on the home (reference screen 1). Here: FAC-2026-000079 (16 050,00 overdue) + FAC-2026-000098 (72 500,00) + FAC-2026-000124 (36 850,00). |
creditUsed | 125 400,00 of open invoices + 24 600,00 of the CREDIT order CMD-2026-000156 still in preparation (not invoiced). |
creditAvailable | « Crédit disponible 250 000 DA » on the home; the same number limits CREDIT at checkout. |
pendingVerificationAmount | The BaridiMob declaration PAY-2026-000077 waiting for finance — the app shows « 16 050,00 DA en cours de vérification » under the overdue amount. |
blocked | Finance blocked the credit account: CREDIT is disabled at checkout (CREDIT_BLOCKED); other methods stay available. V2 adds automatic blocking on overdue (FIN-06). |
Errors — none specific.
Rules & side effects — computed at read time from invoices, allocations, credit notes, CREDIT orders and CreditAccount (never cached across users). The same figures feed catalog.home → account and cart.checkoutOptions → credit.
Used by — RA-29 (« Solde et crédit »), account hub RA-27, RW-13.
GET /invoices
invoices.list · Access session — reseller (self) · Apps RA, RW · Idempotency-Key — · Release V1 · Requirements FIN-01, FIN-10
Purpose. « Factures »: my invoices, newest first, filterable by status (tabs Toutes, À payer, En retard, Payées).
Request
| Query | Type | Required | Notes |
|---|---|---|---|
status | InvoiceStatus, repeatable | no | À payer = UNPAID, PARTIALLY_PAID, OVERDUE |
from, to | YYYY-MM-DD | no | On issueDate |
q | string | no | Invoice or order number |
cursor, limit | — | no | limit default 20, max 100 |
Response — 200 OK: { items: InvoiceSummary[], nextCursor }.
{
"items": [
{
"id": "01a18d53-2980-79c5-a4cd-4c9ba7aef490",
"number": "FAC-2026-000124",
"status": "UNPAID",
"issueDate": "2026-10-30",
"dueDate": "2026-11-29",
"order": { "id": "01a187cf-6b40-7c6f-894d-b1f256947da9", "number": "CMD-2026-000155" },
"totalTtc": 3685000,
"amountPaid": 0,
"creditNotesTotal": 0,
"balance": 3685000,
"daysOverdue": null
},
{
"id": "01a17b2e-8c00-7d41-9e52-3f4a5b6c7d8e",
"number": "FAC-2026-000119",
"status": "PAID",
"issueDate": "2026-10-27",
"dueDate": "2026-11-26",
"order": { "id": "01a17cd2-00e0-7779-8e81-ceca0079d9c9", "number": "CMD-2026-000154" },
"totalTtc": 5565000,
"amountPaid": 5565000,
"creditNotesTotal": 0,
"balance": 0,
"daysOverdue": null
},
{
"id": "01a10b4a-9680-75fb-9818-930d713405c0",
"number": "FAC-2026-000098",
"status": "PARTIALLY_PAID",
"issueDate": "2026-10-05",
"dueDate": "2026-11-04",
"order": { "id": "01a1065b-2900-748c-88c5-976d443033f4", "number": "CMD-2026-000131" },
"totalTtc": 10750000,
"amountPaid": 3500000,
"creditNotesTotal": 0,
"balance": 7250000,
"daysOverdue": null
},
{
"id": "01a0f6b1-2680-7c2e-ac45-445eb2a5459d",
"number": "FAC-2026-000085",
"status": "PAID",
"issueDate": "2026-10-01",
"dueDate": "2026-10-31",
"order": { "id": "01a0f1c1-b900-7f45-b100-f0acc3db1a4e", "number": "CMD-2026-000118" },
"totalTtc": 2180000,
"amountPaid": 2180000,
"creditNotesTotal": 0,
"balance": 0,
"daysOverdue": null
},
{
"id": "01a0e73e-1280-773e-a1c1-3c802e070bd7",
"number": "FAC-2026-000079",
"status": "OVERDUE",
"issueDate": "2026-09-28",
"dueDate": "2026-10-28",
"order": { "id": "01a0e217-b680-7ffa-8c03-a28c8720afb9", "number": "CMD-2026-000112" },
"totalTtc": 4590000,
"amountPaid": 2985000,
"creditNotesTotal": 0,
"balance": 1605000,
"daysOverdue": 6
}
],
"nextCursor": null
}Errors — 400 VALIDATION_FAILED for an unknown status or from after to.
Rules & side effects — read-only, sorted by issueDate then number, descending. daysOverdue is computed in Africa/Algiers days.
Used by — RA-30 (« Factures »), RW-13.
GET /invoices/{invoiceId}
invoices.get · Access session — reseller (self) · Apps RA, RW · Idempotency-Key — · Release V1 · Requirements FIN-01, PRC-04
Purpose. Invoice detail: legal parties, lines, HT / VAT / TTC totals, payments and credit notes allocated, balance and the PDF.
Request — path invoiceId.
Response — 200 OK: an InvoiceDetail.
{
"id": "01a10b4a-9680-75fb-9818-930d713405c0",
"number": "FAC-2026-000098",
"status": "PARTIALLY_PAID",
"issueDate": "2026-10-05",
"dueDate": "2026-11-04",
"order": { "id": "01a1065b-2900-748c-88c5-976d443033f4", "number": "CMD-2026-000131" },
"totalTtc": 10750000,
"amountPaid": 3500000,
"creditNotesTotal": 0,
"balance": 7250000,
"daysOverdue": null,
"currency": "DZD",
"paymentMethod": "BANK_TRANSFER",
"deliveryNoteNumber": "BL-2026-000087",
"seller": {
"name": "HOCO Algérie SARL",
"address": "Zone d'activités, lot 12, Oran",
"rc": "31/00-0000000 B 20",
"nif": "000031000000000",
"nis": "000031000000000",
"ai": "31000000000"
},
"buyer": {
"name": "Magasin El Wafa — Mohamed Benali",
"address": "Cité USTO, local n° 14, Bir El Djir, Oran",
"rc": "31/00-0874512 A 19",
"nif": "001931087451236",
"nis": null,
"ai": null
},
"lines": [
{ "description": "BOROFONE BW06 Écouteurs TWS — Blanc", "sku": "BW06_WHITE", "qty": 20, "unitPrice": { "ht": 242017, "ttc": 288000, "vatRate": 1900 }, "totalHt": 4840340, "vatRate": 1900, "totalTtc": 5760000 },
{ "description": "HOCO N32 Chargeur rapide 30W (USB-C + USB-A) — Noir", "sku": "N32_BLACK_EU", "qty": 10, "unitPrice": { "ht": 209244, "ttc": 249000, "vatRate": 1900 }, "totalHt": 2092440, "vatRate": 1900, "totalTtc": 2490000 },
{ "description": "HOCO X89 Câble USB-C — Noir · 1 m", "sku": "X89_BLACK_1M", "qty": 20, "unitPrice": { "ht": 105042, "ttc": 125000, "vatRate": 1900 }, "totalHt": 2100840, "vatRate": 1900, "totalTtc": 2500000 }
],
"totals": { "subtotalHt": 9033620, "discountTotal": 0, "deliveryFee": 0, "vatTotal": 1716380, "totalTtc": 10750000, "currency": "DZD" },
"vatBreakdown": [ { "vatRate": 1900, "baseHt": 9033620, "vat": 1716380 } ],
"stampDuty": 0,
"allocations": [
{ "paymentId": "01a13f01-1d00-7058-a71a-7c8b4f41e310", "paymentNumber": "PAY-2026-000068", "method": "BANK_TRANSFER", "amount": 3500000, "allocatedAt": "2026-10-15T14:00:00Z" }
],
"creditNotes": [],
"pdf": {
"id": "01a10b4a-aa08-7026-a2f8-de9d2ad58b44",
"url": "https://storage.hoco.dz/hoco-private/generated_document/2026/10/01a10b4a-aa08-7026-a2f8-de9d2ad58b44.pdf?X-Amz-Expires=300&X-Amz-Signature=0c3d…",
"mimeType": "application/pdf",
"size": 51207,
"purpose": "GENERATED_DOCUMENT"
},
"cancelledAt": null
}| Field | Notes |
|---|---|
seller, buyer | Legal mentions of FIN-01 (RC, NIF, NIS, AI), snapshotted at issue; the buyer's identifiers come from the store's documents (profile). Values above are placeholders; HOCO's identifiers and the mandatory mentions are confirmed in D-21. |
totals, vatBreakdown | HT, VAT per rate and TTC (PRC-04); the same figures as the order snapshot. |
stampDuty | Droit de timbre on cash payments; 0 until the accountant's rule is set (D-21). |
pdf | Signed URL valid 5 minutes; refetch the invoice to renew. The same file is served by orders.document. |
Errors
| Status | Code | When |
|---|---|---|
| 404 | NOT_FOUND | Unknown invoice or another reseller's. |
Rules & side effects — read-only. An issued invoice is never edited; a correction is a credit note listed in creditNotes.
Used by — invoice detail of RA-30, RW-13; the payment declaration form pre-selects open invoices from here.
GET /payments
payments.list · Access session — reseller (self) · Apps RA, RW · Idempotency-Key — · Release V1 · Requirements FIN-03
Purpose. « Paiements »: my payments and declarations with their verification status, newest first.
Request
| Query | Type | Required | Notes |
|---|---|---|---|
status | PaymentStatus, repeatable | no | |
method | PaymentMethod, repeatable | no | |
cursor, limit | — | no | limit default 20, max 100 |
Response — 200 OK: { items: PaymentView[], nextCursor }.
{
"items": [
{
"id": "01a1a090-b300-700e-9bd2-856e9e617615",
"number": "PAY-2026-000077",
"method": "BARIDIMOB",
"amount": 1605000,
"paidAt": "2026-11-03T08:20:00Z",
"status": "PENDING_VERIFICATION",
"source": "DECLARATION",
"reference": "BM2611030742",
"proof": { "id": "01a1a08e-de40-7d4c-a0a4-2510fb17fac6", "url": "https://storage.hoco.dz/hoco-private/payment_proof/2026/11/01a1a08e-de40-7d4c-a0a4-2510fb17fac6.jpg?X-Amz-Expires=300&X-Amz-Signature=8e2a…", "thumbnailUrl": "https://storage.hoco.dz/hoco-private/payment_proof/2026/11/01a1a08e-de40-7d4c-a0a4-2510fb17fac6-thumb.webp?X-Amz-Expires=300&X-Amz-Signature=1f5c…", "mimeType": "image/jpeg", "size": 412880, "purpose": "PAYMENT_PROOF" },
"order": null,
"requestedInvoices": [ { "id": "01a0e73e-1280-773e-a1c1-3c802e070bd7", "number": "FAC-2026-000079" } ],
"allocations": [],
"unallocatedAmount": 1605000,
"rejectionReason": null,
"note": "Solde de la facture FAC-2026-000079.",
"declaredAt": "2026-11-03T08:40:00Z",
"verifiedAt": null
},
{
"id": "01a17d9e-4b00-7c3a-8e1f-2a3b4c5d6e7f",
"number": "PAY-2026-000072",
"method": "CASH_ON_DELIVERY",
"amount": 5565000,
"paidAt": "2026-10-28T11:40:00Z",
"status": "CONFIRMED",
"source": "DELIVERY_COLLECTION",
"reference": null,
"proof": null,
"order": { "id": "01a17cd2-00e0-7779-8e81-ceca0079d9c9", "number": "CMD-2026-000154" },
"requestedInvoices": [],
"allocations": [ { "invoiceId": "01a17b2e-8c00-7d41-9e52-3f4a5b6c7d8e", "invoiceNumber": "FAC-2026-000119", "amount": 5565000, "allocatedAt": "2026-10-29T09:12:00Z" } ],
"unallocatedAmount": 0,
"rejectionReason": null,
"note": null,
"declaredAt": null,
"verifiedAt": "2026-10-29T09:12:00Z"
},
{
"id": "01a1630d-a100-7d35-86bf-7d5d40280739",
"number": "PAY-2026-000070",
"method": "CCP",
"amount": 7250000,
"paidAt": "2026-10-21T15:00:00Z",
"status": "REJECTED",
"source": "DECLARATION",
"reference": "CCP-0021-77810",
"proof": { "id": "01a1630b-cc40-72e4-8884-ea7f2e1b3fe4", "url": "https://storage.hoco.dz/hoco-private/payment_proof/2026/10/01a1630b-cc40-72e4-8884-ea7f2e1b3fe4.jpg?X-Amz-Expires=300&X-Amz-Signature=44b9…", "mimeType": "image/jpeg", "size": 198344, "purpose": "PAYMENT_PROOF" },
"order": null,
"requestedInvoices": [ { "id": "01a10b4a-9680-75fb-9818-930d713405c0", "number": "FAC-2026-000098" } ],
"allocations": [],
"unallocatedAmount": 7250000,
"rejectionReason": "Justificatif illisible — merci de renvoyer une photo nette du reçu CCP.",
"note": null,
"declaredAt": "2026-10-22T10:00:00Z",
"verifiedAt": "2026-10-22T14:35:00Z"
},
{
"id": "01a13f01-1d00-7058-a71a-7c8b4f41e310",
"number": "PAY-2026-000068",
"method": "BANK_TRANSFER",
"amount": 3500000,
"paidAt": "2026-10-14T09:00:00Z",
"status": "CONFIRMED",
"source": "DECLARATION",
"reference": "VIR-BEA-20261014-5512",
"proof": { "id": "01a13eff-4840-7488-a9ba-6367cf97c6a2", "url": "https://storage.hoco.dz/hoco-private/payment_proof/2026/10/01a13eff-4840-7488-a9ba-6367cf97c6a2.pdf?X-Amz-Expires=300&X-Amz-Signature=e1d0…", "mimeType": "application/pdf", "size": 88120, "purpose": "PAYMENT_PROOF" },
"order": null,
"requestedInvoices": [ { "id": "01a10b4a-9680-75fb-9818-930d713405c0", "number": "FAC-2026-000098" } ],
"allocations": [ { "invoiceId": "01a10b4a-9680-75fb-9818-930d713405c0", "invoiceNumber": "FAC-2026-000098", "amount": 3500000, "allocatedAt": "2026-10-15T14:00:00Z" } ],
"unallocatedAmount": 0,
"rejectionReason": null,
"note": "Acompte facture FAC-2026-000098.",
"declaredAt": "2026-10-15T10:00:00Z",
"verifiedAt": "2026-10-15T14:00:00Z"
}
],
"nextCursor": "eyJjIjoiMjAyNi0xMC0xNVQxMDowMDowMFoiLCJpIjoiMDFhMTNmMDEifQ"
}Errors — 400 VALIDATION_FAILED for unknown filter values.
Rules & side effects — read-only, sorted by declaredAt (or paidAt for recorded payments) descending. Proof URLs are signed for 5 minutes. A rejected declaration shows the reason chosen by finance (PAYMENT_REJECT_REASON) and can be declared again with a new proof.
Used by — RA-31 (« Paiements »), RW-13.
GET /credit-notes
creditNotes.list · Access session — reseller (self) · Apps RA, RW · Release V1 · Requirements FIN-08 · Added in contract 1.1.0 (SRV-41)
Purpose. My credit notes (returns, after-sales claims, cancelled invoices), newest first, with what is left to apply and the PDF.
Request — cursor, limit (20, max 100).
Response 200 OK
{
"items": [
{ "id": "01931b40-…", "number": "AV-2026-000012", "issuedAt": "2026-11-08T10:20:00Z", "reason": "Retour RET-2026-000012", "totalTtc": 124950, "amountApplied": 0, "available": 124950,
"invoice": { "id": "01930f20-…", "number": "FAC-2026-000157" }, "returnRequest": { "id": "01931a20-…", "number": "RET-2026-000012" }, "cancelled": false,
"pdf": { "id": "01931b41-…", "url": "https://…", "mimeType": "application/pdf" } }
],
"nextCursor": null
}available is totalTtc − amountApplied (0 for a cancelled credit note).
Errors
| Status | Code | When |
|---|---|---|
| 401 | UNAUTHENTICATED | No session |
| 403 | PERMISSION_DENIED | Not a reseller |
Used by RW-13 (« Avoirs » tab)
POST /payments/declarations
payments.declare · Access session — reseller (self) · Apps RA, RW · Idempotency-Key required · Release V1 · Requirements FIN-03
Contract 1.1.0 (SRV-41) — RA-31: reference is optional (3–60 characters when given). The duplicate check (409 PAYMENT_ALREADY_DECLARED, same method and reference, not rejected) applies only when a reference is sent.
Purpose. « Déclarer un paiement »: the reseller reports a transfer, CCP deposit or BaridiMob payment, with the receipt as proof, so finance can verify and allocate it.
Request — the proof is uploaded first through files.createUpload with purpose PAYMENT_PROOF, then files.completeUpload.
interface PaymentDeclarationRequest {
method: "BANK_TRANSFER" | "CCP" | "BARIDIMOB";
amount: Money; // > 0
paidAt: Iso; // not more than 5 minutes in the future, not older than 90 days
reference: string; // 3–60 characters, transaction reference on the receipt
proofFileId: Uuid; // PAYMENT_PROOF, completed, uploaded by me
invoiceIds?: Uuid[]; // open invoices this payment is meant for (optional)
orderId?: Uuid; // or a not-yet-invoiced order paid in advance
note?: string; // ≤ 300 characters
}{
"method": "BARIDIMOB",
"amount": 1605000,
"paidAt": "2026-11-03T08:20:00Z",
"reference": "BM2611030742",
"proofFileId": "01a1a08e-de40-7d4c-a0a4-2510fb17fac6",
"invoiceIds": ["01a0e73e-1280-773e-a1c1-3c802e070bd7"],
"note": "Solde de la facture FAC-2026-000079."
}Response — 201 Created, Location: /v1/payments/01a1a090-b300-700e-9bd2-856e9e617615: the PaymentView in PENDING_VERIFICATION (identical to the first item of the payments.list example).
{
"id": "01a1a090-b300-700e-9bd2-856e9e617615",
"number": "PAY-2026-000077",
"method": "BARIDIMOB",
"amount": 1605000,
"paidAt": "2026-11-03T08:20:00Z",
"status": "PENDING_VERIFICATION",
"source": "DECLARATION",
"reference": "BM2611030742",
"proof": { "id": "01a1a08e-de40-7d4c-a0a4-2510fb17fac6", "url": "https://storage.hoco.dz/hoco-private/payment_proof/2026/11/01a1a08e-de40-7d4c-a0a4-2510fb17fac6.jpg?X-Amz-Expires=300&X-Amz-Signature=8e2a…", "thumbnailUrl": "https://storage.hoco.dz/hoco-private/payment_proof/2026/11/01a1a08e-de40-7d4c-a0a4-2510fb17fac6-thumb.webp?X-Amz-Expires=300&X-Amz-Signature=1f5c…", "mimeType": "image/jpeg", "size": 412880, "purpose": "PAYMENT_PROOF" },
"order": null,
"requestedInvoices": [ { "id": "01a0e73e-1280-773e-a1c1-3c802e070bd7", "number": "FAC-2026-000079" } ],
"allocations": [],
"unallocatedAmount": 1605000,
"rejectionReason": null,
"note": "Solde de la facture FAC-2026-000079.",
"declaredAt": "2026-11-03T08:40:00Z",
"verifiedAt": null
}Errors
| Status | Code | When |
|---|---|---|
| 400 | VALIDATION_FAILED | Field codes: INVALID_ENUM (method is CASH_ON_DELIVERY or CREDIT — not declarable), NOT_POSITIVE (amount), IN_FUTURE / TOO_OLD (paidAt), REQUIRED (reference, proofFileId), UNKNOWN_INVOICE (not mine), INVOICE_NOT_PAYABLE (PAID or CANCELLED), UNKNOWN_ORDER, FILE_NOT_FOUND, FILE_ALREADY_ATTACHED; invoiceIds and orderId together. |
| 422 | FILE_NOT_READY | The proof upload was not completed. |
| 422 | FILE_PURPOSE_MISMATCH | The proof was not uploaded with purpose PAYMENT_PROOF. |
| 409 | PAYMENT_ALREADY_DECLARED | A declaration with the same method and reference exists and is not rejected (details.paymentNumber) — typically the same receipt sent from the app and the web. |
| 422 | PAYMENT_METHOD_NOT_ALLOWED | The method is disabled in the settings (D-03). |
Rules & side effects
- Creates a
Paymentwithsource = DECLARATION, statusPENDING_VERIFICATION, numberPAY-YYYY-NNNNNN, the proof attached (readable by the reseller and finance only).invoiceIds/orderIdare recorded as the reseller's intent; finance allocates at verification, by default to the oldest due invoices first (FIN-04). - Nothing changes in balances, invoice statuses or available credit until finance confirms (
admin.payments.verify); the amount appears inpendingVerificationAmount. An amount above the targeted balances is accepted: the remainder becomes an advance (creditBalance) at confirmation. - Outbox
payment.declared→ in-app alert and daily e-mail digest tofinance.validateholders (BO-45). Confirmation or rejection reaches the reseller aspayment.confirmed/payment.rejected(push and inbox). - Verification target: one working day (D-26).
Used by — « Déclarer un paiement » on RA-31 (from an invoice of RA-30 or from the order of a prepaid method), RW-13.
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.
Promotions, banners & packs
Banners per placement, promotions and daily offers with their eligible products, and V2 profitable packs — targeted server-side to the caller, open to guests without prices.