IVO
Înapoi la centrul de ajutor
Integrare Merchant

Referință API Merchant

Referință completă pentru API-ul de comerciant: autentificare, toate endpoint-urile și semnificația fiecărui câmp de intrare și de ieșire.

Ultima actualizare: 26 august 2026

Obține o cheie API

Autentifică-te cu un cont de comerciant, deschide Setări → Integrări, selectează fila Chei API și creează o cheie. Copiaz-o imediat: cheia completă este afișată o singură dată. Poți revoca cheile din aceeași pagină.

URL de bază și autentificare

https://a.ivo.md/v1/merchant-api

Trimite cheia la fiecare cerere folosind unul dintre headere:

X-API-Key: <CHEIA_API>
Authorization: Bearer <CHEIA_API>

Trimite întotdeauna Accept: application/json și Content-Type: application/json, cu excepția încărcării fișierelor. Fără headerul Accept, erorile de autentificare sunt returnate ca pagină HTML, nu ca JSON.

Structura răspunsului

SituațieHTTPCorp
Succes200Câmpurile endpoint-ului plus "status": "success".
Eroare tratată202, 403, 404, 409, 422, 500"status": "error", un message care poate fi procesat automat (codul erorii) și eventuale câmpuri suplimentare de context.
Eroare de autentificare403Apare înainte de rularea controllerului, deci nu are câmp status — doar {"message": "api_key_invalid"}. Coduri: api_key_missing, api_key_invalid, merchant_not_found, integration_disabled.
Limită de cereri429120 de cereri pe minut per adresă IP. Fiecare răspuns conține X-RateLimit-Limit și X-RateLimit-Remaining.

Important: într-un răspuns 200, câmpul status de nivel superior este întotdeauna șirul success — arată doar că cererea a fost acceptată, nimic mai mult. Endpoint-urile care au și procesare în curs o raportează într-un câmp propriu: sync_status la endpoint-urile de sincronizare și import_status la cele de import.

Un răspuns 202 este o structură de eroare al cărei message explică de ce răspunsul nu este încă gata: queued, processing sau pending_approval.

Verificarea conexiunii

GET /check

Validează cheia API și returnează identitatea comerciantului. Acesta este primul endpoint pe care îl apelezi când configurezi o integrare.

Intrare: nimic în afară de headerul cu cheia API.

{
  "merchant_id": "<ID_COMERCIANT>",
  "merchant_name": "Magazinul meu",
  "status": "success"
}
Câmp returnatTipSemnificație
merchant_idstringIdentificatorul IVO al comerciantului căruia îi aparține cheia. Salvează-l: nu se schimbă niciodată și identifică contul în solicitările de suport.
merchant_namestringDenumirea comerciantului afișată în IVO.
statusstringÎntotdeauna success. Confirmă că cheia este validă și nerevocată; nu este starea contului de comerciant.

Puncte comerciale

Fiecare ofertă aparține unui punct comercial (magazin, depozit sau loc de ridicare). Folosește ID-ul returnat de aceste endpoint-uri drept merchant_point_id. Dacă există un singur punct în cont, sincronizarea îl selectează automat și poți omite câmpul.

GET /merchant-points

Returnează toate punctele comerciantului autentificat.

{
  "points": [
    {
      "_id": "<ID_PUNCT>",
      "name": "Magazin central",
      "contact_person": "Ion Popescu",
      "email": "[email protected]",
      "phone": "+37360000000",
      "street_id": "<ID_STRADA>",
      "number": "12",
      "city_id": "<ID_ORAS>",
      "state_id": "<ID_RAION>",
      "country": "MD",
      "zip_code": "MD-2001",
      "status": "approved",
      "is_active": true
    }
  ],
  "status": "success"
}
Câmp returnatTipSemnificație
points[]._idstringID-ul punctului. Aceasta este valoarea pe care o trimiți ca merchant_point_id.
points[].namestringDenumirea punctului. Poate fi trimisă și ca merchant_point în locul ID-ului; potrivirea este exactă, fără diferență între majuscule și minuscule.
points[].contact_person, email, phonestringPersoana de contact pentru curier și pentru suportul IVO la această locație.
points[].street_id, number, block, entrance, floor, apartment, intercom, zip_code, city_id, state_id, countrystringAdresa de ridicare. ID-urile de localizare sunt identificatorii IVO pentru stradă, oraș și raion.
points[].statusstringpending (așteaptă aprobarea IVO), approved sau rejected. Ofertele dintr-un punct care nu este approved rămân invizibile pe site.
points[].is_activebooleanComutatorul comerciantului. Ofertele dintr-un punct inactiv rămân invizibile.
points[].rejection_reasonstring, nullMotivul respingerii punctului de către IVO, atunci când status este rejected.

