Integrare Emag prin API

Salut,

Incerc sa fac o integrare cu Emag marketplace prin API-ul lor, mai exact sa updatez stocul la unele produse. Am citit documentatia lor si am reusit sa fac un call autentificat pentru a citi produsele dar cand vine vorba de update la stoc, pur si simplu nu functioneaza dar nici nu da eroare. API-ul imi raspunde iar in content are “isError:false”.

Am pus aici un exemplu cu codul pe care l-am folosit: https://github.com/Usergitbit/EmagAPITest/blob/master/EmagAPITest/Form1.cs

Practic in codul de acolo am incercat sa trimit datele ca JSON si ca form-url-encoded. Pe langa ce se vede acolo am incercat sa pun lista din JSON si intr-un alt obiect cu o propietate “data” (scria in documentatie de asta), cat si sa pun datele in query params. Cred ca am mai incercat si altele de care nu mai tin minte. Nu reusesc sa imi dau seama unde e problema deoarece nu primesc nici un fel de eroare de la API. M-am gandit ca poate problema nu e legata de call-ul in sine si poate doar id-ul e gresit dar id-ul l-am luat din datele citite.

Am dat un mesaj si la Emag unde mi-o raspuns un oarecare de la customer support, evident asa de suparat ca l-am deranjat de la sesiunea de Facebook cu programarea si integrarile mele incat nu a citit tot mesajul meu si la final mi-o zis ca sa “dau un exemplu de call unde produsul nu se actualizeaza”… in conditiile in care in mesaj am inclus link-ul catre proiectul exemplu :smiley: Le-am mai trimis un mesaj dar pana raspund ei am zis sa intreb si aici.

Mi-o mai dat de asemea un exemplu care era deja pe site la sectia de documentatie dar in php:

<?php 
 
$data =
    array (

Array(
     "id" => "6050",
     "family" => Array(
     		"id" => 111,
           	"family_type_id" => 97,
           	"name" => "test_family "
     ),
    "category_id" => "1315",
    "part_number" => "test-part-number",
    "name" => "Test name",
    "description" => "Test description",
    "brand" => "Test brand name",
    "images" => Array(
     	Array(
          "display_type" => "1",
          "url" => "http://www.image-url.test"
     	)
    ),
    "url" => "http://www.product-url.test",
    "status" => "1",
    "sale_price" => "406.4515",
    "recommended_price" => "506.4515",
    "min_sale_price" => "200.0000",
    "max_sale_price" => "700.0000",
    "availability" => Array(
      Array(
          "warehouse_id" => "1",
          "id" => "3"
      )
    ),
    "handling_time" => Array(
      Array(
          "warehouse_id" => "1",
          "value" => "2"
      )
    ),
    "stock" => Array(
      Array(
          "warehouse_id" => "1",
          "value" => "2"
      )
    ),
    "commission" => Array(
      "type" => "percentage",
      "value" => "8"
    ),
    "vat_id" => "1",
    "characteristics" => Array(
      Array(
        "id" => "5213",
        "value" => "Characteristic 5213 value"
      ),
     Array(
        "id" => "1339",
        "value" => "Characteristic 1339 1st value"
      ),
     Array(
        "id" => "1339",
        "value" => " Characteristic 1339 2nd value"
      )
    )
  )


    );

