Национална система за е-фактуриране през API

Предварителна проверка (в Румъния CIUS-RO), подаване в националната система (в Румъния SPV), нормализиран статус, подписан отговор и входяща кутия с фактури.

Предварителна проверка (в Румъния CIUS-RO), подаване в националната система (в Румъния SPV), нормализиран статус, подписан отговор и входяща кутия с фактури.

← Обратно към API документацията

Първата фактура в 6 стъпки

  1. Изпълнете POST /v1/invoices/{id}/efactura/validate. Предварителната проверка (в Румъния CIUS-RO) не изпраща нищо към националната система за е-фактуриране и ви казва точно какво би било отхвърлено.
  2. Подайте с POST /v1/invoices/{id}/efactura/submit, винаги с Idempotency-Key. Получавате submission_id и статус.
  3. Проверявайте GET /v1/efactura/submissions/{id}, докато стигне accepted или rejected.
  4. Принудете нова заявка към националната система за е-фактуриране с POST /v1/efactura/submissions/{id}/refresh — тя се отчита в кошницата от 10 на минута.
  5. Изтеглете архива с подписания отговор на националната система (в Румъния ANAF) чрез GET /v1/efactura/submissions/{id}/download.

Всички endpoint-и

МетодEndpointScopeIdempotency-KeyЗаявки / минута
GET/invoices/{invoice_id}/xml
Изтегляне на UBL XML (в Румъния CIUS-RO)
invoices:read—120
POST/invoices/{invoice_id}/efactura/validate
Предварителна проверка (в Румъния CIUS-RO) — валидиране без изпращане
efactura:read—120
POST/invoices/{invoice_id}/efactura/submit
Изпращане на фактурата до националната система за е-фактуриране (в Румъния ANAF/SPV)
efactura:submitзадължително10
GET/efactura/submissions
Списък с подаванията към националната система за е-фактуриране
efactura:read—120
GET/efactura/submissions/{submission_id}
Извличане на едно изпращане
efactura:read—120
POST/efactura/submissions/{submission_id}/refresh
Запитване към националната система за е-фактуриране за текущото състояние
efactura:read—10
GET/efactura/submissions/{submission_id}/download
Изтегляне на архива на подписания отговор
efactura:read—120
GET/efactura/inbox
Фактури от доставчици, получени през националната система за е-фактуриране
efactura:read—120
GET/efactura/inbox/{inbound_id}
Извличане на една входяща фактура
efactura:read—120
GET/efactura/inbox/{inbound_id}/download
Изтегляне на архива на входящата фактура
efactura:read—120
POST/efactura/inbox/sync
Изтегляне на новите съобщения от националната система за е-фактуриране във входящата кутия
efactura:read—10

Какво е 4invoices API

bash
# CIUS-RO preflight. Sends NOTHING to ANAF.
curl -sS -X POST "https://api.4invoices.net/v1/invoices/inv_01J7ABC/efactura/validate?include_xml=true" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# → {"invoice_id":"inv_01J7ABC","valid":false,
#    "errors":["buyer.county is required for RO buyers"],
#    "xml_base64":"PD94bWwg..."}
bash
curl -sS -X POST https://api.4invoices.net/v1/invoices/inv_01J7ABC/efactura/submit \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Idempotency-Key: efactura-inv_01J7ABC-1'

# → {"submission_id":"sub_01J7XYZ","status":"queued"}
python
import time, requests

BASE = "https://api.4invoices.net/v1"
TERMINAL = {"accepted", "rejected"}
H = {"Authorization": f"Bearer {token}"}

def wait_for_anaf(submission_id, timeout=900):
    deadline = time.time() + timeout
    delay = 15
    while time.time() < deadline:
        r = requests.get(f"{BASE}/efactura/submissions/{submission_id}", headers=H, timeout=30)
        r.raise_for_status()
        status = r.json()["status"]
        if status in TERMINAL:
            return r.json()
        # /refresh asks ANAF directly and shares the 10/min submit bucket.
        requests.post(f"{BASE}/efactura/submissions/{submission_id}/refresh", headers=H, timeout=30)
        time.sleep(delay)
        delay = min(delay * 2, 120)
    raise TimeoutError(submission_id)
bash
# Pull new SPV messages, then read the inbound supplier invoices.
curl -sS -X POST https://api.4invoices.net/v1/efactura/inbox/sync \
  -H "Authorization: Bearer $ACCESS_TOKEN"

curl -sS "https://api.4invoices.net/v1/efactura/inbox?limit=50" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# ANAF allows roughly ONE message-list call per minute per CIF,
# затова /inbox/sync се отчита в квотата за изпращане от 10/мин. Пускайте го по cron, не с полинг.

https://api.4invoices.net/v1 · https://api.4invoices.net/v1/openapi.json

Пътят до националната система за е-фактуриране

not_sentvalidatingqueuedsentprocessingacceptedrejectederror

Грешки

СтатусТипКод
422invalid_request_errorcius_ro_incomplete

Често срещани грешки

  • Нормализиран жизнен цикъл: not_sent → валидиране → в опашка → изпратен → обработка → accepted | rejected | грешка.
  • accepted означава законово предадена. rejected означава, че националната система за е-фактуриране я е отказала: коригирайте и подайте отново. error е транспортна грешка от наша страна и повторният опит е безопасен.
  • Подаването е необратимо: второ копие на същата фактура не може да бъде оттеглено от националната система за е-фактуриране. Затова Idempotency-Key е задължителен.
  • GET /v1/invoices/{id}/xml ви дава XML във формат UBL (в Румъния CIUS-RO) изобщо без подаване — за собствен архив или одит.
  • Входяща кутия: POST /v1/efactura/inbox/sync изтегля новите съобщения, GET /v1/efactura/inbox ги изброява, а /download изтегля архива на всяка входяща фактура.
  • Endpoint-ите за e-Factura работят само за румънски тенанти; в противен случай получавате 404.

Въпроси и отговори за разработчици

Колко време отнема на националната система за е-фактуриране да приеме фактура?

Варира — от секунди до часове. Не блокирайте продажбата: подавайте асинхронно и третирайте accepted и rejected като събития.

Мога ли да получа XML (в Румъния по CIUS-RO), без да изпращам нищо към националната система за е-фактуриране?

Да. GET /v1/invoices/{id}/xml генерира документа без подаване, а /efactura/validate с include_xml=true го връща кодиран в base64.

Колко често мога да пускам inbox/sync?

Най-много 10 извиквания в минута, но на практика в Румъния ANAF позволява приблизително едно извикване за списък със съобщения на минута за CIF. Пускайте го от cron, на всеки няколко минути.

Какво да направя, ако статусът остане грешка?

грешка е транспортна или автентикационна грешка от наша страна, така че повторният опит е безопасен. Ако продължава, изпратете request_id на поддръжката.