> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bookingshake.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Payments

> List the payments of an invoice, or retrieve a single payment

<Warning>
  **Beta** - Payment data is currently in beta. The payload structure may still evolve before general availability. Share your feedback at [support@bookingshake.com](mailto:support@bookingshake.com).
</Warning>

## Overview

The payment endpoints expose the payments recorded on your venue's invoices:

* `GET /payments?invoice_id={id}` - list **every payment attached to an invoice**
* `GET /payments/{id}` - retrieve a **single payment** by its document ID

Both return the same per-payment shape. Useful to reconcile an invoice's payments on demand, or to back-fill a missed `payment.*` webhook.

<Note>
  **Security deposits (holds) are out of scope** - they are excluded from the list and return `404` on the single-get, consistent with the payment webhooks (which never emit for holds). Amounts are integer **cents**, dates are `YYYY-MM-DD` strings in the `Europe/Paris` timezone, timestamps are Unix **milliseconds**, and missing values are explicit `null`.
</Note>

## Authentication

All requests require a Bearer token (your BookingShake API key):

```
Authorization: Bearer YOUR_API_KEY
```

## List payments of an invoice

`GET /payments?invoice_id={id}` returns every payment attached to the given invoice. The result is scoped to the authenticated venue, so an invoice that does not exist or belongs to another venue simply returns an empty array.

<ParamField query="invoice_id" type="string" required>
  ID of the invoice whose payments you want to list - the `invoice_id` carried by the `payment.*` webhooks, and the `id` of [`GET /invoices/{id}`](/api-reference/invoices).
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.bookingshake.io/api/payments?invoice_id=file-456" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```javascript Node.js theme={null}
  const res = await fetch(
    "https://api.bookingshake.io/api/payments?invoice_id=file-456",
    { headers: { Authorization: `Bearer ${process.env.BOOKINGSHAKE_API_KEY}` } },
  );
  const { data: payments } = await res.json();
  ```

  ```python Python theme={null}
  import os, requests

  res = requests.get(
      "https://api.bookingshake.io/api/payments",
      params={"invoice_id": "file-456"},
      headers={"Authorization": f"Bearer {os.environ['BOOKINGSHAKE_API_KEY']}"},
  )
  payments = res.json()["data"]
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init("https://api.bookingshake.io/api/payments?invoice_id=file-456");
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      "Authorization: Bearer " . getenv("BOOKINGSHAKE_API_KEY"),
  ]);
  $payments = json_decode(curl_exec($ch), true)["data"];
  curl_close($ch);
  ```
</CodeGroup>

The payments are returned wrapped in the standard `{ message, data }` envelope, where `data` is an array of payment objects (each identical in shape to `GET /payments/{id}`).

```json theme={null}
{
  "message": "success",
  "data": [
    {
      "id": "payment-789",
      "amount": 90000,
      "status": "paid",
      "name": "Acompte 30%",
      "method": "Virement bancaire",
      "received_date": "2026-06-10",
      "due_date": "2026-06-15",
      "created_at": 1749549600000,
      "updated_at": 1749722400000,
      "invoice_id": "file-456",
      "invoice_number": "FAC-2026-0021",
      "quote_id": "quote-123",
      "booking_id": "booking-abc"
    }
  ]
}
```

## Get a payment

`GET /payments/{id}` returns a single payment by its document ID, in the same shape as the list items.

<ParamField path="id" type="string" required>
  The payment document ID - the `id` field carried by the `payment.*` webhooks.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.bookingshake.io/api/payments/payment-789 \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```javascript Node.js theme={null}
  const res = await fetch("https://api.bookingshake.io/api/payments/payment-789", {
    headers: { Authorization: `Bearer ${process.env.BOOKINGSHAKE_API_KEY}` },
  });
  const { data: payment } = await res.json();
  ```

  ```python Python theme={null}
  import os, requests

  res = requests.get(
      "https://api.bookingshake.io/api/payments/payment-789",
      headers={"Authorization": f"Bearer {os.environ['BOOKINGSHAKE_API_KEY']}"},
  )
  payment = res.json()["data"]
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init("https://api.bookingshake.io/api/payments/payment-789");
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      "Authorization: Bearer " . getenv("BOOKINGSHAKE_API_KEY"),
  ]);
  $payment = json_decode(curl_exec($ch), true)["data"];
  curl_close($ch);
  ```
</CodeGroup>

## Fields

| Field            | Type           | Description                                                                                                                           |
| ---------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `id`             | string         | Unique payment ID                                                                                                                     |
| `amount`         | number \| null | Amount in integer cents                                                                                                               |
| `status`         | string \| null | `waiting`, `paid`, or `canceled`                                                                                                      |
| `name`           | string \| null | Payment label as entered by the user                                                                                                  |
| `method`         | string \| null | Payment method, **verbatim** label (not a normalized enum) - appears in the venue locale language. Do not build logic on exact values |
| `received_date`  | string \| null | Date the payment was received, `YYYY-MM-DD`                                                                                           |
| `due_date`       | string \| null | Date the payment is expected, `YYYY-MM-DD`                                                                                            |
| `created_at`     | number \| null | Creation timestamp, Unix milliseconds                                                                                                 |
| `updated_at`     | number \| null | Last update timestamp, Unix milliseconds                                                                                              |
| `invoice_id`     | string \| null | ID of the linked invoice - matches the `id` of [`GET /invoices/{id}`](/api-reference/invoices)                                        |
| `invoice_number` | string \| null | Number of the linked invoice, denormalized for convenience                                                                            |
| `quote_id`       | string \| null | ID of the linked quote                                                                                                                |
| `booking_id`     | string \| null | Correlation key shared with [invoice](/api-reference/webhooks/invoices) and payment events of the same booking                        |

See the [payment webhook documentation](/api-reference/webhooks/payments#data-fields) for the full field reference.

## Errors

| Status | Meaning                                                                                                                                                         |
| ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Missing/invalid token, missing `invoice_id` (`GET /payments`), or missing payment id (`GET /payments/{id}`)                                                     |
| `404`  | Payment not found - it does not exist, belongs to another venue, or is a security deposit (hold). *(single-get only; the list returns `200` with `[]` instead)* |
| `429`  | [Rate limit](/api-reference/rate-limiting) exceeded (60 requests/minute)                                                                                        |
| `500`  | Internal server error                                                                                                                                           |

<Note>
  Out-of-scope payments are never disclosed: the single-get returns a uniform `404`, and the list silently omits them - an invoice belonging to another venue returns an empty array, never an error revealing its existence.
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="Get an Invoice" icon="file-invoice" href="/api-reference/invoices">
    Retrieve the invoice linked to a payment via invoice\_id
  </Card>

  <Card title="Payment Events" icon="credit-card" href="/api-reference/webhooks/payments">
    Receive payments in real time via the payment.\* webhooks
  </Card>
</CardGroup>
