Webhooks
Webhooks allow your application to receive real-time notifications from Buckaroo whenever important events occur—such as new sales, updates to transactions, or changes to customer or subscription data.
When one of your subscribed events happens, Buckaroo sends a push to the webhook URL you configured. Your system can then process the event and, if needed, retrieve additional details through the Buckaroo API.
- Creating a Webhook Subscription
To register a webhook, send a POST request to the Webhooks API with the webhook configuration.
Example: Create a webhook subscription
{
"url": "https://api.example.com/webhook",
"storeId": "s_1234abcd",
"eventTypes": [
"sale.createdsale.create",
"sale.updatedsale.update"
],
"maxConcurrency": 10,
"secret": "secretKey"
}
Field descriptions
| Field | Description |
|---|---|
| url | The HTTPS endpoint in your system where Buckaroo will send events. |
| storeID | Identifier of the store (merchant environment) for which events should be delivered. |
| eventTypes | Array of event types you want to receive. Example: sale.create, sale.update, etc. |
| maxConcurrency | Maximum number of parallel webhook deliveries allowed. Controls throughput and prevents overload. |
| secret | Shared secret used to verify webhook signatures (HMAC). Keep this value secure. |
Once saved, the webhook subscription becomes active immediately.
- Managing Webhook Subscriptions
You can create, update, retrieve, and delete webhook subscriptions using standard CRUD operations.
➤ Retrieve all webhooks (GET)
GET /v1/webhooks Returns a list of webhook subscriptions configured for the authenticated merchant or app.
➤ Retrieve a single webhook (GET)
GET /v1/webhooks/{webhookId}
➤ Update an existing webhook (PATCH or POST)
PATCH /v1/webhooks/{webhookId}
POST /v1/webhooks
You can modify an existing subscription by sending updated fields:
{
"eventTypes": ["sale.createdsale.create", "sale.updatedsale.update", "sale.refunded"],
"maxConcurrency": 20
}
Only fields you include will be modified.
➤ Delete a webhook (DELETE)
DELETE /v1/webhooks/{webhookId}
This immediately disables the webhook and stops all deliveries.
- Webhook Event Delivery
When one of the subscribed events occurs, Buckaroo sends a POST request to your url.
Example webhook payload
{
"id": "evt_001",
"type": "sale.createdsale.create",
"createdAt": "2025-02-18T10:15:00Z",
"data": {
"saleId": "sa_9876def",
"status": "pending"
},
"storeId": "s_1234abcd"
}
Important notes
- You receive only event metadata, not the full sale, subscription, or customer object.
- It is your responsibility to fetch the full resource from the API if your system requires the details.
- The secret you configured is used to verify authenticity of the request (depending on your signing mechanism).
- **Event Types
Each event type corresponds to a specific action. Examples:
| Event Type | Description |
|---|---|
| A new sale has been created. | |
| Status or fields of an existing sale have changed. | |
| ... | Additional event types may be supported depending on your features. |
- Handling Webhooks on Your Side
Best practices
- Verify signatures using your webhook secret.
- Return 2xx responses as soon as possible—acknowledge receipt quickly.
- Avoid long-running operations in your webhook handler. If needed, enqueue processing in the background.
- Retry logic: Buckaroo will retry deliveries if your endpoint returns non-2xx responses.
- Use the event ID to avoid processing the same event twice.
- Retrieving Full Data After a Webhook
Webhook payloads are intentionally lightweight. If you need the full sale/subscription/customer details:
- Receive the event (e.g., "
sale.updatedsale.update"). - Extract the relevant ID from data.
- Call the Buckaroo API for the full resource:
GET /sales/{saleId}
Authorization: Bearer {access_token}
This pattern ensures reliability and security, even if webhook payloads are delayed or retried.
- Summary
- Use webhooks for real-time notifications about important events.
- Register your webhook with POST /webhooks.
- Manage subscriptions with GET, PATCH, and DELETE.
- Webhooks deliver event metadata; you fetch full details through the API.
- Use your secret to verify authenticity and secure your integration.
- Sales & Transactions API
The Sales & Transactions API allows you to create sales, attach one or more transactions to a sale, retrieve their status, and optionally cancel a sale.
A Sale represents the commercial order (amount, customer, order lines, shipment info, etc.).
A Transaction represents the payment attempt performed using a specific payment method (POS, card, bank transfer, etc. currently only POS is available).
A sale may contain multiple transactions over time (e.g., retries, partial payments, POS attempts, etc.).
- Creating a Sale
To initiate a new payment flow, you create a Sale using the POST /v1/sales endpoint. The sale includes all information necessary for payment processing, customer identification, receipts, POS details, and more.
Example: Create a Sale
{
"storeId": "s_1234abcd",
"reference": "unique-reference",
"currency": "EUR",
"totalAmount": "123.45",
"breakdown": {
"baseAmount": "123.45",
"vatAmount": "123.45",
"shippingFee": "123.45",
"handlingFee": "123.45",
"discountAmount": "123.45"
},
"description": "Description of the Sale",
"locale": "nl-NL",
"sequenceType": "OneOff",
"intentType": "Pay",
"statementDescriptor": "Order #123456",
"paymentMethods": ["Pos"],
"paymentMethodOptions": {
"pos": {
"terminalId": "t_abcd1234efgh5678"
}
},
"returnUrl": "https://api.example.com/return",
"cancelUrl": "https://api.example.com/cancel",
"customer": {
"reference": "unique-reference",
"address": {
"street": "Zonnebaan",
"houseNumber": "9",
"postalCode": "3542 EA",
"city": "Utrecht",
"country": "NL"
},
"title": "Mr.",
"givenName": "Mat",
"familyName": "Cauthon",
"email": "[email protected]",
"phoneNumber": "+31 612345678",
"dateOfBirth": "1990-01-01",
"organization": {
"name": "Red Company",
"vatNumber": "NL000099998B57"
},
"preferredLocale": "nl-NL",
"metadata": {
"customField": "value",
"source": "website"
}
},
"sessionData": {
"sessionId": "string",
"deviceFingerprint": "string",
"userAgent": "string",
"referrer": "string",
"ipAddress": "string"
},
"mandateId": "man_abcd1234efgh5678",
"metadata": {
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
},
"shippingCustomer": {
"address": {
"street": "Zonnebaan",
"houseNumber": "9",
"postalCode": "3542 EA",
"city": "Utrecht",
"country": "NL"
},
"title": "Mr.",
"givenName": "Mat",
"familyName": "Cauthon",
"email": "[email protected]",
"phoneNumber": "+31 612345678",
"organization": {
"name": "Red Company",
"vatNumber": "NL000099998B57"
}
},
"shipments": [
{
"carrier": "PostNL",
"trackingNumber": "123456",
"trackingUrl": "https://jouw.postnl.nl/track-and-trace/123456"
}
],
"orderLines": [
{
"name": "Pants",
"sku": "1234 abcd 5678",
"type": "Clothing",
"quantity": "123.45",
"amount": "123.45",
"vatRate": "123.45",
"vatAmount": "123.45",
"totalAmount": "123.45"
}
],
"receipts": [
{
"receiptType": "Customer",
"text": "Receipt text"
}
]
}
- Understanding Sales & Transactions
When you create a sale:
- The Sale object stores all order-related information.
- Buckaroo automatically creates the first transaction based on the payment method (e.g. POS, iDEAL, cardcurrently only POS).
- If a transaction fails or requires retries, additional transactions may be created on the same sale.
Transactions can represent:
- POS terminal actions
- Redirect payments
- Mandate-based payments
- Partial captures/refunds
- Payment retries
This structure allows one sale to maintain the full payment lifecycle.
- Retrieving Sales and Transactions
You can inspect a sale, its status, and all associated transactions using:
Retrieve a sale
GET /v1/sales/{saleId}
Example response contents
A sale response typically includes:
- Sale status (e.g., Pending, Completed, Failed)
- All aggregated amounts
- Customer and order data
- Associated transactions, each with:
- transaction ID
- method
- status
- timestamps
- failure reasons
- POS terminal responses (if applicable)
This endpoint is used for polling or retrieving details after receiving a webhook like~~ sale.updated~~ sale.update.
- Cancelling a Sale
If a sale has not yet been fully processed (e.g., not completed or captured), you can cancel it.
Cancel a sale
POST /v1/sales/{saleId}/cancel
Cancellation triggers a sale.updated sale.update webhook event if configured.
Typical use-cases:
- Customer aborted checkout
- POS terminal cancelled
- Fraud or risk checks failed
- Order fulfilment failed before payment
- Common Sale Statuses
| Status | Description |
|---|---|
| Pending | Awaiting customer interaction or awaiting asynchronous payment confirmation.Description |
| Authorized | Payment is authorized but not captured (depending on payment method). |
| Completed | Payment fully processed, funds secured. |
| Failed | Payment attempt was unsuccessful. |
| Cancelled | Sale was cancelled before completion. |
| Refunded | Whole sale refunded (or see partial refund transactions). |
Each status may trigger a webhook event.
- Best Practices
When creating a sale
- Always use a unique reference to avoid duplicates.
- Only include the payment methods relevant for this sale.
- Store your saleId for future lookups.
When handling transactions
- Use webhooks such as sale.createdsale.create and sale.updatedsale.update to avoid polling.
-
* Retrieve the full sale using GET /v1/sales/{id} after receiving a webhook. - Support multiple transactions per sale—don’t assume only one attempt will occur.
When cancelling
- Only cancel if your system has not shipped or confirmed the order.
- If the cancellation fails, inspect error codes and transaction statuses.
- Summary
-
A Sale is the full order object.
-
A Transaction is an individual payment attempt.
-
Sales can contain multiple transactions.
-
Create sales with POST /v1/sales.
-
Retrieve sales/transactions using GET /v1/sales/{id}. -
Cancel sales with POST /v1/sales/{id}/cancel. -
Always listen for webhook updates to track payment progress.
- POS Payments (Terminal)
For in-store / point-of-sale (POS) payments, the Sales API integrates directly with your Buckaroo payment terminals. A POS payment is just a normal Sale with:
- paymentMethods including "Pos", and
- a terminal ID specified in paymentMethodOptions.pos.terminalId.
- Required: Terminal ID
Every POS sale must be linked to a specific terminal.
"paymentMethods": [
"Pos"
],
"paymentMethodOptions": {
"pos": {
"terminalId": "t_abcd1234efgh5678"
}
}
- terminalId is required for POS payments.
- It identifies which physical terminal should process the transaction.
- You’ll receive terminal IDs from Buckaroo when onboarding your terminals.
If no valid terminalId is provided, the request will fail and no POS transaction will be started.
- POS Sale Flow
2.1 Create a sale with POS as payment method
You call POST /v1/sales with "Pos" in paymentMethods and a valid terminalId in paymentMethodOptions.pos.
2.2 Terminal interaction
Buckaroo sends the payment request to the specified terminal. On the customer-facing device:
- The amount is shown.
- The customer taps/inserts/swipes their card or wallet.
- The terminal communicates with the acquirer and returns a result.
2.3 Transaction creation
A transaction is created under the sale to represent this POS attempt. The transaction contains:
- POS terminal result codes,
- authorization codes (if applicable),
- timestamps and status.
2.4 Status updates & webhooks
As the POS flow progresses, the sale and its transaction(s) change status:
- Pending → waiting for terminal or acquirer
- Completed / Failed → final result
If you subscribed to webhooks (e.g.
sale.updatedsale.update), your system will be notified automatically.
2.5 Check the final result
Use:
6. GET /v1/sales/{saleId}
to retrieve the sale and inspect the POS transaction status and details.
- Multiple POS Transactions per Sale
Sometimes, more than one POS attempt is needed for the same order:
- First card declined, second card accepted.
- Customer cancels on the terminal and tries again.
In these cases:
- The sale stays the same, keeping the original order and reference.
- A new POS transaction is created under the same sale for each attempt.
-
* You can always see the full history by calling GET /v1/sales/{saleId}.
- Cancelling POS Sales
If the POS payment is not yet completed, you may cancel the sale:
POST /v1/sales/{saleId}/cancel
This will:
- Stop further processing on that sale, and
- Trigger a sale.updatedsale.update webhook if configured.
Only cancel a sale if your business process also cancels the in-store order (e.g. the customer left the store or the transaction was clearly aborted).
- Summary (POS)
- Use "Pos" in paymentMethods to trigger a POS flow.
- paymentMethodOptions.pos.terminalId is mandatory and selects the physical terminal.
- Each POS attempt is a separate transaction under the same sale.
-
* Use GET /v1/sales/{id} or webhooks to track POS payment status.
-
* Use POST /v1/sales/{id}/cancel to cancel an incomplete POS sale
- Terminal Configuration API (POS)
You can configure how a POS terminal behaves — including receipts, payment options, and optional WecR settings — by updating the terminal through the Terminal Configuration API.
- Updating a Terminal
To update a terminal, use the following endpoint:
PATCH /v1/pos/terminals/internal/{terminalId}
-
* {terminalId} is the unique ID of the terminal (e.g. t_abcd1234efgh5678).
- The id inside the request body must match the terminal being updated.
Example request body
{
"id": "t_abcd1234efgh5678",
"name": "My Terminal",
"receiptSettings": {
"receiptName": "Example Store",
"receiptLocation": "Utrecht",
"qrReceiptEnabled": true,
"customerReceiptMode": "Enabled",
"merchantReceiptMode": "Enabled"
},
"paymentSettings": {
"bankText": "Bank text",
"paymentReferenceEnabled": true,
"limitedAcceptanceEnabled": true,
"amexEnabled": true,
"refundEnabled": true,
"refundPassword": "12345",
"terminalLoginOptions": "NoLogin",
"fixedAmountMode": "MandatoryNoDeviation"
},
"wecrSettings": {
"wecrEnabled": true,
"wecrSupplier": "None",
"wecrLogin": "true"
}
}
- Receipt Settings
receiptSettings allow you to configure how receipts are printed and presented.
| Field | Description |
|---|---|
| receiptName | Store name printed at the top of the receipt. |
| receiptLocation | City or location printed on the receipt (e.g. “Utrecht”). |
| qrReceiptEnabled | Enables QR codes on the receipt. |
| customerReceiptMode | Controls if/when the customer receipt is printed. |
| merchantReceiptMode | Controls if/when the merchant receipt is printed. |
These fields are used to brand your receipts and comply with store requirements.
- Payment Settings
paymentSettings configure how the terminal handles payment rules and card schemes.
| Field | Description |
|---|---|
| bankText | Text passed to the bank/acquirer (reference field). |
| paymentReferenceEnabled | Enables passing a payment reference. |
| limitedAcceptanceEnabled | Allows restricting what can be accepted (amounts/schemes). |
| amexEnabled | Enables or disables American Express acceptance. |
| refundEnabled | If true, refunds can be initiated from the terminal. |
| refundPassword | Password required for refund operations. |
| terminalLoginOptions | Defines login behaviour (e.g. “NoLogin”). |
| fixedAmountMode | Controls fixed-amount flows (e.g. “MandatoryNoDeviation”). |
These settings allow you to secure sensitive actions (like refunds) and enforce payment rules.
- WecR Settings
wecrSettings configure optional WecR functionality.
| Field | Description |
|---|---|
| wecrEnabled | Enables WecR support. |
| wecrSupplier | Name of the WecR supplier (e.g. “None”). |
| wecrLogin | Whether a WecR login is required. |
Only configure these if your integration uses WecR.
- Behaviour & Best Practices
Partial updates
Although the example shows a full object, the endpoint is a PATCH. You may send only the fields you want to change.
Security
- Protect refundPassword as sensitive information.
- Limit access to this endpoint to backend systems with proper authorization.
Consistency
Ensure the path parameter {terminalId} matches the id in the payload.
Testing
Apply changes on a test terminal before rolling out to production devices.
- Applying Terminal Updates on the Device
After patching a terminal using the API, the device must pull the new configuration. Follow these steps on the terminal:
-
- Open the PAY app
- Hold the menu button for 6 seconds to open the hidden menu
- Click “LOGON & DOWNLOAD” to start downloading the new configuration
The terminal will then update itself with the latest settings from the Buckaroo platform.
Updated about 4 hours ago