Процес: излезни е-фактури
Оваа страница те води од нула до една излезна е-фактура што УЈП ја примил и прифатил. Не треба да знаеш ништо однапред: секој чекор кажува што правиш, ти дава готова команда, покажува каков одговор да очекуваш и што да направиш ако добиеш нешто друго.
Сè се случува на sandbox серверот (https://sandbox.api.earhiva.mk). Тој ја праќа фактурата на
тест системот на УЈП, па ниту една фактура од оваа страница не е вистинска и не создава даночна
обврска.
Патот на фактурата
Дел со наслов „Патот на фактурата“Пред чекорите, целата слика. Фактурата минува низ четири места:
| # | Каде | Што се случува |
|---|---|---|
| 1 | Твојот софтвер | ја составува фактурата како UBL 2.1 XML и ја праќа со еден повик |
| 2 | eArhiva.mk | ја заведува, проверува, ја претвора во порака за УЈП и ја потпишува |
| 3 | УЈП | ја прима, ја проверува и ја прифаќа или одбива |
| 4 | Примачот | ја гледа кај себе и може да ја прифати или одбие |
Ти праќаш само еднаш (чекор 4 подолу), а потоа само прашуваш докаде стигнала (чекорите 5 и 6). Потпишувањето и праќањето кон УЈП ги правиме ние.
Што ти треба
Дел со наслов „Што ти треба“| Што | Зошто |
|---|---|
| е-пошта | за барањето за пристап |
команда curl | за повиците; ја има на Windows 10 и 11, macOS и Linux |
| една празна папка | таму ќе ја снимиш фактурата и од таму ќе ги извршуваш командите |
| податоци за клиентот | од чие име ќе праќаш — име, ЕДБ и e-УЈП ID (в. чекор 1) |
Чекорите
Дел со наслов „Чекорите“-
Побарај пристап
Дел со наслов „Побарај пристап“Пристапот се бара од нас по е-пошта, на support@earhiva.mk, со наслов
Барање за пристап кон sandbox серверот. Копирај го текстот подолу и пополни ги сите три дела:Текст на барањето · копирај го и пополни го Барање за пристап кон sandbox серверот на eArhiva.mk1. Податоци за интеграторотиме на компанијата:лице за контакт:е-пошта:телефон:име на апликацијата што ќе го користи API:2. Податоци за клиентот (од чие име ќе се праќаат фактурите)име на компанијата:ЕДБ:e-УЈП ID:лице за контакт:е-пошта:3. Примач на пробните фактурииме на компанијата:ЕДБ:Трите дела се потребни затоа што фактурата стигнува до УЈП само ако три работи се подготвени однапред:
Што Кој го дава Што се случува без него ЕДБ на клиентот клиентот фактурата не заминува кон УЈП e-УЈП ID на клиентот го доделува УЈП кога клиентот се регистрира за е-фактури; клиентот го има фактурата не заминува кон УЈП Примачот заведен како партнер на клиентот ⚠️ веќе не е предуслов — примач што го нема се заведува од самата фактура; делот 3 сепак помага да го провериме приемот пред тебе — Што ќе добиеш назад: клуч (долга низа знаци) и потврда дека организацијата на клиентот е подготвена за праќање кон УЈП. Клучот чувај го како лозинка — со него се праќа во име на клиентот.
-
Провери дека клучот работи
Дел со наслов „Провери дека клучот работи“Ова е најкраткиот повик: не праќа ништо, само кажува дали клучот е примен. Во командата замени ги двете вредности во
< >:<ВАШИОТ КЛУЧ>— клучот од чекорот 1<ИМЕ И ВЕРЗИЈА НА ВАШАТА АПЛИКАЦИЈА>— слободен текст, на примерSmetkovodstvoPro/2.4
Барање · ова го извршуваш ти curl -i "https://sandbox.api.earhiva.mk/api/integration/v1/ping" \-H "X-Api-Key: <ВАШИОТ КЛУЧ>" \-H "X-Software-Id: <ИМЕ И ВЕРЗИЈА НА ВАШАТА АПЛИКАЦИЈА>"Ако е во ред, првиот ред од одговорот е
HTTP/1.1 200 OK, а на крајот стои:Одговор од API-то · вредностите се пример {"ok": true,"keyValid": true,"serverTime": "2026-09-11T10:14:03.412+02:00"}Ако не е:
Добиваш Што значи Што правиш 401клучот не е препишан точно, или е истечен копирај го повторно, без празни места на почетокот и крајот 403клучот не носи право за интеграцискиот API, или адресата од која праќаш не е дозволена пиши на поддршката и прати го целиот одговор 400соEARH-1008го нема заглавието X-Software-Idдодај го — тоа е задолжително во секој повик -
Подготви ја фактурата
Дел со наслов „Подготви ја фактурата“Преземи ја готовата фактура
invoice-ubl21.xmlи сними ја во празната папка под иметоinvoice.xml.Отвори ја во кој било уредувач на текст и смени точно четири работи. Сè друго остави го како што е.
# Што Каде во фајлот Со што 1 број на фактурата <cbc:ID>0001/2026</cbc:ID>нов број, на пример TEST-00012 датум на издавање <cbc:IssueDate>…</cbc:IssueDate>денешниот датум, во облик 2026-09-113 испраќач cac:AccountingSupplierParty—cbc:Nameиcbc:CompanyIDимето и ЕДБ-то на клиентот од делот 2 од барањето 4 примач cac:AccountingCustomerParty—cbc:Name,cbc:CompanyIDи адресата воcac:PostalAddressимето, ЕДБ-то и адресата на примачот од делот 3 од барањето По измената, тие делови изгледаат вака:
invoice.xml · само сменетите делови <cbc:ID>TEST-0001</cbc:ID><cbc:IssueDate>2026-09-11</cbc:IssueDate><cac:AccountingSupplierParty><cac:Party><cac:PartyName><cbc:Name><ИМЕ НА КЛИЕНТОТ></cbc:Name></cac:PartyName><cac:PartyTaxScheme><cbc:CompanyID><ЕДБ НА КЛИЕНТОТ></cbc:CompanyID></cac:PartyTaxScheme></cac:Party></cac:AccountingSupplierParty><cac:AccountingCustomerParty><cac:Party><cac:PartyName><cbc:Name><ИМЕ НА ПРИМАЧОТ></cbc:Name></cac:PartyName><cac:PostalAddress><cbc:StreetName><УЛИЦА И БРОЈ></cbc:StreetName><cbc:CityName><ГРАД></cbc:CityName><cbc:PostalZone><ПОШТЕНСКИ БРОЈ></cbc:PostalZone><cac:Country><cbc:IdentificationCode>MK</cbc:IdentificationCode></cac:Country></cac:PostalAddress><cac:PartyTaxScheme><cbc:CompanyID><ЕДБ НА ПРИМАЧОТ></cbc:CompanyID></cac:PartyTaxScheme></cac:Party></cac:AccountingCustomerParty>⛔ При секој нов обид земи нов број на фактура и нова
X-Idempotency-Key. Истата ознака со иста содржина го враќа првиот одговор и не создава втор документ (в. чекор 4). Но иста фактура пратена со нова ознака создава втор документ кај нас и заминува кај УЈП по втор пат — а дали таму ќе биде прифатена или одбиена како дупликат зависи од нивниот регистар и не е под наша контрола. Затоа:TEST-0002,TEST-0003и така натаму.⛔ Не ги бриши адресата на примачот и стапката на ДДВ на ставката (
cac:ClassifiedTaxCategory). Приемот не ги бара, но УЈП ги бара: без нив фактурата застанува пред УЈП соEARH-4001. -
Прати ја фактурата
Дел со наслов „Прати ја фактурата“Изврши ја командата од папката каде е
invoice.xml. Покрај двете познати заглавија, ова барање носи уште две:-
X-Idempotency-Key— твоја ознака за ова праќање. Земи ја од бројот на фактурата, на примерinvoice-TEST-0001. Ако врската се прекине и ја повториш истата команда, нема да се создаде втора фактура — ќе го добиеш одговорот од првиот пат.⛔ Ознаката е врзана за содржината, не само за себе. Ист клуч со иста содржина е повторување и враќа
200; ист клуч со изменета содржина се одбива соEARH-2010. Значи ако го прегенерираш документот по поправка, тој бара нова ознака. Заради тоа ознака изведена само од идентитетот на фактурата (фирма + година + тип + број) удира во409при секој втор обид — додај ѝ и нешто што се менува со содржината (верзија, време на генерирање, збир од телото). -
Prefer: wait=30— одговорот да почека до 30 секунди додека нашата обработка не ја поднесе фактурата кон УЈП, и да ти го врати исходот, заедно со бројот што УЈП ѝ го доделил. Без ова заглавие одговорот доаѓа веднаш, само со потврда дека фактурата е примена.⚠️
waitе горна граница на чекањето, не гаранција за конечен исход. Ако обработката трае подолго, одговорот доаѓа по истекот со состојбата што важи во тој момент — најчесто210. Тоа не е грешка и не значи дека нешто паднало: состојбата се дочитува соGET outbound/{docUid}. ЗаглавиетоPreference-Appliedкажува колку навистина е чекано.
Барање · ова го извршуваш ти curl -i -X POST "https://sandbox.api.earhiva.mk/api/integration/v1/outbound" \-H "X-Api-Key: <ВАШИОТ КЛУЧ>" \-H "X-Software-Id: <ИМЕ И ВЕРЗИЈА НА ВАШАТА АПЛИКАЦИЈА>" \-H "X-Idempotency-Key: invoice-TEST-0001" \-H "Prefer: wait=30" \-H "Content-Type: application/xml" \--data-binary @invoice.xmlАко е во ред, првиот ред е
HTTP/1.1 201 Created, меѓу заглавијата стоиPreference-Applied: wait=30, а на крајот:Одговор од API-то · вредностите се пример, твоите ќе бидат други {"docUid": "eah_o_01K3F9YB2M7Q4XVZ8NDHRPTC5E","status": 270,"receivedAt": "2026-09-11T10:16:41.088+02:00","alreadyExisted": false,"failureCode": null,"ujp": {"euid": "<УЈП ID>", // бројот што УЈП ѝ го доделил на фактурата"qrLink": "https://…/euid/<УЈП ID>", // врската за QR кодот, онака како ја вратил УЈП"state": null,"code": null,"message": null,"checkedAt": null}}📌
euidиqrLinkсе пополнети, останатите три се празни — тоа е точниот изглед. Кога УЈП ја прифаќа фактурата, тој враќа идентификатор и врска, не и состојба. Полињатаstate,code,messageиcheckedAtсе пополнуваат подоцна, кога состојбата ќе се прочита од УЈП — прашај соGET outbound/{docUid}кога ти треба. ⛔ Не чекај на нив за да заклучиш дека фактурата е примена: тоа го кажуваeuid.📌 Копирај ја вредноста на
docUidи чувај ја. Тоа е бројот на фактурата кај нас, и секоја следна команда го бара. Вредноста погоре е само пример.Каде оди понатаму зависи од одговорот:
Во одговорот Што правиш ujpне еnullисходот од УЈП е веќе тука — ✅ оди директно на чекорот 6 statusе210или220, а"ujp": null30-те секунди поминале пред исходот — тоа не е грешка, обработката продолжува. Оди на чекорот 5 statusе225или250фактурата застанала пред УЈП или УЈП ја одбил — оди на чекорот 6, таму стои што да направиш Ако не е:
Добиваш Што значи Што правиш 400со шифра одEARH-2001доEARH-2007фајлот не е во ред — лош XML, недостасува задолжително поле, или издавачот не е твојата организација ( EARH-2007)шифрата кажува кое; види го каталогот на грешки, поправи и прати повторно 400соEARH-2011телото носи повеќе од една фактура едно барање носи точно еден документ; подели ги 400соEARH-2013го нема заглавието X-Idempotency-Keyдодај го — без него не можеме да разликуваме повторено барање од нова фактура 409соEARH-2010истата X-Idempotency-Keyвеќе е употребена за друга содржинасмени го бројот на фактурата и ознаката — на пример TEST-0002иinvoice-TEST-0002413соEARH-2012фактурата е преголема одговорот ја именува дозволената големина за таа организација; отстрани го прилогот што ја крева 200наместо201, со"alreadyExisted": trueоваа фактура е веќе пратена со истата ознака не е грешка — docUidе истиот од првиот пат -
-
Следи ја додека не стигне до УЈП
Дел со наслов „Следи ја додека не стигне до УЈП“Овој чекор ти треба само ако одговорот од чекорот 4 немал исход од УЈП. Обработката продолжува во позадина — фактурата се проверува, потпишува и праќа кон УЈП. Со командата подолу прашуваш докаде стигнала, со eArhiva ID-то. Замени го
<docUid>со вредноста од чекорот 4:Барање · ова го извршуваш ти curl -i "https://sandbox.api.earhiva.mk/api/integration/v1/outbound/<docUid>" \-H "X-Api-Key: <ВАШИОТ КЛУЧ>" \-H "X-Software-Id: <ИМЕ И ВЕРЗИЈА НА ВАШАТА АПЛИКАЦИЈА>"Гледај го полето
statusво одговорот. Повторувај ја командата на секои 10 секунди додека статусот не стане еден од последните два реда во табелата:statusШто значи Што правиш 210примена кај нас, обработката уште не почнала чекај и прашај повторно 220се проверува и потпишува чекај и прашај повторно 230поднесена кај УЈП ✅ оди на чекорот 6 270архивирана — по поднесувањето фактурата оди во архивата сама ✅ оди на чекорот 6 225или250застанала пред УЈП, или УЈП ја одбил оди на чекорот 6 — таму стои што да направиш Архивирањето следува веднаш по поднесувањето, па можно е
230воопшто да не го видиш и од220директно да добиеш270. Тоа не е проблем.Ако статусот стои на
210или220подолго од 10 минути, пиши на поддршката и прати гоdocUid. -
Провери дека УЈП ја прифатил
Дел со наслов „Провери дека УЈП ја прифатил“Во последниот одговор — од чекорот 4 или од чекорот 5 — провери три полиња. Фактурата е прифатена кај УЈП кога сите три се исполнети:
Поле Мора да биде status230,240или270failureCodenullujpне е null, внатре во негоcodeеnull, аeuidго носи УЈП ID-тоВака изгледа успешен одговор:
Одговор од API-то · фактура прифатена кај УЈП {"docUid": "eah_o_01K3F9YB2M7Q4XVZ8NDHRPTC5E","status": 270,"failureCode": null, // ништо не паднало"failureMessage": null,"createdAt": "2026-09-11T10:16:41.088+02:00","partnerEdb": "<ЕДБ НА ПРИМАЧОТ>","documentNumber": "TEST-0001","amount": 1180.00,"currency": "MKD","validationErrors": [],"ujp": { // не е null — фактурата била кај УЈП"euid": "<УЈП ID>", // бројот што УЈП ѝ го доделил на фактурата"qrLink": "https://…/euid/<УЈП ID>", // врската за QR кодот, онака како ја вратил УЈП"state": null, // се пополнува подоцна, при читање на состојбата"code": null, // УЈП немал забелешка"message": null,"checkedAt": null}}Ако фактурата ја печатиш во свој PDF, QR кодот на неа е
ujp.qrLink— втисни ја таа вредност таква каква што е. ⛔ Не ја составувај одeuid: адресата е различна на тест и во продукција, и ја одредува УЈП. СоPrefer: waitод чекорот 4 иeuidиqrLinkстигнуваат во истиот одговор.Целиот пат на фактурата, со време за секоја промена, го гледаш со историјата:
Барање · ова го извршуваш ти curl -i "https://sandbox.api.earhiva.mk/api/integration/v1/outbound/<docUid>/history" \-H "X-Api-Key: <ВАШИОТ КЛУЧ>" \-H "X-Software-Id: <ИМЕ И ВЕРЗИЈА НА ВАШАТА АПЛИКАЦИЈА>"Одговор од API-то · фактура што поминала до крај {"docUid": "eah_o_01K3F9YB2M7Q4XVZ8NDHRPTC5E","transitions": [{ "status": 210, "at": "2026-09-11T10:16:41", "failureCode": null },{ "status": 220, "at": "2026-09-11T10:16:49", "failureCode": null },{ "status": 230, "at": "2026-09-11T10:17:03", "failureCode": null },{ "status": 270, "at": "2026-09-11T10:17:05", "failureCode": null }]}Ако не е прифатена, најди го својот случај:
Гледаш Што се случило Што правиш statusе225, или270со"ujp": nullфактурата е проверена, но не е пратена кон УЈП — на организацијата на клиентот ѝ недостасува ЕДБ или e-УЈП ID пиши на поддршката и прати го docUid; кога ќе ти потврдат, прати нова фактура со нов број250соEARH-4005примачот не можел ниту да се разреши ниту да се заведе — редок случај, зашто непознат примач се заведува од самиот документ validationErrorsго носиEARH-5020со истата причина; провери го ЕДБ-то на примачот воinvoice.xml, и дали тој партнер е избришан во организацијата на клиентот250соEARH-4001фактурата не ја поминала проверката пред УЈП секој проблем е наведен во validationErrors, со своја шифраEARH-5xxx; поправи го полето воinvoice.xml250соEARH-4002УЈП ја одбил фактурата причината е во ujp.codeиujp.message; значењето на шифрата е во Шифри од УЈП250соEARH-4004обработката паднала на технички неуспех ⛔ прво погледни failedStep: ако еConvertFormat, документот не можел да се конвертира и причината е во твоето тело; ако е друг чекор, пиши на поддршката и прати гоdocUidФактура во
250не продолжува сама. По поправката прати нова фактура — чекорите 3 и 4 со нов број на фактура и новаX-Idempotency-Key.
Ако си пратил по грешка
Дел со наслов „Ако си пратил по грешка“Сторнирањето е можно само додека фактурата не стигнала до УЈП. Штом УЈП ја прифатил, кај нив постои запис со правно дејство и ниту еден наш повик не го брише.
curl -i -X POST "https://sandbox.api.earhiva.mk/api/integration/v1/outbound/<docUid>/cancel" \ -H "X-Api-Key: <ВАШИОТ КЛУЧ>" \ -H "X-Software-Id: <ИМЕ И ВЕРЗИЈА НА ВАШАТА АПЛИКАЦИЈА>"| Состојба на фактурата | Одговор | Што значи |
|---|---|---|
210 или 220 — примена, обработката трча | 200 со "status": 260 | обработката е запрена; фактурата не заминува кон УЈП |
250 — застаната пред УЈП | 200 со "status": 260 | документот никогаш не заминал, па сторнирањето е чисто |
230, 240 или 270 — веќе кај УЈП | 409 EARH-3003 | доцна е за сторно; исправката оди преку одобрение кај УЈП |
| веќе сторнирана | 409 EARH-3004 | не е грешка во твојот код — веќе е направено |
непознат docUid | 404 EARH-3001 | провери го идентификаторот |
📌 Сторнирањето не брише: документот и понатаму се чита по својот docUid, а преминот кон 260
останува во историјата. Тоа е намерно — трагата мора да остане.
Готово
Дел со наслов „Готово“Ако чекорот 6 е исполнет, твојот софтвер праќа е-фактури кон УЈП преку eArhiva.mk и го добива
УЈП ID-то на секоја. Истите четири повици — ping, POST outbound, GET outbound/{docUid},
GET outbound/{docUid}/history — се целото што ти треба за основниот тек. Во продукција се
менува само адресата и клучот.
📌 Prefer: wait го чека само поднесувањето кон УЈП. Подоцнежните промени кај УЈП — примачот
ја прифатил или одбил фактурата — не се чекаат; тие се читаат со GET outbound/{docUid}. УЈП ID-то
стои и во списокот GET outbound, во полето ujpEuid.
Каде понатаму
Дел со наслов „Каде понатаму“| Кога ти треба | Оди на |
|---|---|
| кој статус што значи и кон што преминува | Излезни документи |
| свои фактури наместо примерот — што смееш да смениш и што е задолжително | Формати |
значењето на секоја шифра EARH-xxxx | Каталог на грешки |
| список на пратените фактури, преземање на фајл, сторно | API Reference |
| колку повици во минута смееш | Ограничувања и правила |