Collega qualsiasi magazzino a ProfitDesk.
La Prep API trasforma il tuo software in un prep center dentro ProfitDesk. Gli annunci ti arrivano come webhook firmati, tu comunichi ricevimenti e outbound, e ogni unità resta tracciabile dall’acquisto alla spedizione FBA.
- Webhook firmati
- REST API
- OpenAPI 3.1
- Replay degli eventi
POST https://wms.example.com/webhooks/profitdesk
X-Webhook-Event-Type: inbound.announced
X-Webhook-Signature: sha256=9f2c41…
{
"type": "inbound.announced",
"connection_id": "pcn_812",
"data": {
"inbound": {
"id": "inb_2000000123",
"fulfillment": "FBA",
"tracking_numbers": ["1Z999AA10123456784"],
"lines": [{
"id": "inl_99",
"purchase_id": "pur_4711",
"item": { "sku": "AB-123", "asin": "B0ABCDEFGH" },
"quantity_expected": 6
}]
}
}
}POST /v1/prep/inbounds/inb_2000000123/receipts
Authorization: Bearer ppk_3f9a…
{
"event_id": "rcpt-8812",
"status": "received",
"lines": [{ "line_id": "inl_99", "quantity_received": 6 }]
}Due modi per iniziare
Una sola API, pensata per due tipi di sviluppatori.
- 1Aggiungi il tuo softwareImpostazioni → Integrazioni → Prep center → Aggiungi → “Software proprio (Webhook)”. Inserisci il tuo endpoint HTTPS e scegli gli eventi che vuoi ricevere.
- 2Salva due credenzialiUn segreto di firma (whsec_…) e una chiave API (ppk_…), mostrati una sola volta. Puoi ruotarli quando vuoi.
- 3Collega un magazzinoDa ora gli acquisti di quel magazzino vengono annunciati al tuo software.
- La chiave vede
- Solo questa connessione
- Rate limit
- 2 req/s, picchi di 10
- Test
- Ping “Invia test” e log delle consegne
- Combina come vuoi
- Accanto a PrepBusiness o PrepTool, per singolo magazzino
Come funziona
Dall’acquisto alla spedizione FBA,
in cinque eventi.
- 01ProfitDeskLa merce è in arrivo
inbound.announcedUn webhook firmato con righe, SKU, ASIN e tracking. Rispondi con 2xx, se vuoi con il tuo external_id. - 02ProfitDeskSeguono i dettagli
inbound.updatedNuovi codici di tracking e l’FNSKU non appena Amazon lo assegna, così puoi stampare le etichette. - 03TuConti la merce
POST …/receiptsConteggi assoluti per riga, unità danneggiate incluse. ProfitDesk aggiorna l’acquisto. - 04TuSpedisci la merce
POST /v1/Righe e ID della spedizione FBA collegano il tuo outbound alla spedizione di Amazon.prep/ outbounds - 05AmazonAmazon riceve
FBA15XYZProfitDesk registra la quantità inoltrata dai dati di Amazon. Il tuo outbound è la traccia.
Ogni unità, tracciabile da capo a capo.
Ogni oggetto ha un id con un prefisso di tipo. L’id dell’acquisto non cambia mai, nemmeno quando la merce viene annunciata di nuovo o cambia magazzino.
pur_4711AcquistoL’acquisto del seller. La chiave per seguire un’unità, per sempre.inb_2000000123InboundUn annuncio. Un nuovo annuncio ne genera uno nuovo.inl_99Riga inboundUn acquisto al suo interno. Usala in ricevimenti e outbound.out_55OutboundCiò che hai spedito, indirizzato con il tuo external_id.FBA15XYZSpedizione FBAL’ID della spedizione Amazon, collegato dal tuo outbound.
Usa anche i tuoi riferimenti: ogni percorso che accetta un id accetta anche ext:<tuo id>.
Pronta per la produzione
Le parti noiose
sono già risolte.
HMAC-SHA256 in una dozzina di righe.
Firma il body grezzo con il tuo segreto whsec_ e il timestamp, confronta in tempo costante, rifiuta tutto ciò che è più vecchio di cinque minuti. Durante una rotazione del segreto vengono inviate entrambe le firme per 24 ore.
import crypto from "node:crypto";
function verify(rawBody, headers, secret) {
const ts = headers["x-webhook-timestamp"];
const signature = headers["x-webhook-signature"];
if (!ts || !signature || !/^\d+$/.test(ts)) return false;
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(`${ts}.${rawBody}`).digest("hex");
return signature.split(",").some((sig) => {
const a = Buffer.from(sig.trim()), b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
});
}import hashlib, hmac, time
def verify(raw_body: bytes, headers, secret: str) -> bool:
ts = headers.get("X-Webhook-Timestamp", "")
signature = headers.get("X-Webhook-Signature", "")
if not ts.isdigit() or not signature:
return False
if abs(time.time() - int(ts)) > 300:
return False
expected = "sha256=" + hmac.new(secret.encode(), ts.encode() + b"." + raw_body, hashlib.sha256).hexdigest()
return any(hmac.compare_digest(sig.strip(), expected) for sig in signature.split(","))function verify(string $rawBody, array $headers, string $secret): bool {
$ts = $headers['X-Webhook-Timestamp'] ?? '';
$signature = $headers['X-Webhook-Signature'] ?? '';
if (!ctype_digit($ts) || $signature === '') return false;
if (abs(time() - (int)$ts) > 300) return false;
$expected = 'sha256=' . hash_hmac('sha256', $ts . '.' . $rawBody, $secret);
foreach (explode(',', $signature) as $sig) {
if (hash_equals($expected, trim($sig))) return true;
}
return false;
}func verify(rawBody []byte, h http.Header, secret string) bool {
ts := h.Get("X-Webhook-Timestamp")
sec, err := strconv.ParseInt(ts, 10, 64)
if err != nil || math.Abs(float64(time.Now().Unix()-sec)) > 300 {
return false
}
mac := hmac.New(sha256.New, []byte(secret))
mac.Write([]byte(ts + "."))
mac.Write(rawBody)
expected := "sha256=" + hex.EncodeToString(mac.Sum(nil))
for _, sig := range strings.Split(h.Get("X-Webhook-Signature"), ",") {
if hmac.Equal([]byte(strings.TrimSpace(sig)), []byte(expected)) {
return true
}
}
return false
}Endpoint
URL base https://api.profitpath.app · Bearer ppk_…
| GET | /v1/La connessione della chiave | La connessione della chiave |
| GET | /v1/Elenco degli inbound | Elenco degli inbound |
| GET | /v1/Un inbound, anche tramite ext: | Un inbound, anche tramite ext: |
| PUT | /v1/Imposta il tuo riferimento | Imposta il tuo riferimento |
| POST | /v1/Comunica la merce ricevuta | Comunica la merce ricevuta |
| POST | /v1/Comunica un outbound | Comunica un outbound |
| GET | /v1/Un outbound | Un outbound |
| GET | /v1/Articoli, uno per SKU | Articoli, uno per SKU |
| GET | /v1/Replay degli eventi webhook | Replay degli eventi webhook |
Eventi webhook
Consegnati almeno una volta, in ordine per inbound.
connection.created · updated · removedUn seller si connette, cambia i dati o se ne va | Provider |
inbound.announcedLa merce è in arrivo da te | Attivo |
inbound.updatedTracking, FNSKU, external id o righe modificati | Attivo |
inbound.cancelledAnnullato, spostato o annunciato di nuovo | Attivo |
inbound.restoredUn inbound annullato è di nuovo attivo | Attivo |
inbound.receivedEco del tuo ricevimento | Opt-in |
outbound.recordedEco del tuo outbound | Opt-in |
ping“Invia test” da ProfitDesk | Software proprio |
Documentazione per il tuo software
FAQ
Domande degli sviluppatori
Se gestisci un tuo software di magazzino per la tua attività su Amazon, usa la connessione per software proprio nelle impostazioni di ProfitDesk. Se sviluppi software usato da molti prep center o seller, registrati come provider prep: un endpoint e una chiave coprono ogni seller.
Con il tuo software usa un magazzino di test e un acquisto di test nel tuo account, e “Invia test” per verificare la connessione. Come provider prep, chiedici una connessione di test da un account seller di test e prova l’intero flusso prima che si colleghi il tuo primo seller reale. Gli eventi si possono sempre rieseguire.
La merce viene annunciata appena esiste l’inserzione su Amazon. Amazon assegna l’FNSKU poco dopo, e arriva in inbound.updated.
ProfitDesk riprova per un massimo di 72 ore. Dopodiché puoi recuperare in qualsiasi momento con GET /v1/prep/events.
No. Gli outbound sono una traccia. Le quantità inoltrate provengono dai dati di spedizione di Amazon, collegati tramite l’ID della spedizione FBA che invii.
Sì. Fai polling su GET /v1/prep/events ogni minuto a partire dall’ultimo id evento elaborato e deduplica per id.
Sviluppi software prep
per più seller?
Fatti inserire nel selettore dei prep center di ogni seller ProfitDesk. Un endpoint e una chiave li coprono tutti.
support@profitpath.com