4invoices kūrėjų API

REST per HTTPS, JSON, viešoji OpenAPI specifikacija. Sąskaitos, klientai, numeravimo serijos ir visas nacionalinis elektroninių sąskaitų faktūrų ciklas (ANAF e-Factura Rumunijoje) — iš jūsų ERP, parduotuvės ar CRM.

Viešoji 4invoices API perduoda jūsų sistemos sąskaitų duomenis į 4invoices ir nuveda sąskaitą iki pat nacionalinės e. sąskaitų faktūrų sistemos (Rumunijoje – ANAF SPV). Vienas gamybinis serveris, vienas client_credentials srautas, idempotentiški fiskaliniai įrašai ir viena klaidų atsakymo struktūra kiekviename maršrute.

https://api.4invoices.net/v1 · OpenAPI specifikacija (raktas nereikalingas)

Kas yra 4invoices API

  • 4invoices viešoji API yra REST per HTTPS, JSON įvedimas ir JSON išvedimas.
  • Vienas gamybinis serveris: https://api.4invoices.net/v1. Atskiro testavimo serverio nėra.
  • OpenAPI 3.1 specifikacija yra viešai prieinama ir be raktų — importuokite ją tiesiai į Postman ar kliento generatorių.
  • Kiekvienas atsakymas turi X-Request-Id antraštę; ją nurodykite kreipdamiesi į palaikymą.
  • Kiekvienas fiskalinis įrašas yra idempotentiškas: pakartojimas po nutrūkimo niekada nesukuria antro dokumento.
Tik serveris–serveris. Niekada nekvieskite API iš naršyklės JavaScript: client_secret pasiektų lankytoją, o CORS vis tiek blokuoja visas kilmes.
  • Visas nacionalinės e. sąskaitų faktūrų sistemos ciklas per API (Rumunijoje – ANAF e-Factura): išankstinis patikrinimas, pateikimas, sekimas, pasirašytas atsakymas ir gaunamoji gautųjų dėžutė. Nė vienas Rumunijos konkurentas to nesiūlo.
  • SmartBill neturi nė vieno galinio taško sąskaitoms pateikti į nacionalinę e. sąskaitų faktūrų sistemą (Rumunijoje – ANAF) — siuntimas yra tik sąsajos paskyros nustatymas — ir visai neturi sąskaitų sąrašo galinio taško.
  • Oblio gali kurti klientus ir produktus tik kaip dokumento išrašymo šalutinį efektą, o ne kaip pirmos klasės išteklius.
  • UBL XML generavimas (Rumunijoje – CIUS-RO) be pateikimo: gaunate teisinį dokumentą kaip failą, nepaliesdami nacionalinės e. sąskaitų faktūrų sistemos.
  • Idempotentiškumas fiskaliniuose įrašuose: pakartojimas po nutrūkimo nesukuria antros sąskaitos ir nesunaudoja antro numerio.
  • Programiškai skaitoma tiekėjų sąskaitų gautųjų dėžutė — automatinio suderinimo pagrindas.

Pirmoji sąskaita per 6 žingsnius

Prieš pirmąjį kvietimą
  1. Sukurkite prieigos duomenis skydelyje, skiltyje Sąskaitos → Nustatymai → API prieiga, ir nukopijuokite client_secret — jis rodomas tik vieną kartą.
  2. Užpildykite įmonės profilį ir aktyvuokite bent vieną fiskalinę seriją (fiscale), kitaip išrašymas grąžins issuer_profile_incomplete arba no_series_configured.
  1. Sukurkite prieigos duomenis skydelyje, skiltyje Sąskaitos → Nustatymai → API prieiga, ir nukopijuokite client_secret — jis rodomas tik vieną kartą.
  2. Užpildykite įmonės profilį ir aktyvuokite bent vieną fiskalinę seriją (fiscale), kitaip išrašymas grąžins issuer_profile_incomplete arba no_series_configured.
  3. Pakeiskite prieigos duomenis žetonu: POST /v1/auth/token su grant_type client_credentials. Žetonas galioja valandą — įsiminkite jį, neimkite naujo kiekvienai užklausai.
  4. Išrašykite sąskaitą: POST /v1/invoices su Idempotency-Key antraště ir vat_rate procentais (21, ne 0.21).
  5. Atlikite išankstinį patikrinimą (Rumunijoje – CIUS-RO) su POST /v1/invoices/{id}/efactura/validate, tada pateikite sąskaitą į nacionalinę e. sąskaitų faktūrų sistemą su POST /v1/invoices/{id}/efactura/submit.
  6. Sekite būseną su GET /v1/efactura/submissions/{id}, kol pasieks accepted arba rejected.
