Cum conectezi un magazin personalizat la easySales prin API
Conectează prin API orice magazin personalizat sau platformă fără integrare: cele două credențiale necesare, trimiterea produselor și a stocului, comenzile și primirea modificărilor înapoi.
Când ai nevoie de asta
easySales are conectori gata făcuți pentru platformele de magazin obișnuite. Dacă rulezi ceva personalizat — un magazin dezvoltat intern sau o platformă pentru care nu avem integrare — îl poți conecta singur prin API.
Este o treabă de dezvoltator. Vei scrie cod care trimite catalogul tău în easySales și transmite comenzile mai departe, iar easySales va apela magazinul tău înapoi când se schimbă ceva. Nimic din ce urmează nu are nevoie de un plugin instalat.
Cum funcționează conexiunea
Sunt implicate două credențiale, iar confundarea lor este cel mai frecvent motiv pentru care o primă integrare returnează 403.
| Credențial | De unde vine | Cum se trimite | Dacă lipsește |
|---|---|---|---|
| Token de acces |
POST /oauth/token, folosind clientul OAuth creat în Setări API
|
Header Authorization: Bearer <token>
|
401 |
| Token de website | Pasul Configurare din wizardul de conectare |
Un câmp website_token în corpul cererii, nu un header
|
403 Invalid website token |
Ambele sunt necesare la fiecare scriere. Token-ul de acces dovedește cine apelează; token-ul de website spune cărui magazin îi aparțin datele.
Pasul 1 — Adaugă website-ul
Mergi la Integrări → Magazine, apasă Conectare Website, completează formularul, apoi alege blocul API și versiunea API V2 de sub el.
| Câmp | Ce face |
|---|---|
| Nume Website | Eticheta ta. Așa îți deosebești magazinele mai târziu. |
| URL Website | Adresa magazinului tău, cu protocolul corect. |
| Țară | Stabilește ce cote de TVA îți oferă câmpul următor. Permanent. |
| TVA | TVA-ul aplicat produselor care sosesc fără unul. Se alege dintr-o listă, nu se scrie. |
| TVA Transport | TVA-ul aplicat livrării când o comandă nu poartă unul. |
| Limba / Valuta | Limba magazinului și moneda în care sunt prețurile tale. Ambele permanente. |
| Status custom pentru comanda noua | Opțional. Aduce fiecare comandă importată într-unul dintre statusurile tale. |
| Sursă stoc produse | Unde se află valoarea de stoc de referință. Implicit easySales. |
| Tip de pachet implicit | Valoarea implicită folosită la generarea AWB-urilor pentru aceste comenzi. |
| Serie Facturi | Seria de facturare folosită când payload-ul tău nu furnizează una. |
Pasul 2 — Copiază token-ul de website
Pasul Configurare din wizard afișează un token de 60 de caractere. Este cel pe care articolul vechi nu îl menționează niciodată și cel de care are nevoie fiecare apel de scriere.
Copiază-l cu butonul, nu rescriindu-l manual, și păstrează-l ca secret în aplicația ta. Apasă Salvare pentru a crea website-ul.
Magazinul apare acum în Integrări → Magazine, purtând același token pe cardul lui — acolo îl găsești din nou mai târziu.
Pasul 3 — Creează un client OAuth
Mergi la Setări → Setări API. Acolo se află credențialele OAuth.
Apasă Creați un client nou, denumește-l după sistemul care va apela și setează Tipul de grant pe Website Grant.
Website Grant este cel construit exact pentru asta: schimbă token-ul tău de website pe un token de acces, fără redirect în browser și fără interacțiune cu utilizatorul. Salvează și copiază ID Client și Secret care apar.
Pasul 4 — Obține un token de acces
POST https://easy-sales.com/oauth/token
Content-Type: application/json
{
"grant_type": "website",
"client_id": "your-client-id",
"client_secret": "your-client-secret",
"website_token": "your-60-character-website-token",
"scope": "add-products update-products update-stock add-orders update-orders read-orders"
}
Răspunsul este un corp OAuth standard:
{
"token_type": "Bearer",
"expires_in": 31536000,
"access_token": "eyJ0eXAiOiJKV1Qi...",
"refresh_token": "def50200a1b2c3..."
}
Trimite-l ca Authorization: Bearer <access_token> la fiecare apel următor.
Pasul 5 — Trimite catalogul
URL-ul de bază pentru tot ce urmează este https://easy-sales.com/api/v2.
Ordinea contează. Categoriile și caracteristicile trebuie să existe înainte ca un produs să le poată referenția, altfel apelul de produs este respins.
POST /categories/save— categoriile talePOST /characteristics/save— atributele talePOST /products/save— produsele tale
POST https://easy-sales.com/api/v2/products/save
Authorization: Bearer <access_token>
Content-Type: application/json
{
"website_token": "your-60-character-website-token",
"product": {
"product_website_id": "10231",
"sku": "TS-BLK-M",
"name": "Black T-shirt, size M",
"sale_price": 79.99,
"full_price": 99.99,
"stock": 24,
"type": "simple",
"tax_rate": 21,
"url": "https://my-shop.example.com/p/ts-blk-m",
"images": ["https://my-shop.example.com/img/ts-blk-m.jpg"],
"categories": ["cat-778"],
"characteristics": [{ "id": "char-12", "value": "Black" }]
}
}
| Câmp | Obligatoriu | Observații |
|---|---|---|
product_website_id
|
Da | ID-ul propriu al magazinului tău pentru produs |
sku
|
Da | Unic per website; cheia de upsert |
name
|
Da | |
sale_price
|
Da | Prețul pe care îl plătește clientul |
stock
|
Da | Trebuie să fie un număr |
type
|
Da |
simple sau complex
|
full_price
|
Nu | Prețul înainte de reducere, dacă afișezi unul |
tax_rate
|
Nu | Trebuie să fie o cotă validă pentru țara website-ului |
categories
|
Nu | ID-urile tale de categorii — fiecare trebuie să existe deja |
characteristics
|
Nu | ID-urile tale de atribute — fiecare trebuie să existe deja |
images
|
Nu | Listă de URL-uri pe care le putem descărca |
weight, handling_time, description, url
|
Nu | Folosite pentru curieri, estimări de livrare și listări pe marketplace |
Pasul 6 — Menține stocul sincronizat
Stocul este lucrul care trebuie să rămână la zi și este cel mai ieftin apel de făcut des. Trimite până la 100 de rânduri odată:
PATCH https://easy-sales.com/api/v2/stocks/bulk
Authorization: Bearer <access_token>
{
"website_token": "your-60-character-website-token",
"data": [
{ "sku": "TS-BLK-M", "stock": 24 },
{ "sku": "TS-BLK-L", "stock": 0 }
]
}
Fiecare SKU trebuie să existe deja pe acest website; cele necunoscute sunt respinse, nu create.
Pasul 7 — Trimite comenzile
POST https://easy-sales.com/api/v2/orders/save
Authorization: Bearer <access_token>
{
"website_token": "your-60-character-website-token",
"order": {
"order_id": "SO-100244",
"order_date": "2026-09-09 14:31:00",
"order_total": 179.98,
"status": "new",
"payment_mode": "card",
"shipment_tax": 21,
"billing_address": { "country": "RO", "city": "Cluj-Napoca", "street": "Str. Memorandumului 4" },
"shipping_address": { "country": "RO", "city": "Cluj-Napoca", "street": "Str. Memorandumului 4" },
"order_products": [
{ "product_website_id": "10231", "sku": "TS-BLK-M", "name": "Black T-shirt, size M",
"quantity": 2, "price": 79.99, "total": 159.98 }
]
}
}
Trimite din nou același order_id și comanda este actualizată, nu duplicată, ceea ce face reîncercările sigure.
Pasul 8 — Primește modificările înapoi
Magazinul tău trebuie să știe când o comandă este facturată, are AWB sau își schimbă statusul. Abonează un webhook în loc să interoghezi periodic:
GET https://easy-sales.com/api/v2/webhooks
Authorization: Bearer <access_token>
POST https://easy-sales.com/api/v2/webhooks/order-updated
Authorization: Bearer <access_token>
{
"url": "https://my-shop.example.com/hooks/easysales",
"secret": "a-shared-secret-of-at-least-24-characters"
}
Te abonezi la câte un eveniment pe rând, deci repetă apelul pentru fiecare dintre order-created, order-updated, awb-created, invoice-created și delivery-status-updated.
Fiecare livrare este semnată, deci verifică semnătura înainte să te încrezi în conținut. Răspunde rapid — cererea expiră după câteva secunde și este reîncercată de un număr limitat de ori, așa că confirmă întâi și procesează după.
Limite
| Limită | Valoare |
|---|---|
| Cereri | 500 pe minut pe tot API-ul |
| Cereri de token | 60 pe minut — păstrează token-ul în cache |
| Produse, stoc, prețuri, categorii, caracteristici per apel bulk | 100 |
| Produse per apel bulk de arhivare | 50 |
| Website-uri per cont | 30 |
| Descrierea produsului | 65.534 de caractere |
Când ceva eșuează
| Cod | Semnificație | Cauză uzuală |
|---|---|---|
| 400 |
Invalid json
|
Corpul cererii nu este JSON valid |
| 401 | Neautentificat | Token de acces lipsă, expirat sau malformat |
| 403 |
Invalid website token
|
website_token lipsă sau greșit
|
| 403 |
The website has been deactivated
|
Comutatorul Activ al website-ului este oprit |
| 422 | Validare eșuată | Lipsește un câmp obligatoriu, un SKU este duplicat sau o categorie ori o caracteristică nu există încă |
| 429 | Prea multe cereri | Peste 500 pe minut |
| 503 | Indisponibil temporar | Preluarea este aglomerată; reîncearcă după intervalul indicat |
Orice eșuează de partea noastră ajunge și în Produse → Magazine Online → Erori website, cu payload-ul și o acțiune de reîncercare, ceea ce este de obicei mai rapid decât reproducerea apelului.
Referință
Referința completă a endpoint-urilor, cu fiecare câmp și fiecare răspuns, este publicată la https://api.easy-sales.com.