- Base URL and sign-in
- Who may do what
- Balances
- Statuses
- The balance object
- GET /wc-sibooking/v1/balances
- GET /wc-sibooking/v1/balances/{id}
- POST /wc-sibooking/v1/balances/{id}/mark-paid
- POST /wc-sibooking/v1/balances/{id}/invoice
- POST /wc-sibooking/v1/balances/{id}/waive
- POST /wc-sibooking/v1/balances/{id}/charge
- Errors of the actions
- The payment object on bookings and orders
- Late fees
- Statuses
- The late-fee object
- GET /wc-sibooking/v1/late-fees
- GET /wc-sibooking/v1/late-fees/{id}
- PATCH /wc-sibooking/v1/late-fees/{id}
- POST /wc-sibooking/v1/late-fees/{id}/accept
- POST /wc-sibooking/v1/late-fees/{id}/counter-payment
- POST /wc-sibooking/v1/late-fees/{id}/send-link
- POST /wc-sibooking/v1/late-fees/{id}/waive
- POST /wc-sibooking/v1/late-fees/{id}/refund
- POST /wc-sibooking/v1/late-fees/{id}/recalculate
- POST /wc-sibooking/v1/late-fees/{id}/retry
- Errors of the actions
- Late fees on a return
- Hooks
The REST API for booking-deposit balances and late fees: list what customers still owe, record a payment taken at the counter, send the payment link again, waive or charge a balance, and review, edit, bill, refund or waive late fees. The actions are the same ones staff use on Rentals > Balances, Rentals > Late fees and the order screen, so an outside system (an accounting tool, a point-of-sale till, a collections dashboard) can do the same. How deposits and late fees work for staff is in Booking deposit and Late fees. The setup and the conventions shared by every endpoint (keys, errors, pagination) are in REST API overview and authentication.
- A balance is the money still owed on a booking order after the customer paid a booking deposit at checkout. Once the deposit is paid, the plugin creates a separate WooCommerce order for the rest (the balance order: Pending payment, its parent is the booking order) and tracks it with a due date until it is paid, waived or cancelled.
- A late fee is the charge for rental units that come back after their due time and the grace period. Each booking order has one open late fee at a time, numbered
LF-<order number>-<n>, which collects every late check-in. While late units are still out it keeps growing (accruing); once everything is back it waits for staff (to_review) before anything is billed.
Base URL and sign-in #
| Namespace | What lives there | Needs |
|---|---|---|
/wp-json/ | balances (list, read, mark paid, payment link, waive, charge) and late-fees (list, read, edit, accept, counter payment, payment link, waive, refund, recalculate, retry) | Rentals & Bookings Regular. Balances appear once “Let customers pay a booking deposit” is on (Rentals > Settings > Booking Deposit), late fees once “Charge late fees” is on (Rentals > Settings > Late fees). The routes answer either way |
wc-sibooking/v1takes a WooCommerce REST API key (WooCommerce > Settings > Advanced > REST API) sent as HTTP Basic, like the other rental endpoints. A read key can call the GET routes; the routes that change something need a read/write key. The key’s user decides what the call may do (next section).- A WordPress Application Password (Users > Profile > Application Passwords) sent as HTTP Basic works too, and inside wp-admin the logged-in cookie with an
X-WP-Nonceheader. - The balances routes are in Rentals & Bookings Regular 1.0.76 and later, the late-fee routes in 1.0.79 and later.
- Send bodies as JSON (
Content-Type: application/json). - Money comes twice: as a decimal number in the store’s currency (
total:150) and in minor units (total_minor:15000, cents for USD). Amounts you send are decimals, as a string or a number ("12.50"). - Times without a suffix (
due,returned) are store time,Y-m-d H:i:s. Fields ending in_gmtare UTC. - Lists take
pageandper_page(default20, at most200) and answer theX-WP-TotalandX-WP-TotalPagesheaders. - Errors use the WordPress shape
{"code", "message", "data": {"status"}}, with codes startingsibooking_rest_. An action the record’s state does not allow answers409. - These calls can move money:
POST /balances/{id}/chargeandPOST /late-fees/{id}/retrycharge a saved card,POST /late-fees/may keep part of a security deposit or charge a saved card, and{id}/ accept POST /late-fees/can refund through the payment gateway. The payment-link actions email the customer.{id}/ refund
STORE="https://example.com/wp-json"
curl -u "ck_your_key:cs_your_secret" "$STORE/wc-sibooking/v1/balances?status=due,overdue"
Who may do what #
| Ability | Who has it | Opens |
|---|---|---|
manage_woocommerce | Shop managers and administrators | Every balances endpoint |
edit_shop_orders | Shop managers and administrators (WooCommerce gives it to both), and any role or user given it | Every late-fees endpoint, like the Rentals > Late fees screen. A user with this ability alone can use the late-fee endpoints but not the rest of the rental API |
A user without the ability gets 401 (not signed in) or 403, code sibooking_.
Balances #
Statuses #
| Status | Meaning |
|---|---|
scheduled | The deposit is paid; the balance is due later |
due | The due date has come; waiting for the payment |
charging | An automatic charge is running |
failed | An automatic charge was declined. It is tried again a day later, then 3 days after that (next_attempt_gmt) |
needs_action | The bank asks the customer to confirm the payment |
overdue | Still unpaid a day after the due date (two days for needs_action), or after the last retry |
paid | Paid in full |
waived | Staff waived it |
cancelled | The booking order, or the balance order itself, was cancelled or refunded |
released | The balance was not paid, so the booking order was cancelled (“When the balance is not paid: Cancel the booking after a number of days” in Rentals > Settings > Booking Deposit). The booking deposit is kept |
The first six are open: money is still owed and the actions below work. The last four are closed.
The balance object #
| Field | Notes |
|---|---|
id | The balance id |
order_id, order_number | The booking order |
balance_order_id, balance_order_number | The balance order the customer pays |
status, status_text | One of the statuses above, and the words staff see (“Deposit paid · balance due Tue 1 Dec”) |
currency | The order’s currency |
amount, tax, total | Before tax, the tax, and what the customer pays; each also as amount_minor, tax_minor, total_minor |
due, due_gmt | When it is due, store time and UTC |
collect | How it is collected: link (the customer pays from a payment link), auto (charged to the saved card on the due date) or pickup (paid at pick-up) |
attempts, next_attempt_gmt, last_error | Automatic charge attempts so far, the next retry, and the last decline or problem |
paid_via, paid_gmt | How and when it was paid: online, auto, counter_cash, counter_card, counter_bank or counter_other; null before |
payment_url | The balance order’s payment page while the balance is open; null otherwise |
customer | id (0 for a guest), name and email from the booking order |
{
"id": 12,
"order_id": 1042,
"order_number": "1042",
"balance_order_id": 1043,
"balance_order_number": "1043",
"status": "scheduled",
"status_text": "Deposit paid · balance due Tue 1 Dec",
"currency": "USD",
"amount": 150,
"tax": 0,
"total": 150,
"amount_minor": 15000,
"tax_minor": 0,
"total_minor": 15000,
"due": "2026-12-01 10:00:00",
"due_gmt": "2026-12-01 15:00:00",
"collect": "link",
"attempts": 0,
"next_attempt_gmt": null,
"last_error": "",
"paid_via": null,
"paid_gmt": null,
"payment_url": "https://example.com/checkout/order-pay/1043/?pay_for_order=true&key=wc_order_AbC123",
"customer": {"id": 0, "name": "Sarah Miller", "email": "[email protected]"}
}
GET /wc-sibooking/v1/balances #
The list, the same as Rentals > Balances. Sorted by due date, earliest first.
| Parameter | Notes |
|---|---|
status | Comma separated: scheduled, due, charging, failed, needs_action, overdue, paid, waived, cancelled, released. Every status when left out |
due_from, due_to | Store date (Y-m-d), a date and time, or ISO 8601. A bare due_to date runs through the end of that day |
order_id | The booking order’s id, or its balance order’s id |
page, per_page | Default 1 and 20; per_page at most 200 |
Answers an array of balance objects.
| Error | When |
|---|---|
400 sibooking_ | A status not in the list |
400 sibooking_ | due_from or due_to is not a date |
400 rest_invalid_param | per_page above 200 |
GET /wc-sibooking/v1/balances/{id} #
One balance. 404 sibooking_ when there is none.
POST /wc-sibooking/v1/balances/{id}/mark-paid #
Record payment: the whole balance was paid at the counter. There is no partial counter payment.
| Parameter | Notes |
|---|---|
method | cash, card (card terminal), bank (bank transfer) or other (default) |
reference | Optional: a receipt or terminal reference. It becomes the balance order’s transaction id and goes in its order note |
The balance order gets the payment method title “Paid at the counter: Cash” (and so on) and is marked paid; the balance answers status paid and paid_via counter_cash (and so on). Refused while an automatic charge runs (409 sibooking_).
POST /wc-sibooking/v1/balances/{id}/invoice #
Emails the customer the “Your balance is due” email: the rental and its dates, the amount, the due date and a Pay button that opens payment_url. It goes out even when the automatic balance reminder is switched off. No body. Answers the balance, unchanged.
POST /wc-sibooking/v1/balances/{id}/waive #
Waives the balance: it becomes waived, the unpaid balance order is cancelled, and the booking order keeps what was paid.
| Parameter | Notes |
|---|---|
reason | Optional; goes in the booking order’s note |
POST /wc-sibooking/v1/balances/{id}/charge #
Charge now: charges the payment method saved on the booking. It must be one of the payment methods ticked under “Automatic charges with” (Rentals > Settings > Booking Deposit). Works on a balance that is scheduled, due or failed. No body.
- Paid: answers the balance with
statuspaidandpaid_viaauto. - The payment method cannot be charged automatically, or the saved card has expired: the balance switches to
collectlink, the customer is emailed the payment link, and the call answers409 sibooking_.rest_ charge_ manual - The bank asks the customer to confirm: the balance is
needs_action, the customer is emailed, and the call answers409 sibooking_.rest_ charge_ needs_ action - Declined: the balance is
failed(retried a day later and 3 days after that, thenoverdue) and the call answers409 sibooking_with the gateway’s message. When the gateway gave no clear answer the balance isrest_ charge_ failed failedwithout a retry: check the payment in the gateway before you charge again.
Errors of the actions #
| Error | When |
|---|---|
404 sibooking_ | No such balance, or its booking order is gone |
409 sibooking_ | The balance is closed (paid, waived, cancelled or released) |
409 sibooking_ | The balance order is gone |
409 sibooking_ | mark-paid while an automatic charge runs |
409 sibooking_ | mark-paid when the balance order is already paid |
409 sibooking_, 409 sibooking_ | invoice: the order has no billing email, or the email could not be sent |
409 sibooking_ | charge while another charge runs |
409 sibooking_ | charge on a balance that is not scheduled, due or failed, or whose balance order turned out to be paid already |
409 sibooking_, .., ..._charge_failed | charge: see above |
400 rest_invalid_param | method not in the list |
curl -u "ck_your_key:cs_your_secret" -X POST \
-H "Content-Type: application/json" \
-d '{"method":"card","reference":"Terminal 4471"}' \
"$STORE/wc-sibooking/v1/balances/12/mark-paid"
The payment object on bookings and orders #
Bookings (see Bookings, availability and serials) and Regular’s orders list (see Pricing and orders) carry payment: null for an order without a booking deposit, {"type": "balance", "balance_of": 1042} for a balance order, and for a booking order:
| Field | Notes |
|---|---|
type | deposit |
status, status_text | The open balance’s status (else the newest balance’s); deposit_unpaid while the booking order is not paid yet |
deposit, deposit_minor | The booking deposit, paid at checkout |
balance_due, balance_due_minor | What is still owed: the open balances, with tax |
due, collect | As on the balance |
balance_id, balance_order_id | The balance and its balance order, for the calls above |
payment_url | While a balance is open |
Late fees #
Statuses #
| Status | Meaning | What you can do |
|---|---|---|
accruing | Late units are still out; the fee grows until they are back. Nothing is billed | Edit the notes, recalculate, waive |
to_review | Everything is back; staff decide | Edit, recalculate, accept, counter-payment, waive |
charging | A card charge is running | Nothing until it ends |
pay_link_sent | A late-fee order exists and the customer pays it from a link | send-link, counter-payment, waive |
failed | A card charge was declined | retry, send-link, counter-payment, waive |
needs_action | The bank asks the customer to confirm the card payment | send-link, counter-payment, waive |
paid | Paid | refund |
part_refunded | Part of it was refunded | refund (what is left) |
refunded, waived | Finished | Nothing |
cancelled | Nothing was late after all (a corrected return time), or the booking order was cancelled or refunded | Nothing |
The late-fee object #
| Field | Notes |
|---|---|
id, number | The id and LF-1042-1 |
order_id | The booking order |
status, status_text | One of the statuses above, and the words staff see |
currency | The order’s currency |
amount, tax, total | Before tax, the tax, and the total; each also as amount_minor, tax_minor, total_minor |
due | The earliest due time of its lines, store time |
returned | The last late check-in, store time; null while nothing is back |
charge_order_id | The late-fee order (a WooCommerce order, parent = the booking order) once it is billed; null before, and for a fee kept from the security deposit |
route | How it is collected: deposit, card, link or counter; null before |
paid_via, paid_gmt | How and when it was paid: online (from the pay link), card, deposit, counter_cash, counter_card, counter_bank or counter_other; null before |
payment_url | The late-fee order’s payment page while the fee is unpaid (pay_link_sent, failed, needs_action, charging); null otherwise |
so_far | While accruing: the charges so far, before tax, in minor units. null otherwise |
lines | The charges (below) |
calculated_minor | What the late-fee rules came to, before any staff edit |
adjusted | true once staff changed an amount or added a line |
note_customer | The note to the customer; it goes on the late-fee order |
staff_reason | The staff note on an edit |
waive_reason | Why it was waived |
location_id | Where the last late units were checked in (Multi Location Inventory); null without one |
Each entry in lines:
| Field | Notes |
|---|---|
key | The line’s key, used by amounts in an edit: b789-r321 (a check-in), b789-out (units still out), flat (the fixed late fee), x1, x2 (staff lines) |
kind | return (a late check-in), running (units still out), flat (the fixed “Late return fee”) or extra (a line staff added) |
name | The product, or the line’s own name. A product name comes as WordPress stores it, so an & arrives as & |
booking_id, quantity | The booking and how many units the line charges for |
due, returned | The due time and the check-in time (Y-m-d H:i). For a running line, returned is the time it was last measured up to |
late_minutes, units, unit | How late, and what it was charged by: units of hour, day or week |
amount, amount_minor | The line’s amount, as entered (before tax) |
calculated_minor | What the rules came to for this line |
edited | true when staff changed the amount |
price_missing | true when the rental price for the late time could not be worked out. Such a fee cannot be accepted until the line’s amount is entered with an edit |
{
"id": 456,
"number": "LF-1042-1",
"order_id": 1042,
"status": "to_review",
"status_text": "To review",
"currency": "USD",
"amount": 80,
"tax": 0,
"total": 80,
"amount_minor": 8000,
"tax_minor": 0,
"total_minor": 8000,
"due": "2026-11-03 23:59:00",
"returned": "2026-11-05 10:15:00",
"charge_order_id": null,
"route": null,
"paid_via": null,
"paid_gmt": null,
"payment_url": null,
"so_far": null,
"lines": [{
"key": "b789-r321", "kind": "return", "name": "Party tent",
"booking_id": 789, "quantity": 1,
"due": "2026-11-03 23:59", "returned": "2026-11-05 10:15",
"late_minutes": 2056, "units": 2, "unit": "day",
"amount": 80, "amount_minor": 8000, "calculated_minor": 8000,
"edited": false, "price_missing": false
}],
"calculated_minor": 8000,
"adjusted": false,
"note_customer": "",
"staff_reason": "",
"waive_reason": "",
"location_id": null
}
GET /wc-sibooking/v1/late-fees #
The list, the same as Rentals > Late fees. Newest first.
| Parameter | Notes |
|---|---|
status | Comma separated: accruing, to_review, charging, pay_link_sent, failed, needs_action, paid, waived, cancelled, refunded, part_refunded; or all. Every status when left out |
order_id | One booking order |
customer | A user id or a billing email; matches that customer’s newest 1,000 orders. With order_id, both must match |
search | A late-fee number or part of one (LF-1042), or an order id (the booking order or its late-fee order) |
created_after, created_before | When the late fee was created: a store date (Y-m-d), a date and time, or ISO 8601. A bare created_before date runs through the end of that day |
page, per_page | Default 1 and 20; per_page at most 200 |
Answers an array of late-fee objects.
| Error | When |
|---|---|
400 sibooking_ | A status not in the list |
400 sibooking_ | customer is neither a number nor an email address |
400 sibooking_ | created_after or created_before is not a date |
curl -u "ck_your_key:cs_your_secret" \
"$STORE/wc-sibooking/v1/late-fees?status=to_review&[email protected]"
GET /wc-sibooking/v1/late-fees/{id} #
One late fee. 404 sibooking_ when there is none.
PATCH /wc-sibooking/v1/late-fees/{id} #
Edits a late fee (PUT works too). Amounts and extra lines can change while the fee is to_review; the two notes also while it is accruing. Send any of:
| Field | Notes |
|---|---|
amounts | An object of line key to the new amount: {"b789-r321": "60.00"}. Amounts are 0 or more; an empty value leaves the line as it is. A changed line is marked edited and keeps its amount until recalculate. Alias: lines |
extras | The staff lines, as a list of {"name", "amount"}. It replaces every staff line there is; [] removes them. Alias: extra, with title for the name |
note_customer | The note to the customer |
staff_reason | The staff note, added to the order note of the edit. Alias: reason_staff |
Answers the late fee with the new totals. An edit that changes something adds an order note listing the changes.
| Error | When |
|---|---|
400 sibooking_ | None of the fields was sent |
400 sibooking_ | A line key the fee does not have |
400 rest_invalid_param | amounts is not an object, or extras is not a list |
400 sibooking_ | An amount that is not a number, or below 0 |
400 sibooking_ | A staff line without a name or an amount |
409 sibooking_ | Amounts or extras on a fee that is not to_review, or notes on a fee that is billed or closed |
curl -u "ck_your_key:cs_your_secret" -X PATCH \
-H "Content-Type: application/json" \
-d '{"amounts":{"b789-r321":"60.00"},"extras":[{"name":"Cleaning","amount":"15.00"}],"staff_reason":"First late return: one day off"}' \
"$STORE/wc-sibooking/v1/late-fees/456"
POST /wc-sibooking/v1/late-fees/{id}/accept #
Bills a fee that is to_review. Every line must have a price (409 sibooking_ otherwise) and the total must be above 0 (409 sibooking_: waive it instead).
| Parameter | Notes |
|---|---|
route | deposit, card or link. Left out (or auto): the first that works |
The routes, in this order, keeping the ones ticked under “How to collect” (Rentals > Settings > Late fees) that can work for this fee:
deposit: Refundable Security Deposits holds an untaxed deposit on the booking order and what is left of it covers the whole fee. The fee is kept from the deposit and ispaidat once (paid_viadeposit, no late-fee order, no tax).card: the booking was paid with a payment method that can be charged without the customer, the customer has an account, agreed to late-fee charges at checkout, and has a saved card. A late-fee order is created and charged now; the fee answerspaid,failed,needs_action, orpay_link_sentwhen the card can no longer be charged (the customer is emailed the pay link).link: a late-fee order is created (Pending payment, its parent is the booking order, one fee line per charge,note_customeras its customer note), the fee ispay_link_sent, and the customer gets the “Late fee: please pay” email with the lines and the pay link (payment_url). The “Late fee: still unpaid” reminders follow 3 and 7 days later; they stop once the fee is paid or waived. It is also the fallback when no ticked route can work, even whenlinkis not ticked.
All three are ticked until the setting is saved. A route that cannot start (the deposit was refused, the card could not be prepared) hands over to the next one, and finally to the link. A declined card still answers 200: read status. A route that is not ticked or cannot work for this fee answers 400 sibooking_.
curl -u "ck_your_key:cs_your_secret" -X POST \
-H "Content-Type: application/json" \
-d '{"route":"link"}' \
"$STORE/wc-sibooking/v1/late-fees/456/accept"
POST /wc-sibooking/v1/late-fees/{id}/counter-payment #
Records the whole fee as paid at the counter. Works on to_review (the late-fee order is created first, route counter), pay_link_sent, failed and needs_action. Alias: /mark-paid.
| Parameter | Notes |
|---|---|
method | cash (default), card (card terminal), bank (bank transfer) or other |
reference | Optional receipt or terminal reference |
The late-fee order is marked paid and Completed, with the payment method title “Paid at the counter: Cash” (“Card terminal”, and so on) and reference as its transaction id; no gateway is involved. The fee answers paid with paid_via counter_cash (and so on); a fee billed by link keeps route link. The customer gets the “Late fee: receipt” email. Refused while a card charge runs (409 sibooking_).
POST /wc-sibooking/v1/late-fees/{id}/send-link #
Emails the customer the pay link again (the “Late fee: please pay” email) and adds an order note. Works on pay_link_sent, failed and needs_action. No body. Answers the fee, unchanged; the reminders keep their dates. Alias: /invoice.
POST /wc-sibooking/v1/late-fees/{id}/waive #
Waives the fee. Works on accruing, to_review, pay_link_sent, failed and needs_action; an unpaid late-fee order is cancelled. The customer is not emailed. The bookings on a waived fee are not charged again, neither for the time still out nor for their check-in; a later late check-in of another booking on the same order opens a new fee (LF-1042-2).
| Parameter | Notes |
|---|---|
reason | Required, not blank: saved as waive_reason and in the order note |
POST /wc-sibooking/v1/late-fees/{id}/refund #
Refunds a paid or part_refunded fee, in part or in full.
| Parameter | Notes |
|---|---|
amount | Decimal ("12.50"). All that is left when left out |
reason | Optional; goes in the refund’s reason |
A fee paid from the link or by card is refunded on its late-fee order: a WooCommerce refund that goes through the payment gateway when the gateway can refund. A fee paid at the counter is only recorded as refunded: give the money back yourself. A fee kept from the security deposit goes back to the deposit (Refundable Security Deposits must be active, else 409 sibooking_). The fee answers part_refunded or refunded; it does not show how much was refunded, so read the refunds on its late-fee order (charge_order_id). WooCommerce emails the customer about the refund as usual, and a full refund leaves the late-fee order Refunded. 400 sibooking_ when the amount is not above 0 or more than is left; a refund WooCommerce or the gateway refuses answers 409 with its message. A fee that is already refunded answers 409 sibooking_.
POST /wc-sibooking/v1/late-fees/{id}/recalculate #
Works the amounts out again from the late-fee rules, and re-measures units still out. Staff edits and staff lines are dropped; the two notes stay. Works on accruing and to_review. No body.
POST /wc-sibooking/v1/late-fees/{id}/retry #
Charges the saved card again now, for a fee that is failed after a card charge (409 sibooking_ for another route). No body. Answers the fee; read status for the outcome.
Errors of the actions #
| Error | When |
|---|---|
404 sibooking_ | No such late fee |
409 sibooking_ | The action does not fit the fee’s status (the message says why: still growing, already paid, waived, cancelled, already billed) |
409 sibooking_rest_busy | Another request is billing or charging the fee |
409 sibooking_, 409 sibooking_ | accept or counter-payment on a fee with an unpriced line, or a total of 0 |
409 sibooking_ | counter-payment while a card charge runs |
409 sibooking_, 409 sibooking_ | The late-fee order or the booking order is gone |
409 sibooking_ | send-link: the booking order has no billing email |
409 sibooking_ | retry on a fee that is not charged to a card |
409 sibooking_ | refund of a deposit-paid fee without Refundable Security Deposits |
400 sibooking_ | accept with a route that is not ticked or cannot work for this fee |
400 sibooking_ | waive with a blank reason (400 rest_ without one) |
400 sibooking_ | refund with an amount that is not above 0, or more than is left |
400 rest_invalid_param | route or method not in its list |
curl -u "ck_your_key:cs_your_secret" -X POST \
-H "Content-Type: application/json" \
-d '{"reason":"Our delivery van broke down"}' \
"$STORE/wc-sibooking/v1/late-fees/456/waive"
Late fees on a return #
A return that creates or changes a late fee (POST /bookings/{id}/return in Bookings, availability and serials, POST /return and POST /return/scan in Sending and returning rentals) adds late_fees to its answer: each fee in the short form, which is the late-fee object without lines, calculated_minor, adjusted, the notes and location_id. Use its id with the calls above.
Hooks #
To react inside WordPress instead of polling, use the actions sibooking_, sibooking_ and sibooking_, and sibooking_, sibooking_, sibooking_, sibooking_, sibooking_, sibooking_ and sibooking_. The filter sibooking_ changes the ways a late fee can be collected, sibooking_ the reminder days (default 3 and 7), and sibooking_ decides whether a late-fee refund goes through the gateway.
