Skip to main content

How to set up and use Invoice Webhooks

Invoice webhooks allow you to automatically send invoice data from bsport to another system (such as your accounting software or internal tools) whenever an invoice event occurs.

G
Written by Georges Pirini
Updated this week

What Is a Webhook?

A webhook is an automatic message sent from our system to another application whenever something important happens, like when an invoice is created or reverted. You receive these notifications instantly, allowing you to react in real time.

This allows you to:

  • Synchronise invoices with accounting tools

  • Trigger automations

  • Keep external systems updated in real time

Note: Webhooks require technical setup and are not plug-and-play features. Please make sure you have Software development knowledge before running through the end of this guide.


Before You Start

To use invoice webhooks, you must have a secure HTTPS endpoint (URL) capable of receiving POST requests with JSON data.

Step-by-Step Guide

  1. Once you have your endpoint ready, visit https://backoffice.bsport.io/settings/webhook.

  2. Click on the "Add a webhook" button

  3. Select the event you would like to subscribe (types of event listed here).

  4. Enter the URL you would like the webhook to send the message to.

  5. Click on confirm.

  6. You can now see your new webhook being created 🎉.

  7. (Optional) By clicking on the "Test" button, you can simulate an event to ensure your webhook is working.


Types of events

You can subscribe to different events related to the lifecycle of an invoice:

  • invoice-finalize – Triggered when an invoice is created and opened (finalized).

  • invoice-revert – Triggered when an invoice is reverted (cancelled or refunded)

  • invoice-pay – Triggered when an invoice is fully paid.

  • invoice-dispute – Triggered when an invoice is disputed.

The following invoice events are deprecated and should therefore not being used.

  • invoice-create

  • invoice-update

Event payload

Each of theses events send the same shape of payload defined as follow.

You can also find here the JSON Schema description of the payload.

Fields description

Field

Type

Description

Example

event_type

string

"invoice-finalize"

date

number (timestamp)

Timestamp of when the event was triggered

1762246989

data

Object

Details about the event and invoice (see below).

-

data.date

"2025-11-04T09:03:11.653072Z"

data.object.id

string (uuid)

Unique identifier of the invoice

"923e2c97-8228-4d42-8a44-1783c70c50a1"

data.object.object

string

Object type (always invoice).

"invoice"

data.object.status

string

Invoice status (open, paid, refunded, voided).

"open"

data.object.date_created

string (date-time)

When the invoice was created (UTC).

"2025-11-04T09:03:06.515219Z"

data.object.date_created

string (date-time)

When the invoice was created (UTC).

"2025-11-04T09:03:06.515219Z"

data.object.date_issued

string (date-time)

When the invoice was issued (UTC).

"2025-11-04T09:03:08.225042Z"

data.object.date_due

string (date-time)

Payment due date (UTC).

"2025-11-04T09:03:07.292000Z"

data.object.date_cancelled

string (date-time) | null

When the invoice was cancelled (if applicable).

null

data.object.currency

string

Invoice currency (ISO 4217 code).

"eur"

data.object.total

number (cents)

Total invoice amount in smallest unit (e.g., cents).

36665

data.object.amount_due

number (cents)

Amount due in smallest unit (e.g., cents).

36665

data.object.amount_paid

number (cents)

Amount already paid in smallest unit (e.g., cents).

0

data.object.company

object

Company issuing the invoice.

{ ... }

data.object.company.id

number

Unique company ID. To know your company ID, please go this backoffice page.

85329

data.object.company.name

string

Company name.

"SaudeViva Portugal"

data.object.company.country

string

Country code.

"PT"

data.object.company.city

string

City.

"Lisbon"

data.object.company.address

string

Address.

"Rua do Ouro 115"

data.object.company.postal_code

string

Postal/ZIP code.

"1100-062"

data.object.customer

object | null

Customer being invoiced (can be null for anonymous Point Of Sales invoices).

{ ... }

data.object.customer.id

number

Unique customer/member ID.

7644312

data.object.customer.type

string

Customer type (always individual here).

"individual"

data.object.customer.name

string

Full name.

"Maria Oliveira"

data.object.customer.first_name

string

First name.

"Maria"

data.object.customer.last_name

string

Last name.

"Oliveira"

data.object.customer.email

string

Contact email.

"maria.oliveira77@example.com"

data.object.customer.phone

string

Phone number.

"+351 912 345 678"

data.object.customer.official_document_id

string

Official/National ID (can be tax ID/NIF).

"PT-19847765"

data.object.customer.address

object

Customer address.

{ ... }

data.object.customer.address.line1

string

Street address.

"Avenida da Liberdade 202"

data.object.customer.address.line2

string (optional)

Additional address info.

"4º Esq."

data.object.customer.address.city

string

City.

"Lisbon"

data.object.customer.address.postal_code

string

Postal code.

"1250-147"

data.object.customer.address.state

string

State/region.

"Lisboa"

data.object.customer.address.country

string

Country code.

"PT"

data.object.line_items

object

Line items container.

{ ... }

data.object.line_items.line_count

number

Number of line items.

6

data.object.line_items.data

array<object>

Array of invoice line items.

[{ ... }, { ... }]

data.object.line_items.data[].id

number

Unique identifier for the line item.

2153

data.object.line_items.data[].description

string

Name/label of the product or service.

"£100 General Gift Voucher"

data.object.line_items.data[].quantity

number