bash
# 1 — žetonas (1 valanda, įsiminkite jį)
ACCESS_TOKEN=$(curl -sS -X POST https://api.4invoices.net/v1/auth/token \
  -H 'Content-Type: application/json' \
  -d '{"grant_type":"client_credentials","client_id":"cli_XXX","client_secret":"sec_XXX"}' \
  | python3 -c 'import sys,json; print(json.load(sys.stdin)["access_token"])')

# 2 — išrašykite sąskaitą (Idempotency-Key PRIVALOMAS)
curl -sS -X POST https://api.4invoices.net/v1/invoices \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: order-10457-invoice' \
  -d '{"buyer":{"name":"Exemplu Comert SRL","tax_id":"RO12345678","county":"Cluj","city":"Cluj-Napoca","country":"RO"},
       "lines":[{"description":"Abonament SaaS","quantity":1,"unit_price":400,"vat_rate":21}]}'

# 3 — preflight CIUS-RO, then send to ANAF
curl -sS -X POST https://api.4invoices.net/v1/invoices/inv_01J7ABC/efactura/validate \
  -H "Authorization: Bearer $ACCESS_TOKEN"

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'
javascript
const BASE = "https://api.4invoices.net/v1";

const token = await fetch(`${BASE}/auth/token`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    grant_type: "client_credentials",
    client_id: process.env.FOURINVOICES_CLIENT_ID,
    client_secret: process.env.FOURINVOICES_CLIENT_SECRET,
  }),
}).then((r) => r.json()).then((d) => d.access_token);

const invoice = await fetch(`${BASE}/invoices`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/json",
    "Idempotency-Key": `order-${orderId}-invoice`,
  },
  body: JSON.stringify({
    buyer: { name: "Exemplu Comert SRL", tax_id: "RO12345678", county: "Cluj", city: "Cluj-Napoca", country: "RO" },
    lines: [{ description: "Abonament SaaS", quantity: 1, unit_price: 400, vat_rate: 21 }],
    currency: "RON",
    metadata: { order_id: String(orderId) },
  }),
}).then((r) => r.json());

console.log(invoice.number, invoice.totals); // "FCT-000123" { net, vat, gross }
python
import os, uuid, requests

BASE = "https://api.4invoices.net/v1"

token = requests.post(f"{BASE}/auth/token", json={
    "grant_type": "client_credentials",
    "client_id": os.environ["FOURINVOICES_CLIENT_ID"],
    "client_secret": os.environ["FOURINVOICES_CLIENT_SECRET"],
}, timeout=30).json()["access_token"]

headers = {
    "Authorization": f"Bearer {token}",
    # Vienas raktas LOGINEI operacijai — kartodami naudokite jį pakartotinai, niekada negeneruokite naujo.
    "Idempotency-Key": f"order-{order_id}-invoice",
}

invoice = requests.post(f"{BASE}/invoices", headers=headers, json={
    "buyer": {"name": "Exemplu Comert SRL", "tax_id": "RO12345678",
              "county": "Cluj", "city": "Cluj-Napoca", "country": "RO"},
    "lines": [{"description": "Abonament SaaS", "quantity": 1,
               "unit_price": 400, "vat_rate": 21}],   # procentais, ne 0.21
    "currency": "RON",
}, timeout=60).json()

print(invoice["number"], invoice["totals"])

Autentifikavimas

  • Srautas yra client_credentials: keičiate client_id + client_secret porą į Bearer access_token.
  • Žetonas galioja 3600 sekundžių. Atnaujinkite jį prieš galiojimo pabaigą, o ne kiekvienam kvietimui — POST /auth/token turi savo IP limitą.
  • client_secret saugomas tik kaip maiša ir negali būti atkurtas. Jį praradę, sukurkite naujus prieigos duomenis ir panaikinkite senus.
  • Tik serveris–serveris. CORS neleidžia jokios naršyklės kilmės: iš puslapio JavaScript secret nutekėtų lankytojui.
  • Scope'ai suteikiami kiekvienam prieigos duomenų rinkiniui atskirai. Sukurkite atskirus duomenis kiekvienai sistemai ir suteikite kiekvienai mažiausiai reikalingus scope'us.