POST /merchant-points/store

Creează un punct. Este creat întotdeauna cu status: pending și is_active: true și rămâne invizibil pentru cumpărători până când IVO îl aprobă.

Câmp de intrareTipSemnificație
namestringDenumirea locației în sistemul tău și în panoul de comerciant.
contact_personstringPersoana pe care o caută curierul la ridicare.
email, phonestringDatele de contact pentru această locație.
street_id, city_id, state_idstringIdentificatorii IVO de localizare pentru adresă.
number, block, entrance, floor, apartment, intercomstringRestul adresei, ca să ajungă curierul la ușa potrivită.
zip_code, countrystringCodul poștal și codul de țară.

Orice câmp din afara acestei liste este ignorat. Răspunsul este {"point": { … }, "status": "success"}, unde point este înregistrarea creată, inclusiv noul _id.

POST /merchant-points/update/{id}

Actualizează un punct care aparține comerciantului. {id} este ID-ul punctului. Acceptă toate câmpurile de creare plus is_active (boolean — setează-l pe false ca să scoți din vânzare tot stocul locației, fără să ștergi nimic). Returnează punctul actualizat. ID necunoscut: point_not_found (404).

POST /merchant-points/delete/{id}

Șterge un punct care aparține comerciantului. Returnează {"deleted": true, "status": "success"}. Înregistrarea este ștearsă logic, deci istoricul se păstrează, dar punctul nu mai poate fi folosit pentru oferte.

Actualizarea unei oferte existente

POST /product-offer/update

Actualizează prețul sau stocul unei oferte care există deja, fără a rula importul de produse. Este cel mai rapid și mai ieftin endpoint — folosește-l pentru actualizările curente de preț și stoc.

{
  "merchant_internal_id": "PRODUS-123",
  "merchant_point_id": "<ID_PUNCT>",
  "price": 1999,
  "currency": "MDL",
  "availability": 5,
  "availability_on_order": 0
}
Câmp de intrareTipSemnificație
offer_idstringID-ul ofertei în IVO. Trimite acest câmp sau merchant_internal_id. Oferta trebuie să aparțină contului tău.
merchant_internal_idstringIdentificatorul tău de produs (SKU), așa cum a fost trimis la crearea ofertei. Căutarea se face doar în contul tău.
merchant_point_idstringFolosit doar împreună cu merchant_internal_id: restrânge căutarea la un singur punct. Obligatoriu când același SKU există în mai multe puncte, altfel cererea eșuează cu merchant_internal_id_not_unique.
pricenumberNoul preț de vânzare, în moneda currency. O ofertă cu prețul 0 sau gol nu este niciodată afișată pe site.
currencystringCod ISO 4217. Acceptate: MDL (implicit), EUR, USD, RON, UAH, RUB, GBP. Prețurile în altă monedă sunt convertite pentru afișare la cursul stocat de IVO.
availabilityintegerUnități aflate fizic în stoc la acest punct, care pot fi livrate imediat.
availability_on_orderintegerUnități pe care le poți aduce la comandă (stoc de la furnizor). Menține produsul disponibil când availability este 0, cu un termen de livrare mai lung.

Este obligatoriu cel puțin unul dintre câmpurile availability, availability_on_order, price sau currency; trimiterea doar a unui identificator eșuează cu no_fields_to_update. Câmpurile omise își păstrează valoarea curentă. Fiecare modificare este scrisă în istoricul de preț și stoc al ofertei.

