Powiadomienia push
allee wysyła POST z JSON na Twój adres https, gdy coś się zmieni: zamówienie, oferta, wiadomość, zwrot, reklamacja, koniec wsadu lub raportu, zdarzenie bezpieczeństwa klucza. Wzór: Amazon SP-API Notifications, podpis jak Stripe.
1. Destynacja
Twój serwer musi odpowiedzieć na wyzwanie DESTINATION_VERIFICATION: 2xx z treścią {"challenge": "<payload.challenge>"} w 5 s. W odpowiedzi dostaniesz secret — tylko raz.
curl -sS -X POST "${ALLEE_API_URL:-https://api.allee.pl}/allee/notifications/destinations" \
-H "Authorization: Bearer $ALLEE_API_KEY" \
-H "Accept: application/vnd.allegro.public.v1+json" \
-H "Content-Type: application/vnd.allegro.public.v1+json" \
--data-binary @- \
-w '\nHTTP %{http_code}\n' <<'JSON'
{
"name": "Serwer sklepu",
"url": "https://sklep.example.com/allee/webhook"
}
JSON<?php
// allee API: POST /allee/notifications/destinations (PHP 8, rozszerzenie curl)
$base = getenv('ALLEE_API_URL') ?: 'https://api.allee.pl';
$body = [
'name' => 'Serwer sklepu',
'url' => 'https://sklep.example.com/allee/webhook',
];
$ch = curl_init($base . '/allee/notifications/destinations');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('ALLEE_API_KEY'),
'Accept: application/vnd.allegro.public.v1+json',
'Content-Type: application/vnd.allegro.public.v1+json',
],
CURLOPT_POSTFIELDS => json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
CURLOPT_RETURNTRANSFER => true,
]);
$odp = curl_exec($ch);
echo 'HTTP ', curl_getinfo($ch, CURLINFO_RESPONSE_CODE), "\n", $odp, "\n";# allee API: POST /allee/notifications/destinations (Python 3, biblioteka requests)
import os
import requests
BASE = os.environ.get("ALLEE_API_URL", "https://api.allee.pl")
headers = {
"Authorization": "Bearer " + os.environ["ALLEE_API_KEY"],
"Accept": "application/vnd.allegro.public.v1+json",
"Content-Type": "application/vnd.allegro.public.v1+json",
}
body = {
"name": "Serwer sklepu",
"url": "https://sklep.example.com/allee/webhook",
}
r = requests.request("POST", BASE + "/allee/notifications/destinations", headers=headers, json=body, timeout=60, allow_redirects=False)
print("HTTP", r.status_code)
print(r.text)// allee API: POST /allee/notifications/destinations (Node.js 18+, wbudowany fetch; plik .mjs)
const BASE = process.env.ALLEE_API_URL ?? "https://api.allee.pl";
const body = {
"name": "Serwer sklepu",
"url": "https://sklep.example.com/allee/webhook"
};
const res = await fetch(`${BASE}/allee/notifications/destinations`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ALLEE_API_KEY}`,
"Accept": "application/vnd.allegro.public.v1+json",
"Content-Type": "application/vnd.allegro.public.v1+json",
},
body: JSON.stringify(body),
redirect: "manual",
});
console.log("HTTP", res.status);
console.log(await res.text());// allee API: POST /allee/notifications/destinations (C#, .NET 8+, HttpClient)
using System.Net.Http.Headers;
using System.Text;
var baseUrl = Environment.GetEnvironmentVariable("ALLEE_API_URL") ?? "https://api.allee.pl";
using var http = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
using var req = new HttpRequestMessage(new HttpMethod("POST"), baseUrl + "/allee/notifications/destinations");
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("ALLEE_API_KEY"));
req.Headers.Accept.ParseAdd("application/vnd.allegro.public.v1+json");
var json = """
{
"name": "Serwer sklepu",
"url": "https://sklep.example.com/allee/webhook"
}
""";
req.Content = new StringContent(json, Encoding.UTF8);
req.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.allegro.public.v1+json");
using var res = await http.SendAsync(req);
Console.WriteLine($"HTTP {(int)res.StatusCode}");
Console.WriteLine(await res.Content.ReadAsStringAsync());// allee API: POST /allee/notifications/destinations (Java 11+, java.net.http; uruchom: java Main.java)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Main {
public static void main(String[] args) throws Exception {
String base = System.getenv().getOrDefault("ALLEE_API_URL", "https://api.allee.pl");
String body = """
{
"name": "Serwer sklepu",
"url": "https://sklep.example.com/allee/webhook"
}
""";
HttpRequest req = HttpRequest.newBuilder(URI.create(base + "/allee/notifications/destinations"))
.header("Authorization", "Bearer " + System.getenv("ALLEE_API_KEY"))
.header("Accept", "application/vnd.allegro.public.v1+json")
.header("Content-Type", "application/vnd.allegro.public.v1+json")
.method("POST", HttpRequest.BodyPublishers.ofString(body))
.build();
HttpClient http = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build();
HttpResponse<String> res = http.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println("HTTP " + res.statusCode());
System.out.println(res.body());
}
}// allee API: POST /allee/notifications/destinations (Go 1.20+, net/http; uruchom: go run main.go)
package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
base := os.Getenv("ALLEE_API_URL")
if base == "" {
base = "https://api.allee.pl"
}
body := `{
"name": "Serwer sklepu",
"url": "https://sklep.example.com/allee/webhook"
}`
req, err := http.NewRequest("POST", base+"/allee/notifications/destinations", strings.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("ALLEE_API_KEY"))
req.Header.Set("Accept", "application/vnd.allegro.public.v1+json")
req.Header.Set("Content-Type", "application/vnd.allegro.public.v1+json")
klient := &http.Client{CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }}
res, err := klient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
dane, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
fmt.Println("HTTP", res.StatusCode)
fmt.Println(string(dane))
}2. Subskrypcja
curl -sS -X POST "${ALLEE_API_URL:-https://api.allee.pl}/allee/notifications/subscriptions/ORDER_CHANGE" \
-H "Authorization: Bearer $ALLEE_API_KEY" \
-H "Accept: application/vnd.allegro.public.v1+json" \
-H "Content-Type: application/vnd.allegro.public.v1+json" \
--data-binary @- \
-w '\nHTTP %{http_code}\n' <<'JSON'
{
"destinationId": "b24ba1c2-f3d2-4872-8c7a-9df3c560f76d"
}
JSON<?php
// allee API: POST /allee/notifications/subscriptions/ORDER_CHANGE (PHP 8, rozszerzenie curl)
$base = getenv('ALLEE_API_URL') ?: 'https://api.allee.pl';
$body = [
'destinationId' => 'b24ba1c2-f3d2-4872-8c7a-9df3c560f76d',
];
$ch = curl_init($base . '/allee/notifications/subscriptions/ORDER_CHANGE');
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('ALLEE_API_KEY'),
'Accept: application/vnd.allegro.public.v1+json',
'Content-Type: application/vnd.allegro.public.v1+json',
],
CURLOPT_POSTFIELDS => json_encode($body, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
CURLOPT_RETURNTRANSFER => true,
]);
$odp = curl_exec($ch);
echo 'HTTP ', curl_getinfo($ch, CURLINFO_RESPONSE_CODE), "\n", $odp, "\n";# allee API: POST /allee/notifications/subscriptions/ORDER_CHANGE (Python 3, biblioteka requests)
import os
import requests
BASE = os.environ.get("ALLEE_API_URL", "https://api.allee.pl")
headers = {
"Authorization": "Bearer " + os.environ["ALLEE_API_KEY"],
"Accept": "application/vnd.allegro.public.v1+json",
"Content-Type": "application/vnd.allegro.public.v1+json",
}
body = {
"destinationId": "b24ba1c2-f3d2-4872-8c7a-9df3c560f76d",
}
r = requests.request("POST", BASE + "/allee/notifications/subscriptions/ORDER_CHANGE", headers=headers, json=body, timeout=60, allow_redirects=False)
print("HTTP", r.status_code)
print(r.text)// allee API: POST /allee/notifications/subscriptions/ORDER_CHANGE (Node.js 18+, wbudowany fetch; plik .mjs)
const BASE = process.env.ALLEE_API_URL ?? "https://api.allee.pl";
const body = {
"destinationId": "b24ba1c2-f3d2-4872-8c7a-9df3c560f76d"
};
const res = await fetch(`${BASE}/allee/notifications/subscriptions/ORDER_CHANGE`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ALLEE_API_KEY}`,
"Accept": "application/vnd.allegro.public.v1+json",
"Content-Type": "application/vnd.allegro.public.v1+json",
},
body: JSON.stringify(body),
redirect: "manual",
});
console.log("HTTP", res.status);
console.log(await res.text());// allee API: POST /allee/notifications/subscriptions/ORDER_CHANGE (C#, .NET 8+, HttpClient)
using System.Net.Http.Headers;
using System.Text;
var baseUrl = Environment.GetEnvironmentVariable("ALLEE_API_URL") ?? "https://api.allee.pl";
using var http = new HttpClient(new HttpClientHandler { AllowAutoRedirect = false });
using var req = new HttpRequestMessage(new HttpMethod("POST"), baseUrl + "/allee/notifications/subscriptions/ORDER_CHANGE");
req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("ALLEE_API_KEY"));
req.Headers.Accept.ParseAdd("application/vnd.allegro.public.v1+json");
var json = """
{
"destinationId": "b24ba1c2-f3d2-4872-8c7a-9df3c560f76d"
}
""";
req.Content = new StringContent(json, Encoding.UTF8);
req.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.allegro.public.v1+json");
using var res = await http.SendAsync(req);
Console.WriteLine($"HTTP {(int)res.StatusCode}");
Console.WriteLine(await res.Content.ReadAsStringAsync());// allee API: POST /allee/notifications/subscriptions/ORDER_CHANGE (Java 11+, java.net.http; uruchom: java Main.java)
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Main {
public static void main(String[] args) throws Exception {
String base = System.getenv().getOrDefault("ALLEE_API_URL", "https://api.allee.pl");
String body = """
{
"destinationId": "b24ba1c2-f3d2-4872-8c7a-9df3c560f76d"
}
""";
HttpRequest req = HttpRequest.newBuilder(URI.create(base + "/allee/notifications/subscriptions/ORDER_CHANGE"))
.header("Authorization", "Bearer " + System.getenv("ALLEE_API_KEY"))
.header("Accept", "application/vnd.allegro.public.v1+json")
.header("Content-Type", "application/vnd.allegro.public.v1+json")
.method("POST", HttpRequest.BodyPublishers.ofString(body))
.build();
HttpClient http = HttpClient.newBuilder().version(HttpClient.Version.HTTP_1_1).build();
HttpResponse<String> res = http.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println("HTTP " + res.statusCode());
System.out.println(res.body());
}
}// allee API: POST /allee/notifications/subscriptions/ORDER_CHANGE (Go 1.20+, net/http; uruchom: go run main.go)
package main
import (
"fmt"
"io"
"net/http"
"os"
"strings"
)
func main() {
base := os.Getenv("ALLEE_API_URL")
if base == "" {
base = "https://api.allee.pl"
}
body := `{
"destinationId": "b24ba1c2-f3d2-4872-8c7a-9df3c560f76d"
}`
req, err := http.NewRequest("POST", base+"/allee/notifications/subscriptions/ORDER_CHANGE", strings.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("ALLEE_API_KEY"))
req.Header.Set("Accept", "application/vnd.allegro.public.v1+json")
req.Header.Set("Content-Type", "application/vnd.allegro.public.v1+json")
klient := &http.Client{CheckRedirect: func(*http.Request, []*http.Request) error { return http.ErrUseLastResponse }}
res, err := klient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
dane, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
fmt.Println("HTTP", res.StatusCode)
fmt.Println(string(dane))
}Sprawdź odbiór: POST /allee/notifications/destinations/{destinationId}/test.
3. Odbiór i podpis
Nagłówki każdego powiadomienia:
Allee-Signature: t=1794205145,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
Allee-Notification-Id: 660f7167-ff79-4bb4-92e7-1d90b6189d83
Allee-Notification-Type: ORDER_CHANGE
Allee-Delivery-Attempt: 1v1 = HEX(HMAC-SHA256(secret, t + "." + surowa_treść)). Sprawdzaj podpis na surowych bajtach treści (przed parsowaniem JSON), odrzucaj podpisy starsze niż 300 s i duplikaty notificationId. Po rotacji sekretu nagłówek ma dwa v1 — przyjmij, gdy pasuje którykolwiek. Kod poniżej przeszedł test na prawdziwym powiadomieniu (i odrzucił zmienioną treść) w każdym języku:
#!/usr/bin/env bash
# Weryfikacja podpisu powiadomienia allee w powłoce (openssl) — do testów ręcznych; w produkcji użyj kodu swojej aplikacji.
naglowek="$ALLEE_WEBHOOK_PODPIS" # wartość nagłówka Allee-Signature
t=$(printf '%s' "$naglowek" | tr ',' '\n' | sed -n 's/^ *t=//p')
oczekiwany=$( { printf '%s.' "$t"; cat "$ALLEE_WEBHOOK_PLIK"; } | openssl dgst -sha256 -hmac "$ALLEE_WEBHOOK_SECRET" | sed 's/^.*= //')
teraz=$(date +%s)
if [ $(( teraz - t )) -le 300 ] && [ $(( t - teraz )) -le 300 ] && printf '%s' "$naglowek" | tr ',' '\n' | sed 's/^ *//' | grep -qx "v1=$oczekiwany"; then
echo OK
else
echo ODRZUCONE
fi<?php
// Weryfikacja podpisu powiadomienia allee (PHP 8): Allee-Signature: t=<unix>,v1=<hex>[,v1=<hex>]
function allee_podpis_ok(string $sekret, string $naglowek, string $tresc, int $tolerancja = 300): bool {
$t = null; $podpisy = [];
foreach (explode(',', $naglowek) as $czesc) {
[$k, $v] = array_pad(explode('=', trim($czesc), 2), 2, '');
if ($k === 't') $t = (int)$v; elseif ($k === 'v1') $podpisy[] = $v;
}
if ($t === null || abs(time() - $t) > $tolerancja) return false; // ochrona przed powtórką starego żądania
$oczekiwany = hash_hmac('sha256', $t . '.' . $tresc, $sekret);
foreach ($podpisy as $p) if (hash_equals($oczekiwany, $p)) return true; // porównanie w stałym czasie
return false;
}
// użycie w odbiorniku: $tresc = file_get_contents('php://input'); $naglowek = $_SERVER['HTTP_ALLEE_SIGNATURE'] ?? '';
$tresc = file_get_contents(getenv('ALLEE_WEBHOOK_PLIK'));
echo allee_podpis_ok(getenv('ALLEE_WEBHOOK_SECRET'), getenv('ALLEE_WEBHOOK_PODPIS'), $tresc) ? "OK\n" : "ODRZUCONE\n";# Weryfikacja podpisu powiadomienia allee (Python 3): Allee-Signature: t=<unix>,v1=<hex>[,v1=<hex>]
import hashlib
import hmac
import os
import time
def allee_podpis_ok(sekret: str, naglowek: str, tresc: bytes, tolerancja: int = 300) -> bool:
t, podpisy = None, []
for czesc in naglowek.split(","):
k, _, v = czesc.strip().partition("=")
if k == "t":
t = int(v)
elif k == "v1":
podpisy.append(v)
if t is None or abs(time.time() - t) > tolerancja: # ochrona przed powtórką starego żądania
return False
oczekiwany = hmac.new(sekret.encode(), str(t).encode() + b"." + tresc, hashlib.sha256).hexdigest()
return any(hmac.compare_digest(oczekiwany, p) for p in podpisy) # porównanie w stałym czasie
# użycie: tresc = surowe bajty żądania (np. request.get_data() we Flasku), naglowek = request.headers["Allee-Signature"]
with open(os.environ["ALLEE_WEBHOOK_PLIK"], "rb") as f:
tresc = f.read()
print("OK" if allee_podpis_ok(os.environ["ALLEE_WEBHOOK_SECRET"], os.environ["ALLEE_WEBHOOK_PODPIS"], tresc) else "ODRZUCONE")// Weryfikacja podpisu powiadomienia allee (Node.js 18+, moduł ES): Allee-Signature: t=<unix>,v1=<hex>[,v1=<hex>]
import { createHmac, timingSafeEqual } from "node:crypto";
import { readFile } from "node:fs/promises";
function alleePodpisOk(sekret, naglowek, tresc, tolerancja = 300) {
let t = null;
const podpisy = [];
for (const czesc of naglowek.split(",")) {
const [k, v] = czesc.trim().split("=", 2);
if (k === "t") t = Number(v);
else if (k === "v1") podpisy.push(v);
}
if (t === null || Math.abs(Date.now() / 1000 - t) > tolerancja) return false; // ochrona przed powtórką
const oczekiwany = createHmac("sha256", sekret).update(`${t}.`).update(tresc).digest("hex");
return podpisy.some((p) => p.length === oczekiwany.length && timingSafeEqual(Buffer.from(p), Buffer.from(oczekiwany)));
}
// użycie (Express): app.post("/allee/webhook", express.raw({ type: "*/*" }), (req, res) => alleePodpisOk(SEKRET, req.get("Allee-Signature"), req.body) …)
const tresc = await readFile(process.env.ALLEE_WEBHOOK_PLIK);
console.log(alleePodpisOk(process.env.ALLEE_WEBHOOK_SECRET, process.env.ALLEE_WEBHOOK_PODPIS, tresc) ? "OK" : "ODRZUCONE");// Weryfikacja podpisu powiadomienia allee (C#, .NET 8+): Allee-Signature: t=<unix>,v1=<hex>[,v1=<hex>]
using System.Security.Cryptography;
using System.Text;
static bool AlleePodpisOk(string sekret, string naglowek, byte[] tresc, int tolerancja = 300)
{
long? t = null;
var podpisy = new List<string>();
foreach (var czesc in naglowek.Split(','))
{
var kv = czesc.Trim().Split('=', 2);
if (kv.Length != 2) continue;
if (kv[0] == "t" && long.TryParse(kv[1], out var tt)) t = tt;
else if (kv[0] == "v1") podpisy.Add(kv[1]);
}
if (t is null || Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - t.Value) > tolerancja) return false; // ochrona przed powtórką
var dane = Encoding.UTF8.GetBytes(t + ".").Concat(tresc).ToArray();
var oczekiwany = Convert.ToHexString(HMACSHA256.HashData(Encoding.UTF8.GetBytes(sekret), dane)).ToLowerInvariant();
return podpisy.Any(p => CryptographicOperations.FixedTimeEquals(Encoding.ASCII.GetBytes(p), Encoding.ASCII.GetBytes(oczekiwany)));
}
// użycie (ASP.NET Core): wczytaj surowe bajty Request.Body i nagłówek Request.Headers["Allee-Signature"]
var tresc = File.ReadAllBytes(Environment.GetEnvironmentVariable("ALLEE_WEBHOOK_PLIK")!);
Console.WriteLine(AlleePodpisOk(Environment.GetEnvironmentVariable("ALLEE_WEBHOOK_SECRET")!, Environment.GetEnvironmentVariable("ALLEE_WEBHOOK_PODPIS")!, tresc) ? "OK" : "ODRZUCONE");// Weryfikacja podpisu powiadomienia allee (Java 17+; uruchom: java Main.java): Allee-Signature: t=<unix>,v1=<hex>[,v1=<hex>]
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HexFormat;
import java.util.List;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public class Main {
static boolean alleePodpisOk(String sekret, String naglowek, byte[] tresc, long tolerancja) throws Exception {
Long t = null;
List<String> podpisy = new ArrayList<>();
for (String czesc : naglowek.split(",")) {
String[] kv = czesc.trim().split("=", 2);
if (kv.length != 2) continue;
if (kv[0].equals("t")) t = Long.parseLong(kv[1]);
else if (kv[0].equals("v1")) podpisy.add(kv[1]);
}
if (t == null || Math.abs(System.currentTimeMillis() / 1000 - t) > tolerancja) return false; // ochrona przed powtórką
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(sekret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
mac.update((t + ".").getBytes(StandardCharsets.UTF_8));
byte[] oczekiwany = HexFormat.of().formatHex(mac.doFinal(tresc)).getBytes(StandardCharsets.US_ASCII);
for (String p : podpisy) if (MessageDigest.isEqual(oczekiwany, p.getBytes(StandardCharsets.US_ASCII))) return true; // stały czas
return false;
}
public static void main(String[] args) throws Exception {
byte[] tresc = Files.readAllBytes(Path.of(System.getenv("ALLEE_WEBHOOK_PLIK")));
boolean ok = alleePodpisOk(System.getenv("ALLEE_WEBHOOK_SECRET"), System.getenv("ALLEE_WEBHOOK_PODPIS"), tresc, 300);
System.out.println(ok ? "OK" : "ODRZUCONE");
}
}// Weryfikacja podpisu powiadomienia allee (Go 1.20+): Allee-Signature: t=<unix>,v1=<hex>[,v1=<hex>]
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"os"
"strconv"
"strings"
"time"
)
func alleePodpisOk(sekret, naglowek string, tresc []byte, tolerancja int64) bool {
var t int64 = -1
var podpisy []string
for _, czesc := range strings.Split(naglowek, ",") {
k, v, _ := strings.Cut(strings.TrimSpace(czesc), "=")
if k == "t" {
if n, err := strconv.ParseInt(v, 10, 64); err == nil {
t = n
}
} else if k == "v1" {
podpisy = append(podpisy, v)
}
}
if t < 0 || abs(time.Now().Unix()-t) > tolerancja { // ochrona przed powtórką
return false
}
mac := hmac.New(sha256.New, []byte(sekret))
mac.Write([]byte(strconv.FormatInt(t, 10) + "."))
mac.Write(tresc)
oczekiwany := hex.EncodeToString(mac.Sum(nil))
for _, p := range podpisy {
if hmac.Equal([]byte(oczekiwany), []byte(p)) { // porównanie w stałym czasie
return true
}
}
return false
}
func abs(x int64) int64 {
if x < 0 {
return -x
}
return x
}
func main() {
tresc, err := os.ReadFile(os.Getenv("ALLEE_WEBHOOK_PLIK"))
if err != nil {
panic(err)
}
if alleePodpisOk(os.Getenv("ALLEE_WEBHOOK_SECRET"), os.Getenv("ALLEE_WEBHOOK_PODPIS"), tresc, 300) {
fmt.Println("OK")
} else {
fmt.Println("ODRZUCONE")
}
}Ponowienia
Odpowiedz 2xx w 5 s, a pracę wykonaj w tle. Brak 2xx → ponowienia wykładnicze (30 s, 1 min, 2 min, 5 min … do 24 h), potem destynacja jest wyłączana i dostajesz powiadomienie w panelu. Historia: GET /allee/notifications/deliveries.
Typy
| Typ | Treść (payload) |
|---|---|
ORDER_CHANGE | ORDER_CHANGE — zmiana zamówienia. |
OFFER_STATUS_CHANGE | OFFER_STATUS_CHANGE — aktywacja, zakończenie. |
OFFER_ISSUES_CHANGE | OFFER_ISSUES_CHANGE — nowe problemy oferty. |
MESSAGE_RECEIVED | MESSAGE_RECEIVED — nowa wiadomość kupującego (bez treści — pobierz GET /messaging/messages/{id}). |
RETURN_CHANGE | RETURN_CHANGE — zwrot. |
ISSUE_CHANGE | ISSUE_CHANGE — reklamacja lub dyskusja. |
FEED_PROCESSING_FINISHED | FEED_PROCESSING_FINISHED — wsad przetworzony. |
REPORT_PROCESSING_FINISHED | REPORT_PROCESSING_FINISHED — raport gotowy. |
API_KEY_SECURITY_EVENT | API_KEY_SECURITY_EVENT — zdarzenie bezpieczeństwa klucza lub aplikacji. |
SELLER_COMPLIANCE_CHANGED | SELLER_COMPLIANCE_CHANGED — zmienił się stan zgodności (status, braki, oświadczenia albo blokada). Szczegóły: GET /allee/sellers/compliance. Bez danych osobowych. |
OFFER_NOTICE_RECEIVED | OFFER_NOTICE_RECEIVED — nowe zgłoszenie nielegalnej treści dotyczące oferty lub sklepu. Szczegóły: GET /allee/notices. |
OFFER_RESTRICTED | OFFER_RESTRICTED — decyzja allee wobec oferty lub konta. Uzasadnienie: GET /allee/decisions/{id}. |
TEST_NOTIFICATION | TEST_NOTIFICATION — wysyłane przez …/test. |
DESTINATION_VERIFICATION | DESTINATION_VERIFICATION — weryfikacja adresu przy zakładaniu destynacji. |