Open Application Platform Docs

Webhooks

Verifying the events Superroute sends about deposits and pickups.

Events

Event Meaning
partner_locker.delivery.doors_opened Compartment doors were opened for a delivery.
partner_locker.delivery.delivered A delivery was confirmed into the lockers. Carries the pickup code and the compartments.
partner_locker.pickup.completed The recipient collected the delivery.
partner_locker.delivery.failed A delivery failed.
partner_locker.delivery.expired A delivery expired.
partner_locker.delivery.cancelled A delivery was cancelled.
partner_locker.delivery.correction_reopened Compartments were reopened to correct a delivery.
partner_locker.delivery.code_rotated An access or pickup code was replaced.

The carrier_package.distribution.* events of the carrier channel are verified the same way.

Verification

Verify every webhook against the raw body exactly as received, before parsing it. sLocker checks the timestamp (5 minutes either way by default), the X-Webhook-Content-Digest header and the X-Webhook-Signature header, and returns the event.

// JavaScript / TypeScript (Express)
import { verifyWebhook, WebhookVerificationError } from '@superrouteca/slocker';

app.post('/webhooks/slocker', express.raw({ type: '*/*' }), async (req, res) => {
  try {
    const event = await verifyWebhook(req.body, req.headers, [process.env.SLOCKER_SECRET, process.env.SLOCKER_OLD_SECRET]);
    if (!event.test) await queue.add(event.eventId, event);
    res.sendStatus(204);
  } catch (e) {
    if (e instanceof WebhookVerificationError) return res.status(400).send(e.reason);
    throw e;
  }
});

Each language

Language Verify Sign a test request
JavaScript / TypeScript await verifyWebhook(body, headers, secrets) await signWebhook(secret, body)
Python slocker.verify(body, headers, secrets) slocker.sign(secret, body)
PHP Webhooks::verify(file_get_contents('php://input'), getallheaders(), $secrets) Webhooks::sign($secret, $body)
Java / Kotlin Webhooks.verify(body, headers, secrets) Webhooks.sign(...)
Go slocker.Verify(body, slocker.HeaderMap(r.Header), secrets, nil) slocker.Sign(secret, body, slocker.SignOptions{})
C# / .NET Webhooks.Verify(body, headers, secrets) Webhooks.Sign(secret, body)
Dart / Flutter verifyWebhook(bodyBytes, headers, secrets) signWebhook(secret, bodyBytes)
Swift try Webhooks.verify(body:headers:secrets:) Webhooks.sign(secret:body:)
# Python
import slocker

event = slocker.verify(request.get_data(), dict(request.headers), [secret, old_secret])
// PHP
use Superroute\SLocker\Webhooks;

$event = Webhooks::verify(file_get_contents('php://input'), getallheaders(), [$secret, $oldSecret]);
// Go
event, err := slocker.Verify(body, slocker.HeaderMap(r.Header), []string{secret, oldSecret}, nil)
// C# / .NET
var webhookEvent = Webhooks.Verify(body, headers, new[] { secret, oldSecret });

A refused webhook raises an error with one of these reasons: