Facturi (billing)
Trimite facturile de platformă în modulul Facturi din Tabloul de bord al fiecărui tenant. Folosit de NotSoCRM (sau de orice alt sistem extern) pentru a încărca facturile generate în WMS-ul clientului.
Datele ajung exact în tabela pe care o citește modalul Facturi din dashboard, deci facturile apar imediat în UI după un POST reușit.
Endpoint-uri
| Metodă | Cale | Descriere |
|---|---|---|
| GET | /api/v1/billing/invoices | Listă paginată; filtre status, search, date_from, date_to. |
| POST | /api/v1/billing/invoices | Upsert după external_id — același id rescrie în loc să dubleze. |
| GET | /api/v1/billing/invoices/{externalId} | Citește o factură după external_id. |
| PATCH | /api/v1/billing/invoices/{externalId} | Modificare parțială (orice subset de câmpuri valide). |
| DELETE | /api/v1/billing/invoices/{externalId} | Șterge factura. |
Schema unei facturi
Câmpurile acceptate la POST și PATCH:
| Câmp | Tip | Obligatoriu | Note |
|---|---|---|---|
external_id | integer pozitiv | la POST | Id-ul tău intern. Cheie de upsert — același id înlocuiește rândul existent. |
series | string ≤ 20 | da | ex. FAC, RET. |
number | string ≤ 50 | da | Numărul facturii. |
date_emitted | YYYY-MM-DD | da | Data emiterii. |
date_due | YYYY-MM-DD | da | Termen de plată. |
total | numeric ≥ 0 | da | Total fără TVA. |
total_tva | numeric ≥ 0 | nu | Implicit 0. |
currency | string 3 caractere | nu | Implicit RON. |
status | enum | nu | emisa | incasata | anulata. Implicit emisa. |
description | text | nu | Descriere liberă, vizibilă în modal. |
doc_link | URL ≤ 500 caractere | nu | Link către PDF-ul facturii (afișat ca buton "PDF" în modal). |
Exemplu — trimitere idempotentă
curl -X POST https://tenant.notsowms.ro/api/v1/billing/invoices \
-H "Authorization: Bearer tenant.7c4a8d09ca3762af61e59520943dc26494f8941b" \
-H "Content-Type: application/json" \
-d '{
"external_id": 12345,
"series": "FAC",
"number": "00012345",
"date_emitted": "2026-04-30",
"date_due": "2026-05-30",
"total": 1000.00,
"total_tva": 190.00,
"currency": "RON",
"description": "Abonament aprilie 2026",
"doc_link": "https://startco.ro/facturi/12345.pdf"
}'Răspuns:
{
"action": "created",
"data": {
"id": 87,
"external_id": 12345,
"series": "FAC",
"number": "00012345",
"date_emitted": "2026-04-30T00:00:00.000000Z",
"date_due": "2026-05-30T00:00:00.000000Z",
"total": "1000.00",
"total_tva": "190.00",
"currency": "RON",
"status": "emisa",
"description": "Abonament aprilie 2026",
"doc_link": "https://startco.ro/facturi/12345.pdf",
"created_at": "2026-04-30T08:42:11.000000Z",
"updated_at": "2026-04-30T08:42:11.000000Z"
}
}A doua oară când trimiți același external_id, primești "action": "updated" și 200 OK în loc de 201 Created. Util când CRM-ul tău are retry policy — niciodată nu vei avea duplicate.
Marcarea unei facturi ca încasată
curl -X PATCH https://tenant.notsowms.ro/api/v1/billing/invoices/12345 \
-H "Authorization: Bearer tenant.7c4a8d09ca3762af61e59520943dc26494f8941b" \
-H "Content-Type: application/json" \
-d '{ "status": "incasata" }'Răspuns:
{ "data": { /* factura actualizată */ } }Anularea unei facturi
curl -X PATCH https://tenant.notsowms.ro/api/v1/billing/invoices/12345 \
-H "Authorization: Bearer tenant.7c4a8d09ca3762af61e59520943dc26494f8941b" \
-H "Content-Type: application/json" \
-d '{ "status": "anulata" }'Statusul anulata apare cu badge roșu în modalul Facturi; factura nu mai contribuie la sumarul de "Neachitate" și "Total datorat" din dashboard.
Listă cu filtre
curl "https://tenant.notsowms.ro/api/v1/billing/invoices?status=emisa&date_from=2026-04-01&per_page=50" \
-H "Authorization: Bearer tenant.7c4a8d09ca3762af61e59520943dc26494f8941b"Răspunsul respectă forma standard de paginare — paginatorul Laravel cu rândurile în data și metadatele de paginare (current_page, per_page, total, …) la nivelul de sus.
Erori uzuale
| Status | Cauză |
|---|---|
| 401 | Token lipsă sau invalid (vezi autentificare). |
| 403 | Tenantul a fost suspendat sau cheia API a fost revocată / a expirat. |
| 422 | Validarea câmpurilor a eșuat — body-ul răspunsului include lista de erori per câmp. |
| 404 | external_id nu există în baza tenantului (la GET/PATCH/DELETE). |
Autentificare
Generează o cheie API per-tenant din Setări → Chei API (vezi autentificare) și trimite-o ca Authorization: Bearer <slug>.<cheie>, la fel ca pentru restul API-ului.