Автентикација со API-то на 4invoices

Разменете client_id и client_secret за Bearer токен со важност од еден час, само сервер-кон-сервер.

Разменете client_id и client_secret за Bearer токен со важност од еден час, само сервер-кон-сервер.

← Назад кон API документацијата

Првата фактура во 6 чекори

  1. Создајте акредитиви во панелот под Фактурирање → Поставки → API пристап и веднаш копирајте го client_secret — се прикажува еднаш.
  2. Испратете POST /v1/auth/token со grant_type client_credentials, client_id и client_secret.
  3. Добивате access_token, token_type Bearer, expires_in 3600 и список на доделените scopes.
  4. Ставете го токенот во заглавието Authorization: Bearer <access_token> на сите други повици.
  5. Проверете што навистина добивте со GET /v1/me: тенант, scopes и тековните кофи за ограничувања.

Сите крајни точки

МетодКрајна точкаScopeIdempotency-KeyБарања / минута
POST/auth/token
Размена на акредитиви за access токен
——120
GET/me
Тенант, scopes и тековни ограничувања
invoices:read—120

Што е API-то на 4invoices

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"}
bash
curl -sS https://api.4invoices.net/v1/me \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# → тенант, доделени scopes и тековните кофи за ограничувања
javascript
// Чувајте го токенот во кеш; не создавајте по еден за секое барање.
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;
}

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

Scopes (опсези)

  • invoices:read
  • invoices:write
  • clients:read
  • clients:write
  • efactura:read
  • efactura:submit
Само сервер-кон-сервер. Никогаш не повикувајте го API од JavaScript во прелистувачот: client_secret би стигнал до посетителот, а CORS и онака блокира секое потекло.

Грешки

СтатусТипКод
401authentication_errorinvalid_client
401authentication_errortoken_expired
401authentication_errorinvalid_token
403permission_errorinsufficient_scope

Чести грешки

  • Крајната точка за токени има сопствено ограничување по IP. Еден токен по процес, освежуван пред истекот — не по еден токен за секое барање.
  • client_secret се чува само како хеш; ако го изгубите, создајте нов акредитив и повлечете го стариот.
  • Издајте посебни акредитиви за ERP, продавницата и интерните скрипти, секој со минимални scopes. Повлекувањето на еден не влијае на другите.
  • CORS не дозволува ниедно потекло од прелистувач: API-то е по дизајн сервер-кон-сервер.

Прашања и одговори за програмери

Што се случува ако client_secret е погрешен?

Добивате 401 со кодот invalid_client. Премногу краток secret паѓа порано, при валидација, со 422 validation_failed и param client_secret.

Има ли посебна sandbox средина?

Не. Има една производствена адреса. Тестирајте со проформи (document_kind proforma) и со /invoices/preview-totals, кој не троши фискален број.

Можам ли да ги стеснам scopes на постоечки акредитив?

Можете, од панелот. Токените што веќе се издадени ги задржуваат scopes со кои се создадени до истекот, во рок од еден час.