Webhooks¶
PharmaOne can POST JSON to your HTTPS URL when subscribed events occur.
Configure in Manager → Org Settings → Integrations → Webhook subscriptions (max 5 per org).
Inbound vs outbound
Webhooks are outbound from PharmaOne to your server. They are not part of the OpenAPI path list — document your receiver separately.
Subscription setup¶
- Create subscription with HTTPS URL (must return 2xx).
- Select event types (checkboxes in UI).
- Save the signing secret — shown once.
Use Send test event in the Manager UI to verify your endpoint.
Delivery request¶
POST https://your-server.example/webhooks/pharmaone
Content-Type: application/json
X-PharmaOne-Event: order_status_updated
X-PharmaOne-Delivery-Id: 3c0d62fb-c683-4644-a74c-9e3ad3d52622
X-PharmaOne-Signature: sha256=<hmac-sha256-hex-of-raw-body>
Headers¶
| Header | Description |
|---|---|
Content-Type |
application/json |
X-PharmaOne-Event |
Event type slug |
X-PharmaOne-Delivery-Id |
Unique delivery id (for idempotency) |
X-PharmaOne-Signature |
sha256= + HMAC-SHA256 hex of raw body |
Payload shape¶
{
"id": "uuid-event-id",
"org_id": "org1",
"event_type": "order_status_updated",
"title": "Order status updated",
"description": "Order ORD_20260605_abc123 updated via external API",
"metadata": {
"order_id": "ORD_20260605_abc123",
"old_status": "awaiting_packing",
"new_status": "ready_pickup"
},
"created_at": "2026-06-05T12:00:00Z"
}
Verify signature (Python)¶
import hmac
import hashlib
def verify(secret: str, raw_body: bytes, header_signature: str) -> bool:
expected = "sha256=" + hmac.new(
secret.encode(), raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(header_signature, expected)
Subscribable event types¶
Orders¶
| Event | Trigger |
|---|---|
order_created |
New order |
order_updated |
Order fields updated |
order_status_updated |
Status or flags changed (incl. external API PATCH) |
order_marked_paid |
Payment marked paid |
order_deleted |
Order deleted |
Order requests¶
| Event | Trigger |
|---|---|
order_request_submitted |
External order request received |
order_request_approved |
Staff approved request |
order_request_deleted |
Request deleted |
Prescriptions¶
| Event | Trigger |
|---|---|
prescription_approved |
Prescription approved |
paperless_signature_completed |
QES signature completed |
Products & stock¶
| Event | Trigger |
|---|---|
product_created |
Product created |
product_updated |
Product updated |
product_deleted |
Product deleted |
low_stock |
Stock below threshold |
out_of_stock |
Stock reached zero |
Payments¶
| Event | Trigger |
|---|---|
payment_link_created |
Payment link generated |
Retries¶
- Up to 3 delivery attempts with backoff.
- Failed deliveries logged per subscription (visible in Manager UI).
- Return 2xx quickly; process asynchronously if needed.
Local testing¶
Expose your local receiver with a tunnel (e.g. ngrok) and use the HTTPS URL when creating the subscription in Manager.
Example: order request submitted¶
{
"id": "3c0d62fb-c683-4644-a74c-9e3ad3d52622",
"org_id": "org1",
"event_type": "order_request_submitted",
"title": "Order request submitted",
"description": "External order request 7b8e6bef-… received",
"metadata": {
"order_request_id": "7b8e6bef-75e0-40ea-8168-de30d1329972",
"external_reference": "doc-example",
"shop_id": "shop1",
"source": "api-docs"
},
"created_at": "2026-06-06T00:27:41Z"
}