{
  "offer": {
    "id": "<ID_OFERTĂ>",
    "merchant_internal_id": "PRODUS-123",
    "product_id": "<ID_PRODUS>",
    "merchant_point_id": "<ID_PUNCT>",
    "condition": "new",
    "quality": null,
    "price": 1999,
    "currency": "MDL",
    "availability": 5,
    "availability_on_order": 0
  },
  "status": "success"
}
Câmp returnatTipSemnificație
offer.idstringID-ul ofertei. Refolosește-l ca offer_id pentru a evita căutarea după SKU la apelurile următoare.
offer.merchant_internal_idstring, nullSKU-ul tău, așa cum este stocat pe ofertă.
offer.product_idstringProdusul IVO (varianta) de care este atașată oferta.
offer.merchant_point_idstringPunctul în care este ținut stocul ofertei.
offer.conditionstringnew, used sau refurbished.
offer.qualitystring, nullText liber care diferențiază mai multe oferte care nu sunt noi pentru același produs.
offer.price, offer.currency, offer.availability, offer.availability_on_ordernumber / string / integerValorile stocate după actualizare.

Erori: missing_identifier (422) — nu a fost trimis nici offer_id, nici merchant_internal_id; no_fields_to_update (422); offer_not_found (404) — oferta nu există sau aparține altui comerciant; merchant_internal_id_not_unique (409) — SKU-ul corespunde mai multor oferte, iar corpul conține count. Trimite merchant_point_id pentru a dezambiguiza.

Informații despre produs și ofertă

GET /product/{id}/info

Folosește ID-ul ofertei drept {id}, nu ID-ul produsului. Oferta trebuie să aparțină comerciantului autentificat.

{
  "product": {
    "id": "<ID_PRODUS_OFERTĂ>",
    "root_product_id": "<ID_PRODUS_PRINCIPAL>",
    "type": "variant",
    "status": "active",
    "name": {"ro": "Nume", "en": "Name", "ru": "Название"},
    "slug": {"ro": "nume", "en": "name", "ru": "nazvanie"},
    "url": "https://ivo.md/nume/p",
    "urls": {"ro": "https://ivo.md/nume/p", "en": "https://ivo.md/en/name/p", "ru": "https://ivo.md/ru/nazvanie/p"}
  },
  "offer": {
    "id": "<ID_OFERTĂ>",
    "price": 1999,
    "currency": "MDL",
    "availability": 5,
    "availability_on_order": 0
  },
  "history": [
    {
      "price": 2099,
      "currency": "MDL",
      "availability": 3,
      "availability_on_order": 0,
      "changed_at": "2026-08-20T11:04:35+03:00",
      "source": "merchant_api"
    }
  ],
  "status": "success"
}
Câmp returnatTipSemnificație
product.idstringProdusul de care este atașată oferta. Pentru un produs cu variante, aceasta este varianta, nu produsul-părinte.
product.root_product_idstringProdusul principal (părinte). Mai multe variante îl împart, iar pagina publică îi aparține.
product.typestringmain sau variant.
product.statusstringStarea în catalog a produsului ofertei, de exemplu active sau draft.
product.nameobjectDenumirea din catalog pe limbi (ro, en, ru). Este scrisă de IVO, deci poate diferi de denumirea trimisă de tine.
product.slugobjectSegmentul de URL pe fiecare limbă.
product.urlstringURL-ul public în română — cel mai scurt link pe care îl poți da unui cumpărător.
product.urlsobjectURL-ul public pe fiecare limbă.
offer.id, offer.price, offer.currency, offer.availability, offer.availability_on_orderValorile curente ale ofertei, așa cum le stochează IVO în acest moment.
history[]arrayCel mult 100 de modificări de preț și stoc, cele mai recente primele. Fiecare intrare conține price, currency, availability, availability_on_order, changed_at (ISO 8601) și source — sistemul care a făcut modificarea (merchant_api, api_sync și așa mai departe).

Erori: offer_not_found (404); product_not_accessible (403) — oferta aparține altui comerciant; product_not_found (404); pending_approval (202) — produsul principal nu este încă publicat, iar corpul conține product_id și product_status; product_slug_missing (422).

POST /product/info-by-sku

Același răspuns detaliat, găsit după SKU-ul tău în loc de un ID IVO. Folosește-l dacă nu stochezi identificatori IVO în sistemul tău.

