Skip to content

Webhooks

Note

This functionality is exclusively accessible with paid subscriptions. Verify whether your plan includes this feature, upgrade if necessary, or reach out to us for assistance.

When incorporating Oveit integrations, you may want your applications to promptly
receive events as they transpire in your Oveit accounts. This allows your backend
systems to execute corresponding actions.

To activate webhook events, the process involves registering webhook endpoints. Once
registered, Oveit can push real-time event data to the designated webhook endpoint of
your application whenever events occur in your Oveit account. Oveit utilizes HTTPS to
transmit webhook events to your app, delivering them in the form of a JSON payload
that encompasses an event object.

Receiving webhook events proves particularly beneficial for monitoring asynchronous
occurrences, such as when an order is placed, an attendee completes a registration form,
or an invoice is issued.

Event Overview

Oveit produces event data that we can transmit to keep you informed of activities within
your account. Each time an event takes place, Oveit generates a new event object (see below).

By enlisting webhook endpoints in your Oveit account, you empower Oveit to
autonomously dispatch event objects via POST requests to the designated webhook
endpoint hosted by your application. Once your webhook endpoint receives the event,
your application can execute backend actions, such as invoking your CRM APIs to store
customer information upon receiving an "order.create" event.

Event Trigger Event object
order.place When an order is placed and awaits payment confirmation (bank transfer, house account) order (see below)
order.create When an order is completed (paid, tickets issued) order (see below)
order.cancel When an order is canceled (manually by an operator or after a failed or canceled payment) order (see below)
ticket.create When a ticket is issued ticket (see below)
ticket.update When a registration form is changed ticket (see below)
pms.reservation.update When Oveit syncs a reservation from a connected PMS ( create or update ) reservation (varies by PMS)
payment.create When a payment on a house account order is confirmed (bank transfer or check recorded, Shift4 card or payment link charge confirmed) payment, order (see below)
payment.cancel When a recorded bank transfer or check on a house account order is voided payment, order (see below)
payment.refund When a payment is refunded, in full or in part (see scope) payment, refund, order (see below)

Payment events are new and opt-in: existing webhooks only receive them once you select them on the webhook. To read recent payments in the same shape without waiting for an event, use List payments.

Let's get started

Log in to your account and navigate to the Webhooks section within the Apps panel. From there, you can create a new webhook by entering your webhook callback URL and choosing the events you wish to monitor.

Ensure the Security of Your Webhooks

Once you've confirmed that your webhook endpoint connection functions as expected,
enhance the security of the connection by implementing best practices outlined in the
section below.

One crucial best practice involves using webhook signatures to validate that Oveit
generated the webhook request and that it didn't originate from a server posing as
Oveit.

Event Delivery Behaviors

Retry Behavior

Oveit makes attempts to deliver a specific event to your webhook endpoint for up to 2
days at intervals of 1 minute, 10 minutes, 30 minutes, 1 hour, 2 hours, 6 hours, 12 hours,
18 hours, 24 hours, 36 hours, 48 hours, or until the endpoint responds with a 200 HTTP
status code.

Disable Behavior

Oveit endeavors to notify you of a misconfigured endpoint via email if the endpoint
hasn't responded with a 200 HTTP status code for multiple consecutive days and also it will be automatically disabled.

Best Practices for Using Webhooks

Handle Duplicate Events

Webhook endpoints may occasionally receive the same event more than once. One
approach is to log the events you've processed and avoid processing events that have
already been logged. Every event has an unique uuid identifier.

Only Listen to Event Types Your Integration Requires

Configure your webhook endpoints to receive only the necessary event types for your
integration. Listening to extra events (or all events) can strain your server unnecessarily,
and it is not recommended.

Receive Events with an HTTPS Server

If you use an HTTPS URL for your webhook endpoint, Oveit validates that the connection
to your server is secure before transmitting your webhook data. Your server must be
properly configured to support HTTPS with a valid server certificate for this to work.

Verify Events Are Sent from Oveit

Authenticate the origin of received events from Oveit by confirming webhook signatures. Oveit secures webhook events sent to your endpoints by appending two headers to each event: a signature header named Oveit-WH-Signature and a timestamp header named Oveit-WH-Signature-Timestamp. This setup enables you to validate the authenticity of the events, ensuring they are genuinely dispatched by Oveit and not manipulated by a third party.

