@beel_es/sdk 1.2.0 → 2.0.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/README.md CHANGED
@@ -62,8 +62,22 @@ const company = beel.company('company-uuid');
62
62
  // Invoices — full lifecycle
63
63
  const { invoices, pagination } = await company.invoices.list({ status: 'ISSUED' });
64
64
  await company.invoices.issue('invoice-uuid');
65
- await company.invoices.void('invoice-uuid', { reason: 'Billing error' });
66
- await company.invoices.createCorrective('invoice-uuid', { ... });
65
+ // A void is only for an invoice issued by mistake; `issued_in_error: true` is required
66
+ // once it has been sent or paid. An operation that did happen gets a corrective instead.
67
+ await company.invoices.void('invoice-uuid', { reason: 'Duplicate', issued_in_error: true });
68
+ await company.invoices.createCorrective('invoice-uuid', {
69
+ rectification_type: 'PARTIAL',
70
+ rectification_code: 'R1',
71
+ reason: 'Discount granted after the sale',
72
+ circumstance_date: '2026-09-01', // when the art. 80 circumstance happened, if any
73
+ lines: [ ... ],
74
+ });
75
+ // Exchange issued simplified invoices for a full one with the customer identified
76
+ await company.invoices.createSimplifiedExchange({
77
+ simplified_invoice_ids: ['simplified-uuid'],
78
+ recipient: { customer_id: 'customer-uuid' },
79
+ });
80
+ const records = await company.invoices.verifactuRecords('invoice-uuid'); // registration, cancellation
67
81
  const pdf = await company.invoices.getPdf('invoice-uuid');
68
82
 
69
83
  // Customers, products, series
@@ -75,11 +89,74 @@ await company.series.ensureDefaults(); // idempotent seeding of the typed defaul
75
89
  await company.recurringInvoices.create({ ... });
76
90
  await company.recurringInvoices.setStatus('rec-uuid', { status: 'PAUSED' });
77
91
 
92
+ // Scheduling — one PUT sets or moves it, one DELETE clears it
93
+ await company.invoices.schedule.set('invoice-uuid', { scheduled_for: '2026-12-01' });
94
+ await company.invoices.schedule.clear('invoice-uuid');
95
+
96
+ // Derive a new invoice from an existing one
97
+ const copy = await company.invoices.derive({ from_invoice_id: 'invoice-uuid' });
98
+
99
+ // Fiscal configuration of this NIF
100
+ const verifactu = await company.verifactuConfiguration.get();
101
+ await company.verifactuConfiguration.update({ enabled: true });
102
+ const taxes = await company.taxConfiguration.get();
103
+
78
104
  // Company health
79
105
  const summary = await company.fiscalSummary({ year: 2026 });
80
106
  const readiness = await company.issuingReadiness();
81
107
  ```
82
108
 
109
+ Whether an invoice reaches AEAT is a fact of the **NIF**, resolved at issue time — not a
110
+ per-invoice choice. `enabled` is the only writable field of the VeriFactu configuration.
111
+
112
+ ### Payment connections (Stripe per NIF)
113
+
114
+ A connection links Stripe to one NIF so its charges auto-generate invoices under it. It is
115
+ addressed by **its own UUID**, not by the provider slug — a NIF can hold several
116
+ connections of the same provider. The slug only appears when you start an authorization.
117
+
118
+ ```typescript
119
+ const { connections } = await company.paymentConnections.list();
120
+
121
+ const { authorization_url } = await company.paymentConnections.authorize({
122
+ provider: 'stripe',
123
+ });
124
+
125
+ const events = company.paymentConnections.events(connections[0].id);
126
+ const { events: pending } = await events.list({ needs_action: true });
127
+
128
+ // Recovery levers for a charge that did not invoice
129
+ await events.retry('event-uuid');
130
+ const { invoice_id } = await events.draft('event-uuid'); // review before issuing
131
+ await events.resolve('event-uuid');
132
+
133
+ await company.paymentConnections.disconnect(connections[0].id);
134
+ ```
135
+
136
+ ## Catalogs and preferences
137
+
138
+ ```typescript
139
+ const taxTypes = await beel.catalogs.taxTypes();
140
+ const options = await beel.catalogs.invoiceCustomizationOptions();
141
+ await beel.catalogs.updateMe({ language: 'es' }); // the language belongs to the person
142
+ ```
143
+
144
+ ## Any endpoint: `beel.raw`
145
+
146
+ A route reaches the generated types as soon as the contract is synced, but its ergonomic
147
+ wrapper is written by hand. `beel.raw` lets you call anything in the contract today,
148
+ without waiting for a release:
149
+
150
+ ```typescript
151
+ const { data } = await beel.raw.GET('/v1/companies/{company_id}/invoice-customization', {
152
+ params: { path: { company_id: 'company-uuid' } },
153
+ });
154
+ ```
155
+
156
+ It is the same client the resources use — authentication, retries and `Idempotency-Key`
157
+ still apply — and it stays typed: a path, parameter or body the contract does not have
158
+ will not compile. What you give up is the sugar and the naming stability of the wrappers.
159
+
83
160
  ## Accounts (managed accounts, members & webhooks)
84
161
 
85
162
  For integrators managing several accounts (provisioning, gestorías, platforms):
@@ -227,8 +304,11 @@ app.post('/webhooks/beel', express.raw({ type: 'application/json' }), (req, res)
227
304
  req.headers['beel-signature'] as string,
228
305
  );
229
306
 
307
+ // "Send test" deliveries carry a synthetic `data`: acknowledge and stop.
308
+ if (event.test) return res.status(200).send('OK');
309
+
230
310
  if (event.type === 'verifactu.status.updated') {
231
- console.log(event.data.new_status); // 'ACCEPTED' | 'REJECTED'
311
+ console.log(event.data.new_status); // 'PENDING' | 'ACCEPTED' | 'REJECTED' | 'VOIDED'
232
312
  }
233
313
 
234
314
  res.status(200).send('OK');