{
  "import_name": "sincronizare-zilnica",
  "merchant_internal_id": "PRODUS-123"
}
Câmp de intrareTipSemnificație
merchant_internal_idstring, obligatoriuSKU-ul tău. Căutarea se face în rândurile importate ale contului tău.
import_namestring, obligatoriuEste validat ca obligatoriu, dar căutarea nu filtrează după el: un SKU este căutat în toate importurile tale. Trimite același nume folosit la /product/sync.

În caz de succes, corpul este identic cu cel de la GET /product/{id}/info. Cât timp produsul încă parcurge fluxul de procesare, răspunsul este o structură de eroare:

messageHTTPSemnificație
not_imported404Niciun rând importat nu conține acest SKU. Trimite mai întâi produsul prin /product/sync.
queued202Rândul așteaptă să fie procesat. Reia interogarea.
processing202Rândul este procesat chiar acum. Reia interogarea.
pending_approval202Produsul există, dar nu este încă publicat. Nu ai nimic de făcut.
codul de eroare al rândului500Procesarea a eșuat. Corpul conține import_row_id, import_id, ai_product_id, ai_error și error.
starea ofertei din rând404Rândul s-a finalizat fără a produce o ofertă (de exemplu unauthorized_category).
offer_deleted404Rândul indică o ofertă care nu mai există.

Crearea sau sincronizarea unui produs

POST /product/sync

Creează un produs sau actualizează o ofertă existentă. Reutilizarea aceluiași import_name cu un merchant_internal_id stabil actualizează același rând în loc să creeze duplicate, deci endpoint-ul poate fi apelat repetat pentru același catalog.

{
  "mode": "async",
  "import_name": "sincronizare-zilnica",
  "merchant_internal_id": "PRODUS-123",
  "name": "Telefon Exemplu 256 GB Negru",
  "price": 1999,
  "currency": "MDL",
  "availability": 5,
  "availability_on_order": 0,
  "merchant_point_id": "<ID_PUNCT>",
  "brand": "Exemplu",
  "ean": "5940000000000",
  "description": "Descrierea produsului",
  "images": ["https://example.com/produs.jpg"]
}
Câmp de intrareTipSemnificație
pricenumber, obligatoriuPrețul de vânzare, mai mare decât 0 (minimum 0.01). Trebuie să fie un număr simplu — 1999 sau 1999.00, nu "1 999,00".
namestring, obligatoriu fără product_idDenumirea completă a produsului. IVO o compară cu catalogul și creează produsul pe baza ei, deci include marca, modelul și atributele care îl disting (capacitate, culoare). O denumire prea vagă este respinsă cu eroarea de rând too_generic.
product_idstringID-ul unui produs IVO existent. Ocolește complet identificarea în catalog și scrie doar oferta — calea cea mai rapidă atunci când știi deja produsul. Dacă acel produs are deja variante, trebuie să trimiți și offer_product_id.
offer_product_idstringVarianta produsului product_id de care se atașează oferta. Obligatorie când produsul principal are variante, pentru că IVO nu ghicește niciodată ce variantă ai pe stoc.
merchant_internal_idstringIdentificatorul tău stabil de produs (SKU). Este cheia care leagă catalogul tău de IVO la fiecare apel ulterior. Recomandat insistent: fără el, rândurile sunt potrivite după un hash al întregii cereri.
legacy_merchant_internal_id / legacy_merchant_internal_idsstring / arrayIdentificatorii sub care produsul era trimis anterior. Folosește-i când îți schimbi schema de SKU-uri, ca să fie reutilizate rândul și oferta existente în loc să se creeze un produs duplicat.
import_namestringNumele listei de import din care face parte produsul și cheia după care interoghezi starea. Este transformat în slug: spațiile și semnele de punctuație devin _ sau sunt eliminate, iar numele este tăiat la 64 de caractere ("Sincronizarea mea"sincronizarea_mea). Dacă lipsește, devine default. Folosește un singur nume stabil per sursă.
merchant_point_id / merchant_pointstringID-ul punctului sau denumirea exactă a punctului. Dacă în cont există un singur punct, este selectat automat.
availabilityinteger sau stringStocul imediat. Textul este interpretat permisiv: "10 buc" → 10, "2-3" → 3, "in stoc"/"da" → 1, "out of stock" și orice valoare nerecunoscută → 0. Dacă nu trimiți nici availability, nici availability_on_order, stocul imediat este implicit 1.
availability_on_orderinteger sau stringStocul disponibil la comandă, interpretat la fel.
currencystringCod ISO 4217, implicit MDL.
conditionstringnew (implicit), used sau refurbished. Există o singură ofertă new per produs și punct; ofertele care nu sunt noi pot fi mai multe.
qualitystringText liber care diferențiază mai multe oferte care nu sunt noi pentru același produs, în același punct.
brandstringDenumirea mărcii. Ajută la identificare și este folosită atunci când produsul trebuie creat.
ean, asin, janstringCoduri de bare și identificatori globali de produs. Cel mai puternic semnal de identificare — trimite-le când le ai.
descriptionstringDescrierea produsului, folosită la identificare și, pentru un produs nou, ca material sursă.
images (sau image)array sau stringURL-urile imaginilor, prima fiind cea principală. IVO le descarcă; trebuie să fie accesibile public.
weight, volumenumberGreutatea la expediere (grame) și volumul, folosite la calculul livrării.
item_group_id, item_group_title, variant_option, variant_optionsstring / objectIndicii de grupare a variantelor: produsele cu același item_group_id sunt tratate ca variante ale aceluiași părinte, iar valorile opțiunilor spun ce le diferențiază (culoare, mărime).
force_reprocessbooleantrue repornește rândul de la zero, renunțând la rezultatele anterioare de identificare. Folosește-l pentru a repara un rând potrivit greșit — nu la fiecare sincronizare, pentru că reia tot fluxul de identificare.
modestringasync (implicit) returnează imediat. sync ține conexiunea deschisă până se finalizează rândul, în limita stabilită pe server (implicit 300 de secunde), și returnează oricum dacă procesarea continuă.