To verify, generate an HMAC (Hash-based Message Authentication Code) signature. This process involves hashing a combination of the payload and timestamp using the webhook secret key from the Dashboard. As the timestamp is a crucial element of the signed payload, any tampering by an attacker would invalidate the signature. If the signature is correct but the timestamp is excessively outdated, your application retains the option to reject the payload. Consider allowing a tolerance of 5 to 10 minutes between the timestamp and the current time.

Retrieve Your Endpoint's Secret

Navigate to the Webhooks section of the Dashboard. Choose the specific endpoint for
which you want to acquire the secret and locate the secret.
Oveit generates a distinctive secret key for each endpoint. In case you utilize multiple
endpoints, you need to procure a secret for each one that requires signature
verification. Oveit then begins signing each webhook it dispatches to the respective
endpoint.

Event Object

{
  "data": {

  },
  "version": "1.0",
  "event_id": "54d6f3cc-6901-4897-8b89-6fa3cb9f8419",
  "event_type": "ticket.create"
}

Order Data Object

{
    "order": {
    "id": 1,
    "uuid": "e0847e21-21ab-4096-89ae-3819fd42026e",
    "date": "2024-01-10T18:48:51+02:00",
    "date_formatted": "Jan 10, 2024, at 18:48",
    "language": "en",
    "currency": "USD",
    "payment_processor": null,
    "status": "Completed",
    "is_canceled": false,
    "cancellation_date": null,
    "pending_reason": null,
    "email": "[email protected]",
    "items": [
      {
        "name": "Event with Registration Form (VIP Ticket)",
        "quantity": "2",
        "currency": "USD",
        "type": "ticket",
        "price_without_tax": "8.40",
        "price_tax": "3.19",
        "fee_without_tax": "0.84",
        "fee_tax": "0.32",
        "discount": "0.00",
        "final_price": "11.00",
        "event": {
          "name": "Event with Registration Form",
          "hash": "e3aefd2bf9",
          "location": "Studio4",
          "has_venue": false,
          "starts_at": null,
          "ends_at": null,
          "is_perpetual": true
        },
        "ticket_type": {
          "name": "VIP Ticket",
          "has_nft": false,
          "is_seatless": false
        }
      },
      {
        "name": "Mango",
        "quantity": "3",
        "currency": "USD",
        "type": "addon",
        "price_without_tax": "8.40",
        "price_tax": "4.79",
        "fee_without_tax": "0.84",
        "fee_tax": "0.48",
        "discount": "0.00",
        "final_price": "11.00",
        "event": {
          "name": "Event with Registration Form",
          "hash": "e3aefd2bf9",
          "location": "Studio4",
          "has_venue": false,
          "starts_at": null,
          "ends_at": null,
          "is_perpetual": true
        },
        "ticket_type": {
          "name": "VIP Ticket",
          "has_nft": false,
          "is_seatless": false
        }
      },
      {
        "name": "Shirt",
        "quantity": "3",
        "currency": "USD",
        "type": "addon",
        "price_without_tax": "16.81",
        "price_tax": "9.58",
        "fee_without_tax": "1.68",
        "fee_tax": "0.96",
        "discount": "0.00",
        "final_price": "22.00",
        "event": {
          "name": "Event with Registration Form",
          "hash": "e3aefd2bf9",
          "location": "Studio4",
          "has_venue": false,
          "starts_at": null,
          "ends_at": null,
          "is_perpetual": true
        },
        "ticket_type": {
          "name": "VIP Ticket",
          "has_nft": false,
          "is_seatless": false
        }
      },
      {
        "name": "Hat",
        "quantity": "8",
        "currency": "USD",
        "type": "addon",
        "price_without_tax": "12.61",
        "price_tax": "19.16",
        "fee_without_tax": "1.26",
        "fee_tax": "1.92",
        "discount": "0.00",
        "final_price": "16.50",
        "event": {
          "name": "Event with Registration Form",
          "hash": "e3aefd2bf9",
          "location": "Studio4",
          "has_venue": false,
          "starts_at": null,
          "ends_at": null,
          "is_perpetual": true
        },
        "ticket_type": {
          "name": "VIP Ticket",
          "has_nft": false,
          "is_seatless": false
        }
      },
      {
        "name": "Virtual wallet credit (VIP Ticket)",
        "quantity": "1",
        "currency": "USD",
        "type": "wallet_credit",
        "price_without_tax": "84.03",
        "price_tax": "15.97",
        "fee_without_tax": "0.00",
        "fee_tax": "0.00",
        "discount": "0.00",
        "final_price": "100.00",
        "event": {
          "name": "Event with Registration Form",
          "hash": "e3aefd2bf9",
          "location": "Studio4",
          "has_venue": false,
          "starts_at": null,
          "ends_at": null,
          "is_perpetual": true
        },
        "ticket_type": {
          "name": "VIP Ticket",
          "has_nft": false,
          "is_seatless": false
        }
      },
      {
        "name": "Virtual wallet credit (VIP Ticket)",
        "quantity": "1",
        "currency": "USD",
        "type": "wallet_credit",
        "price_without_tax": "16.81",
        "price_tax": "3.19",
        "fee_without_tax": "0.00",
        "fee_tax": "0.00",
        "discount": "0.00",
        "final_price": "20.00",
        "event": {
          "name": "Event with Registration Form",
          "hash": "e3aefd2bf9",
          "location": "Studio4",
          "has_venue": false,
          "starts_at": null,
          "ends_at": null,
          "is_perpetual": true
        },
        "ticket_type": {
          "name": "VIP Ticket",
          "has_nft": false,
          "is_seatless": false
        }
      }
    ],
    "customer": {
      "name": "Oveit Developer",
      "is_company": false,
      "tax_code": null,
      "address": "115 Wild Basin Rd. S Ste 307",
      "city": "Austin",
      "state": "Texas",
      "state_code": "TX",
      "country": "United States",
      "country_code": "US"
    },
    "customer_form": [
      {
        "name": "Type",
        "value": "Online"
      }
    ],
    "tickets": [
      {
        "id": 1,
        "code": "9bab7e36",
        "event": {
          "name": "Event with Registration Form",
          "hash": "e3aefd2bf9",
          "location": "Studio4",
          "has_venue": false,
          "starts_at": null,
          "ends_at": null,
          "is_perpetual": true
        },
        "ticket_type": {
          "name": "VIP Ticket",
          "has_nft": false,
          "is_seatless": false
        },
        "series": "DDD 16",
        "seat": null,
        "registration_form": [
          {
            "name": "Name",
            "value": "Oveit Attendee"
          },
          {
            "name": "Position",
            "value": "Developer"
          }
        ],
        "wallet_credit": {
          "amount": "100.00",
          "currency": "USD"
        },
        "addons": [
          {
            "name": "Beer",
            "uses": 2
          },
          {
            "name": "Mango",
            "uses": 2
          },
          {
            "name": "Shirt",
            "uses": 1
          },
          {
            "name": "Hat",
            "uses": 5
          }
        ]
      },
      {
        "id": 2,
        "code": "958f5916",
        "event": {
          "name": "Event with Registration Form",
          "hash": "e3aefd2bf9",
          "location": "Studio4",
          "has_venue": false,
          "starts_at": null,
          "ends_at": null,
          "is_perpetual": true
        },
        "ticket_type": {
          "name": "VIP Ticket",
          "has_nft": false,
          "is_seatless": false
        },
        "series": "DDD 17",
        "seat": null,
        "registration_form": [
          {
            "name": "Name",
            "value": "Oveit Attendee2"
          },
          {
            "name": "Position",
            "value": "Developer"
          }
        ],
        "wallet_credit": {
          "amount": "20.00",
          "currency": "USD"
        },
        "addons": [
          {
            "name": "Beer",
            "uses": 2
          },
          {
            "name": "Mango",
            "uses": 1
          },
          {
            "name": "Shirt",
            "uses": 2
          },
          {
            "name": "Hat",
            "uses": 3
          }
        ]
      }
    ],
    "invoice": [
      {
        "name": "Invoice - Oveit Developer - Nr. OVEIT 001",
        "number": "OVEIT 1",
        "items": [
          {
            "name": "Event with Registration Form (VIP Ticket)",
            "quantity": 2,
            "currency": "USD",
            "unit_net_price": "8.40",
            "unit_tax_price": "1.60",
            "total_price": "20.00"
          },
          {
            "name": "Mango",
            "quantity": 3,
            "currency": "USD",
            "unit_net_price": "8.40",
            "unit_tax_price": "1.60",
            "total_price": "30.00"
          },
          {
            "name": "Shirt",
            "quantity": 3,
            "currency": "USD",
            "unit_net_price": "16.81",
            "unit_tax_price": "3.19",
            "total_price": "60.00"
          },
          {
            "name": "Hat",
            "quantity": 8,
            "currency": "USD",
            "unit_net_price": "12.61",
            "unit_tax_price": "2.39",
            "total_price": "120.00"
          },
          {
            "name": "Virtual wallet credit (VIP Ticket)",
            "quantity": 1,
            "currency": "USD",
            "unit_net_price": "84.03",
            "unit_tax_price": "15.97",
            "total_price": "100.00"
          },
          {
            "name": "Virtual wallet credit (VIP Ticket)",
            "quantity": 1,
            "currency": "USD",
            "unit_net_price": "16.81",
            "unit_tax_price": "3.19",
            "total_price": "20.00"
          },
          {
            "name": "Online processing fee",
            "quantity": 1,
            "currency": "USD",
            "unit_net_price": "19.33",
            "unit_tax_price": "3.67",
            "total_price": "23.00"
          }
        ],
        "statements": [
          "VAT exempt, according to Directive 2006/112/EC"
        ],
        "download_link": "https://l.oveit.com/orders/download_invoice",
        "currency": "USD",
        "net_price": "313.45",
        "tax_price": "59.55",
        "total_price": "373.00",
        "is_canceled": false,
        "is_paid": true,
        "is_reversed": false,
        "is_reverse": false,
        "status": "paid"
      }
    ]
  }
}