Sąskaitos → Nustatymai → API prieiga

bash
curl -sS -X POST https://api.4invoices.net/v1/auth/token \
  -H 'Content-Type: application/json' \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "cli_XXXXXXXXXXXX",
    "client_secret": "sec_XXXXXXXXXXXXXXXXXXXX"
  }'

# → {"access_token":"eyJ...","token_type":"Bearer","expires_in":3600,
#    "scope":"invoices:read invoices:write efactura:submit"}
javascript
// Įsiminkite žetoną; neimkite naujo kiekvienai užklausai.
let cached = { token: "", expiresAt: 0 };

async function getToken() {
  if (cached.token && Date.now() < cached.expiresAt - 60_000) return cached.token;

  const res = await fetch("https://api.4invoices.net/v1/auth/token", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      grant_type: "client_credentials",
      client_id: process.env.FOURINVOICES_CLIENT_ID,
      client_secret: process.env.FOURINVOICES_CLIENT_SECRET,
    }),
  });
  if (!res.ok) throw new Error(`token ${res.status}`);

  const data = await res.json();
  cached = { token: data.access_token, expiresAt: Date.now() + data.expires_in * 1000 };
  return cached.token;
}

PVM tarifai yra procentai

vat_rate: 21 ✓  ·  vat_rate: 0.19 ✗  ·  vat_rate: 1 ✗
  • vat_rate yra PROCENTAS: 21 reiškia 21 %.
  • Reikšmės intervale (0, 1] atmetamos — 0.19 yra trupmena, o 1 yra neaiškus (1 % ar 100 %).
  • 0 yra leidžiama ir reiškia atleidimą nuo mokesčio arba apmokestinimą atvirkščiai; teisinę nuorodą įrašykite į notes lauką.
  • unit_price yra NETO vieneto kaina, kai išrašytojas yra PVM mokėtojas.
  • Reikia sumų prieš patvirtinant? POST /v1/invoices/preview-totals atlieka tą patį skaičiavimą nesunaudodamas fiskalinio numerio.

Idempotentiškumas fiskaliniuose įrašuose

  • Idempotency-Key antraštė PRIVALOMA užklausose POST /invoices, POST /invoices/{id}/storno ir POST /invoices/{id}/efactura/submit.
  • Raktai prisimenami 24 valandas. Pakartojus tą patį raktą su tuo pačiu turiniu grąžinamas pradinis rezultatas ir nustatoma Idempotency-Replayed: true.
  • Tas pats raktas su kitu turiniu grąžina 409 idempotency_key_reuse — jau išrašytas fiskalinis dokumentas niekada nebus perrašytas.
  • Vienas raktas vienai LOGINEI operacijai, o ne vienai HTTP bandymui: order-10457-invoice, o ne nauja UUID kiekvienam pakartojimui.
  • Priežastis yra teisinė, ne techninė: sunaudoto fiskalinio numerio ir į nacionalinę e. sąskaitų faktūrų sistemą pateiktos sąskaitos atšaukti nebeįmanoma.
bash
curl -sS -X POST https://api.4invoices.net/v1/invoices \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: order-10457-invoice' \
  -d '{
    "buyer": {
      "name": "Exemplu Comert SRL",
      "tax_id": "RO12345678",
      "address": "Str. Fabricii 12",
      "city": "Cluj-Napoca",
      "county": "Cluj",
      "country": "RO",
      "email": "[email protected]"
    },
    "lines": [
      { "description": "Abonament SaaS, iulie", "quantity": 1, "unit_price": 400, "vat_rate": 21, "unit": "buc" },
      { "description": "Implementare", "quantity": 6, "unit_price": 250, "vat_rate": 21, "unit": "ora" }
    ],
    "currency": "RON",
    "document_kind": "factura",
    "due_date": "2026-08-15",
    "metadata": { "order_id": "10457" }
  }'

Visi galiniai taškai