Orice alt câmp este stocat împreună cu rândul, dar este înțeles doar dacă denumirea lui corespunde unei coloane de import.

Răspunsuri

Toate trei sunt HTTP 200 cu "status": "success". Câmpurile prezente îți spun ce s-a întâmplat.

Câmpuri returnateCe s-a întâmplat
sync_status: "completed", offer_id, offer_product_id, message: "Offer saved (AI bypassed)"Ai trimis product_id: oferta a fost scrisă direct, fără identificare și fără etapă de aprobare.
sync_status: "completed", offer_id, offer_product_id, import_id, row_id și matched_by dacă a fost folosit un identificator vechiA fost găsită și actualizată imediat o ofertă existentă cu acest merchant_internal_id. Acesta este răspunsul obișnuit pentru un produs deja aflat în catalog.
sync_status: "processing", import_id, message: "Product creation started"Un produs nou — sau redenumit semnificativ — a intrat în fluxul de import și aprobare. Interoghează /product-import/status sau /product/info-by-sku pentru rezultat.
Câmp returnatTipSemnificație
sync_statusstringcompleted — oferta există și nu a rămas nimic în așteptare. processing — produsul a fost pus la coadă și trebuie să interoghezi rezultatul. Acesta este câmpul după care ramifici logica, nu status.
offer_idstringOferta creată sau actualizată. Salveaz-o: transformă actualizările ulterioare de preț și stoc într-un singur apel rapid.
offer_product_idstringProdusul IVO (varianta) de care atârnă oferta.
import_idstringLista de import în care a fost înregistrat produsul — cea denumită de import_name.
row_idstringRândul de import al acestui produs.
matched_bystringmerchant_internal_id sau legacy_merchant_internal_id, dacă oferta a fost găsită prin unul dintre identificatorii vechi trimiși de tine.
row_statusstringDoar în mode: sync, când timpul de așteptare a expirat: starea rândului în acel moment.

Erori: invalid_product_id (422), product_not_found (404), offer_product_not_found (404), offer_product_invalid (422) — varianta nu aparține acelui produs principal, missing_offer_product_id (422), missing_merchant_point (422) — nu s-a putut determina niciun punct pe calea cu product_id, invalid_price (422), unauthorized_category (403) — contul tău nu este autorizat să vândă în acea categorie, integration_not_found / integration_disabled (403) — import_name denumește o integrare ștearsă sau dezactivată, și processing_failed (422) în mode: sync, cu error și import_id.