Tickets on order.place

On order.place, tickets are not issued yet. The tickets array lists the tickets the order will issue once payment is confirmed (one entry per ticket), with the same properties as on order.create, so registration forms are always read from tickets[].registration_form. Properties that only exist once a ticket is issued are empty: id, code and series are null, and download_link is empty. When the order is completed, order.create sends the issued tickets in the same order.

"tickets": [
  {
    "id": null,
    "code": null,
    "cancelled": false,
    "event": {
      "name": "Event with Registration Form",
      "hash": "e3aefd2bf9",
      "location": "Studio4",
      "has_venue": false,
      "starts_at": null,
      "ends_at": null,
      "is_perpetual": true
    },
    "ticket_type": {
      "name": "VIP Ticket",
      "has_nft": false,
      "is_seatless": false,
      "id": 10
    },
    "series": null,
    "seat": null,
    "registration_form": [
      {
        "name": "Name",
        "value": "Oveit Attendee"
      },
      {
        "name": "Position",
        "value": "Developer"
      }
    ],
    "wallet_credit": null,
    "addons": null,
    "date": null,
    "time_start": null,
    "time_end": null,
    "download_link": []
  }
]

Tickets on order.cancel

On order.cancel, status is canceled, is_canceled is true and cancellation_date holds the moment the order was canceled. Every ticket has cancelled: true and an empty download_link.

  • If the order was completed, tickets lists the issued tickets, as on order.create.
  • If the order was canceled while awaiting payment, no ticket was issued and tickets lists the same entries as on order.place. Seats.io seats are released on cancellation, so their seat is null.

