Dokumentacja API webhooków
Zintegruj swój sklep z Deneeu, aby automatycznie zgłaszać konwersje i naliczać prowizje influencerom w czasie rzeczywistym.
Wprowadzenie do webhooków
Deneeu śledzi konwersje w modelu CPS (Cost Per Sale) — płacisz wyłącznie za zarejestrowane sprzedaże. Aby to działało, Twój sklep musi po każdym udanym zamówieniu wysłać żądanie POST do naszego API z danymi zamówienia i identyfikatorem influencera.
Udostępniamy dwa endpointy webhookowe: /api/conversion — rekomendowany endpoint bazujący na identyfikatorze influencera (ref), oraz /api/track — alternatywny endpoint bazujący bezpośrednio na kodzie linku afiliacyjnego (code). Oba tworzą prowizję ze statusem PENDING, którą marka zatwierdza w panelu.
Szybki start
Najszybszy sposób na sprawdzenie integracji to wysłanie żądania cURL bezpośrednio z terminala:
curl -X POST https://www.deneeu.pl/api/conversion \
-H "Content-Type: application/json" \
-H "x-api-key: TWOJ_API_KEY" \
-d '{
"orderId": "zamowienie-123",
"amount": 299.99,
"ref": "id_influencera",
"email": "klient@example.com"
}'W odpowiedzi otrzymasz potwierdzenie zarejestrowania konwersji wraz z rozbiciem prowizji:
{
"success": true,
"message": "Conversion registered",
"breakdown": {
"orderAmount": 299.99,
"totalCommission": 44.99,
"influencerCommission": 37.49,
"platformCommission": 7.5,
"currency": "PLN"
}
}Autentykacja
Każde żądanie musi zawierać nagłówek x-api-key z Twoim kluczem API. Klucz znajdziesz w panelu marki, w sekcji Ustawienia → Integracja.
POST /api/conversion HTTP/1.1
Host: www.deneeu.pl
Content-Type: application/json
x-api-key: TWOJ_API_KEYOpcjonalnie możesz dodatkowo podpisać treść żądania, aby zabezpieczyć się przed jego modyfikacją w tranzycie. Oblicz HMAC-SHA256 z surowej treści żądania (JSON), używając swojego webhookSecret, i prześlij wynik jako nagłówek x-signature. Podpis jest weryfikowany tylko wtedy, gdy nagłówek zostanie wysłany — jego brak nie blokuje żądania, ale zalecamy jego używanie w środowisku produkcyjnym.
/api/track
Rejestruje konwersję na podstawie kodu linku afiliacyjnego (code). Link musi należeć do produktu Twojej marki, w przeciwnym razie żądanie zostanie odrzucone.
| Pole | Typ | Wymagane | Opis |
|---|---|---|---|
| code | string | wymagane | Kod unikalnego linku afiliacyjnego (AffiliateLink.code). |
| orderValue | number | wymagane | Wartość zamówienia. Musi być liczbą dodatnią. |
| orderId | string | opcjonalne | Twój identyfikator zamówienia. Używany do ochrony przed duplikatami (sprawdzany w obrębie Twojej marki). |
Przykładowe żądanie
{
"code": "abc123",
"orderValue": 199.0,
"orderId": "zamowienie-124"
}Odpowiedź 200 OK
{
"success": true,
"commissionId": "cmn_...",
"commissionAmount": 29.85,
"breakdown": {
"orderAmount": 199.0,
"totalCommission": 39.8,
"influencerCommission": 29.85,
"platformCommission": 9.95
}
}/api/conversion
RekomendowanyRejestruje konwersję na podstawie identyfikatora influencera (ref). To domyślny endpoint prezentowany w panelu marki i zalecany dla większości integracji sklepowych.
| Pole | Typ | Wymagane | Opis |
|---|---|---|---|
| orderId | string | wymagane | Twój identyfikator zamówienia. Używany globalnie do ochrony przed duplikatami. |
| amount | number | wymagane | Wartość zamówienia (musi być różna od zera). |
| ref | string | wymagane | Identyfikator influencera (InfluencerProfile.id) przypisany do konwersji. |
| currency | string | opcjonalne | Kod waluty, domyślnie "PLN". Zwracany w odpowiedzi, nie jest zapisywany w bazie danych. |
| string | opcjonalne | Adres e-mail klienta — zapisywany jako dane konwersji. | |
| productSlug | string | opcjonalne | Slug produktu — pozwala rozróżnić linki, jeśli influencer promuje kilka produktów Twojej marki. |
Przykładowe żądanie
{
"orderId": "zamowienie-123",
"amount": 299.99,
"ref": "id_influencera",
"currency": "PLN",
"email": "klient@example.com",
"productSlug": "twoj-produkt"
}Odpowiedź 200 OK
{
"success": true,
"message": "Conversion registered",
"breakdown": {
"orderAmount": 299.99,
"totalCommission": 44.99,
"influencerCommission": 37.49,
"platformCommission": 7.5,
"currency": "PLN"
}
}Kody błędów
Oba endpointy zwracają błędy w formacie { "error": "..." } wraz z odpowiednim kodem HTTP.
| Kod | Kiedy występuje |
|---|---|
| 400 | Nieprawidłowy JSON lub brak wymaganych pól w treści żądania. |
| 401 | Brak nagłówka x-api-key, nieprawidłowy klucz API lub niezgodny podpis HMAC (x-signature). |
| 403 | Link afiliacyjny należy do innej marki niż ta uwierzytelniona kluczem API (dotyczy /api/track). |
| 404 | Nie znaleziono linku afiliacyjnego dla podanego code / ref. |
| 409 | Zamówienie o podanym orderId zostało już zarejestrowane. |
| 500 | Wewnętrzny błąd serwera podczas przetwarzania żądania. |
Przykłady integracji
Poniżej znajdziesz gotowe fragmenty kodu do wysłania webhooka po zakończeniu zamówienia — dla WooCommerce, Node.js/JavaScript, Pythona oraz cURL.
WooCommerce (PHP)
Zapisz identyfikator influencera z parametru ?ref= w ciasteczku Twojego sklepu, a następnie wyślij webhook po zakończeniu zamówienia.
<?php
// 1) Zapisz ref przy wejściu z linku afiliacyjnego
add_action('init', function () {
if (!empty($_GET['ref'])) {
setcookie('deneeu_ref', sanitize_text_field($_GET['ref']), time() + 30 * DAY_IN_SECONDS, '/');
}
});
// 2) Zgłoś konwersję po opłaceniu zamówienia
add_action('woocommerce_order_status_completed', function ($order_id) {
$order = wc_get_order($order_id);
if (!$order || empty($_COOKIE['deneeu_ref'])) {
return;
}
$payload = wp_json_encode([
'orderId' => (string) $order_id,
'amount' => (float) $order->get_total(),
'ref' => sanitize_text_field($_COOKIE['deneeu_ref']),
'email' => $order->get_billing_email(),
]);
$signature = hash_hmac('sha256', $payload, 'TWOJ_WEBHOOK_SECRET');
wp_remote_post('https://www.deneeu.pl/api/conversion', [
'headers' => [
'Content-Type' => 'application/json',
'x-api-key' => 'TWOJ_API_KEY',
'x-signature' => $signature,
],
'body' => $payload,
'timeout' => 10,
]);
});JavaScript / Node.js
const crypto = require("crypto");
async function reportConversion({ orderId, amount, ref, email }) {
const payload = JSON.stringify({ orderId, amount, ref, email });
const signature = crypto
.createHmac("sha256", process.env.DENEEU_WEBHOOK_SECRET)
.update(payload)
.digest("hex");
const response = await fetch("https://www.deneeu.pl/api/conversion", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": process.env.DENEEU_API_KEY,
"x-signature": signature,
},
body: payload,
});
if (!response.ok) {
throw new Error(`Deneeu webhook error: ${response.status}`);
}
return response.json();
}Python
import hashlib
import hmac
import json
import requests
API_KEY = "TWOJ_API_KEY"
WEBHOOK_SECRET = "TWOJ_WEBHOOK_SECRET"
def report_conversion(order_id: str, amount: float, ref: str, email: str | None = None) -> dict:
payload = json.dumps({
"orderId": order_id,
"amount": amount,
"ref": ref,
"email": email,
})
signature = hmac.new(WEBHOOK_SECRET.encode(), payload.encode(), hashlib.sha256).hexdigest()
response = requests.post(
"https://www.deneeu.pl/api/conversion",
data=payload,
headers={
"Content-Type": "application/json",
"x-api-key": API_KEY,
"x-signature": signature,
},
timeout=10,
)
response.raise_for_status()
return response.json()cURL
curl -X POST https://www.deneeu.pl/api/conversion \
-H "Content-Type: application/json" \
-H "x-api-key: TWOJ_API_KEY" \
-H "x-signature: OBLICZONY_HMAC_SHA256" \
-d '{
"orderId": "zamowienie-123",
"amount": 299.99,
"ref": "id_influencera",
"email": "klient@example.com"
}'Checklist testowania
- Skopiuj swój x-api-key z panelu marki (Ustawienia → Integracja).
- Kliknij testowy link afiliacyjny (/r/kod) i odczytaj parametr ?ref= dołączony do przekierowania.
- Wyślij testowe żądanie POST /api/conversion z unikalnym orderId i poprawnym ref.
- Sprawdź, czy odpowiedź zwraca "success": true oraz poprawny breakdown prowizji.
- Wyślij dokładnie to samo żądanie ponownie i potwierdź, że otrzymujesz błąd 409.
- Sprawdź w panelu marki i influencera, czy konwersja pojawiła się ze statusem PENDING.
- Wyślij żądanie bez pola ref (lub amount / orderId) i potwierdź odpowiedź 400.
- Opcjonalnie: włącz podpis x-signature (HMAC-SHA256) i sprawdź, że nieprawidłowy podpis zwraca 401.