Sincronizarea mai multor produse

POST /product/sync-multiple

Între 1 și 100 de produse într-o cerere. Fiecare element din products acceptă exact câmpurile de la /product/sync, plus cele de mai jos. Acesta este endpoint-ul pe care construiești o sincronizare completă de catalog.

{
  "mode": "async",
  "import_name": "sincronizare-zilnica",
  "image_base_url": "https://shop.example.com/images",
  "products": [
    {
      "merchant_internal_id": "PRODUS-123",
      "name": "Telefon Exemplu 256 GB Negru",
      "price": 1999,
      "availability_by_point": {
        "<ID_PUNCT_1>": 5,
        "<ID_PUNCT_2>": 2
      }
    }
  ]
}
Câmp de lotTipSemnificație
productsarray, obligatoriuDe la 1 la 100 de obiecte produs. Împarte un catalog mai mare în cereri succesive cu același import_name.
import_namestringAceleași reguli ca la /product/sync și aceeași listă: cele două endpoint-uri folosesc același import când numele coincide.
modestringasync (implicit) sau sync.
image_base_urlstring (URL)Prefixul adăugat înaintea căilor relative de imagine, ca un feed să poată trimite /catalog/x.jpg. Este stocat pe import și reutilizat la reîncercări.
image_split_spacesbooleanTratează spațiile dintr-o valoare de imagine ca separatori între mai multe căi.
image_split_commasbooleanTratează virgulele dintr-o valoare de imagine ca separatori între mai multe căi.
integration_run_idstring, max 64Marchează toate rândurile unei rulări complete de catalog. Permite IVO să măsoare progresul față de totalul real al rulării, nu față de dimensiunea unui singur lot, și permite unei rulări noi să elimine stocul rămas de la configurația anterioară.
Câmp suplimentar per produsTipSemnificație
availability_by_pointobjectStoc pe puncte: {"<ID_PUNCT>": 5}. Trimite imaginea completă pentru acel SKU într-un singur element — ea înlocuiește instantaneul anterior. Produsul ajunge astfel pe un singur rând de import, nu pe câte unul pentru fiecare punct.
availability_onlybooleantrue transformă elementul într-o actualizare pură de stoc: sunt obligatorii doar merchant_internal_id și availability, iar name și price nu. Identificatorii necunoscuți sunt ignorați în loc să creeze produse — acesta este un flux de actualizare, nu o sursă de produse.
force_reprocessbooleanOcolește calea rapidă a ofertei existente și repornește identificarea rândului.

Răspuns: sync_status (completed dacă toate produsele erau deja actualizate, processing dacă au fost puse rânduri la coadă) și import_id, plus message atunci când a fost pusă la coadă procesare. Nu se returnează nimic pentru fiecare produs — citește rezultatele individuale din /product-import/status sau /product/info-by-sku. O cerere care nu trece validarea este respinsă în întregime cu validation_failed (422), împreună cu index-ul produsului problematic și errors; de asemenea invalid_product_payload (422) și products_required (422).

Încărcarea unui fișier de produse

POST /product-import/upload-and-import

Trimite un catalog întreg într-o singură cerere, exact ca la încărcarea din panoul de comerciant. Folosește multipart/form-data.

