Tutorial: Subscribing to Shipment Webhooks
Cosmo Cargo sends an HTTP POST request to your server when something happens to a shipment: shipment.created, shipment.delivered and the other events you register for with POST /webhooks.
Always verify the HMAC SHA-256 signature on incoming webhooks to ensure payloads originate from Cosmo Cargo.
Verifying Webhook Signatures
Section titled “Verifying Webhook Signatures”Each webhook request includes a header named CosmoCargo-Signature:
CosmoCargo-Signature: t=1697621400,v1=92f98e826b14a273b027cf8f4cbb23...Verify the signature using your webhook signing secret:
import crypto from "node:crypto";
export function verifyCosmoCargoWebhook(rawBody, signatureHeader, secret) { const parts = Object.fromEntries( signatureHeader.split(",").map(p => p.split("=")) ); const timestamp = parts.t; const signature = parts.v1;
const signedPayload = `${timestamp}.${rawBody}`; const expectedSignature = crypto .createHmac("sha256", secret) .update(signedPayload) .digest("hex");
return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expectedSignature) );}import hmacimport hashlib
def verify_cosmo_cargo_webhook(raw_body: str, signature_header: str, secret: str) -> bool: parts = dict(item.split("=") for item in signature_header.split(",")) timestamp = parts["t"] signature = parts["v1"]
signed_payload = f"{timestamp}.{raw_body}".encode("utf-8") expected_sig = hmac.new(secret.encode("utf-8"), signed_payload, hashlib.sha256).hexdigest()
return hmac.compare_digest(signature, expected_sig)