Number of units purchased.

1

data.object.line_items.data[].tax_included_unit_amount

number (cents)

Unit price incl. tax, in cents.

10000

data.object.line_items.data[].tax_included_amount

number (cents)

Total price incl. tax before discount (quantity * unit_amount).

10000

data.object.line_items.data[].voucher_applied

number (cents)

Discount/voucher applied to this line, in cents.

0

data.object.line_items.data[].line_total

number (cents)

Final line amount after discount, in cents.

10000

data.object.line_items.data[].tax_breakdown

object

Tax calculation details.

{ ... }

data.object.line_items.data[].tax_breakdown.rate

number (%)

Tax rate percentage (e.g., 20 = 20%).

0

data.object.line_items.data[].tax_breakdown.total_tax

number (cents)

Total tax included in this line, in cents.

0

data.object.line_items.data[].tax_breakdown.unit_tax

number (cents)

Tax included per unit, in cents.

0

data.object.line_items.data[].item_type

string

Type of bsport item (shop-product, pass, private_pass, consumer_giftcard, refund).

"consumer_giftcard"

data.object.invoice_pdf

string (url)

Link to the invoice PDF.

"https://assets.staging.bsport.io/.../invoice-24092226.pdf"

data.object.receipt_pdf

string (url) | null

Link to the payment receipt PDF (if applicable).

null

data.object.invoice_type

number

Invoice type: 0=normal, 1=reverse, 2=credit note, 3=migration.

0

data.object.source_invoice_id

string (uuid) | null

UUID of original invoice cancelled through this one (if applicable).

null

Example

{
"event_type": "invoice-finalize",
"date": 1762246989,
"data": {
"date": "2025-11-04T09:03:11.653072Z",
"object": {
"id": "923e2c97-8228-4d42-8a44-1783c70c50a1",
"object": "invoice",
"status": "open",
"date_created": "2025-11-04T09:03:06.515219Z",
"date_issued": "2025-11-04T09:03:08.225042Z",
"date_due": "2025-11-04T09:03:07.292000Z",
"date_cancelled": null,
"currency": "eur",
"total": 36665,
"amount_due": 36665,
"amount_paid": 0,
"company": {
"id": 85329,
"name": "SaudeViva Portugal",
"country": "PT",
"city": "Lisbon",
"address": "Rua do Ouro 115",
"postal_code": "1100-062"
},
"customer": {
"id": 7644312,
"type": "individual",
"name": "Maria Oliveira",
"first_name": "Maria",
"last_name": "Oliveira",
"email": "maria.oliveira77@example.com",
"phone": "+351 912 345 678",
"official_document_id": "PT-19847765",
"address": {
"line1": "Avenida da Liberdade 202",
"line2": "4º Esq.",
"city": "Lisbon",
"postal_code": "1250-147",
"state": "Lisboa",
"country": "PT"
}
},
"line_items": {
"line_count": 6,
"data": [
{
"id": 2153,
"description": "£100 General Gift Voucher",
"quantity": 1,
"tax_included_unit_amount": 10000,
"tax_included_amount": 10000,
"voucher_applied": 0,
"line_total": 10000,
"tax_breakdown": {
"rate": 0,
"total_tax": 0,
"unit_tax": 0
},
"item_type": "consumer_giftcard"
},
{
"id": 249955,
"description": "Classic Jumper - Peacoat Navy",
"quantity": 2,
"tax_included_unit_amount": 4500,
"tax_included_amount": 9000,
"voucher_applied": 964,
"line_total": 8036,
"tax_breakdown": {
"rate": 20,
"total_tax": 1339,
"unit_tax": 670
},
"item_type": "shop-product"
},
{
"id": 15305,
"description": "Single 60 Minute Reiki Treatment",
"quantity": 1,
"tax_included_unit_amount": 7500,
"tax_included_amount": 7500,
"voucher_applied": 1384,
"line_total": 6116,
"tax_breakdown": {
"rate": 20,
"total_tax": 1019,
"unit_tax": 1019
},
"item_type": "private_pass"
},
{
"id": 15301,
"description": "Single 60 Minute Session",
"quantity": 1,
"tax_included_unit_amount": 7500,
"tax_included_amount": 7500,
"voucher_applied": 1383,
"line_total": 6117,
"tax_breakdown": {
"rate": 20,
"total_tax": 1019,
"unit_tax": 1019
},
"item_type": "private_pass"
},
{
"id": 427448,
"description": "Newbies",
"quantity": 1,
"tax_included_unit_amount": 4900,
"tax_included_amount": 4900,
"voucher_applied": 904,
"line_total": 3996,
"tax_breakdown": {
"rate": 20,
"total_tax": 666,
"unit_tax": 666
},
"item_type": "pass"
},
{
"id": 427451,
"description": "1 Session",
"quantity": 1,
"tax_included_unit_amount": 2500,
"tax_included_amount": 2500,
"voucher_applied": 100,
"line_total": 2400,
"tax_breakdown": {
"rate": 20,
"total_tax": 400,
"unit_tax": 400
},
"item_type": "pass"
}
]
},
"invoice_pdf": "https://assets.staging.bsport.io/invoices/2025-11-04/5cab7c93-cd01-4d15-9362-46b0a89919b5/invoice-24092226.pdf",
"receipt_pdf": null,
"invoice_type": 0,
"source_invoice_id": null
}
}
}

Did this answer your question?