Câmp de intrareTipSemnificație
filefișier, obligatoriuFișierul de catalog. Extensii acceptate: XLSX, XLS, CSV, TSV, ODS, JSON și XML.
modestringasync (implicit) returnează imediat ce fișierul este pus la coadă. sync așteaptă finalizarea importului, implicit până la 300 de secunde.
import_namestringNume opțional sub care este înregistrată încărcarea, transformat în slug ca peste tot. Trimite-l dacă vrei să interoghezi importul: GET /product-import/status îl găsește apoi după acest nume. Fără el, importul păstrează numele fișierului încărcat, iar interogarea se face după import_id (sau după exact acel nume de fișier).
columnsarrayMaparea coloanelor, câte o intrare pentru fiecare coloană a fișierului, în ordine. Folosește denumirile canonice: name, description, brand, ean, asin, jan, weight, volume, image, availability, availability_on_order, price, price_and_currency, currency, merchant_internal_id și ignore pentru coloanele de sărit. Mapează mai multe coloane la image pentru a importa mai multe imagini. Dacă columns lipsește, IVO detectează maparea din rândul de antet.
Câmp returnatTipSemnificație
import_idstringImportul creat. Păstrează-l: cu el interoghezi endpoint-ul de stare.
import_namestringNumele sub care a fost înregistrat importul — import_name-ul tău după transformarea în slug sau numele fișierului încărcat. Interoghează exact cu această valoare.
import_statusstringStarea reală a importului: pending, ready_to_process, processing, completed, completed_with_errors sau error.
messagestringImport started successfully sau o notă că procesarea continuă, în mode: sync.
importobjectDoar în mode: sync, când importul a ajuns într-o stare finală: înregistrarea completă a importului.

Pentru sincronizarea recurentă folosește mai degrabă /product/sync-multiple: actualizează aceleași rânduri pe loc, raportează rezultatul pentru fiecare produs și nu necesită fișier.

Verificarea stării importului

GET /product-import/status

Raportează progresul oricărui import creat de tine — prin /product/sync, /product/sync-multiple sau /product-import/upload-and-import — și rezultatul pentru un produs din el.

GET /product-import/status?import_name=sincronizare-zilnica&merchant_internal_id=PRODUS-123
GET /product-import/status?import_id=<ID_IMPORT>
Câmp de intrareTipSemnificație
import_idstringImportul despre care se raportează, așa cum a fost returnat de orice apel de sincronizare sau de încărcare. Trimite acest câmp sau import_name; dacă lipsesc ambele, cererea eșuează cu missing_identifier (422).
import_namestringNumele listei de import. Este căutat atât transformat în slug (așa cum îl înregistrează sincronizarea), cât și exact așa cum a fost scris (așa cum îl înregistrează o încărcare), deci numele primit înapoi găsește întotdeauna importul. Trebuie să aparțină contului tău de comerciant.
merchant_internal_idstringRândul cărui produs să fie raportat. Poate lipsi doar dacă importul conține exact un rând; la un import cu mai multe rânduri, omiterea lui eșuează cu merchant_internal_id_required (422).
{
  "import_id": "<ID_IMPORT>",
  "import_name": "sincronizare_zilnica",
  "import_status": "processing",
  "error_type": null,
  "processed_rows": 87,
  "total_rows": 120,
  "row_count": 120,
  "row": {
    "id": "<ID_RÂND>",
    "row_number": 12,
    "status": "completed",
    "error": null,
    "merchant_internal_id": "PRODUS-123",
    "ai_product_id": "<ID_PRODUS_AI>",
    "offer_product_id": "<ID_VARIANTĂ>",
    "product_id": "<ID_PRODUS>",
    "offer_id": "<ID_OFERTĂ>",
    "product": {
      "id": "<ID_VARIANTĂ>",
      "root_product_id": "<ID_PRODUS_PRINCIPAL>",
      "type": "variant",
      "root_type": "main",
      "status": "active",
      "name": {"ro": "Nume", "en": "Name", "ru": "Название"},
      "slug": {"ro": "nume", "en": "name", "ru": "nazvanie"},
      "url": "https://ivo.md/nume/p",
      "urls": {"ro": "https://ivo.md/nume/p"},
      "has_public_url": true
    },
    "started_at": "2026-08-26T09:12:00+03:00",
    "ended_at": "2026-08-26T09:12:41+03:00"
  },
  "status": "success"
}
Câmp returnatTipSemnificație
import_idstringImportul la care se rezolvă cererea.
import_namestringNumele sub care este înregistrat.
import_statusstringStarea întregului import: pending, ready_to_process, processing, completed, completed_with_errors sau error. Aceasta este starea importului — câmpul status de nivel superior arată doar că cererea în sine a reușit.
processed_rows / total_rowsintegerProgresul întregului import: rândurile ajunse în starea completed sau error, din totalul așteptat. Valorile egale înseamnă că importul s-a încheiat.
row_countintegerCâte rânduri conține importul în acest moment.
error_typestring, nullEste setat când a eșuat importul în sine (de exemplu un fișier ilizibil), nu un rând individual.
row.statusstringStarea produsului selectat: ready (la coadă), processing, completed sau error. Acesta este câmpul de interogat pentru un SKU.
row.errorstring, nullMotivul eșecului rândului, sub formă de cod procesabil automat — vezi codurile de rând de mai jos.
row.merchant_internal_idstring, nullSKU-ul tău, așa cum este stocat pe rând.
row.ai_product_idstring, nullÎnregistrarea intermediară produsă în timpul construirii produsului. Utilă doar în solicitările de suport.
row.product_id / row.offer_product_idstring, nullProdusul identificat și varianta de care se atașează oferta.
row.offer_idstring, nullOferta rezultată. Odată ce apare, actualizările ulterioare pot merge prin /product-offer/update.
row.productobject, nullInformații publice despre produs: name și slug pe limbi, url și urls, starea din catalog status și has_public_urlfalse cât timp produsul nu are încă pagină publică.
row.started_at / row.ended_atdatetime, nullMomentul în care a început și s-a încheiat procesarea rândului.
statusstringÎntotdeauna success — arată că cererea în sine a reușit. Starea importului este import_status.

