@beel_es/sdk 1.3.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +227 -0
- package/README.md +237 -29
- package/dist/index.d.mts +4875 -1235
- package/dist/index.d.ts +4875 -1235
- package/dist/index.js +1462 -184
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1460 -184
- package/dist/index.mjs.map +1 -1
- package/docs/reference/README.md +233 -0
- package/docs/reference/account-companies.md +55 -0
- package/docs/reference/account-invitations.md +57 -0
- package/docs/reference/account-members.md +97 -0
- package/docs/reference/account-webhooks.md +123 -0
- package/docs/reference/account.md +94 -0
- package/docs/reference/accounts.md +72 -0
- package/docs/reference/catalogs.md +68 -0
- package/docs/reference/client.md +113 -0
- package/docs/reference/company-customers.md +85 -0
- package/docs/reference/company-invoices-schedule.md +52 -0
- package/docs/reference/company-invoices.md +316 -0
- package/docs/reference/company-payment-connections-events.md +103 -0
- package/docs/reference/company-payment-connections.md +87 -0
- package/docs/reference/company-products.md +72 -0
- package/docs/reference/company-recurring-invoices.md +136 -0
- package/docs/reference/company-series.md +94 -0
- package/docs/reference/company-tax-configuration.md +36 -0
- package/docs/reference/company-verifactu-configuration.md +41 -0
- package/docs/reference/company.md +94 -0
- package/docs/reference/configuration.md +90 -0
- package/docs/reference/customer-builder.md +107 -0
- package/docs/reference/customers.md +91 -0
- package/docs/reference/errors.md +72 -0
- package/docs/reference/invoice-builder.md +149 -0
- package/docs/reference/invoices.md +250 -0
- package/docs/reference/nif.md +31 -0
- package/docs/reference/products.md +111 -0
- package/docs/reference/series.md +81 -0
- package/docs/reference/types.md +222 -0
- package/docs/reference/webhook-verifier.md +95 -0
- package/llms.txt +52 -0
- package/package.json +11 -4
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<!-- Generated by `npm run docs:reference` from the SDK source and openapi/public-api.yaml. Do not edit. -->
|
|
2
|
+
|
|
3
|
+
# `beel.products` — `ProductsResource`
|
|
4
|
+
|
|
5
|
+
[Reference index](README.md)
|
|
6
|
+
|
|
7
|
+
> **Deprecated.** The contract deprecates the session-focus routes. Use `beel.company(companyId).products` instead.
|
|
8
|
+
|
|
9
|
+
Products of the focused company, on the flat `/v1/products` routes.
|
|
10
|
+
|
|
11
|
+
## Methods
|
|
12
|
+
|
|
13
|
+
| Method | HTTP | Summary |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| [`beel.products.list(params?)`](#products-list) | `GET /v1/products` | List products with optional filters and pagination. |
|
|
16
|
+
| [`beel.products.create(body)`](#products-create) | `POST /v1/products` | Create a new product or service. |
|
|
17
|
+
| [`beel.products.get(id)`](#products-get) | `GET /v1/products/{product_id}` | Get a product by ID. |
|
|
18
|
+
| [`beel.products.update(id, body)`](#products-update) | `PUT /v1/products/{product_id}` | Update a product. |
|
|
19
|
+
| [`beel.products.delete(id)`](#products-delete) | `DELETE /v1/products/{product_id}` | Delete a product permanently. |
|
|
20
|
+
| [`beel.products.search(q, limit?)`](#products-search) | `GET /v1/products/search` | Search products by name or code. |
|
|
21
|
+
|
|
22
|
+
<a id="products-list"></a>
|
|
23
|
+
### `list(params?)`
|
|
24
|
+
|
|
25
|
+
List products with optional filters and pagination.
|
|
26
|
+
|
|
27
|
+
- **HTTP:** `GET /v1/products` · operation `listProducts` · scopes `products:read` · **deprecated in the contract**
|
|
28
|
+
- **Parameters:**
|
|
29
|
+
- `params?: ListParams` — Filters and pagination.
|
|
30
|
+
- **Returns:** The page of `products` and its `pagination`. Response `200` `data`: `{ products: Product[]; pagination: Pagination }`.
|
|
31
|
+
- **Throws:** `401`/`403` `BeeLAuthError` · `422` `BeeLValidationError` · `500` `BeeLApiError`
|
|
32
|
+
|
|
33
|
+
**Example**
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
const { products, pagination } = await beel.products.list({ category: 'SERVICE' });
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
<a id="products-create"></a>
|
|
40
|
+
### `create(body)`
|
|
41
|
+
|
|
42
|
+
Create a new product or service.
|
|
43
|
+
|
|
44
|
+
- **HTTP:** `POST /v1/products` · operation `createProduct` · scopes `products:write` · accepts `Idempotency-Key` · **deprecated in the contract**
|
|
45
|
+
- **Parameters:**
|
|
46
|
+
- `body: components['schemas']['CreateProductRequest']` — Name, category, price and main tax.
|
|
47
|
+
- **Returns:** The created product. Response `201` `data`: `Product`.
|
|
48
|
+
- **Throws:** `400`/`500` `BeeLApiError` · `401`/`403` `BeeLAuthError` · `409` `BeeLConflictError` · `422` `BeeLValidationError`
|
|
49
|
+
|
|
50
|
+
**Example**
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
const product = await beel.products.create({
|
|
54
|
+
name: 'Consulting',
|
|
55
|
+
code: 'CONS-001',
|
|
56
|
+
category: 'SERVICE',
|
|
57
|
+
default_price: 100,
|
|
58
|
+
main_tax: { type: 'IVA', percentage: 21 },
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
<a id="products-get"></a>
|
|
63
|
+
### `get(id)`
|
|
64
|
+
|
|
65
|
+
Get a product by ID.
|
|
66
|
+
|
|
67
|
+
- **HTTP:** `GET /v1/products/{product_id}` · operation `getProduct` · scopes `products:read` · **deprecated in the contract**
|
|
68
|
+
- **Parameters:**
|
|
69
|
+
- `id: string` — Product UUID.
|
|
70
|
+
- **Returns:** The product. Response `200` `data`: `Product`.
|
|
71
|
+
- **Throws:** `400`/`500` `BeeLApiError` · `401`/`403` `BeeLAuthError` · `404` `BeeLNotFoundError`
|
|
72
|
+
|
|
73
|
+
<a id="products-update"></a>
|
|
74
|
+
### `update(id, body)`
|
|
75
|
+
|
|
76
|
+
Update a product. Only provided fields are changed.
|
|
77
|
+
|
|
78
|
+
- **HTTP:** `PUT /v1/products/{product_id}` · operation `updateProduct` · scopes `products:write` · **deprecated in the contract**
|
|
79
|
+
- **Parameters:**
|
|
80
|
+
- `id: string` — Product UUID.
|
|
81
|
+
- `body: components['schemas']['UpdateProductRequest']` — Fields to change.
|
|
82
|
+
- **Returns:** The updated product. Response `200` `data`: `Product`.
|
|
83
|
+
- **Throws:** `400`/`500` `BeeLApiError` · `401`/`403` `BeeLAuthError` · `404` `BeeLNotFoundError` · `409` `BeeLConflictError` · `422` `BeeLValidationError`
|
|
84
|
+
|
|
85
|
+
<a id="products-delete"></a>
|
|
86
|
+
### `delete(id)`
|
|
87
|
+
|
|
88
|
+
Delete a product permanently.
|
|
89
|
+
|
|
90
|
+
- **HTTP:** `DELETE /v1/products/{product_id}` · operation `deleteProduct` · scopes `products:write` · **deprecated in the contract**
|
|
91
|
+
- **Parameters:**
|
|
92
|
+
- `id: string` — Product UUID.
|
|
93
|
+
- **Throws:** `401`/`403` `BeeLAuthError` · `404` `BeeLNotFoundError` · `500` `BeeLApiError`
|
|
94
|
+
|
|
95
|
+
<a id="products-search"></a>
|
|
96
|
+
### `search(q, limit?)`
|
|
97
|
+
|
|
98
|
+
Search products by name or code. Returns up to `limit` results.
|
|
99
|
+
|
|
100
|
+
- **HTTP:** `GET /v1/products/search` · operation `searchProducts` · scopes `products:read` · **deprecated in the contract**
|
|
101
|
+
- **Parameters:**
|
|
102
|
+
- `q: string` — Text to search in name or code.
|
|
103
|
+
- `limit?: number` — Maximum results.
|
|
104
|
+
- **Returns:** The matching products, as a bare array. Response `200` `data`: `Product[]`.
|
|
105
|
+
- **Throws:** `400`/`500` `BeeLApiError` · `401`/`403` `BeeLAuthError` · `422` `BeeLValidationError`
|
|
106
|
+
|
|
107
|
+
**Example**
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
const results = await beel.products.search('consulting', 5);
|
|
111
|
+
```
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<!-- Generated by `npm run docs:reference` from the SDK source and openapi/public-api.yaml. Do not edit. -->
|
|
2
|
+
|
|
3
|
+
# `beel.series` — `SeriesResource`
|
|
4
|
+
|
|
5
|
+
[Reference index](README.md)
|
|
6
|
+
|
|
7
|
+
> **Deprecated.** The contract deprecates the session-focus routes. Use `beel.company(companyId).series` instead.
|
|
8
|
+
|
|
9
|
+
Invoice series of the focused company, on the flat `/v1/configuration/series` routes.
|
|
10
|
+
|
|
11
|
+
## Methods
|
|
12
|
+
|
|
13
|
+
| Method | HTTP | Summary |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| [`beel.series.list(active?)`](#series-list) | `GET /v1/configuration/series` | List all invoice series. |
|
|
16
|
+
| [`beel.series.create(body)`](#series-create) | `POST /v1/configuration/series` | Create a new invoice series (e.g. "A-2026", "RECT"). |
|
|
17
|
+
| [`beel.series.update(id, body)`](#series-update) | `PUT /v1/configuration/series/{series_id}` | Update a series (name, description, etc.). |
|
|
18
|
+
| [`beel.series.delete(id)`](#series-delete) | `DELETE /v1/configuration/series/{series_id}` | Delete an invoice series. |
|
|
19
|
+
| [`beel.series.setDefault(id)`](#series-set-default) | `POST /v1/configuration/series/{series_id}/default` | Set a series as the default for new invoices. |
|
|
20
|
+
|
|
21
|
+
<a id="series-list"></a>
|
|
22
|
+
### `list(active?)`
|
|
23
|
+
|
|
24
|
+
List all invoice series. Optionally filter by active status.
|
|
25
|
+
|
|
26
|
+
- **HTTP:** `GET /v1/configuration/series` · operation `listSeries` · scopes `series:read` · **deprecated in the contract**
|
|
27
|
+
- **Parameters:**
|
|
28
|
+
- `active?: boolean` — Only active (`true`) or inactive (`false`) series; all when omitted.
|
|
29
|
+
- **Returns:** The series. Response `200` `data`: `{ series: InvoiceSeries[]; pagination?: Pagination }`.
|
|
30
|
+
- **Throws:** `401`/`403` `BeeLAuthError` · `422` `BeeLValidationError` · `500` `BeeLApiError`
|
|
31
|
+
|
|
32
|
+
**Example**
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
const series = await beel.series.list();
|
|
36
|
+
const activeSeries = await beel.series.list(true);
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
<a id="series-create"></a>
|
|
40
|
+
### `create(body)`
|
|
41
|
+
|
|
42
|
+
Create a new invoice series (e.g. "A-2026", "RECT").
|
|
43
|
+
|
|
44
|
+
- **HTTP:** `POST /v1/configuration/series` · operation `createSeries` · scopes `series:write` · accepts `Idempotency-Key` · **deprecated in the contract**
|
|
45
|
+
- **Parameters:**
|
|
46
|
+
- `body: any` — Code, name and format.
|
|
47
|
+
- **Returns:** The created series. Response `201` `data`: `InvoiceSeries`.
|
|
48
|
+
- **Throws:** `400`/`500` `BeeLApiError` · `401`/`403` `BeeLAuthError` · `409` `BeeLConflictError` · `422` `BeeLValidationError`
|
|
49
|
+
|
|
50
|
+
<a id="series-update"></a>
|
|
51
|
+
### `update(id, body)`
|
|
52
|
+
|
|
53
|
+
Update a series (name, description, etc.).
|
|
54
|
+
|
|
55
|
+
- **HTTP:** `PUT /v1/configuration/series/{series_id}` · operation `updateSeries` · scopes `series:write` · **deprecated in the contract**
|
|
56
|
+
- **Parameters:**
|
|
57
|
+
- `id: string` — Series UUID.
|
|
58
|
+
- `body: any` — Fields to change.
|
|
59
|
+
- **Returns:** The updated series. Response `200` `data`: `InvoiceSeries`.
|
|
60
|
+
- **Throws:** `400`/`500` `BeeLApiError` · `401`/`403` `BeeLAuthError` · `404` `BeeLNotFoundError` · `422` `BeeLValidationError`
|
|
61
|
+
|
|
62
|
+
<a id="series-delete"></a>
|
|
63
|
+
### `delete(id)`
|
|
64
|
+
|
|
65
|
+
Delete an invoice series. Only empty series can be deleted.
|
|
66
|
+
|
|
67
|
+
- **HTTP:** `DELETE /v1/configuration/series/{series_id}` · operation `deleteSeries` · scopes `series:write` · **deprecated in the contract**
|
|
68
|
+
- **Parameters:**
|
|
69
|
+
- `id: string` — Series UUID.
|
|
70
|
+
- **Throws:** `400`/`500` `BeeLApiError` · `401`/`403` `BeeLAuthError` · `404` `BeeLNotFoundError`
|
|
71
|
+
|
|
72
|
+
<a id="series-set-default"></a>
|
|
73
|
+
### `setDefault(id)`
|
|
74
|
+
|
|
75
|
+
Set a series as the default for new invoices.
|
|
76
|
+
|
|
77
|
+
- **HTTP:** `POST /v1/configuration/series/{series_id}/default` · operation `setDefaultSeries` · scopes `series:write` · accepts `Idempotency-Key` · **deprecated in the contract**
|
|
78
|
+
- **Parameters:**
|
|
79
|
+
- `id: string` — Series UUID.
|
|
80
|
+
- **Returns:** The series. Response `200` `data`: `InvoiceSeries`.
|
|
81
|
+
- **Throws:** `400`/`500` `BeeLApiError` · `401`/`403` `BeeLAuthError` · `404` `BeeLNotFoundError` · `409` `BeeLConflictError`
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
<!-- Generated by `npm run docs:reference` from the SDK source and openapi/public-api.yaml. Do not edit. -->
|
|
2
|
+
|
|
3
|
+
# Types
|
|
4
|
+
|
|
5
|
+
[Reference index](README.md)
|
|
6
|
+
|
|
7
|
+
Types defined by the SDK. The API's own types are generated from the contract: `import type { components, operations, paths } from '@beel_es/sdk'`.
|
|
8
|
+
|
|
9
|
+
<a id="beelconfig"></a>
|
|
10
|
+
## `BeeLConfig`
|
|
11
|
+
|
|
12
|
+
Options of `new BeeL(config)`. Only `apiKey` is required.
|
|
13
|
+
|
|
14
|
+
**Retries and idempotency.** A call is retried automatically, up to `maxRetries` times,
|
|
15
|
+
only when sending it again can never apply it twice:
|
|
16
|
+
|
|
17
|
+
- `429` is always retried, after `Retry-After`: the API refused the request unprocessed.
|
|
18
|
+
- `409 IDEMPOTENCY_KEY_PROCESSING` is retried with the same key after `Retry-After`.
|
|
19
|
+
- `5xx` and network errors are retried for `GET` requests and for requests that carry an
|
|
20
|
+
`Idempotency-Key` — every `POST` does, unless `autoIdempotencyKey` is `false`. A `5xx`
|
|
21
|
+
the API marks `Idempotency-Replay: true` is the stored outcome of that key and is not
|
|
22
|
+
retried: the same key would return it again.
|
|
23
|
+
- `PUT`, `PATCH` and `DELETE` without a key are not retried after a `5xx` or network error.
|
|
24
|
+
|
|
25
|
+
Every retry of a call reuses that call's `Idempotency-Key`, so an automatic retry never
|
|
26
|
+
creates a second invoice. Two separate calls get two keys: to retry a create yourself
|
|
27
|
+
after it failed with a `5xx` or a network error, use `invoices.createOnce`, or look the
|
|
28
|
+
invoice up by `external_ref` before creating it again.
|
|
29
|
+
|
|
30
|
+
| Field | Type | Description |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| `apiKey` | `string` | API key: `beel_sk_live_*` (production) or `beel_sk_test_*` (sandbox). |
|
|
33
|
+
| `baseUrl?` | `string` | Base URL. Default: `https://app.beel.es/api`. |
|
|
34
|
+
| `maxRetries?` | `number` | Automatic retries after the first attempt, for the cases listed on `BeeLConfig`. `0` disables them. Default: `3`. |
|
|
35
|
+
| `retryDelayMs?` | `number` | Base delay of the exponential backoff, in milliseconds. Default: `500`. |
|
|
36
|
+
| `maxRetryDelayMs?` | `number` | Upper bound of any single wait between attempts, `Retry-After` included, in ms. Default: `30000`. |
|
|
37
|
+
| `autoIdempotencyKey?` | `boolean` | Add one `Idempotency-Key` (a UUID) to every `POST` that does not carry its own, reused by every automatic retry of that call. With `false`, a `POST` without a key is only retried after a `429`. Default: `true`. |
|
|
38
|
+
|
|
39
|
+
<a id="requestoptions"></a>
|
|
40
|
+
## `RequestOptions`
|
|
41
|
+
|
|
42
|
+
Per-call options, accepted as the last argument of the `company.invoices` methods.
|
|
43
|
+
|
|
44
|
+
| Field | Type | Description |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| `idempotencyKey?` | `string` | `Idempotency-Key` of this call, instead of the automatic one: letters, digits, `_` and `-`, up to 255 characters. Every automatic retry of the call reuses it. Persist it with your order to retry the same operation later: within 24 hours the API replays the first `2xx` or `5xx` answer instead of running the operation again. |
|
|
47
|
+
| `signal?` | `AbortSignal` | Aborts the call — the automatic retries and the waits between them included. |
|
|
48
|
+
| `timeoutMs?` | `number` | Aborts the call after this many milliseconds, automatic retries included. |
|
|
49
|
+
|
|
50
|
+
**Example**
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
await company.invoices.create(body, undefined, {
|
|
54
|
+
idempotencyKey: `order-${order.id}`,
|
|
55
|
+
timeoutMs: 15_000,
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
<a id="beelerrorcode"></a>
|
|
60
|
+
## `BeeLErrorCode`
|
|
61
|
+
|
|
62
|
+
One of the `BeeLErrorCodes` values.
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
type BeeLErrorCode = (typeof BeeLErrorCodes)[keyof typeof BeeLErrorCodes]
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
<a id="webhookevent"></a>
|
|
69
|
+
## `WebhookEvent`
|
|
70
|
+
|
|
71
|
+
Union type of all possible webhook events
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
type WebhookEvent = | VeriFactuStatusUpdatedEvent | InvoiceIssuedEvent | InvoiceVoidedEvent | InvoiceEmailSentEvent | InvoicePdfGeneratedEvent | InvoiceScheduleFailedEvent | RecurringInvoicePausedEvent | AccountClaimedEvent | CompanyCreatedEvent | RepresentationSignedEvent | WebhookTestEvent
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
<a id="webhookeventenvelope"></a>
|
|
78
|
+
## `WebhookEventEnvelope`
|
|
79
|
+
|
|
80
|
+
Fields every delivery carries, whatever its type.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
type WebhookEventEnvelope = Omit<GeneratedEnvelope, 'type'> & { type: `${WebhookEventType}` }
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
<a id="verifactustatusupdatedevent"></a>
|
|
87
|
+
## `VeriFactuStatusUpdatedEvent`
|
|
88
|
+
|
|
89
|
+
`verifactu.status.updated`: AEAT answered for an invoice's VeriFactu record (`new_status`, `qr_url`…).
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
type VeriFactuStatusUpdatedEvent = BusinessEvent<'verifactu.status.updated', WebhookEventDataVeriFactuStatusUpdated>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
<a id="invoiceissuedevent"></a>
|
|
96
|
+
## `InvoiceIssuedEvent`
|
|
97
|
+
|
|
98
|
+
`invoice.issued`: an invoice was issued.
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
type InvoiceIssuedEvent = BusinessEvent<'invoice.issued', WebhookEventDataInvoiceIssued>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
<a id="invoicevoidedevent"></a>
|
|
105
|
+
## `InvoiceVoidedEvent`
|
|
106
|
+
|
|
107
|
+
`invoice.voided`: an invoice was voided.
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
type InvoiceVoidedEvent = BusinessEvent<'invoice.voided', WebhookEventDataInvoiceVoided>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
<a id="invoiceemailsentevent"></a>
|
|
114
|
+
## `InvoiceEmailSentEvent`
|
|
115
|
+
|
|
116
|
+
`invoice.email.sent`: an invoice email was accepted by the email provider.
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
type InvoiceEmailSentEvent = BusinessEvent<'invoice.email.sent', WebhookEventDataInvoiceEmailSent>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
<a id="invoicepdfgeneratedevent"></a>
|
|
123
|
+
## `InvoicePdfGeneratedEvent`
|
|
124
|
+
|
|
125
|
+
`invoice.pdf.generated`: the PDF of an invoice is ready.
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
type InvoicePdfGeneratedEvent = BusinessEvent<'invoice.pdf.generated', WebhookEventDataInvoicePdfGenerated>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
<a id="invoiceschedulefailedevent"></a>
|
|
132
|
+
## `InvoiceScheduleFailedEvent`
|
|
133
|
+
|
|
134
|
+
`invoice.schedule_failed`: a scheduled invoice could not be processed.
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
type InvoiceScheduleFailedEvent = BusinessEvent<'invoice.schedule_failed', WebhookEventDataInvoiceScheduleFailed>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
<a id="recurringinvoicepausedevent"></a>
|
|
141
|
+
## `RecurringInvoicePausedEvent`
|
|
142
|
+
|
|
143
|
+
`recurring_invoice.paused`: a recurring invoice was paused.
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
type RecurringInvoicePausedEvent = BusinessEvent<'recurring_invoice.paused', WebhookEventDataRecurringInvoicePaused>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
<a id="accountclaimedevent"></a>
|
|
150
|
+
## `AccountClaimedEvent`
|
|
151
|
+
|
|
152
|
+
`account.claimed`: the holder of a provisioned account took ownership.
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
type AccountClaimedEvent = BusinessEvent<'account.claimed', WebhookEventDataAccountClaimed>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
<a id="companycreatedevent"></a>
|
|
159
|
+
## `CompanyCreatedEvent`
|
|
160
|
+
|
|
161
|
+
`company.created`: a company (NIF) was created.
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
type CompanyCreatedEvent = BusinessEvent<'company.created', WebhookEventDataCompanyCreated>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
<a id="representationsignedevent"></a>
|
|
168
|
+
## `RepresentationSignedEvent`
|
|
169
|
+
|
|
170
|
+
`representation.signed`: a representation document was signed.
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
type RepresentationSignedEvent = BusinessEvent<'representation.signed', WebhookEventDataRepresentationSigned>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
<a id="webhooktestevent"></a>
|
|
177
|
+
## `WebhookTestEvent`
|
|
178
|
+
|
|
179
|
+
A delivery sent with "Send test": `test` is `true` and `data` is a synthetic message,
|
|
180
|
+
whatever `type` says. Check `event.test` before narrowing on `event.type`.
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
type WebhookTestEvent = Omit<GeneratedEnvelope, 'type' | 'test'> & { type: `${WebhookEventType}`; test: true; data: WebhookEventDataTest; }
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
<a id="external_ref_unique_invoice_types"></a>
|
|
187
|
+
## `EXTERNAL_REF_UNIQUE_INVOICE_TYPES`
|
|
188
|
+
|
|
189
|
+
Invoice types whose `external_ref` the API keeps unique: at most one live (not deleted)
|
|
190
|
+
invoice of these types per reference and environment, whatever its status — a `VOIDED`
|
|
191
|
+
one included. Correctives are exempt, and proformas are not covered.
|
|
192
|
+
|
|
193
|
+
| Key | Value | Description |
|
|
194
|
+
|---|---|---|
|
|
195
|
+
|
|
196
|
+
<a id="createinvoiceoncerequest"></a>
|
|
197
|
+
## `CreateInvoiceOnceRequest`
|
|
198
|
+
|
|
199
|
+
Body of `invoices.createOnce`: a `CreateInvoiceRequest` whose `type` is `STANDARD` or
|
|
200
|
+
`SIMPLIFIED` and whose `external_ref` is required — it is what makes the call safe to repeat.
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
type CreateInvoiceOnceRequest = Omit<CreateInvoiceRequest, 'type' | 'external_ref'> & { type: ExternalRefUniqueInvoiceType; external_ref: string; }
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
<a id="createinvoiceonceparams"></a>
|
|
207
|
+
## `CreateInvoiceOnceParams`
|
|
208
|
+
|
|
209
|
+
Query of `invoices.createOnce`: the same as `invoices.create`.
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
type CreateInvoiceOnceParams = operations['createCompanyInvoice']['parameters']['query']
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
<a id="externalrefuniqueinvoicetype"></a>
|
|
216
|
+
## `ExternalRefUniqueInvoiceType`
|
|
217
|
+
|
|
218
|
+
Invoice types `createInvoiceOnce` accepts.
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
type ExternalRefUniqueInvoiceType = (typeof EXTERNAL_REF_UNIQUE_INVOICE_TYPES)[number]
|
|
222
|
+
```
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<!-- Generated by `npm run docs:reference` from the SDK source and openapi/public-api.yaml. Do not edit. -->
|
|
2
|
+
|
|
3
|
+
# `WebhookVerifier`
|
|
4
|
+
|
|
5
|
+
[Reference index](README.md)
|
|
6
|
+
|
|
7
|
+
Webhook signature verification for BeeL webhooks
|
|
8
|
+
|
|
9
|
+
Every webhook delivery includes a `BeeL-Signature` header that must be verified
|
|
10
|
+
to ensure the webhook came from BeeL and hasn't been tampered with.
|
|
11
|
+
|
|
12
|
+
### Security Requirements
|
|
13
|
+
|
|
14
|
+
1. **Always verify** the signature before processing the webhook
|
|
15
|
+
2. **Use constant-time comparison** to prevent timing attacks
|
|
16
|
+
3. **Reject old events** (older than 5 minutes)
|
|
17
|
+
4. **Use raw request body** (before parsing JSON)
|
|
18
|
+
|
|
19
|
+
### Header Format
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
BeeL-Signature: t=1741362026,v1=3c4f7a2e1b9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Where:
|
|
26
|
+
- `t` = Unix timestamp when the webhook was sent
|
|
27
|
+
- `v1` = HMAC-SHA256 signature of the payload
|
|
28
|
+
|
|
29
|
+
**Example — Express.js**
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import express from 'express';
|
|
33
|
+
import { WebhookVerifier } from '@beel_es/sdk';
|
|
34
|
+
|
|
35
|
+
const verifier = new WebhookVerifier('your_webhook_secret');
|
|
36
|
+
|
|
37
|
+
app.post('/webhooks/beel', express.raw({ type: 'application/json' }), (req, res) => {
|
|
38
|
+
const signature = req.headers['beel-signature'] as string;
|
|
39
|
+
const rawBody = req.body.toString('utf8');
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const event = verifier.verify(rawBody, signature);
|
|
43
|
+
|
|
44
|
+
if (event.type === 'verifactu.status.updated') {
|
|
45
|
+
console.log('VeriFactu status:', event.data.new_status);
|
|
46
|
+
if (event.data.new_status === 'ACCEPTED') {
|
|
47
|
+
console.log('QR URL:', event.data.qr_url);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
res.status(200).send('OK');
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error('Invalid webhook:', error.message);
|
|
54
|
+
res.status(400).send('Invalid signature');
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Constructor
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
new WebhookVerifier(secret: string, toleranceSeconds?: number)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Creates a new WebhookVerifier
|
|
66
|
+
|
|
67
|
+
## Methods
|
|
68
|
+
|
|
69
|
+
| Method | HTTP | Summary |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| [`WebhookVerifier.verify(rawBody, signatureHeader)`](#webhook-verifier-verify) | via `parseSignatureHeader`, `computeSignature`, `secureCompare` | Verify a webhook signature and return the parsed event |
|
|
72
|
+
|
|
73
|
+
<a id="webhook-verifier-verify"></a>
|
|
74
|
+
### `verify(rawBody, signatureHeader)`
|
|
75
|
+
|
|
76
|
+
Verify a webhook signature and return the parsed event
|
|
77
|
+
|
|
78
|
+
- **Parameters:**
|
|
79
|
+
- `rawBody: string | Buffer` — Raw request body (string or Buffer, before JSON parsing)
|
|
80
|
+
- `signatureHeader: string | undefined` — Value of the `BeeL-Signature` header
|
|
81
|
+
- **Returns:** Parsed webhook event
|
|
82
|
+
- **Throws:** `WebhookVerificationError` If signature is invalid or event is too old
|
|
83
|
+
|
|
84
|
+
**Example — Basic usage**
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
const verifier = new WebhookVerifier('your_secret');
|
|
88
|
+
const event = verifier.verify(rawBody, signature);
|
|
89
|
+
|
|
90
|
+
if (event.test) return; // a "Send test" delivery carries a synthetic `data`
|
|
91
|
+
if (event.type === 'verifactu.status.updated') {
|
|
92
|
+
console.log('Invoice:', event.data.invoice_number);
|
|
93
|
+
console.log('Status:', event.data.new_status);
|
|
94
|
+
}
|
|
95
|
+
```
|
package/llms.txt
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# @beel_es/sdk
|
|
2
|
+
|
|
3
|
+
> Official Node.js/TypeScript SDK for the BeeL invoicing API (Spain, VeriFactu). Read these
|
|
4
|
+
> Markdown files instead of `dist/index.d.ts`: every method, its HTTP operation, parameters,
|
|
5
|
+
> return shape and errors are documented here, generated from the source and the contract.
|
|
6
|
+
|
|
7
|
+
## Start here
|
|
8
|
+
|
|
9
|
+
- [README](README.md): client setup and common tasks — find the company id, create and issue
|
|
10
|
+
invoices, correctives, `external_ref` lookups, VeriFactu status, retries and idempotency.
|
|
11
|
+
- [Reference index](docs/reference/README.md): every resource and method in one table.
|
|
12
|
+
|
|
13
|
+
## Rules that prevent duplicate invoices
|
|
14
|
+
|
|
15
|
+
- Always address a company explicitly: `beel.company(companyId)`.
|
|
16
|
+
- Set `external_ref` on every invoice you create from your own order, and create it with
|
|
17
|
+
`beel.company(id).invoices.createOnce(body)`: it is safe to call again after any failure.
|
|
18
|
+
- Automatic retries reuse the call's `Idempotency-Key`; they never create a second invoice.
|
|
19
|
+
Do not disable them to write your own unless you reuse one key per operation.
|
|
20
|
+
|
|
21
|
+
## Reference pages
|
|
22
|
+
|
|
23
|
+
- [beel](docs/reference/client.md): The BeeL API client.
|
|
24
|
+
- [beel.account(accountId)](docs/reference/account.md): Operations scoped to one account: its companies (NIFs), members, invitations, webhooks and usage.
|
|
25
|
+
- [beel.account(accountId).companies](docs/reference/account-companies.md): Companies (NIFs) of an account — where the `companyId` of `beel.company(companyId)` comes from.
|
|
26
|
+
- [beel.account(accountId).invitations](docs/reference/account-invitations.md): Invitations to join an account.
|
|
27
|
+
- [beel.account(accountId).members](docs/reference/account-members.md): Members of an account and their per-company grants.
|
|
28
|
+
- [beel.account(accountId).webhooks](docs/reference/account-webhooks.md): Webhook subscriptions of an account.
|
|
29
|
+
- [beel.accounts](docs/reference/accounts.md): Accounts you provisioned and manage (multi-account provisioning for platforms and advisory firms).
|
|
30
|
+
- [beel.catalogs](docs/reference/catalogs.md): Account-wide catalogs, the credential's identity and personal preferences, on their canonical paths.
|
|
31
|
+
- [beel.company(companyId)](docs/reference/company.md): Operations scoped to a single company (NIF).
|
|
32
|
+
- [beel.company(companyId).customers](docs/reference/company-customers.md): Customers of one company.
|
|
33
|
+
- [beel.company(companyId).invoices](docs/reference/company-invoices.md): Invoice lifecycle of one company: create a draft (or issue it directly), issue, void, correct, list and read, PDF and email.
|
|
34
|
+
- [beel.company(companyId).invoices.schedule](docs/reference/company-invoices-schedule.md): Scheduled issuing of one invoice: read it, set it, clear it.
|
|
35
|
+
- [beel.company(companyId).paymentConnections](docs/reference/company-payment-connections.md): Payment connections of a company (NIF): the Stripe Connect link whose charges auto-generate invoices under that NIF.
|
|
36
|
+
- [beel.company(companyId).paymentConnections.events(connectionId)](docs/reference/company-payment-connections-events.md): Payment events received through a connection, and the recovery levers for the ones that did not produce an invoice.
|
|
37
|
+
- [beel.company(companyId).products](docs/reference/company-products.md): Products and services of one company.
|
|
38
|
+
- [beel.company(companyId).recurringInvoices](docs/reference/company-recurring-invoices.md): Recurring invoice templates of one company.
|
|
39
|
+
- [beel.company(companyId).series](docs/reference/company-series.md): Invoice series (numbering) of one company.
|
|
40
|
+
- [beel.company(companyId).taxConfiguration](docs/reference/company-tax-configuration.md): Tax defaults of one company (main tax, IRPF, equivalence surcharge).
|
|
41
|
+
- [beel.company(companyId).verifactuConfiguration](docs/reference/company-verifactu-configuration.md): VeriFactu configuration of one company.
|
|
42
|
+
- [beel.nif](docs/reference/nif.md): NIF validation against the AEAT register.
|
|
43
|
+
- [CustomerBuilder](docs/reference/customer-builder.md): Fluent builder for the body of `customers.create`.
|
|
44
|
+
- [InvoiceBuilder](docs/reference/invoice-builder.md): Fluent builder for the body of `invoices.create`.
|
|
45
|
+
- [WebhookVerifier](docs/reference/webhook-verifier.md): Webhook signature verification for BeeL webhooks
|
|
46
|
+
- [beel.configuration](docs/reference/configuration.md) (deprecated): Account-wide configuration on the flat `/v1/configuration/*` routes.
|
|
47
|
+
- [beel.customers](docs/reference/customers.md) (deprecated): Customers of the focused company, on the flat `/v1/customers` routes.
|
|
48
|
+
- [beel.invoices](docs/reference/invoices.md) (deprecated): Invoices of the focused company, on the flat `/v1/invoices` routes.
|
|
49
|
+
- [beel.products](docs/reference/products.md) (deprecated): Products of the focused company, on the flat `/v1/products` routes.
|
|
50
|
+
- [beel.series](docs/reference/series.md) (deprecated): Invoice series of the focused company, on the flat `/v1/configuration/series` routes.
|
|
51
|
+
- [Errors](docs/reference/errors.md): error classes and codes.
|
|
52
|
+
- [Types](docs/reference/types.md): exported interfaces and constants.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beel_es/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Official Node.js SDK for BeeL Public API - Spanish invoicing platform with VeriFactu support",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -14,20 +14,26 @@
|
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
|
+
"docs/reference",
|
|
18
|
+
"llms.txt",
|
|
17
19
|
"README.md",
|
|
20
|
+
"CHANGELOG.md",
|
|
18
21
|
"LICENSE"
|
|
19
22
|
],
|
|
20
23
|
"scripts": {
|
|
21
|
-
"generate": "
|
|
24
|
+
"generate": "node scripts/generate-types.mjs",
|
|
22
25
|
"generate:webhooks": "npx openapi-typescript-codegen -i openapi/webhook-receiver-api.yaml -o src/generated-webhooks --client fetch",
|
|
23
26
|
"build": "tsup",
|
|
27
|
+
"typecheck": "tsc --noEmit -p .",
|
|
24
28
|
"build:full": "npm run generate && npm run generate:webhooks && npm run build",
|
|
25
29
|
"dev": "tsup --watch",
|
|
26
30
|
"check:deprecated": "node scripts/check-deprecated.mjs",
|
|
27
|
-
"test": "npm run check:deprecated && npm run check:coverage && vitest run",
|
|
31
|
+
"test": "npm run check:deprecated && npm run check:coverage && npm run check:reference && vitest run",
|
|
28
32
|
"test:e2e": "vitest run --config vitest.e2e.config.ts",
|
|
29
33
|
"prepublishOnly": "npm run build:full && npm test",
|
|
30
|
-
"check:coverage": "node scripts/check-coverage.mjs"
|
|
34
|
+
"check:coverage": "node scripts/check-coverage.mjs",
|
|
35
|
+
"docs:reference": "node scripts/generate-reference.mjs",
|
|
36
|
+
"check:reference": "node scripts/generate-reference.mjs --check"
|
|
31
37
|
},
|
|
32
38
|
"keywords": [
|
|
33
39
|
"beel",
|
|
@@ -53,6 +59,7 @@
|
|
|
53
59
|
"homepage": "https://beel.es",
|
|
54
60
|
"devDependencies": {
|
|
55
61
|
"@types/node": "^22.19.15",
|
|
62
|
+
"js-yaml": "^4.3.2",
|
|
56
63
|
"openapi-typescript": "^7.13.0",
|
|
57
64
|
"openapi-typescript-codegen": "^0.30.0",
|
|
58
65
|
"tsup": "^8.5.1",
|