MetodasGalinis taškasScopeIdempotency-KeyUžklausų / min.
POST/auth/token
Pakeiskite prieigos duomenis į prieigos žetoną
——120
GET/me
Tenant, scope'ai ir dabartiniai limitai
invoices:read—120
POST/invoices
Išrašyti sąskaitą arba proforma sąskaitą
invoices:writeprivaloma30
GET/invoices
Išvardyti sąskaitas (puslapiavimas žymekliu)
invoices:read—120
POST/invoices/preview-totals
Apskaičiuoti sumas nieko nekuriant
invoices:read—120
GET/invoices/{invoice_id}
Gauti vieną sąskaitą
invoices:read—120
GET/invoices/{invoice_id}/pdf
Atsisiųsti sąskaitos PDF
invoices:read—120
GET/invoices/{invoice_id}/xml
Atsisiųsti UBL XML (Rumunijoje – CIUS-RO)
invoices:read—120
POST/invoices/{invoice_id}/storno
Išrašyti kreditinę sąskaitą, panaikinančią šią sąskaitą
invoices:writeprivaloma30
POST/invoices/{invoice_id}/payments
Pažymėti sąskaitą apmokėta
invoices:write—30
DELETE/invoices/{invoice_id}/payments
Pažymėti sąskaitą neapmokėta
invoices:write—30
GET/clients
Išvardyti klientus
clients:read—120
POST/clients
Sukurti arba atnaujinti klientą
clients:write—30
GET/lookup/company/{tax_id}
Patikrinti CUI pagal Rumunijos ANAF registrą
clients:read—120
GET/series
Išvardyti numeravimo serijas
invoices:read—120
POST/invoices/{invoice_id}/efactura/validate
Išankstinis patikrinimas (Rumunijoje – CIUS-RO) — tikrinti nesiunčiant
efactura:read—120
POST/invoices/{invoice_id}/efactura/submit
Pateikti sąskaitą į nacionalinę e. sąskaitų faktūrų sistemą
efactura:submitprivaloma10
GET/efactura/submissions
Išvardyti pateikimus į e. sąskaitų faktūrų sistemą
efactura:read—120
GET/efactura/submissions/{submission_id}
Gauti vieną pateikimą
efactura:read—120
POST/efactura/submissions/{submission_id}/refresh
Paklausti nacionalinės e. sąskaitų faktūrų sistemos dabartinės būsenos
efactura:read—10
GET/efactura/submissions/{submission_id}/download
Atsisiųsti pasirašytų atsakymų archyvą
efactura:read—120
GET/efactura/inbox
Per nacionalinę e. sąskaitų faktūrų sistemą gautos tiekėjų sąskaitos
efactura:read—120
GET/efactura/inbox/{inbound_id}
Gauti vieną gautą sąskaitą
efactura:read—120
GET/efactura/inbox/{inbound_id}/download
Atsisiųsti gautos sąskaitos archyvą
efactura:read—120
POST/efactura/inbox/sync
Gauti naujas sistemos žinutes į gautųjų dėžutę
efactura:read—10

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

Scope'ai

  • invoices:read
  • invoices:write
  • clients:read
  • clients:write
  • efactura:read
  • efactura:submit

Nacionalinė e. sąskaitų faktūrų sistema

not_sentvalidatingqueuedsentprocessingacceptedrejectederror
  • Tikrasis skirtumas: visas nacionalinės e. sąskaitų faktūrų sistemos ciklas (Rumunijoje – ANAF e-Factura) vyksta per API, o ne tik dokumento generavimas.
  • POST /invoices/{id}/efactura/validate atlieka išankstinį patikrinimą (Rumunijoje – CIUS-RO) ir grąžina tiksliai tuos laukus, kuriuos nacionalinė e. sąskaitų faktūrų sistema atmestų, nieko neišsiųsdamas.
  • GET /invoices/{id}/xml generuoja UBL XML (Rumunijoje – CIUS-RO) be pateikimo — naudinga jūsų archyvui ar vidiniam auditui.
  • POST /invoices/{id}/efactura/submit pateikia sąskaitą į nacionalinę e. sąskaitų faktūrų sistemą. Tai neatšaukiama: tos pačios sąskaitos antros kopijos iš sistemos nebeįmanoma atsiimti.
  • Ciklas normalizuotas: not_sent → validating → queued → sent → processing → accepted | rejected | error. accepted reiškia teisiškai perduota; error yra mūsų pusės perdavimo klaida ir ją saugu bandyti pakartoti.
  • GET /efactura/submissions/{id}/download atsisiunčia archyvą su nacionalinės e. sąskaitų faktūrų sistemos pasirašytu atsakymu.
  • Gaunamoji pusė taip pat yra: POST /efactura/inbox/sync gauna naujas žinutes iš nacionalinės e. sąskaitų faktūrų sistemos, o GET /efactura/inbox išvardija jūsų tiekėjų atsiųstas sąskaitas.
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)

