Unicraft-ის API
წაიკითხეთ სამშენებლო კომპანიის ფინანსები, როგორც კი თანამშრომლები მათ Unicraft-ში აღრიცხავენ - შესყიდვები, იჯარა, დღიური მუშების და ტაბელის ხელფასები, გადახდები, აქტები (ფორმა 2), შემოსავლები და ავანსები ანგარიშვალდებულ პირზე - და დააბრუნეთ პასუხი, თუ რა გააკეთა თქვენმა პროგრამამ თითოეულ ჩანაწერზე. შექმნილია უპირველეს ყოვლისა კომპანიის საბუღალტრო პროგრამის დასაკავშირებლად, რათა არავის მოუწიოს ერთი და იმავე გადახდის ორჯერ შეყვანა.
დაწყება
- კომპანიის ადმინისტრატორი ხსნის კომპანია → ინტეგრაციები Unicraft-ში, ქმნის გასაღებს და აკოპირებს მას. ის ნაჩვენებია მხოლოდ ერთხელ.
- ყოველი გამოძახება იგზავნება
https://unicraft.ge/api/v1/…-ზეAuthorizationჰედერში მითითებული გასაღებით. - წაიკითხეთ ცვლილებების ნაკადი თავიდან (
after=0): თქვენ მიიღებთ კომპანიის მთელ ისტორიას, უძველესიდან დაწყებული, შემდეგ კი ყველაფერ ახალს, როგორც კი მოხდება.
curl https://unicraft.ge/api/v1/me \
-H "Authorization: Bearer uck_your_key"
{
"company": { "id": "cc39…", "name": "Your Construction LLC" },
"key": { "id": "eddd…", "name": "ORIS connector" },
"scopes": ["accounting:read", "accounting:write"]
}
გასაღებები
გასაღები ეკუთვნის ერთ კომპანიას და ხსნის მხოლოდ ამ კომპანიის ჩანაწერებს. გაგზავნეთ ის როგორც Authorization: Bearer uck_… (ან X-Api-Key: uck_…). შეინახეთ ის თქვენს სერვერზე და არასდროს ვებ-გვერდზე.
| წვდომის არეალი | რისი გაკეთება შეუძლია გასაღებს |
|---|---|
accounting:read | პროექტების, ცვლილებების ნაკადის და ცალკეული ჩანაწერების წაკითხვა. აქვს ყველა გასაღებს. |
accounting:write | ასევე ჩანაწერების მონიშვნა როგორც გაგზავნილი, შეცდომით დასრულებული ან გამოტოვებული (/v1/sync) და იმის მითითება, თუ რა გადაიხადა თქვენს პროგრამაში (/v1/paid). საჭიროა კონექტორისთვის. |
people:read | ასევე მუშების პირადი ნომრების (timesheet_month-ის worker.personal_no) წაკითხვა, ხელფასების დასათვლელად. ამის გარეშე ისინი მოდის როგორც null. |
გასაღებს შეუძლია წუთში 600-მდე გამოძახების შესრულება. ადმინისტრატორს შეუძლია ნებისმიერ დროს გააუქმოს გასაღები; ამის შემდეგ ის იღებს 401-ს. კომპანიას აქვს 10-მდე გასაღები - მიეცით თითოეულ პროგრამას საკუთარი.
ცვლილებების ნაკადი
ყველა დამატებული, შეცვლილი ან წაშლილი შესყიდვა, იჯარა, დღიური მუშების თვე, ტაბელის თვე, გადახდა, აქტი, შემოსული თანხა და ავანსი ანგარიშვალდებულ პირზე იღებს მომდევნო ნომერს (seq) კომპანიის ცვლილებების ნაკადში. თქვენ ინახავთ თქვენთან არსებულ ბოლო ნომერს და ითხოვთ იმას, რაც მის შემდეგ მოხდა.
- თითოეულ ცვლილებას მოჰყვება ჩანაწერი როგორც ის ახლაა (
data) და არა როგორც ადრე იყო. ხუთჯერ შეცვლილი ჩანაწერი ჩნდება ხუთჯერ, ყოველ ჯერზე თავისი უახლესი მდგომარეობით - დაამუშავეთ თითოეული მისიid-ით, რათა მის ხელახლა ნახვისას მხოლოდ განახლდეს ის, რაც მანამდე შექმენით. opარისupsert(დამატებული ან შეცვლილი) ანdelete. წაშლილი ჩანაწერისdataარისnull; ასეთივეა იმ ჩანაწერისაც, რომელიც წაიშალა ცვლილების განხორციელების შემდეგ.- ცვლილება გაიცემა მას შემდეგ, რაც მას ერთი წუთი შეუსრულდება, რათა შენახვის პროცესი, რომელიც ჯერ კიდევ სრულდება, ვერასდროს მოხვდეს იმ ნომრის უკან, რომელიც უკვე გაიარეთ. გაითვალისწინეთ, რომ ჩაწერილი მონაცემი თქვენამდე დაახლოებით ერთი წუთის შემდეგ მოვა.
- ჩანაწერი ასევე ხელახლა მოდის, როდესაც მასში ნაჩვენები რამ სხვაგან იცვლება: ავანსი ანგარიშვალდებულ პირზე - როდესაც მასზე რაიმე იყიდება, მოთხოვნა - როდესაც მისი საქონელი ჩამოდის, დღეებით დათვლილი იჯარა ყოველ ღამე (მისი ღირებულება ყოველდღიურად იზრდება), დღიური მუშების თვე - როდესაც იცვლება ჟურნალი, ტაბელის დღე ან მისი გადახდა.
- ჩანაწერები თქვენს ჩანაწერებთან შეუსაბამეთ
id-ით (ხოლო ქვეკონტრაქტორი, მომწოდებელი ან პროექტი - მისიid-ით, სადაც ის არსებობს) და არასდროს სახელით: სახელები კოპირდება ისე, როგორც იყო ცვლილების შეტანის მომენტში. - მოითხოვეთ თავიდან, სანამ
moreარ იქნებაfalse, შემდეგ კი გამოკითხეთ ყოველ რამდენიმე წუთში.
Endpoint-ები
/v1/meგასაღების კომპანია, გასაღების სახელი და მისი scopes. გასაღების მუშაობის სწრაფი შემოწმება.
/v1/projectsკომპანიის პროექტები - თითოეულის თქვენს პროექტთან შესაბამისობისთვის (მაგალითად ORIS-ის დანახარჯების ცენტრი).
{ "projects": [ { "id": "bb2e…", "name": "Vake Residence", "name_ka": "ვაკე რეზიდენსი", "name_ru": null,
"currency": "GEL", "start_date": "2026-03-01", "end_date": null, "closed_on": null } ] }
/v1/changes?after=0&limit=100after: ბოლო seq, რომელიც გაქვთ (0 დასაწყისისთვის). limit: 1-დან 500-მდე, 100 თუ მითითებული არ არის.
{
"changes": [
{ "seq": 19, "entity": "purchase", "id": "3d04…", "op": "upsert", "at": "2026-10-24T12:39:15Z",
"project_id": "bb2e…",
"data": { "entity": "purchase", "id": "3d04…", "date": "2026-10-24", "item": "Cement M400",
"quantity": 12, "unit": "bag", "unit_price": 16.5, "amount": 198, "currency": "GEL",
"supplier": { "name": "Beton Service LLC", "name_ka": "შპს ბეტონ სერვისი", "code": "205123456" },
"vat": "included", "vat_rate": 18, "net": 167.8, "vat_amount": 30.2,
"waybill_no": "0712345678", "paid_on": "2026-10-24", "due_on": null,
"project": { "id": "bb2e…", "name": "Vake Residence", "currency": "GEL" }, … } }
],
"next": 19,
"more": false
}
/v1/records/{entity}/{id}ერთი ჩანაწერი მიმდინარე მდგომარეობით - იგივე სტრუქტურა, რაც ცვლილების data-ს აქვს. 404 თუ ის აღარ არსებობს ან კომპანიას არ ეკუთვნის.
/v1/syncრა გააკეთა თქვენმა პროგრამამ ჩანაწერებთან დაკავშირებით - იხილეთ გაგზავნილად მონიშვნა. საჭიროებს accounting:write-ს.
/v1/paidრა გადაიხადეს თქვენს პროგრამაში, Unicraft-ში გადახდილად მონიშნული - იხილეთ გადახდილია თქვენს პროგრამაში. საჭიროებს accounting:write-ს.
ჩანაწერები
თითოეულ ჩანაწერს აქვს entity, id, project (id, name, name_ka, name_ru, currency) და currency. თარიღები არის YYYY-MM-DD; თანხები არის რიცხვები პროექტის ვალუტაში. სახელები მოცემულია ინგლისურ, ქართულ და რუსულ ენებზე, სადაც ისინი ასე იყო შეყვანილი.
| ობიექტი | რა არის ეს | საკუთარი ველები |
|---|---|---|
project | პროექტი შეიქმნა, გადაერქვა სახელი ან წაიშალა. წაშლისას მასში არსებული ყველაფერი მასთან ერთად იშლება - მისი საკუთარი ჩანაწერები ცალ-ცალკე წაშლის სახით არ მოდის. | name, name_ka, name_ru, currency, start_date, end_date, closed_on |
purchase | პროექტისთვის შეძენილი პოზიცია: მასალები, ხელსაწყოები, მომსახურება. ანაზღაურებული ერთიანად, კრედიტით (due_on) ან ავანსი ანგარიშვალდებულ პირზე გადახდით. | purchase_id (ერთად შეძენილი პოზიციები), date, kind, item, quantity, unit, unit_price, amount, supplier (name, code: მისი საიდენტიფიკაციო კოდი), vat, vat_rate, net, vat_amount (იხ. დღგ), waybill_no, due_on, paid_on (null: ჯერ კიდევ დასაფარია), paid_from (cash_advance ან null), cash_advance_id, request_id, note |
request | დამტკიცებული მოთხოვნა მასალებზე, გადახდილი შერჩეული შეთავაზების მომწოდებლისთვის (მისი საქონელი მიღებისთანავე ხდება შესყიდვა). | number, status, date, supplier (name, code), paid_on, amount, vat, vat_rate, net, vat_amount, invoice_no, waybill_nos |
site_payment | დღიური მუშების ან დაცვის ერთი თვის ანაზღაურება, ან ტექნიკის იჯარა. | kind, month (YYYY-MM), paid_on, amount, rental (equipment, supplier), note |
subcontractor_payment | ქვეკონტრაქტორისთვის გადახდა მისი გრაფიკის ერთ-ერთ პუნქტზე, დაკავებული თანხის გამოკლებით - ან დაბრუნებული დაკავებული თანხა. | kind (interim ან retention_release), paid_on, amount (ნაღდი ანგარიშსწორებით გადახდილი), retention (დაკავებული), gross, subcontractor, item, act_id (აქტი (ფორმა 2), რომელსაც ის ფარავს, ასეთის არსებობისას), note |
act | აქტი (ფორმა 2): დამკვეთის (მისაღები თანხა) ან ქვეკონტრაქტორის (გადასახდელი თანხა). | party (client ან subcontractor), number, period_from, period_to, date, total, retention, retention_pct, is_final, signed_on, paid_on (გადახდილი ან მიღებული), money_in_id, subcontractor |
money_in | პროექტისთვის მიღებული თანხა: დამკვეთისგან, ბინის მყიდველისგან, სესხი. | kind, date, amount, from, certificate_no, retention (true: დაკავებული თანხა ბრუნდება), note |
rental | ტექნიკის იჯარა: რა თანხა ერიცხება მომწოდებელს დღეების გასვლასთან ერთად (გადახდის შემდეგ ეს არის site_payment). | equipment, supplier, date (დაწყება), daily_rate, counted (days: დღეების ფიქსირებული რაოდენობა დაწყებიდან; timesheet: დღეები, როდესაც მანქანა ტაბელშია, ნახევარი დღე ნახევრად), days, months ([{ month, days, amount }] დღევანდელ დღემდე), cost_to_date, note |
labour_month | პროექტის დღიური მუშების (kind: labour) ან დაცვის (guard) თვე: რა თანხა ერიცხება მასზე, დათვლილი ისე, როგორც ბუღალტერიის გვერდი ითვლის - ყოველდღიური ჟურნალების მუშახელის რაოდენობა გამრავლებული მათ დღიურ განაკვეთზე, ან ტაბელით, სადაც ობიექტზე ის იწარმოება. გადახდის შემდეგ ეს არის იმავე ტიპისა და თვის site_payment. ეს არის გასატარებელი ხელფასი. | kind, month (YYYY-MM), days (კაც-დღეები), amount (დარიცხული დღევანდელ დღემდე), paid |
timesheet_month | ერთი მუშის თვე ტაბელში: ვინ რა გამოიმუშავა, სახელფასო განაცემებისა და მისი საშემოსავლო გადასახადისთვის. ეს არის labour_month-ის გაშიფვრა - ნუ გაატარებთ ხარჯად მეორედ. მისი id უცვლელი რჩება ამ მუშისთვის და თვისთვის; ის თავიდან მოდის ყოველ ჯერზე, როდესაც დღე იცვლება. | month (YYYY-MM), worker (name, personal_no, trade, day_rate), days (ნახევარი დღე ითვლება 0.5-ად), amount |
cash_advance | ავანსი ანგარიშვალდებულ პირზე (საქვეანგარიშო). ამ თანხით შეძენილი ნივთები წარმოადგენს შესყიდვებს paid_from: "cash_advance"-ით. | date, amount, purpose, report_by, holder (name), spent, settled_on, settled_amount (+ დაბრუნდა, − გადაუხადეს უკან ანგარიშვალდებულ პირს), note |
დღგ. vat არის included (თანხა მოიცავს 18%-იან დღგ-ს: net არის დღგ-მდე, vat_amount არის ჩასათვლელი დღგ), none (გამყიდველი დღგ-ს არ ადგენს) ან null (არავის მიუთითებია - net და vat_amount ასევე null-ია). თანხა ყოველთვის არის ის, რაც გადაიხადეს.
შესყიდვას, რომელსაც აქვს amount 0, ჯერ არ აქვს ფასი - ოფისი მას მოგვიანებით აფასებს და ამის შემდეგ ის კვლავ შემოდის ცვლილებების ნაკადში. საბუღალტრო კონექტორმა მანამდე ის უნდა გამოტოვოს.
გაგზავნილად მონიშვნა
მას შემდეგ, რაც თქვენი პროგრამა ჩანაწერებს დაამუშავებს, აცნობეთ Unicraft-ს. კომპანიის ბუღალტერი ხედავს ამას ბუღალტერიის გვერდზე თითოეული სტრიქონის გვერდით: გაგზავნილია ORIS-ში, ან შეცდომას სრულად, რათა არაფერი დაიკარგოს უჩუმრად.
curl -X POST https://unicraft.ge/api/v1/sync \
-H "Authorization: Bearer uck_your_key" -H "Content-Type: application/json" \
-d '{ "system": "oris",
"items": [
{ "entity": "purchase", "id": "3d04…", "status": "sent", "external_id": "31" },
{ "entity": "act", "id": "9a1c…", "status": "error", "message": "Account [3110 7] is closed" }
] }'
{ "marked": 2, "of": 2 }
system მიუთითებს თქვენი პროგრამის სახელს (oris, fina, balance ან საკუთარი). status არის sent, error ან skipped (შეგნებულად გამოტოვებული - მაგალითად, შესყიდვა, რომელსაც ჯერ არ აქვს ფასი, ან სახეობა, რომელსაც თქვენი პროგრამა არ აღრიცხავს; ბუღალტერი მას ხედავს როგორც გამოტოვებულს და არა როგორც გაგზავნილს). შეინახეთ თქვენი საკუთარი id external_id-ში - მაგალითად, ORIS-ის ტრანზაქცია - რათა განაახლოთ ან წაშალოთ ის ჩანაწერის შეცვლისას. ჩანაწერის ხელახლა მონიშვნა ცვლის მის წინა ნიშნულს. 500 ერთეულამდე თითო გამოძახებაზე; ჩანაწერები, რომლებიც კომპანიას არ ეკუთვნის, marked-დან გამოტოვებულია.
გადახდილია თქვენს პროგრამაში
როდესაც გადახდა შესრულდება საბუღალტრო პროგრამაში, აცნობეთ Unicraft-ს და ის იქაც მოინიშნება გადახდილად - ბუღალტერიის გვერდზე მას ხელახლა აღარავინ მონიშნავს.
curl -X POST https://unicraft.ge/api/v1/paid \
-H "Authorization: Bearer uck_your_key" -H "Content-Type: application/json" \
-d '{ "system": "oris",
"items": [
{ "entity": "purchase", "id": "3d04…", "paid_on": "2026-10-25", "external_id": "PAY-118" },
{ "entity": "labour_month", "id": "71be…", "paid_on": "2026-10-25", "amount": 2400, "external_id": "PAY-119" }
] }'
{ "results": [ { "entity": "purchase", "id": "3d04…", "result": "paid" },
{ "entity": "labour_month", "id": "71be…", "result": "paid" } ] }
| ობიექტი | რა ხდება |
|---|---|
purchase | მთელი შესყიდვა (თითოეული სტრიქონი იგივე purchase_id-ით) აღინიშნება გადახდილად paid_on-ზე, თუ თანხა ჯერ კიდევ გადასახდელი იყო. |
request | აღინიშნება გადახდილად ისე, როგორც ბუღალტერი მონიშნავდა: amount-ზე, ან არჩეული შეთავაზების ჯამით. უკვე მიღებული საქონელი მასთან ერთად აღინიშნება გადახდილად; შესყიდვების განყოფილებას ეცნობება. |
labour_month, rental | რეგისტრირდება amount გადახდა (ან დარჩენილი დავალიანების სრული ოდენობა). მიუთითეთ external_id (თქვენი გადახდის ნომერი): ერთი და იგივე ნომრით ხელმეორედ გაგზავნილი გადახდა ორჯერ არ განხორციელდება. |
თუ paid_on მითითებული არ არის, იგულისხმება დღევანდელი დღე; amount არასავალდებულოა. თითოეულ ელემენტზე პასუხად ბრუნდება result: paid, already_paid, not_approved (მოთხოვნა ჯერ დამტკიცებული არ არის), not_found (კომპანიას არ ეკუთვნის), future_date ან bad_amount. გადახდა გიბრუნდებათ ცვლილებების ნაკადში (ჩანაწერი შეიცვალა, ან ახალი site_payment) - რადგან გადახდა თქვენმა პროგრამამ განახორციელა, მონიშნეთ იგი როგორც skipped.
შეცდომები
შეცდომა ბრუნდება JSON ფორმატში: { "error": { "code": "bad_key", "message": "…" } }.
| სტატუსი | კოდი | მნიშვნელობა |
|---|---|---|
| 400 | bad_after, bad_id, bad_json, bad_body, bad_item, too_long, refused | მოთხოვნა არასწორია - შეტყობინებაში მითითებულია, რა უნდა შეიცვალოს. |
| 401 | no_key, bad_key | გასაღები არ არის მითითებული, არავალიდურია ან გაუქმებულია. |
| 403 | scope | გასაღებს არ აქვს ამ მოქმედების შესრულების უფლება. |
| 404 | no_route, no_entity, not_found | ასეთი მისამართი, ჩანაწერის ტიპი ან ჩანაწერი არ არსებობს. |
| 429 | too_many | წუთში 600-ზე მეტი მოთხოვნა - დაელოდეთ და სცადეთ ხელახლა. |
| 500 | server | ჩვენს მხარეს რაღაც შეფერხდა - სცადეთ ხელახლა. |
კონექტორი მოკლედ
რას აკეთებს საბუღალტრო პროგრამის კონექტორი ყოველ რამდენიმე წუთში:
let after = loadLastSeq(); // 0 the first time
for (;;) {
const r = await get(`/v1/changes?after=${after}&limit=200`);
const marks = [];
for (const c of r.changes) {
try {
if (!c.data) removeEntry(c.entity, c.id); // deleted in Unicraft
else if (c.data.amount === 0) { marks.push({ entity: c.entity, id: c.id, status: 'skipped' }); continue; }
else {
const own = upsertEntry(c.data); // e.g. an ORIS transaction, by c.id
marks.push({ entity: c.entity, id: c.id, status: 'sent', external_id: String(own) });
}
} catch (e) {
marks.push({ entity: c.entity, id: c.id, status: 'error', message: e.message });
}
}
if (marks.length) await post('/v1/sync', { system: 'oris', items: marks });
saveLastSeq(after = r.next);
if (!r.more) break;
}
რომელ ანგარიშებზე აისახება ჩანაწერი - მომწოდებლები, ბანკი, სალარო, მასალები - თავად კომპანიის არჩევანია, რომელიც კონექტორში ერთხელ განისაზღვრება. rs.ge-ის ზედნადებით თქვენს პროგრამაში უკვე არსებული შესყიდვა იგივე შესყიდვაა: ხელახლა გატარების ნაცვლად შეადარეთ ის waybill_no-ით და მომწოდებლის code-ით. კითხვების შემთხვევაში ან თქვენი პროგრამისთვის კონექტორის შესაქმნელად: [email protected].