$username = 'user';
$password = 'pass';
$hash = base64_encode($username . ':' . $password);
$headers = array(
    'Authorization: Basic ' . $hash
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://marketplace.emag.ro/api-3/product_offer/save');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array('data' => $data)));
$result = curl_exec($ch);
echo $result . "\n";


?>

Desi nu stiu php m-am uitat peste el si am folosit ceva de php online sa incerc sa vad daca formatul la datele trimise e diferit dar nu am vazut sa fie vreo diferenta fata de cele ce le incercasem pana acum. De asemenea linia asta mi se pare suspecta deoarece callurile ar trebui sa fie POST si sa aibe content:

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

A mai facut cineva o integrare cu Emag marketplace in .Net si s-a lovit de problema asta sau poate vede unde gresesc?

In. Net nu însă am făcut câteva în php. Din ce am obersvat, tu faci request ul ca PUT, nu POST. Schimba asta și setează content type ca multipart/form-data

Da, ramasese pe PUT de la ce incercari am facut inainte sa copii codu intr-un proiect separat. L-am modificat inapoi pe POST si am incercat sa ii setez content-ul la multipart/form-data dar e la fel, stocul nu se modifica iar API-ul nu da nici o eroare :thinking:

Primul pas este sa gasesti care e forma corecta de payload. Recomand sa folosesti Postman pentru treaba asta.
Al doilea pas este sa iti organizezi datele in .net in structuri care se serializeaza JSON intr-o structura asemanatoare cu cea a payload-ului. Recomand libraria asta https://www.newtonsoft.com/json

3 Likes

presupun ca in testele tale nu trimiti ce e pe github, ci niste parametri care includ si stoc-ul, right?

Vezi să nu fi întâmpinat problema pe care am avut-o eu.

Mai exact: stăteam cu fereastra de editare a produsului din emag deschisă în browser. Actualizam datele produsului prin API și apoi reîncărcam pagina. Nu se întâmpla nimic. Datele erau aceleași. Părea că actualizarea prin API nu s-a făcut.

De fapt, se actualizau, dar pagina de editare a produsului are (nu știu dacă acum e la fel) un sistem … nu mai zic, care actualiza datele fără să folosești butonul “salvează”. Greu mi-am dat seama care e problema pentru că nici eu nu primeam vreun mesaj de eroare.

Le-am raportat problema atunci și mi-au zis că o să verifice. Și așa s-a încheiat discuția. Cu verificarea.

Nu știu dacă întâmpini aceeași problemă. Eu zic ce am pățit eu.

1 Like

Nu cred că apiul celor de la eMag este perfect nici nu mă aștept să fie o prioritate a lor, deci și eu merg pe varianta unui bug. Din capul locului răspunsul la request trebuia să fie mai mult decât “isError:false”.

2 Likes

:thinking: si eu am facut ceva asemanator, actualizam prin API dar avea pagina cu lista de oferte deschisa si ii dadeam refresh (deci nu cea de editare). Voi relua testele fara sa am marketplace-ul deschis in browser sa vad daca se schimba ceva.

Am incercat sa fac update-ul fara sa am browser-ul deschis, din pacate situatia este aceeasi: indiferent de formatul trimis API-ul raspunde cu {“isError”:false,“messages”:[],“results”:[]}.

Intre timp am primit si un raspuns de la customer support care imi zic ca “Nu am reusit sa identific in loguri nicio eroare, tot ce am gasit este ca face read pe produse” :roll_eyes: ceea ce nu e chiar de mirare pentru ca le-am precizat deja ca API-ul imi raspunde dar nu indica eroare. Si mi-au zis ca “Avand in vedere ca produsele au fost listate de la inceput din interfata sellerul ar trebui sa faca read, dupa sa le salveze la el in baza si dupa sa trimita update-urile”. Lucru pe care l-am facut deja: am facut read sa iau id-ul ca sa il pot folosi in call-ul de update.

Practic din ce imi zic ei inteleg ca au vazut ca am facut read-uri dar nu si update-uri ca si cum call-ul meu nu ar fi ajuns de loc pe server. Dar din moment ce am primit raspunsul in formatul lor e clar ca a ajuns dar ca nu a facut nimic. E posibil si ca in log-urile lor sa nu se scrie nimic decat in cazul in care call-ul rezulta intr-o anumita operatie sau o eroare.

Le-am mai trimis un alt mesaj si astept din nou raspuns.

P.S.: le-am trimis si cum arata call-urile in sine in 3 formate pe care le-am folosit, pentru ca au insistat foarte tare ca tebuie sa le trimit dar ce sa vezi in raspunsul lor nu au precizat nimic de ele: care din alea e 3 corect? unu singur? toate? nici unu? De exemplu ce l-am dat nici nu mai zic pentru ca sunt destul de sigur ca nu s-au obosit sa se uite la el.

1 Like

Pai nu emag-ul zicea ca se astepta sa fie dezastru acuma ca angajatii lor lucreaza de acasa, dar treaba merge de fapt bine.

Din firul asta de discutii ma intreb ce inseamna “bine” pentru Emag.

Support-ul pe care îl primești în marketplace se rezumă la “descurcă-te singur”. Prin mesajele pe care ți le dau, ca și răspuns la tickete, doar te susțin în a te descurca singur. O știu din proprie experiență.

În fine. Câteva idei:

  1. Ai zis că ai încercat cu 3 modele de call-uri. Din astea 3, la câte primești eroare ? La niciunul ? Datele trimise ar trebui să arate ca aici (chiar dacă trimiți datele unui singur produs): Problema implementare api emag

  2. Ești 100% sigur că datele se trimit prin POST la https://marketplace.emag.ro/api-3/product_offer/product_offer/save ?

  3. Încearcă să pornești un produs din platforma marketplace, asigură-te că e pornit și apoi oprește-l prin API folosind doar parametrii “id” și “status” (fără alți parametrii). Funcționează sau nu ?

  4. Încearcă să pui preț 0 pentru un produs și vezi dacă primești eroare. Dacă din greșeală funcționează, dă-mi link-ul produsului să cumpăr și eu.

  5. Încearcă să actualizezi datele unui produs folosind un ID pe care știi sigur că nu-l deții. Primești eroare sau nu ?

  6. Nu cunosc limbaul pe care îl folosești, dar, încearcă ca dintr-un foc să extragi datele unui produs și să afișezi rezultatul, să actualizezi datele produsului (un singur detaliu - cum ar fi sale_price) și să afișezi rezultatul, și apoi să extragi din nou datele produsului și să afișezi. Deci, dintr-un foc 3 lucruri (3 call-uri). Ceva, ceva ?

  7. Actualizează statusul unei comenzi prin API. Funcționează sau nu ?

1 Like

Salut,
daca vrei te pot ajuta cu un script php functional. apoi sa-ti dai seama cum sa adaptezi la nevoile tale.

@anon80386878 multumesc pentru sugestii. Weekend-ul asta o sa mai fac o runda de incercari sa vad care sunt rezultate. Customer support-ul inca nu au raspuns la ultimul ticket pe care l-am trimis.

@cotzo Daca ai un exemplu care stii ca este functional de update la stoc, as fi recunoscator. Planuiam sa incerc sa fac call-urile si din php cu exemplele lor si apoi sa compar cu ce imi rezulta din .net. Sunt de asemenea curios cum se compara ce ai facut tu cu exemplele lor.

@TGeorge uite aici un exemplu, este testat, functioneaza.
probabil nu o sa-ti mearga direct, pt ca, trebuie sa ai acces la categoriile mele de produs dar, ar trebui sa primesti eroare.
trebuie sa fii atent la cod, sa fie exact cum zic ei, altfel primesti o eroare ambigua si nici nu stii unde e problema :)).
nu stiu daca au mai schimbat ceva de cand am implementat eu, dar codul acesta functioneaza in acest moment.