Each issued ticket of the canceled order is also sent as a ticket.update event.

Payment Data Object

payment.create, payment.cancel and payment.refund send the payment, its order and, on payment.refund only, the refund that was just made. The payment is always in its current state, so an event that arrives out of order can be handled by looking at payment.status.

payment.create for a bank transfer or check recorded on a house account order:

{
  "payment": {
    "id": 123,
    "source": "house_account",
    "processor": null,
    "method": "bank_transfer",
    "status": "successful",
    "amount": "50.00",
    "refunded_amount": "0.00",
    "currency": "EUR",
    "reference": "TRX-1",
    "created_at": "2026-11-05T10:00:00+02:00",
    "updated_at": "2026-11-05T10:00:00+02:00"
  },
  "order": {
    "id": 1,
    "uuid": "e0847e21-21ab-4096-89ae-3819fd42026e",
    "status": "pending_payment",
    "...": "same properties as the order data object"
  }
}

payment.refund for a partial refund of an online order paid by card through Shift4:

{
  "payment": {
    "id": 77,
    "source": "online",
    "processor": "shift4",
    "method": "card",
    "status": "partially_refunded",
    "amount": "119.00",
    "refunded_amount": "20.00",
    "currency": "EUR",
    "reference": "char_3d8fa1b2c4e5",
    "created_at": "2026-10-01T09:00:00+03:00",
    "updated_at": "2026-11-05T12:00:00+02:00"
  },
  "refund": {
    "amount": "20.00",
    "currency": "EUR",
    "type": "partial",
    "notes": "Parking was closed",
    "credit_note_id": 901,
    "refunded_at": "2026-11-05T12:00:00+02:00"
  },
  "order": {
    "id": 2,
    "uuid": "6f1c2a9e-0d5b-4c1e-9a43-2b7e8f0c1d22",
    "status": "complete",
    "...": "same properties as the order data object"
  }
}

