POS Webhooks
Real-time notifications for POS events via webhooks. Subscribe to events like ticket updates to keep your system synchronized with the POS.
Overview
POS webhooks (subscriptions) provide real-time notifications when specific events occur in the POS system. Instead of polling for changes, your application receives HTTP POST requests containing event data.
Benefits:
- Real-time Updates - Receive notifications within seconds of events
- Reduced API Calls - No need to poll for changes
- Efficient Synchronization - Keep systems in sync automatically
- Event-Driven Architecture - Build responsive integrations
Authentication
To verify that webhook payloads are genuinely from Shift4 and haven't been tampered with, you must implement HMAC authentication.
HMAC Signature Verification
HMAC (Hash-based Message Authentication Code) constructs an information-rich header that ensures the request:
- Actually comes from Shift4
- Has not been forged
- Has not been tampered with in transit
For detailed information on implementing HMAC authentication for webhooks, see the Overview Subscriptions documentation.
Quick Reference
Each webhook request includes HMAC headers:
x-signature- The HMAC signature to verifyx-timestamp- Unix timestamp of the requestx-access-key- Your client ID
Verification steps:
- Extract the request body and headers
- Construct the signature string using method, path, body, and timestamp
- Generate HMAC-SHA256 signature using your secret key
- Compare generated signature with
x-signatureheader - Reject request if signatures don't match
Available Subscriptions
Batch Ticket Updated
Notification when POS tickets are created or updated.
Event: pos.BatchTicket.updated
Availability: SkyTab POS only
Batch Ticket Updated
Receives notifications whenever tracked ticket fields are created or changed in the POS. Notifications are delivered near real-time, with up to a 3-minute delay.
Availability
Note: This subscription is currently available only for SkyTab POS. All other POS systems are not yet supported.
Tracked Fields
The following fields and objects trigger notifications when changed:
Ticket Fields
| Field | Description |
|---|---|
posRef | POS reference ID |
locationId | Location identifier |
orderNumber | Order number |
openedAt | When ticket was opened |
closedAt | When ticket was closed |
guestCount | Number of guests |
orderTypeName | Type of order |
orderTypeRef | Order type reference |
type | Ticket type (sale, void, refund, overring) |
openedByEmployeeRef | Employee who opened ticket |
totalItems | Total items amount |
totalTax | Total tax amount |
totalGrand | Grand total |
totalDiscounts | Total discounts |
totalSurcharges | Total surcharges |
totalGratuities | Total gratuities |
tableName | Table name |
tableRef | Table reference |
ticketSpecialRequests | Special requests |
TicketItem Fields
| Field | Description |
|---|---|
name | Item name |
price | Item price |
type | Item type |
quantity | Quantity |
kitchenSentAt | When sent to kitchen |
isOnHold | Whether item is on hold |
ticketSpecialRequests | Item special requests |
TicketItemModifier Fields
| Field | Description |
|---|---|
name | Modifier name |
price | Modifier price |
type | Modifier type |
quantity | Quantity |
TicketPayments Fields
| Field | Description |
|---|---|
amount | Payment amount |
tipAmount | Tip amount |
tenderName | Payment method name |
Webhook Payload
When a ticket is created or any tracked field is updated, you'll receive a webhook with the event details and an array of affected ticket references.
Event Structure:
name- Event identifiercomponent- Always "pos"resource- Always "BatchTicket"action- Always "updated"version- API versionsubscriptionId- Your subscription IDdispatchedAt- When webhook was sent
Payload Structure:
tickets- Array of ticket references
Each ticket reference contains:
locationId- Location identifierposRef- Ticket POS reference
Webhook Payload
{
"event": {
"name": "pos.BatchTicket.updated",
"component": "pos",
"resource": "BatchTicket",
"action": "updated",
"version": "v2",
"subscriptionId": 51,
"dispatchedAt": "2023-05-08T11:01:41.592Z"
},
"payload": {
"tickets": [
{
"locationId": 2,
"posRef": "3ba13095-93c2-48cc-87d3-e5a8cc21115f"
},
{
"locationId": 2,
"posRef": "677f9395-32bf-40cc-81fc-c43d59d7f289"
},
{
"locationId": 1,
"posRef": "7840c2dc-4d8f-47ad-97dd-f5fe54942920"
}
]
}
}
Processing Webhooks
When you receive a webhook:
- Verify Signature - Always verify the HMAC signature before processing
- Extract Ticket References - Get the array of affected tickets
- Fetch Full Data - Use the Ticket Lookup API to get full ticket details:
curl -X POST https://conecto-api.shift4payments.com/pos/v2/lookup/tickets \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"filter": {
"refs": [
{
"locationId": 2,
"posRef": "3ba13095-93c2-48cc-87d3-e5a8cc21115f"
}
]
}
}'
- Update Your System - Process the ticket data and update your system
- Return 200 OK - Acknowledge receipt within 30 seconds
Webhook Delivery
Timing:
- Near real-time delivery (up to 3-minute delay)
- Multiple tickets may be batched in a single webhook
Retries:
- Failed deliveries are retried with exponential backoff
- Return 200 OK within 30 seconds to avoid retries
- After multiple failures, subscription may be disabled
Best Practices:
- Process webhooks asynchronously (queue for background processing)
- Return 200 OK immediately, process later
- Implement idempotency (handle duplicate deliveries)
- Log all webhook receipts for debugging
Webhook Response
Your webhook endpoint must:
- Verify HMAC Signature - Reject requests with invalid signatures
- Return 200 OK - Within 30 seconds
- Process Asynchronously - Don't block the webhook response
Successful Response
Return HTTP 200 with an empty body or simple acknowledgment.
Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"received": true
}
Best Practices
- Name
Signature Verification- Description
Always verify HMAC signatures before processing webhooks. Reject any requests with invalid or missing signatures to prevent unauthorized access.
- Name
Asynchronous Processing- Description
Queue webhooks for background processing and return 200 OK immediately. Don't perform time-consuming operations in the webhook handler.
- Name
Idempotency- Description
Handle duplicate webhook deliveries gracefully. Use the ticket references to check if you've already processed the update.
- Name
Error Handling- Description
If processing fails, don't return an error to avoid retries. Log the error and handle it separately. Return 200 OK to acknowledge receipt.
- Name
Batch Processing- Description
A single webhook may contain multiple ticket references. Process them efficiently in batch rather than one at a time.
- Name
Monitoring- Description
Monitor webhook delivery and processing. Track failed verifications, processing errors, and delivery delays.
- Name
Timeout Handling- Description
Ensure your endpoint responds within 30 seconds. Use timeouts on external API calls to prevent blocking.