<?php 
//***************************** Emag send product api PHP *****************************************************
// initialization array
$data=array();
$data[] = Array
       (
           'id' => "3350",
           'category_id' => "3131",
           'part_number' => "lr3350",
           'name' => "product_name",
           'description' => "product_decription",
           'brand' => "product_brand",
           'images' => Array
               (
                   Array
                       (
                           'display_type' => "1",
                           'url' => "image_url"
                       )

               ),

           'url' => "product_url",
           "status" => "1",
           "warranty" => "1",
           "sale_price" => "40.9285",
           "recommended_price" => "",
           "min_sale_price" => "35.59",
           "max_sale_price" => "53.385",
           "availability" => Array
               (
                  Array
                       (
                           "warehouse_id" => "1",
                           "id" => "0"
                       )

               ),

           "stock" => Array
               (
                   Array
                       (
                           "warehouse_id" => "1",
                           "value" => "10"
                       )

               ),

           "handling_time" => Array
               (
                   Array
                       (
                           "warehouse_id" => "1",
                           "value" => "3"
                       )

               ),

           "commission" => Array
               (
                   "type" => "percentage",
                   "value" => "20"
               ),

           "vat_id" => "5",
           "ean" => Array
               (
                   "0" => "5901688226735",
               ),

           "characteristics" => Array
               (
                   "0" => Array
                       (
                           "id" => "5258",
                           "value" => "Femei"
                       ),

                   "1" => Array
                       (
                           "id" => "5401",
                           "value" => "Bej"
                       ),

                   "2" => Array
                       (
                           "id" => "6140",
                           "value" => "Lenjerie sexy"
                       ),

                   "3" => Array
                       (
                           "id" => "4478",
                           "value" => "Accesorii Sexy"
                       ),

                   "4" => Array
                       (
                           "id" => "6506",
                           "value" => "One Size EU"
                       )

               )

       );
// username & password from emag account.
$username = 'emag_username';
$password = 'emag_password';

//create hash
$hash = base64_encode($username . ':' . $password);
$headers = array(
   'Authorization: Basic ' . $hash
);

// send data with cUrl
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://marketplace-api.emag.ro/api-3/product_offer/save');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array('data'=>($data))));

$result = curl_exec($ch);

// decode response
$all=json_decode($result);

// print array response
echo '<hr>';
echo '<pre>';
print_r($all);
echo '</pre>';
//echo '<hr>';