Payment properties

Property Description
id Payment id. It is unique only within its source: identify a payment by source and id together.
source house_account for payments collected on a house account order, online for orders paid at checkout.
processor shift4, or null for bank transfers and checks, which are not collected through a processor.
method bank_transfer, check, shift4_card or shift4_payment_link on house account orders; card on online orders.
status successful, canceled (a voided bank transfer or check), refunded or partially_refunded.
amount Amount paid, as a string with two decimals.
refunded_amount Total refunded so far on this payment. 0.00 when nothing was refunded.
currency ISO 4217 currency code.
reference Bank transfer or check reference entered by the operator, or the Shift4 charge id. Can be null.
created_at, updated_at ISO 8601 dates, in the same timezone as the order date (the event timezone, or the organizer timezone for orders without a single event).

New values may be added to source, processor and method as more payment processors are covered, so do not reject values you do not recognize.

Refund properties

refund is present only on payment.refund and describes the refund that triggered the event.

Property Description
amount, currency What went back to the customer in this refund.
type full when the payment has nothing left to refund (its status is refunded), partial otherwise (its status is partially_refunded).
notes The reason entered when refunding an online order. null on house account refunds.
credit_note_id Id of the credit note issued for an online refund. null on house account refunds, which do not issue one.
refunded_at ISO 8601 date of the refund, in the same timezone as the payment dates.

Order on payment events

order has the same properties as on the other order events. House account orders are usually still awaiting payment when their payments change, so tickets lists the tickets the order will issue, as on order.place (see above).

When a payment completes an order, order.create is sent as well. If canceling an order refunds a payment covered below, both order.cancel and payment.refund are sent.

Payment events scope

  • payment.create and payment.cancel cover house account orders only. Online orders keep using order.create (money in) and order.cancel (money out).
  • On house account orders, payment.create is sent when an operator records a bank transfer or check, and when a Shift4 card or payment link charge is confirmed (once, even if the confirmation reaches us twice). payment.cancel is sent when an operator voids a recorded bank transfer or check.
  • House account payment.refund is sent when a confirmed Shift4 card or payment link payment is refunded. These refunds are always full.
  • Online payment.refund covers Shift4 only: it is sent when an invoice of an order paid through Shift4 is refunded in full or in part from the order page.

No payment event is sent for:

  • Retail Cloud (Box Office POS) tenders.
  • Failed, abandoned or pending payment attempts.
  • Other payment processors (JCC, Callpay, Crypto.com, Stripe, PayPal and others), including the refunds they make when an order is canceled or an invoice is reversed.
  • Refunds made directly in the Shift4 dashboard.

Ticket Data Object

{
  "ticket": {
    "id": 1,
    "code": "958f5916",
    "seat": null,
    "event": {
      "hash": "e3aefd2bf9",
      "name": "Event with registration form",
      "ends_at": null,
      "location": "Studio4",
      "has_venue": false,
      "starts_at": null,
      "is_perpetual": true
    },
    "series": "DDD 17",
    "ticket_type": {
      "name": "VIP Ticket",
      "has_nft": false,
      "is_seatless": false
    },
    "wallet_credit": {
      "amount": "100.00",
      "currency": "USD"
    },
    "addons": [
      {
        "name": "Beer",
        "uses": 2
      },
      {
        "name": "Mango",
        "uses": 2
      },
      {
        "name": "Shirt",
        "uses": 1
      },
      {
        "name": "Hat",
        "uses": 5
      }
    ],
    "registration_form": [
      {
        "name": "Name",
        "value": "Oveit Attendee2"
      },
      {
        "name": "Position",
        "value": "Developer"
      }
    ]
  }
}