Erori: missing_identifier (422) — nu a fost trimis nici import_id, nici import_name, import_not_found (404), import_row_not_found (404), merchant_internal_id_required (422).

Când devine vizibilă o ofertă

Un apel reușit nu înseamnă automat un produs publicat. O ofertă apare pe ivo.md doar când toate condițiile de mai jos sunt îndeplinite:

  • contul de comerciant este activ;
  • punctul comercial este approved și is_active;
  • produsul a trecut aprobarea IVO și are pagină publică;
  • price există și este mai mare decât zero;
  • availability sau availability_on_order este mai mare decât zero.

Dacă un produs sincronizat nu apare, verifică aceste cinci condiții în ordine înainte de a deschide o solicitare de suport.

Coduri de eroare frecvente

CodHTTPSemnificație
api_key_missing403Lipsesc atât headerul X-API-Key, cât și Authorization: Bearer.
api_key_invalid403Cheie necunoscută sau revocată.
merchant_not_found403Cheia este validă, dar contul de comerciant nu mai există.
integration_disabled / integration_not_found403import_name denumește o integrare pe care comerciantul a dezactivat-o sau a șters-o.
unauthorized_category403Contul tău nu este autorizat să vândă în acea categorie.
product_not_accessible403Oferta aparține altui comerciant.
offer_not_found, product_not_found, offer_product_not_found, point_not_found, import_not_found, import_row_not_found, not_imported, offer_deleted404Înregistrarea indicată nu există sau nu aparține contului tău.
merchant_internal_id_not_unique409SKU-ul corespunde mai multor oferte. Adaugă merchant_point_id.
missing_identifier, no_fields_to_update, invalid_price, invalid_product_id, missing_merchant_point, missing_offer_product_id, offer_product_invalid, merchant_internal_id_required, products_required, invalid_product_payload, validation_failed, product_slug_missing, processing_failed422Cererea este incompletă sau inconsecventă. validation_failed conține index și errors.
queued, processing, pending_approval202Nu este o eroare: răspunsul nu este încă gata. Reia interogarea.

Erorile la nivel de rând apar în row.error, nu ca stare HTTP: too_generic (denumirea nu identifică un produs concret), missing_name_value, missing_category, unauthorized_category, variant_not_found, duplicate, no_availability și missing_merchant_point.

Ți-a fost util acest articol?

Spune-ne rapid dacă ți-a fost de ajutor.

Articole similare

Integrare Merchant

Extensii: cum funcționează

O prezentare generală despre cum extensiile IVO se instalează, se autorizează, sincronizează și raportează statusul.

Integrare Merchant

Extensie Magento 2: instalare

Instalează extensia Magento 2 pentru IVO Marketplace și conectează magazinul la IVO.

Integrare Merchant

Extensie OpenCart 4: instalare

Instalează extensia OpenCart pentru IVO Marketplace și conectează magazinul la IVO.

Integrare Merchant

Modul PrestaShop: instalare

Instalează modulul PrestaShop pentru IVO Marketplace și conectează magazinul la IVO.