?>
1 Like

raspunsul de succes trebuie sa fie acesta:

stdClass Object
(
    [isError] => 
    [messages] => Array
        (
        )

    [results] => Array
        (
        )

)

cand sunt erori, arata cam asa:

stdClass Object
(
    [isError] => 1
    [messages] => Array
        (
            [0] => ERROR: Product url is not valid. It must contain a valid URL (http(s)://valid-url.tld) - Product id: 3350
            [1] => WARNING: Product image url is not valid - Product id: 3350
        )

    [results] => Array
        (
            [0] => Array
                (
                    [0] => stdClass Object
                        (
                            [id] => 3350
                            [category_id] => 3131
                            [part_number] => lr3350
                            [name] => product_name
                            [description] => product_decription
                            [brand] => product_brand
                            [images] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [display_type] => 1
                                            [url] => image_url
                                        )

                                )

                            [url] => product_url
                            [status] => 1
                            [warranty] => 1
                            [sale_price] => 40.9285
                            [recommended_price] => 
                            [min_sale_price] => 35.59
                            [max_sale_price] => 53.385
                            [availability] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [warehouse_id] => 1
                                            [id] => 0
                                        )

                                )

                            [stock] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [warehouse_id] => 1
                                            [value] => 10
                                        )

                                )

                            [handling_time] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [warehouse_id] => 1
                                            [value] => 3
                                        )

                                )

                            [commission] => stdClass Object
                                (
                                    [type] => percentage
                                    [value] => 20
                                )

                            [vat_id] => 5
                            [ean] => Array
                                (
                                    [0] => 5901688226735
                                )

                            [characteristics] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [id] => 5258
                                            [value] => Femei
                                        )

                                    [1] => stdClass Object
                                        (
                                            [id] => 5401
                                            [value] => Bej
                                        )

                                    [2] => stdClass Object
                                        (
                                            [id] => 6140
                                            [value] => Lenjerie sexy
                                        )

                                    [3] => stdClass Object
                                        (
                                            [id] => 4478
                                            [value] => Accesorii Sexy
                                        )

                                    [4] => stdClass Object
                                        (
                                            [id] => 6506
                                            [value] => One Size EU
                                        )

                                )

                        )

                )

        )

)

ps: scuze, n-am reusit sa asez prea bine codul, ca sunt in limita de timp… vreau sa inchei ziua mai devreme :)).

iar cand nu ai datele de login corecte primesti ceva de genul:

stdClass Object
(
    [isError] => 1
    [messages] => Array
        (
            [0] => You are not allowed to use this API.
        )

    [results] => Array
        (
        )

)

sper sa te ajute. spor :).

Ok, am reusit in sfarsit sa rezolv. Mi-am instalat php si am rulat script-ul de la @cotzo cu datele de la mine si update-ul in sfarsit a functionat. Am analizat call-ul cu Fiddler si am vazut ca datele se trimit cu ContentType application/x-www-form-urlencoded. Analizand si formatul datelor trimise si revenind in .net codul pentru a updata doua produse trebuie sa arate ceva de genul:

                var keyValueList = new List<KeyValuePair<string, string>>();
                keyValueList.Add(new KeyValuePair<string, string>("data[0][id]", "2"));
                keyValueList.Add(new KeyValuePair<string, string>("data[0][status]", "1"));
                keyValueList.Add(new KeyValuePair<string, string>("data[0][sale_price]", "63"));
                keyValueList.Add(new KeyValuePair<string, string>("data[0][stock][0][warehouse_id]", "1"));
                keyValueList.Add(new KeyValuePair<string, string>("data[0][stock][0][value]", "2")); //2
                keyValueList.Add(new KeyValuePair<string, string>("data[0][handling_time][0][warehouse_id]", ""));
                keyValueList.Add(new KeyValuePair<string, string>("data[0][handling_time][0]", "0"));
                keyValueList.Add(new KeyValuePair<string, string>("data[0][vat_id]", "1"));

                keyValueList.Add(new KeyValuePair<string, string>("data[1][id]", "46"));
                keyValueList.Add(new KeyValuePair<string, string>("data[1][status]", "1"));
                keyValueList.Add(new KeyValuePair<string, string>("data[1][sale_price]", "46.8"));
                keyValueList.Add(new KeyValuePair<string, string>("data[1][stock][0][warehouse_id]", "1"));
                keyValueList.Add(new KeyValuePair<string, string>("data[1][stock][0][value]", "0")); //0
                keyValueList.Add(new KeyValuePair<string, string>("data[1][handling_time][0][warehouse_id]", "1"));
                keyValueList.Add(new KeyValuePair<string, string>("data[1][handling_time][0]", "0"));
                keyValueList.Add(new KeyValuePair<string, string>("data[1][vat_id]", "1"));

                var postData = new FormUrlEncodedContent(keyValueList);

               request.Content = postData;

