Conecta cualquier almacén a ProfitDesk.
La Prep API convierte tu software en un prep center dentro de ProfitDesk. Los avisos te llegan como webhooks firmados, tú devuelves recepciones y salidas, y cada unidad queda trazable desde la compra hasta el envío a FBA.
- Webhooks firmados
- REST API
- OpenAPI 3.1
- Reproducción de eventos
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 }]
}Dos formas de entrar
Una API, pensada para dos tipos de desarrolladores.
- 1Añade tu softwareAjustes → Integraciones → Prep centers → Añadir → «Software propio (Webhook)». Introduce tu endpoint HTTPS y elige los eventos que quieras.
- 2Guarda dos credencialesUn secreto de firma (whsec_…) y una clave de API (ppk_…), que se muestran una sola vez. Puedes rotar ambas cuando quieras.
- 3Vincula un almacénA partir de ahora, las compras de ese almacén se anuncian a tu software.
- La clave ve
- Solo esta conexión
- Límite de uso
- 2 req/s, ráfagas de 10
- Pruebas
- Ping «Enviar prueba» y registro de entregas
- Combínalo
- Junto a PrepBusiness o PrepTool, por almacén
Cómo funciona
De la compra al envío a FBA,
en cinco eventos.
- 01ProfitDeskLa mercancía está en camino
inbound.announcedUn webhook firmado con líneas, SKU, ASIN y seguimiento. Responde 2xx, opcionalmente con tu propio external_id. - 02ProfitDeskLlegan los detalles
inbound.updatedNuevos códigos de seguimiento y el FNSKU en cuanto Amazon lo asigna, para que puedas imprimir etiquetas. - 03TúCuentas la mercancía
POST …/receiptsRecuentos absolutos por línea, incluidas las unidades dañadas. ProfitDesk actualiza la compra. - 04TúLa envías
POST /v1/Las líneas más el ID del envío FBA vinculan tu salida con el envío de Amazon.prep/ outbounds - 05AmazonAmazon la recibe
FBA15XYZProfitDesk registra la cantidad reenviada a partir de los datos propios de Amazon. Tu salida es el rastro.
Cada unidad, trazable de principio a fin.
Cada objeto lleva un id con prefijo de tipo. El id de la compra nunca cambia, ni siquiera cuando la mercancía se vuelve a anunciar o cambia de almacén.
pur_4711CompraLa compra del vendedor. La clave para seguir una unidad, para siempre.inb_2000000123EntradaUn aviso. Un nuevo aviso genera una entrada nueva.inl_99Línea de entradaUna compra dentro de ella. Úsala en recepciones y salidas.out_55SalidaLo que has enviado, identificado con tu propio external_id.FBA15XYZEnvío FBAEl ID de envío de Amazon, vinculado desde tu salida.
Usa también tus propias referencias: cada ruta que acepta un id acepta además ext:<tu id>.
Hecho para producción
Las partes aburridas
ya están resueltas.
HMAC-SHA256 en una docena de líneas.
Firma el cuerpo sin procesar con tu secreto whsec_ y la marca de tiempo, compara en tiempo constante y rechaza todo lo que tenga más de cinco minutos. Durante una rotación de secreto se envían ambas firmas durante 24 horas.
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
}Endpoints
URL base https://api.profitpath.app · Bearer ppk_…
| GET | /v1/La conexión de la clave | La conexión de la clave |
| GET | /v1/Listar entradas | Listar entradas |
| GET | /v1/Una entrada, también por ext: | Una entrada, también por ext: |
| PUT | /v1/Define tu referencia | Define tu referencia |
| POST | /v1/Informar de mercancía recibida | Informar de mercancía recibida |
| POST | /v1/Informar de una salida | Informar de una salida |
| GET | /v1/Una salida | Una salida |
| GET | /v1/Artículos, uno por SKU | Artículos, uno por SKU |
| GET | /v1/Reproducir eventos de webhook | Reproducir eventos de webhook |
Eventos de webhook
Se entregan al menos una vez, en orden por entrada.
connection.created · updated · removedUn vendedor se conecta, cambia sus datos o se va | Proveedores |
inbound.announcedLa mercancía está en camino hacia ti | Activo |
inbound.updatedHan cambiado el seguimiento, el FNSKU, el id externo o las líneas | Activo |
inbound.cancelledCancelada, movida o anunciada de nuevo | Activo |
inbound.restoredUna entrada cancelada vuelve a estar activa | Activo |
inbound.receivedEco de tu propia recepción | Opcional |
outbound.recordedEco de tu propia salida | Opcional |
ping«Enviar prueba» desde ProfitDesk | Software propio |
Documentación para tu propio software
prep-v1.mdReferencia de la APICada endpoint, parámetro, respuesta y webhook, con ejemplos.ReferenceEsquemasCada objeto de la API, campo por campo. Genera un cliente a partir del archivo OpenAPI 3.1.prep-v1.openapi.yamlFAQ
Preguntas de desarrolladores
Si usas tu propio software de almacén para tu propio negocio en Amazon, utiliza la conexión de software propio en los ajustes de ProfitDesk. Si desarrollas software que usan muchos prep centers o vendedores, regístrate como proveedor de prep: un endpoint y una clave cubren a todos los vendedores.
Con tu propio software, usa un almacén de prueba y una compra de prueba en tu cuenta, y «Enviar prueba» para comprobar la conectividad. Como proveedor de prep, pídenos una conexión de prueba desde una cuenta de vendedor de prueba y ejecuta todo el flujo antes de que se conecte tu primer vendedor real. Los eventos siempre se pueden reproducir.
La mercancía se anuncia en cuanto existe el listing en Amazon. Amazon asigna el FNSKU un poco más tarde, y llega después en inbound.updated.
ProfitDesk reintenta durante hasta 72 horas. Después puedes ponerte al día cuando quieras con GET /v1/prep/events.
No. Las salidas son un rastro. Las cantidades reenviadas proceden de los datos de envío de Amazon, vinculados mediante el ID de envío FBA que mandas.
Sí. Consulta GET /v1/prep/events cada minuto a partir del último id de evento que hayas procesado, y deduplica por id.
¿Desarrollas software de prep
para muchos vendedores?
Aparece en el selector de prep centers de cada vendedor de ProfitDesk. Un endpoint y una clave los cubren a todos.
support@profitpath.com