Skip to main content
DrapierDrapier

Webhook Events

Planned publisher-facing webhook events for real-time commission and invoice notifications.

How commissions are created today

When a customer completes a purchase on a storefront with Drapier app installed, the order is automatically checked for click attribution. If a valid click ID is found, commissions are created in real time for the attributed publisher. Cancelled orders automatically reverse any associated commissions.

You don't need to do anything to trigger this — it happens automatically on the storefront side.

Publisher-facing webhooks (planned)

Publisher webhooks are planned but not yet implemented. The events and payload formats below represent the target design. Until launch, use the Commissions API and Click Statistics API to poll for updates.

Planned events

EventTrigger
commission.createdA new commission is created from a tracked sale
commission.status_changedA commission transitions between lifecycle states
commission.reversedA commission is reversed (refund, cancellation, or fraud)
invoice.generatedYour monthly invoice is created and ready for review
invoice.paidPayment for an invoice has been processed

Planned payload format

Every webhook POST will carry a JSON body with a consistent envelope:

{
  "event": "commission.created",
  "timestamp": "2026-03-15T10:30:00Z",
  "data": {
    "id": "comm_abc123",
    "orderId": "ORD-1234",
    "orderName": "#1234",
    "productTitle": "Gucci Marmont Bag",
    "salePrice": 1200.00,
    "commissionAmount": 240.00,
    "status": "PENDING",
    "currency": "USD"
  }
}

commission.status_changed

{
  "event": "commission.status_changed",
  "timestamp": "2026-03-16T08:00:00Z",
  "data": {
    "id": "comm_abc123",
    "orderId": "ORD-1234",
    "previousStatus": "PENDING",
    "newStatus": "APPROVED",
    "commissionAmount": 240.00,
    "currency": "USD"
  }
}

commission.reversed

{
  "event": "commission.reversed",
  "timestamp": "2026-03-18T14:22:00Z",
  "data": {
    "id": "comm_abc123",
    "orderId": "ORD-1234",
    "reason": "order_refunded",
    "commissionAmount": 240.00,
    "currency": "USD"
  }
}

invoice.generated

{
  "event": "invoice.generated",
  "timestamp": "2026-04-01T00:05:00Z",
  "data": {
    "id": "inv_2026_03",
    "period": "2026-03",
    "totalAmount": 3420.00,
    "commissionCount": 47,
    "currency": "USD",
    "dueDate": "2026-04-15"
  }
}

invoice.paid

{
  "event": "invoice.paid",
  "timestamp": "2026-04-15T09:00:00Z",
  "data": {
    "id": "inv_2026_03",
    "totalAmount": 3420.00,
    "currency": "USD",
    "paidAt": "2026-04-15T09:00:00Z",
    "paymentMethod": "bank_transfer"
  }
}

Planned: verifying webhook signatures

When publisher webhooks launch, every webhook will include an X-IN-Signature header containing an HMAC-SHA256 signature of the raw request body, signed with your webhook secret.

Node.js

import crypto from "node:crypto";

function verifySignature(body, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(body, "utf8")
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Python

import hashlib
import hmac

def verify_signature(body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(), body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

Planned: retry policy

AttemptDelay
1st retry1 minute
2nd retry5 minutes
3rd retry30 minutes

After 3 failed retries the delivery will be marked as failed and visible in the dashboard.

Best practices

  • Respond with 200 immediately when publisher webhooks launch. Perform heavy processing asynchronously.
  • Handle duplicate deliveries. Use the data.id field as an idempotency key.
  • Log raw payloads. Store the raw JSON body before processing so you can replay events if your handler has a bug.
  • Use HTTPS. Webhook URLs must use TLS.

On this page