Se pare ca FormUrlEncodedContent nu are vreo metoda care sa accepte array-uri si sa isi creeze singur key-urile dar in fine.

Multumuesc tuturor pentru timpul si ajutorul acordat! Momentan nu se cere decat update de stoc dar probabil ca pe viitor va fi nevoie si de altele, sper ca si celelalte API end points sa functioneze similar si sa nu fie probabil dar sincer nu pot sa zic ca am mari sperante dupa experienta cu customer support.

P.S. Intre timp am primit raspuns si de la customer support care mi-o zis asa: “Am verificat. In primul rand Content Type-ul trebuie sa fie in format Json. In cazul de fata m-am uitat peste jsonul pe care l-a atasat sellerul. Call-ul pe care il face el un object, adica cu {}, el trebuie sa trimita un array adica cu []. Am identificat si un log unde are eroare. Il poti gasi mai jos:” De curiozitate am incercat din nou si trimitand un array (cu toate ca am mai incercat asta) dar cum era de asteptat nu a functionat. Iar eroarea aia de care zic ei e de mai in urma cand am incercat de curiozitate cu un singur obiect trimis ca FormUrlEncoded si a fost SINGURA data cand am primit eroare de la API.

Practic “suportul” nu s-a uitat NICIODATA peste codul ce le-am dat, fara sa dea vreo explicatie DE CE, nu mi-o dat nici un fisier cu un exemplu de call corect pe care sa il pot compara cu ale mele si nu au testat niciodata call-urile cu formatul trimis de mine ci doar s-au uitat in log-uri sa vada daca sunt erori si de fiecare data cand gaseau una imi spuneau de ce primesc eroarea aia de parca eu nu o puteam citi. Cel de la customer support sunt sigur ca nu era programator dar dupa raspunsurile primite am o presimtire ca si “cel de la tehnic” care nu a facut altceva vreodata decat sa caute in logs nu e. Sau pur si simplu nu ii pasa (asumand ca exista si ca nu a fost o singura persoana care s-a ocupat de treaba asta).

Oricare ar fi situatia din punctul meu de vedere nu este normal ca API-ul sa nu iti dea eroare atunci cand formatul datelor pe care il trimiti este invalid.

3 Likes

Salut,
am cumva aceeasi problema. Desi cred ca am formatat Jsonul corect, initial primeam acelasi rezultat

{
    "isError": false,
    "messages": [],
    "results": []
}

am incercat sa respect array-urile pe care le-am vazut in exemplul tau
Json-ul meu este trimis din postman, si arata cam asa:

{
  "data":[
    {
      "id":"116",
      "status":"1",
      "vat_id":"1",
      "stock":[
        {
          "warehouse_id":1,
          "value":200
        }
      ],
      "handling_time":[
        {
          "warehouse_id":1,
          "value":0
        }
      ],
      "sale_price":"336.138"
    },
    {
      "id":"117",
      "status":"1",
      "vat_id":"1",
      "stock":[
        {
          "warehouse_id":1,
          "value":200
        }
      ],
      "handling_time":[
        {
          "warehouse_id":1,
          "value":0
        }
      ],
      "sale_price":"336.138"
    }
  ]
}

rezultatul acestui call este

{
    "isError": true,
    "messages": [
        "Expected list of arrays, single array received. Try to encapsulate the call into another array"
    ],
    "results": []
}

Chiar nu pricep ce trebuie sa mai fac ca sa am un reply corect…
Multumesc anticipat!

Cu JSON nu am reusit sa ii dau de cap de ce nu functioneaza, pana la urma le-am trimis ca FormUrlEncoded cu formatul din post-ul meu. In ce incerci sa faci? Daca e pe .net poti sa iti dau codul mai complet. Daca e php poti sa folosesti exemplul lui cotzo.

Sau daca vrei sa iti incerci norocul poti intreba la customer support poate dai peste unu care stie despre ce e vorba si nu doar da raspunsuri generice si copy paste la pdf-ul de documentatie si apoi inchide imediat tichetul ca deh numaru de tichete inchise da bine la KPI la sfarsitu lunii.

salut! ma poate ajuta si pe mine cineva cu aceasta integrare?