Klaidos

  • Kiekvienas 4xx ir 5xx naudoja tą patį apvalkalą: { "error": { type, code, message, param?, doc_url, request_id, errors? } }.
  • type yra bendra klasė, pagal kurią sprendžiate („ar galima bandyti dar kartą?”), o code yra stabili priežastis, kurią susiejate su savo sistema.
  • param yra pažeidžiamo lauko taškais atskirtas kelias, pavyzdžiui lines.0.vat_rate.
  • errors[] atsiranda, kai vienoje užklausoje yra problemų daugiau nei viename lauke.
  • request_id registruojamas mūsų pusėje. Nurodykite jį kiekviename palaikymo prašyme — jis tiksliai nustato užklausą.
  • 404 grąžinamas ir tuo atveju, kai identifikatorius priklauso kitam tenant: niekada nepatvirtiname, kad kito asmens duomenys egzistuoja.
json
{
  "error": {
    "type": "invalid_request_error",
    "code": "validation_failed",
    "message": "Datele trimise nu sunt valide.",
    "param": "lines.0.vat_rate",
    "doc_url": "https://4invoices.net/ro/api-dezvoltatori#errors",
    "request_id": "req_8a893f2f33d4472da8d6e144",
    "errors": [
      { "param": "lines.0.vat_rate", "message": "VAT rate must be a percent (21), not a fraction", "type": "value_error" }
    ]
  }
}
BūsenaTipasKodas
401authentication_errormissing_bearer_token
401authentication_errorinvalid_client
401authentication_errortoken_expired
401authentication_errorinvalid_token
401authentication_errorunauthorized
403permission_errorinsufficient_scope
403permission_errorforbidden
404not_found_errornot_found
409conflict_erroridempotency_key_reuse
409conflict_erroridempotency_in_progress
409conflict_errorno_series_configured
422invalid_request_errorvalidation_failed
422invalid_request_errorissuer_profile_incomplete
422invalid_request_errorcius_ro_incomplete
422invalid_request_errorcannot_storno_draft
422invalid_request_errornothing_to_storno
422invalid_request_errorinvalid_json_number
429rate_limit_errorrate_limit_exceeded
502upstream_errorupstream_error
503service_unavailable_errorservice_unavailable

Užklausų limitai

GrupėUžklausų / min.Ką reiškia
read120GET *, POST /invoices/preview-totals, POST /invoices/{id}/efactura/validate
write30POST /invoices, POST /invoices/{id}/storno, POST|DELETE /invoices/{id}/payments, POST /clients
submit10POST /invoices/{id}/efactura/submit, POST /efactura/submissions/{id}/refresh, POST /efactura/inbox/sync
  • Limitai taikomi prieigos duomenims per minutę: 120 skaitymų, 30 rašymų, 10 e. sąskaitų faktūrų sistemos operacijų (submit, refresh, inbox/sync).
  • X-RateLimit-Limit, X-RateLimit-Remaining ir X-RateLimit-Reset pateikiami KIEKVIENAME atsakyme, įskaitant 429.
  • 429 atsakyme taip pat yra Retry-After sekundėmis. Laikykitės jo; nekartokite užklausos staigiu ciklu.
  • 10/min grupė egzistuoja, nes Rumunijos ANAF leidžia maždaug vieną žinučių sąrašo užklausą per minutę vienam mokesčių mokėtojo kodui (CIF).
  • Įjunkite /efactura/inbox/sync pagal cron, o ne agresyvų apklausimą.
  • Reikia didesnių ribų? Kreipkitės per Kontaktai, nurodydami numatomą dienos apimtį.

X-RateLimit-Limit · X-RateLimit-Remaining · X-RateLimit-Reset · Retry-After

http
HTTP/2 429
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1785312000
Retry-After: 17
Content-Type: application/json

