Webhook Integration

SolaBill customer callbacks describe the exact Orchida-backed application evidence retained by SolaBill. They are not callbacks sent by Orchida and do not replace status reconciliation.

Current Events

EventMeaning
einvoice.submission.updatedAn Orchida submission or validation result was retained.
einvoice.status.changedAt least one provider-validation, Orchida invoice, tax-authority, or receiver state changed.
einvoice.terminalAll regulated outcome dimensions reached terminal states.
einvoice.incoming.receivedA new Orchida purchase document was retained.
einvoice.incoming.revisedOrchida supplied a changed revision of a retained purchase document.

Create subscriptions through POST /api/v1/webhooks/subscriptions. The destination must use HTTPS and cannot contain credentials, a query string, or a fragment. The signing secret is returned once. Deactivation retains the subscription and delivery evidence.

Headers

HeaderDescription
X-Webhook-EventExact event name.
X-Webhook-DeliveryStable event UUID; use it for idempotency.
X-Webhook-TimestampUTC ISO-8601 event time used in the signature base string.
X-Webhook-Signaturev1= followed by a lowercase HMAC SHA-256 digest.

Envelope

{
  "schema_version": "solabill-webhook-v2",
  "id": "stable-event-uuid",
  "event": "einvoice.status.changed",
  "resource_type": "submission",
  "resource_id": "123",
  "occurred_at": "2026-08-18T10:00:00+00:00",
  "payload": {
    "submission_state": "accepted_by_provider",
    "provider_invoice_state": "accepted",
    "tax_authority_state": "accepted",
    "receiver_state": "accepted"
  }
}

The provider-validation, top-level Orchida invoice, authority and receiver dimensions remain separate. Never infer network exchange, authority reporting or receiver acceptance from another state or HTTP 2xx.

Signature Verification Example (PHP)

$payload = file_get_contents('php://input');
$timestamp = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? '';
$provided = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$expected = 'v1='.hash_hmac('sha256', $timestamp.'.'.$payload, $secret);

if (! hash_equals($expected, $provided)) {
    http_response_code(401);
    exit('invalid signature');
}

Delivery Rules

  1. Respond with HTTP 2xx quickly after signature and timestamp validation.
  2. Process the event asynchronously in your application worker.
  3. Store event IDs to protect against duplicate callback retries.
  4. Retries occur only for transport errors, HTTP 408/409/425/429, and 5xx responses, with bounded exponential backoff.
  5. Redirects are not followed. A changed or unsafe destination is blocked and its subscription is deactivated.
  6. Continue periodic Orchida status reconciliation; a callback is notification, not the sole legal evidence source.