Documentație parteneri
Tot ce aveți nevoie pentru a publica anunțurile dvs. de vânzare și răscumpărare pe QuizzBuy și pentru a ne notifica comenzile atribuite traficului nostru.
1. Obținerea unei chei API
Contactați interlocutorul dvs. QuizzBuy (sau formularul de contact). Generăm pentru dvs. o cheie în formatul zzb_live_… — vă este comunicată o singură dată, păstrați-o în siguranță. Transmiteți-o la fiecare cerere în antetul HTTP:
Authorization: Bearer zzb_live_VOTRE_CLE2. Verificarea cheii dvs.
curl https://quizzbuy.com/api/v1/me \
-H "Authorization: Bearer zzb_live_VOTRE_CLE"
# Réponse
{
"company": { "id": "…", "name": "Votre société", "slug": "votre-societe" },
"commission_rate": 0.05,
"click_param": "zzb_click"
}3. Publicarea anunțurilor
Un anunț este fie o ofertă de răscumpărare (BUYBACK — preluați un dispozitiv la un preț dat), fie o ofertă de vânzare (SALE — un produs recondiționat pe care îl vindeți). Trimiterea este un upsert: retrimiterea aceluiași externalId actualizează anunțul.
curl -X POST https://quizzbuy.com/api/v1/listings \
-H "Authorization: Bearer zzb_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{
"externalId": "ref-interne-123",
"type": "BUYBACK",
"title": "Reprise iPhone 15 Pro 256 Go",
"brand": "Apple",
"model": "iPhone 15 Pro",
"category": "SMARTPHONE",
"storage": "256 GB",
"condition": "GOOD",
"priceCents": 52000,
"currency": "EUR",
"url": "https://votre-site.fr/reprise/iphone-15-pro",
"country": "FR"
}'category: SMARTPHONE, LAPTOP, SMARTWATCH, AUDIO sau GAMING.condition: LIKE_NEW, EXCELLENT, GOOD, FAIR sau BROKEN.priceCents: preț în cenți (52000 = 520 €).- Fiecare anunț nou (sau modificare) trece în moderare înainte de publicare.
Actualizare, listare sau dezactivare:
# Lister vos annonces
curl "https://quizzbuy.com/api/v1/listings?type=BUYBACK&status=APPROVED" \
-H "Authorization: Bearer zzb_live_VOTRE_CLE"
# Mise à jour partielle
curl -X PATCH https://quizzbuy.com/api/v1/listings/ID_ANNONCE \
-H "Authorization: Bearer zzb_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{ "priceCents": 49000 }'
# Désactiver (soft delete)
curl -X DELETE https://quizzbuy.com/api/v1/listings/ID_ANNONCE \
-H "Authorization: Bearer zzb_live_VOTRE_CLE"4. Urmărirea click-urilor
Când un vizitator QuizzBuy dă click către site-ul dvs., URL-ul de destinație conține un identificator de click:
https://votre-site.fr/vendre?zzb_click=6f1e0c9a-3b2d-4e8f-9a10-abcdef123456Stocați această valoare (cookie sau sesiune pe partea site-ului dvs., durată recomandată: 45 de zile). Aceasta este cea care va permite atribuirea comenzii. Numele parametrului (zzb_click implicit) este configurabil la cerere.
5. Notificarea unei comenzi (postback S2S)
Imediat ce un client plasează o comandă (achiziție sau cerere de răscumpărare validată) și dispuneți de un zzb_click, apelați postback-ul nostru de pe serverul dvs.:
curl -X POST https://quizzbuy.com/api/v1/postback \
-H "Authorization: Bearer zzb_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{
"click_id": "6f1e0c9a-3b2d-4e8f-9a10-abcdef123456",
"type": "BUYBACK",
"amount_cents": 52000,
"currency": "EUR",
"order_ref": "CMD-2026-000123"
}'
# Réponse 201
{ "conversion_id": "…", "status": "TO_INVOICE", "commission_cents": 2600 }- Fereastră de atribuire: 45 de zile după click; peste această limită, răspuns
422 attribution_window_expired. order_reftrebuie să fie unic: un duplicat returnează409 duplicate_order_ref(idempotență — puteți reîncerca fără risc).type:SALEpentru o achiziție,BUYBACKpentru o răscumpărare.currency: doar EUR — orice altă monedă este refuzată (422 unsupported_currency).
6. Testare în sandbox
Adăugați "test": true la postback: cererea este validată integral (cheie, click_id, fereastra de 45 zile), dar nicio conversie nu este înregistrată sau facturată.
{ "click_id": "…", "type": "SALE", "amount_cents": 10000, "order_ref": "TEST-1", "test": true }
# → 200 { "test": true, "valid": true, "commission_cents": 500 }7. Coduri de eroare
| Cod | Eroare | Explicație |
|---|---|---|
| 400 | invalid_input | Corp de cerere invalid (detalii în răspuns). |
| 401 | unauthorized | Cheie API absentă, revocată sau invalidă. |
| 404 | click_not_found / not_found | click_id sau anunț necunoscut (sau nu vă aparține). |
| 409 | duplicate_order_ref | Comandă deja notificată. |
| 422 | attribution_window_expired | Click mai vechi de 45 de zile. |
| 429 | rate_limited | Prea multe cereri — reîncercați într-un minut. |
8. Facturare
Fiecare conversie atribuită generează un comision (rată contractuală, vizibilă prin /api/v1/me). QuizzBuy vă trimite o factură recapitulativă periodică a conversiilor validate. Pentru orice întrebare: contactați-ne.
9. Marketplace — vânzare pe QuizzBuy
Anunțurile SALE cu un quantity > 0 sunt vândute direct pe QuizzBuy (plata clientului la noi, virarea sumei nete de comision). Câmpuri suplimentare: quantity (stoc), color, grade (A/B/C), batteryHealth (%), warrantyMonths. Anunțul este atașat automat fișei de produs corespunzătoare (marcă + model + capacitate + culoare).
# Mettre à jour le stock (sans re-modération)
curl -X PATCH https://quizzbuy.com/api/v1/listings/ID_ANNONCE/stock \
-H "Authorization: Bearer zzb_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{ "quantity": 12 }'
# Ajouter une photo (multipart, max 5 × 5 Mo, jpeg/png/webp)
curl -X POST https://quizzbuy.com/api/v1/listings/ID_ANNONCE/images \
-H "Authorization: Bearer zzb_live_VOTRE_CLE" \
-F "file=@photo.jpg"10. Webhook-uri — fiți informat despre vânzări
Înregistrați un endpoint HTTPS; vă notificăm la fiecare etapă a unei comenzi care conține produsele dvs. (order.created, order.paid, order.cancelled). Secretul este returnat doar la creare — stocați-l.
curl -X POST https://quizzbuy.com/api/v1/webhooks \
-H "Authorization: Bearer zzb_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{ "url": "https://votre-site.fr/webhooks/quizzbuy", "events": ["order.paid"] }'
# Réponse (secret affiché une seule fois)
{ "webhook": { "id": "…", "secret": "whsec_…", "events": ["order.paid"] } }
# Tester
curl -X POST https://quizzbuy.com/api/v1/webhooks/ID_WEBHOOK/test \
-H "Authorization: Bearer zzb_live_VOTRE_CLE"Fiecare livrare este semnată. Verificați antetul X-ZZbuy-Signature (t=timestamp,v1=hex):
// Node.js
const [t, v1] = signature.split(",").map((p) => p.split("=")[1]);
const expected = crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(`${t}.${rawBody}`)
.digest("hex");
const valid =
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1)) &&
Math.abs(Date.now() / 1000 - Number(t)) < 300; // anti-replay 5 minÎn caz de eșec (≠ 2xx), reîncercăm cu backoff: 1 min, 5 min, 30 min, 2 h, 12 h. Primiți de asemenea un email de notificare de vânzare.
11. Procesarea comenzilor dvs.
Listați liniile de comandă, confirmați primirea, apoi expediați cu un număr de urmărire (clientul este notificat automat). Adresa de livrare este vizibilă doar după plată.
# Lister les commandes à traiter
curl "https://quizzbuy.com/api/v1/orders?status=PENDING" \
-H "Authorization: Bearer zzb_live_VOTRE_CLE"
# Accuser réception
curl -X POST https://quizzbuy.com/api/v1/orders/ID_LIGNE/ack \
-H "Authorization: Bearer zzb_live_VOTRE_CLE"
# Expédier
curl -X POST https://quizzbuy.com/api/v1/orders/ID_LIGNE/ship \
-H "Authorization: Bearer zzb_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{ "carrier": "Colissimo", "trackingNumber": "6A123456789FR" }'12. Reprise gérée (trade-in)
Reprise gérée merge mai departe decât simpla răscumpărare prin redirecționare: persoana fizică își trimite dispozitivul de pe QuizzBuy, iar dvs. gestionați întregul dosar prin API (acceptare, primire, contraofertă, plată). Prețul afișat clientului este blocat la trimitere pe baza grilei dvs. de răscumpărare (a se vedea §14); îl puteți revizui în scădere doar după primire, printr-o contraofertă motivată.
Toate endpoint-urile se autentifică cu cheia dvs. API (Authorization: Bearer zzb_live_…) și returnează doar dosarele dvs.
Ciclu de viață
SUBMITTED → ACCEPTED → SHIPPED → RECEIVED → PAID. Două ramificații: REJECTED (refuz înainte de expediere) și COUNTER_OFFER (contraofertă după inspecție, pe care persoana fizică o acceptă — apoi PAID — sau o refuză — returnare dispozitiv, CANCELLED).
| Statut | Semnificație |
|---|---|
| SUBMITTED | Cerere creată de persoana fizică, în așteptarea deciziei dvs. |
| ACCEPTED | Ați confirmat răscumpărarea; clientul trebuie să expedieze dispozitivul. |
| SHIPPED | Persoana fizică a introdus numărul de urmărire. |
| RECEIVED | Ați primit dispozitivul; inspecție în curs. |
| COUNTER_OFFER | După inspecție, propuneți o sumă revizuită (mai mică). |
| PAID | Plată efectuată către persoana fizică — dosar închis. |
| REJECTED | Cerere refuzată înainte de expediere (neeligibil, fraudă…). |
| CANCELLED | Anulată (refuzul unei contraoferte, returnare dispozitiv). |
Listare și consultare
# Lister vos reprises (plus récentes d'abord)
curl "https://quizzbuy.com/api/v1/trade-ins?status=SUBMITTED&limit=50&offset=0" \
-H "Authorization: Bearer zzb_live_VOTRE_CLE"
# Réponse
{
"total": 3,
"trade_ins": [
{
"trade_in_id": "…",
"reference": "TI-2026-000042",
"status": "SUBMITTED",
"device": {
"brand": "Apple", "category": "SMARTPHONE", "model": "iPhone 15 Pro",
"storage": "256 GB", "condition": "GOOD",
"functional_status": "FULLY_WORKING", "battery_health": 92, "imei": "…"
},
"offer_cents": 52000,
"currency": "EUR",
"price_locked_until": "2026-08-05T12:00:00.000Z",
"country": "FR",
"customer": { "email": "…", "first_name": "…", "last_name": "…", "locale": "fr" },
"comment": null,
"counter_offer_cents": null, "counter_reason": null,
"tracking_carrier": null, "tracking_number": null,
"shipping_label_url": null, "payout_ref": null,
"accepted_at": null, "shipped_at": null, "received_at": null,
"paid_at": null, "cancelled_at": null,
"created_at": "2026-07-21T12:00:00.000Z"
}
]
}
# Détail d'une reprise
curl https://quizzbuy.com/api/v1/trade-ins/ID_REPRISE \
-H "Authorization: Bearer zzb_live_VOTRE_CLE"
# → { "trade_in": { … } }status(filtru opțional): o valoare din tabelul de mai sus — altfel400 invalid_status.limit: max 200 (implicit 50);offsetpentru paginare.customer(contactul persoanei fizice) este vizibil doar în acest API partener, niciodată în webhook-uri.
Tranziții
Fiecare acțiune este un POST și returnează { "ok": true, "trade_in": { … } }. O tranziție dintr-un statut incompatibil returnează 409 invalid_status (cu current real). Persoana fizică este notificată prin email la fiecare etapă.
# 1. Accepter (depuis SUBMITTED) — shippingLabelUrl facultatif (étiquette prépayée)
curl -X POST https://quizzbuy.com/api/v1/trade-ins/ID_REPRISE/accept \
-H "Authorization: Bearer zzb_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{ "shippingLabelUrl": "https://votre-site.fr/labels/ti-42.pdf" }'
# 2. Réceptionner l'appareil (depuis SHIPPED ou ACCEPTED)
curl -X POST https://quizzbuy.com/api/v1/trade-ins/ID_REPRISE/receive \
-H "Authorization: Bearer zzb_live_VOTRE_CLE"
# 3a. Payer le montant garanti (depuis RECEIVED) — clôt la reprise
curl -X POST https://quizzbuy.com/api/v1/trade-ins/ID_REPRISE/pay \
-H "Authorization: Bearer zzb_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{ "payoutRef": "VIR-2026-000123" }'
# 3b. …ou contre-offrer après inspection (depuis RECEIVED) — montant < offre garantie
curl -X POST https://quizzbuy.com/api/v1/trade-ins/ID_REPRISE/counter \
-H "Authorization: Bearer zzb_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{ "amountCents": 42000, "reason": "Rayures écran non déclarées" }'
# Refuser avant envoi (depuis SUBMITTED uniquement)
curl -X POST https://quizzbuy.com/api/v1/trade-ins/ID_REPRISE/reject \
-H "Authorization: Bearer zzb_live_VOTRE_CLE"- accept: doar din
SUBMITTED.shippingLabelUrlopțional (URL, ≤ 500 car.). - receive: din
SHIPPEDsauACCEPTED(depunere/expediere nedeclarată de client). - counter: din
RECEIVED.amountCentstrebuie să fie strict inferior luioffer_cents, altfel400 counter_not_lower;reasonobligatoriu (1–500 car.). Ulterior, persoana fizică este cea care acceptă sau refuză din pagina sa de urmărire. - pay: din
RECEIVED.payoutRefobligatoriu (referință de virament, 1–120 car.). - reject: doar din
SUBMITTED— niciun corp necesar.
13. Webhook-uri reprise (trade_in.*)
Aceleași webhook-uri (§10, semnătură X-ZZbuy-Signature identică) acoperă reprise gérée. Abonați-vă la toate sau o parte din evenimentele trade_in.* la crearea unui endpoint:
curl -X POST https://quizzbuy.com/api/v1/webhooks \
-H "Authorization: Bearer zzb_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{
"url": "https://votre-site.fr/webhooks/quizzbuy",
"events": ["trade_in.created", "trade_in.shipped", "trade_in.counter_accepted"]
}'| Eveniment | Declanșator |
|---|---|
| trade_in.created | Cerere nouă trimisă de o persoană fizică (statut SUBMITTED). |
| trade_in.shipped | Persoana fizică a introdus numărul de urmărire al expedierii. |
| trade_in.counter_accepted | Persoana fizică a acceptat contraoferta dvs. |
| trade_in.counter_declined | Persoana fizică a refuzat contraoferta dvs. (returnare dispozitiv). |
| trade_in.cancelled | Răscumpărare anulată. |
Corpul livrării (contactul persoanei fizice nu figurează aici — obțineți-l prin GET /api/v1/trade-ins/:id):
{
"trade_in_id": "…",
"reference": "TI-2026-000042",
"status": "SHIPPED",
"device": {
"brand": "Apple", "category": "SMARTPHONE", "model": "iPhone 15 Pro",
"storage": "256 GB", "condition": "GOOD",
"functional_status": "FULLY_WORKING", "battery_health": 92, "imei": "…"
},
"offer_cents": 52000,
"currency": "EUR",
"price_locked_until": "2026-08-05T12:00:00.000Z",
"country": "FR"
}14. Trimiterea grilei dvs. de răscumpărare
Alternativă „push” la fluxul CSV preluat de noi: trimiteți direct grila dvs. de prețuri de răscumpărare. Fiecare linie conține 4 sume în funcție de starea dispozitivului. Prețurile alimentează același tabel ca sincronizarea automată — apar deci imediat în comparator și servesc drept preț blocat pentru reprise gérée (§12). Operația este un upsert pe (marcă, categorie, model, capacitate).
curl -X PUT https://quizzbuy.com/api/v1/buyback/prices \
-H "Authorization: Bearer zzb_live_VOTRE_CLE" \
-H "Content-Type: application/json" \
-d '{
"prices": [
{
"brand": "Apple",
"category": "SMARTPHONE",
"model": "iPhone 15 Pro",
"storage": "256 GB",
"priceNewCents": 60000,
"priceGoodCents": 52000,
"priceFairCents": 40000,
"priceBrokenCents": 15000,
"currency": "EUR",
"url": "https://votre-site.fr/reprise/iphone-15-pro"
}
]
}'
# Réponse
{ "ok": true, "upserted": 1 }prices: 1 până la 2000 de linii per cerere.category: SMARTPHONE, TABLET, LAPTOP, SMARTWATCH, AUDIO sau GAMING.priceNewCents(nou),priceGoodCents(bun),priceFairCents(marcat),priceBrokenCents(spart) — în cenți, ≥ 0.storageșiurlopționale; capacitatea este normalizată automat (ex. „256go” → „256 GB”).