{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded",
 "message":"...","doc_url":"https://4invoices.net/ro/api-dezvoltatori#errors",
 "request_id":"req_..."}}
javascript
// Laikykitės Retry-After; nekartokite jokios 4xx klaidos, išskyrus 429.
async function call(url, init, attempt = 0) {
  const res = await fetch(url, init);
  if (res.status === 429 || res.status >= 500) {
    if (attempt >= 5) return res;
    const retryAfter = Number(res.headers.get("Retry-After")) || 2 ** attempt;
    await new Promise((r) => setTimeout(r, retryAfter * 1000));
    return call(url, init, attempt + 1);
  }
  return res;
}

// Kartojant rašymą PRIVALU naudoti TĄ PATĮ Idempotency-Key, kitaip išrašysite
// antrą fiskalinį dokumentą.

Vadovai pagal temas

Kiekviena tema turi savo puslapį su atitinkamais galiniais taškais, pavyzdžiais ir klaidomis.

Dažniausios klaidos

  • PVM siunčiamas kaip trupmena (0.19) arba kaip 1. Abi reikšmės atmetamos; siųskite 19 arba 21.
  • Žetonas kuriamas kiekvienai užklausai. Žetonas galioja valandą; įsiminkite jį, kitaip pasieksite žetono galinio taško IP limitą.
  • Naujo idempotentiškumo rakto generavimas kiekvienam pakartojimui — būtent tas scenarijus sukuria dublikuotas sąskaitas.
  • Kvietimas iš naršyklės JavaScript. CORS blokuoja visas kilmes, o secret vis tiek būtų atskleistas.
  • Pateikimas į nacionalinę e. sąskaitų faktūrų sistemą be išankstinio patikrinimo. Klaidingo pateikimo atšaukti nebeįmanoma.
  • /efactura/submissions/{id}/refresh apklausimas dažniau nei 10 kartų per minutę — ši grupė bendrinama su pateikimu.
  • Sąskaitų išrašymas prieš tai, kai įmonės profilis užpildytas ir yra aktyvi fiskalinė serija.

Kūrėjų klausimai ir atsakymai

Kaip gauti 4invoices API prieigos duomenis?

Skydelyje, skiltyje Sąskaitos → Nustatymai → API prieiga. Gausite client_id ir client_secret; secret rodomas tik vieną kartą ir saugomas tik kaip maiša.

Kiek laiko galioja access_token?

3600 sekundžių, t. y. vieną valandą. Įsiminkite jį talpykloje ir atnaujinkite prieš galiojimo pabaigą — žetono galiniam taškui taikomas atskiras IP limitas.

Kaip siųsti PVM tarifą?

Procentais: 21 reiškia 21 %. Reikšmės intervale (0, 1] atmetamos, todėl ir 0.19, ir 1 neįveikia validacijos.

Kurioms užklausoms reikalingas Idempotency-Key?

POST /invoices, POST /invoices/{id}/storno ir POST /invoices/{id}/efactura/submit. Raktai prisimenami 24 valandas, o pakartotinis kvietimas grąžina pradinį dokumentą su antrašte Idempotency-Replayed: true.

Ar galiu pateikti sąskaitą į nacionalinę e. sąskaitų faktūrų sistemą tiesiai per API?

Taip — Rumunijos rinkoje į ANAF e-Factura. Atlikite išankstinį patikrinimą su /efactura/validate, pateikite sąskaitą su /efactura/submit, tikrinkite normalizuotą būseną /efactura/submissions/{id} ir atsisiųskite sistemos pasirašytą atsakymą.

Kokie yra užklausų limitai?

Pagal prieigos duomenis per minutę: 120 skaitymų, 30 rašymų ir 10 e. sąskaitų faktūrų sistemos operacijų. Kiekvienas atsakymas turi X-RateLimit-* antraštes, o 429 papildomai grąžina Retry-After.

Ar galiu kviesti API iš savo svetainės priekinės dalies?

Ne. Tai tik serveris–serveris: jokia naršyklės kilmė nepraeina CORS, o client_secret neturi būti kode, kurį pasiekia lankytojas.

Kodėl pirmoje sąskaitoje gaunu issuer_profile_incomplete?

Įmonės profilis neužpildytas arba nėra aktyvios fiskalinės serijos. Užpildykite abu skydelyje; API atsisako generuoti neteisingą fiskalinį dokumentą.