@behio/storefront-sdk 2.23.0 → 2.25.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
@@ -207,6 +207,7 @@ The provider notifies hooks after restoring browser session storage.
207
207
  | `faq` | FAQ groups and visible questions in the requested language (web + e-shop) |
208
208
  | `blog` | Blogs and published posts (web + e-shop) |
209
209
  | `forms` | Merchant-defined forms: definition + validated submit with per-field errors (web + e-shop) |
210
+ | `bookings` | Online appointments: services and staff, free times, create, change and cancel by token (web + e-shop) |
210
211
 
211
212
  ### React Hooks (30+)
212
213
 
@@ -232,6 +233,47 @@ from `@behio/storefront-sdk/react` within `BehioProvider`. For SEO, include the
232
233
  questions in server-rendered HTML and emit one FAQPage JSON-LD object containing
233
234
  only the questions actually visible on that page.
234
235
 
236
+ ### Withdrawal from contract (2.25.0)
237
+
238
+ EU law (Art. 11a Directive 2011/83/EU, from 19 Jun 2026) requires an online
239
+ withdrawal function for consumer purchases. When `shopInfo.withdrawal.enabled`,
240
+ link it from the footer and the customer account with a clear label such as
241
+ "Withdraw from contract here". The flow has two steps: a form (name, order
242
+ number, e-mail), then a summary with a "Confirm withdrawal" button. Only the
243
+ confirmation calls `withdraw`; show the returned acknowledgement, the same
244
+ content with date and time goes out by e-mail.
245
+
246
+ ```ts
247
+ const {data: order} = await storefront.returns.lookupOrder('B-2026-0042', 'jana@example.com');
248
+ // order.customerName prefills the name, order.withdrawal tells the period and flags
249
+ const {data: ack, error} = await storefront.returns.withdraw({
250
+ orderNumber: 'B-2026-0042',
251
+ email: 'jana@example.com',
252
+ name: 'Jana Nováková',
253
+ confirmed: true, // the consumer pressed "Confirm withdrawal"
254
+ });
255
+ // ack.submittedAt, ack.items, ack.confirmationSent
256
+ ```
257
+
258
+ ### Bookings (2.24.0)
259
+
260
+ Online appointments from the Behio Bookings module. Days are `YYYY-MM-DD` in the
261
+ branch time zone (`config.timezone`); a taken time answers 409
262
+ `be.bookings.slotTaken`, so reload free times and let the customer pick again.
263
+
264
+ ```ts
265
+ const {data: config} = await storefront.bookings.getConfig();
266
+ const {data: free} = await storefront.bookings.getSlots({serviceIds: [config.services[0].id], from: '2026-10-21', to: '2026-11-03'});
267
+ const {data, error} = await storefront.bookings.create({serviceIds: [config.services[0].id], startMs: free.slots[0].startMs, name: 'Jana', email: 'jana@example.com', website: ''});
268
+ // data.booking.code, data.booking.status ('CONFIRMED' or 'PENDING'), data.manageToken
269
+ ```
270
+
271
+ Change and cancel by the token from the confirmation email: `getByToken`,
272
+ `getManageSlots`, `reschedule`, `cancel`. React: `useBookingConfig`,
273
+ `useBookingSlots`, `useCreateBooking`, `useManagedBooking`, `useCancelBooking`,
274
+ `useRescheduleBooking`. Without your own UI, embed the hosted widget instead
275
+ (see the Bookings page of the docs).
276
+
235
277
  ### Framework Support
236
278
 
237
279
  - **Next.js**: Server components + client hooks, SSR ready
@@ -204,6 +204,7 @@ var BehioStorefront = class {
204
204
  this.forms = new FormsModule(this);
205
205
  this.collections = new CollectionsModule(this);
206
206
  this.faq = new FaqModule(this);
207
+ this.bookings = new BookingsModule(this);
207
208
  this.wishlist = new WishlistModule(this);
208
209
  this.reviews = new ReviewsModule(this);
209
210
  this.returns = new ReturnsModule(this);
@@ -1880,6 +1881,60 @@ var FaqModule = class {
1880
1881
  });
1881
1882
  }
1882
1883
  };
1884
+ var BookingsModule = class {
1885
+ constructor(client) {
1886
+ this.client = client;
1887
+ }
1888
+ /** Services, categories, staff, branches and rules of the booking flow. */
1889
+ async getConfig() {
1890
+ return this.client.request("GET", "/bookings/config", { auth: false });
1891
+ }
1892
+ /** Free start times for the selected services (at most 31 days per call). */
1893
+ async getSlots(query) {
1894
+ return this.client.request("GET", "/bookings/slots", {
1895
+ query: {
1896
+ serviceIds: query.serviceIds.join(","),
1897
+ staffId: query.staffId ?? void 0,
1898
+ from: query.from,
1899
+ to: query.to
1900
+ },
1901
+ auth: false
1902
+ });
1903
+ }
1904
+ /**
1905
+ * Create a booking. Counts toward the monthly online limit of the plan.
1906
+ * Keep `manageToken` only to link the customer to the change and cancel
1907
+ * page; the same link arrives in the confirmation email.
1908
+ */
1909
+ async create(input) {
1910
+ return this.client.request("POST", "/bookings", { body: input, auth: false });
1911
+ }
1912
+ /** The booking behind the token from the confirmation email. */
1913
+ async getByToken(token) {
1914
+ return this.client.request("GET", `/bookings/manage/${encodeURIComponent(token)}`, { auth: false });
1915
+ }
1916
+ /** Free times to move the booking to (same services and person rules). */
1917
+ async getManageSlots(token, query) {
1918
+ return this.client.request("GET", `/bookings/manage/${encodeURIComponent(token)}/slots`, {
1919
+ query: { from: query.from, to: query.to },
1920
+ auth: false
1921
+ });
1922
+ }
1923
+ /** Cancel the booking (optional reason for the business). */
1924
+ async cancel(token, input) {
1925
+ return this.client.request("POST", `/bookings/manage/${encodeURIComponent(token)}/cancel`, {
1926
+ body: { reason: input?.reason ?? null },
1927
+ auth: false
1928
+ });
1929
+ }
1930
+ /** Move the booking to `startMs` of a slot from `getManageSlots`. */
1931
+ async reschedule(token, input) {
1932
+ return this.client.request("POST", `/bookings/manage/${encodeURIComponent(token)}/reschedule`, {
1933
+ body: { startMs: input.startMs },
1934
+ auth: false
1935
+ });
1936
+ }
1937
+ };
1883
1938
  var FormsModule = class {
1884
1939
  constructor(client) {
1885
1940
  this.client = client;
@@ -2043,6 +2098,19 @@ var ReturnsModule = class {
2043
2098
  }
2044
2099
  );
2045
2100
  }
2101
+ /**
2102
+ * EU withdrawal function (Art. 11a Directive 2011/83/EU, 2.25.0). Two steps
2103
+ * in the template: the form (name, order number, e-mail), then a summary
2104
+ * with the "Confirm withdrawal" button that calls this. The result is the
2105
+ * acknowledgement to show; the same content with date and time goes out by
2106
+ * e-mail. Guests welcome, the order e-mail is the gate.
2107
+ */
2108
+ async withdraw(input) {
2109
+ return this.client.request("POST", "/returns/withdrawal", {
2110
+ body: input
2111
+ });
2112
+ }
2113
+ /** Return or complaint. Reason CHANGED_MIND is recorded as a withdrawal on the server. */
2046
2114
  async submit(input) {
2047
2115
  return this.client.request("POST", "/returns", {
2048
2116
  body: input
@@ -204,6 +204,7 @@ var BehioStorefront = class {
204
204
  this.forms = new FormsModule(this);
205
205
  this.collections = new CollectionsModule(this);
206
206
  this.faq = new FaqModule(this);
207
+ this.bookings = new BookingsModule(this);
207
208
  this.wishlist = new WishlistModule(this);
208
209
  this.reviews = new ReviewsModule(this);
209
210
  this.returns = new ReturnsModule(this);
@@ -1880,6 +1881,60 @@ var FaqModule = class {
1880
1881
  });
1881
1882
  }
1882
1883
  };
1884
+ var BookingsModule = class {
1885
+ constructor(client) {
1886
+ this.client = client;
1887
+ }
1888
+ /** Services, categories, staff, branches and rules of the booking flow. */
1889
+ async getConfig() {
1890
+ return this.client.request("GET", "/bookings/config", { auth: false });
1891
+ }
1892
+ /** Free start times for the selected services (at most 31 days per call). */
1893
+ async getSlots(query) {
1894
+ return this.client.request("GET", "/bookings/slots", {
1895
+ query: {
1896
+ serviceIds: query.serviceIds.join(","),
1897
+ staffId: _nullishCoalesce(query.staffId, () => ( void 0)),
1898
+ from: query.from,
1899
+ to: query.to
1900
+ },
1901
+ auth: false
1902
+ });
1903
+ }
1904
+ /**
1905
+ * Create a booking. Counts toward the monthly online limit of the plan.
1906
+ * Keep `manageToken` only to link the customer to the change and cancel
1907
+ * page; the same link arrives in the confirmation email.
1908
+ */
1909
+ async create(input) {
1910
+ return this.client.request("POST", "/bookings", { body: input, auth: false });
1911
+ }
1912
+ /** The booking behind the token from the confirmation email. */
1913
+ async getByToken(token) {
1914
+ return this.client.request("GET", `/bookings/manage/${encodeURIComponent(token)}`, { auth: false });
1915
+ }
1916
+ /** Free times to move the booking to (same services and person rules). */
1917
+ async getManageSlots(token, query) {
1918
+ return this.client.request("GET", `/bookings/manage/${encodeURIComponent(token)}/slots`, {
1919
+ query: { from: query.from, to: query.to },
1920
+ auth: false
1921
+ });
1922
+ }
1923
+ /** Cancel the booking (optional reason for the business). */
1924
+ async cancel(token, input) {
1925
+ return this.client.request("POST", `/bookings/manage/${encodeURIComponent(token)}/cancel`, {
1926
+ body: { reason: _nullishCoalesce(_optionalChain([input, 'optionalAccess', _51 => _51.reason]), () => ( null)) },
1927
+ auth: false
1928
+ });
1929
+ }
1930
+ /** Move the booking to `startMs` of a slot from `getManageSlots`. */
1931
+ async reschedule(token, input) {
1932
+ return this.client.request("POST", `/bookings/manage/${encodeURIComponent(token)}/reschedule`, {
1933
+ body: { startMs: input.startMs },
1934
+ auth: false
1935
+ });
1936
+ }
1937
+ };
1883
1938
  var FormsModule = class {
1884
1939
  constructor(client) {
1885
1940
  this.client = client;
@@ -2043,6 +2098,19 @@ var ReturnsModule = class {
2043
2098
  }
2044
2099
  );
2045
2100
  }
2101
+ /**
2102
+ * EU withdrawal function (Art. 11a Directive 2011/83/EU, 2.25.0). Two steps
2103
+ * in the template: the form (name, order number, e-mail), then a summary
2104
+ * with the "Confirm withdrawal" button that calls this. The result is the
2105
+ * acknowledgement to show; the same content with date and time goes out by
2106
+ * e-mail. Guests welcome, the order e-mail is the gate.
2107
+ */
2108
+ async withdraw(input) {
2109
+ return this.client.request("POST", "/returns/withdrawal", {
2110
+ body: input
2111
+ });
2112
+ }
2113
+ /** Return or complaint. Reason CHANGED_MIND is recorded as a withdrawal on the server. */
2046
2114
  async submit(input) {
2047
2115
  return this.client.request("POST", "/returns", {
2048
2116
  body: input
@@ -2081,7 +2149,7 @@ var ConsentModule = class {
2081
2149
  }
2082
2150
  if (result.error) return { data: null, error: result.error };
2083
2151
  return {
2084
- data: _optionalChain([result, 'access', _51 => _51.data, 'optionalAccess', _52 => _52.consented]) ? result.data.consent : null,
2152
+ data: _optionalChain([result, 'access', _52 => _52.data, 'optionalAccess', _53 => _53.consented]) ? result.data.consent : null,
2085
2153
  error: null
2086
2154
  };
2087
2155
  }
@@ -2168,10 +2236,10 @@ var ShippingModule = class {
2168
2236
  */
2169
2237
  async listMethods(opts) {
2170
2238
  const query = {};
2171
- if (_optionalChain([opts, 'optionalAccess', _53 => _53.currency])) query.currency = opts.currency;
2172
- if (_optionalChain([opts, 'optionalAccess', _54 => _54.country])) query.country = opts.country;
2173
- if (_optionalChain([opts, 'optionalAccess', _55 => _55.cartTotal]) != null) query.cartTotal = String(opts.cartTotal);
2174
- if (_optionalChain([opts, 'optionalAccess', _56 => _56.cartWeightKg]) != null)
2239
+ if (_optionalChain([opts, 'optionalAccess', _54 => _54.currency])) query.currency = opts.currency;
2240
+ if (_optionalChain([opts, 'optionalAccess', _55 => _55.country])) query.country = opts.country;
2241
+ if (_optionalChain([opts, 'optionalAccess', _56 => _56.cartTotal]) != null) query.cartTotal = String(opts.cartTotal);
2242
+ if (_optionalChain([opts, 'optionalAccess', _57 => _57.cartWeightKg]) != null)
2175
2243
  query.cartWeightKg = String(opts.cartWeightKg);
2176
2244
  return this.client.request(
2177
2245
  "GET",
@@ -261,6 +261,20 @@ interface ShopInfo {
261
261
  * may still be served.
262
262
  */
263
263
  seo?: ShopSeoIdentity;
264
+ /**
265
+ * Online withdrawal function (Art. 11a Directive 2011/83/EU, mandatory in
266
+ * the EU from 19 Jun 2026). When `enabled`, render a clearly labelled link
267
+ * ("Withdraw from contract here") in the footer and in the customer account,
268
+ * leading to the withdrawal form (`returns.withdraw`). Optional because
269
+ * cached ShopInfo payloads predating the field may still be served (2.25.0).
270
+ */
271
+ withdrawal?: WithdrawalSettings;
272
+ }
273
+ /** Merchant setting of the online withdrawal function (2.25.0). */
274
+ interface WithdrawalSettings {
275
+ enabled: boolean;
276
+ /** Withdrawal period in days from receipt of the goods (14 by law). */
277
+ periodDays: number;
264
278
  }
265
279
  interface ShopAppearance {
266
280
  primaryColor: string | null;
@@ -3110,9 +3124,70 @@ interface ReturnableOrder {
3110
3124
  orderId: string;
3111
3125
  orderNumber: string;
3112
3126
  status: string;
3127
+ /** Name from the order billing address, to prefill the withdrawal form (2.25.0). */
3128
+ customerName: string | null;
3113
3129
  items: ReturnableOrderItem[];
3130
+ /** Withdrawal window of this order (2.25.0). */
3131
+ withdrawal: WithdrawalWindow;
3114
3132
  createdAt: number;
3115
3133
  }
3134
+ /**
3135
+ * What the withdrawal form should say about the period. The form stays
3136
+ * usable outside the window: the consumer may always submit, the merchant
3137
+ * decides. (2.25.0)
3138
+ */
3139
+ interface WithdrawalWindow {
3140
+ /** The e-shop offers the online withdrawal function. */
3141
+ enabled: boolean;
3142
+ periodDays: number;
3143
+ /** Last moment of the period (ms). Null while it has not started or delivery is not recorded. */
3144
+ deadlineAt: number | null;
3145
+ /** False only when the period demonstrably ended. */
3146
+ withinPeriod: boolean;
3147
+ /** AFTER_DEADLINE | BEFORE_DISPATCH | DELIVERY_UNKNOWN | DIGITAL_CONTENT_CONSENT */
3148
+ flags: WithdrawalFlag[];
3149
+ }
3150
+ type WithdrawalFlag = "AFTER_DEADLINE" | "BEFORE_DISPATCH" | "DELIVERY_UNKNOWN" | "DIGITAL_CONTENT_CONSENT";
3151
+ /**
3152
+ * Input of `returns.withdraw()`: the withdrawal statement of Art. 11a(2):
3153
+ * the consumer's name, the contract (order number) and the e-mail the
3154
+ * acknowledgement goes to. Send it only after the consumer pressed the
3155
+ * confirmation button ("Confirm withdrawal"), hence `confirmed: true`. (2.25.0)
3156
+ */
3157
+ interface SubmitWithdrawalInput {
3158
+ orderNumber: string;
3159
+ /** Order e-mail: the ownership gate and where the acknowledgement is sent. */
3160
+ email: string;
3161
+ name: string;
3162
+ /** Omit to withdraw from every still returnable item of the order. */
3163
+ items?: {
3164
+ orderItemId: string;
3165
+ quantity: number;
3166
+ }[];
3167
+ note?: string;
3168
+ confirmed: true;
3169
+ }
3170
+ /**
3171
+ * Returned by `returns.withdraw()`. Show it as the acknowledgement: the same
3172
+ * content with date and time also goes out by e-mail. `confirmationSent`
3173
+ * says whether that e-mail really went out. (2.25.0)
3174
+ */
3175
+ interface WithdrawalAcknowledgement {
3176
+ id: string;
3177
+ orderNumber: string;
3178
+ customerName: string;
3179
+ email: string;
3180
+ /** Date and time of submission (ms). */
3181
+ submittedAt: number;
3182
+ items: {
3183
+ productName: string;
3184
+ quantity: number;
3185
+ }[];
3186
+ note: string | null;
3187
+ deadlineAt: number | null;
3188
+ withinPeriod: boolean;
3189
+ confirmationSent: boolean;
3190
+ }
3116
3191
  interface ReturnRequestItem {
3117
3192
  id: string;
3118
3193
  orderItemId: string;
@@ -3143,6 +3218,8 @@ interface ReturnStatusItem {
3143
3218
  interface ReturnStatus {
3144
3219
  id: string;
3145
3220
  orderNumber: string;
3221
+ /** WITHDRAWAL = withdrawal from the contract, RETURN = return or complaint (2.25.0). */
3222
+ type: "RETURN" | "WITHDRAWAL";
3146
3223
  /** REQUESTED | APPROVED | SHIPPED_BACK | RECEIVED | REFUNDED | REJECTED | CLOSED */
3147
3224
  status: string;
3148
3225
  reason: string;
@@ -3302,6 +3379,145 @@ interface GamificationRefreshResult {
3302
3379
  awarded: number;
3303
3380
  completed: number;
3304
3381
  }
3382
+ type BookingLocale = "cs" | "sk" | "en";
3383
+ type BookingStatus = "PENDING" | "CONFIRMED" | "CANCELLED" | "NO_SHOW" | "COMPLETED";
3384
+ interface BookingService {
3385
+ id: string;
3386
+ categoryId: string | null;
3387
+ name: string;
3388
+ description: string | null;
3389
+ durationMinutes: number;
3390
+ /** Null = price on site (show it as such, never as 0). */
3391
+ price: number | null;
3392
+ /** ISO 4217 code (CZK, EUR, ...). */
3393
+ currency: string;
3394
+ }
3395
+ interface BookingCategory {
3396
+ id: string;
3397
+ name: string;
3398
+ }
3399
+ interface BookingStaff {
3400
+ id: string;
3401
+ name: string;
3402
+ title: string | null;
3403
+ bio: string | null;
3404
+ /** `#rrggbb` or null. */
3405
+ color: string | null;
3406
+ /** Services this person does. */
3407
+ serviceIds: string[];
3408
+ }
3409
+ interface BookingLocation {
3410
+ id: string;
3411
+ name: string;
3412
+ address: string | null;
3413
+ timezone: string;
3414
+ }
3415
+ /** Public booking setup of the site owner (`GET /bookings/config`). */
3416
+ interface BookingConfig {
3417
+ businessName: string;
3418
+ intro: string | null;
3419
+ /** `#rrggbb` brand colour of the widget, or null. */
3420
+ accentColor: string | null;
3421
+ defaultLocale: BookingLocale;
3422
+ /** Offer a staff choice step (otherwise send `staffId: null`). */
3423
+ allowStaffChoice: boolean;
3424
+ /** New bookings start as PENDING and the business confirms them. */
3425
+ requireApproval: boolean;
3426
+ /** How many days ahead a customer may book. */
3427
+ maxAdvanceDays: number;
3428
+ /** Customer may change or cancel until this many hours before the start. */
3429
+ customerCancelHours: number;
3430
+ contactPhone: string | null;
3431
+ contactEmail: string | null;
3432
+ /**
3433
+ * Online booking is paused (plan limit). Do not offer the flow, show the
3434
+ * contact instead: `create` would answer `be.bookings.onlineLimitReached`.
3435
+ */
3436
+ onlinePaused: boolean;
3437
+ /** IANA time zone of the branch; show every day and time in it. */
3438
+ timezone: string;
3439
+ locations: BookingLocation[];
3440
+ categories: BookingCategory[];
3441
+ services: BookingService[];
3442
+ staff: BookingStaff[];
3443
+ }
3444
+ interface BookingSlot {
3445
+ startMs: number;
3446
+ endMs: number;
3447
+ }
3448
+ interface BookingSlots {
3449
+ timezone: string;
3450
+ /** Total length of the selected services. */
3451
+ durationMinutes: number;
3452
+ slots: BookingSlot[];
3453
+ }
3454
+ interface BookingSlotsQuery {
3455
+ /** Selected services in the order they follow each other (1 to 10). */
3456
+ serviceIds: string[];
3457
+ /** Only this person; omit for anyone free. */
3458
+ staffId?: string | null;
3459
+ /** First day `YYYY-MM-DD` (branch time zone). */
3460
+ from: string;
3461
+ /** Last day `YYYY-MM-DD`, at most 31 days after `from`. */
3462
+ to: string;
3463
+ }
3464
+ interface BookingManageSlotsQuery {
3465
+ from: string;
3466
+ to: string;
3467
+ }
3468
+ interface BookingCreateInput {
3469
+ serviceIds: string[];
3470
+ /** Null or omitted = anyone free. */
3471
+ staffId?: string | null;
3472
+ /** `startMs` of a slot from `getSlots`. */
3473
+ startMs: number;
3474
+ name: string;
3475
+ email: string;
3476
+ phone?: string | null;
3477
+ note?: string | null;
3478
+ /** Language of the confirmation email. */
3479
+ locale?: BookingLocale;
3480
+ /** Honeypot: render a hidden input and send its value; people leave it empty. */
3481
+ website?: string;
3482
+ /** Analytics visitor (consent-gated), only for the CRM. */
3483
+ visitorId?: string | null;
3484
+ }
3485
+ /** One booking as the customer sees it. */
3486
+ interface Booking {
3487
+ id: string;
3488
+ /** Short code shown to the customer and in emails. */
3489
+ code: string;
3490
+ status: BookingStatus;
3491
+ startMs: number;
3492
+ endMs: number;
3493
+ timezone: string;
3494
+ businessName: string;
3495
+ staffName: string;
3496
+ locationName: string;
3497
+ locationAddress: string | null;
3498
+ services: string[];
3499
+ serviceIds: string[];
3500
+ /** Person chosen by the customer; null = anyone. */
3501
+ staffId: string | null;
3502
+ totalPrice: number | null;
3503
+ currency: string;
3504
+ customerName: string;
3505
+ /** The customer may still change or cancel (deadline from the settings). */
3506
+ canChange: boolean;
3507
+ /** Until when (ms) the customer may change or cancel. */
3508
+ changeDeadline: number | null;
3509
+ /** Phone of the business to show once `canChange` is false. */
3510
+ contactPhone: string | null;
3511
+ locale: string;
3512
+ }
3513
+ interface BookingCreated {
3514
+ booking: Booking;
3515
+ /**
3516
+ * Token for the change and cancel link (the same one the confirmation email
3517
+ * carries). Treat it like a password: never put it in analytics or logs.
3518
+ */
3519
+ manageToken: string;
3520
+ }
3305
3521
 
3306
3522
  declare class BehioStorefront {
3307
3523
  private baseUrl;
@@ -3356,6 +3572,7 @@ declare class BehioStorefront {
3356
3572
  readonly forms: FormsModule;
3357
3573
  readonly collections: CollectionsModule;
3358
3574
  readonly faq: FaqModule;
3575
+ readonly bookings: BookingsModule;
3359
3576
  readonly wishlist: WishlistModule;
3360
3577
  readonly reviews: ReviewsModule;
3361
3578
  readonly returns: ReturnsModule;
@@ -4109,6 +4326,49 @@ declare class FaqModule {
4109
4326
  */
4110
4327
  get(group: string, query?: StorefrontFaqQuery): Promise<SdkResult<StorefrontFaqGroup>>;
4111
4328
  }
4329
+ /**
4330
+ * Online booking of the site owner's services (hair salon, clinic, lessons):
4331
+ * the public setup, free times, a new booking, and the change and cancel flow
4332
+ * behind the token from the confirmation email. Works with website keys that
4333
+ * have no e-shop attached; the Bookings module must be on in the admin
4334
+ * (otherwise 404 `be.bookings.widgetNotFound`).
4335
+ *
4336
+ * Days are `YYYY-MM-DD` in the branch time zone (`config.timezone`), not the
4337
+ * visitor's; format times with `timeZone: config.timezone`.
4338
+ *
4339
+ * Errors worth handling: 409 `be.bookings.slotTaken` (someone was faster:
4340
+ * reload the slots and let the customer pick again), 403
4341
+ * `be.bookings.onlineLimitReached` (online booking paused, show the contact),
4342
+ * 403 `be.bookings.changeTooLate` (too late to change, show
4343
+ * `booking.contactPhone`), 404 `be.bookings.manageNotFound` (old or wrong
4344
+ * token), 429 (rate limit: 10 new bookings and 20 changes per minute).
4345
+ */
4346
+ declare class BookingsModule {
4347
+ private client;
4348
+ constructor(client: BehioStorefront);
4349
+ /** Services, categories, staff, branches and rules of the booking flow. */
4350
+ getConfig(): Promise<SdkResult<BookingConfig>>;
4351
+ /** Free start times for the selected services (at most 31 days per call). */
4352
+ getSlots(query: BookingSlotsQuery): Promise<SdkResult<BookingSlots>>;
4353
+ /**
4354
+ * Create a booking. Counts toward the monthly online limit of the plan.
4355
+ * Keep `manageToken` only to link the customer to the change and cancel
4356
+ * page; the same link arrives in the confirmation email.
4357
+ */
4358
+ create(input: BookingCreateInput): Promise<SdkResult<BookingCreated>>;
4359
+ /** The booking behind the token from the confirmation email. */
4360
+ getByToken(token: string): Promise<SdkResult<Booking>>;
4361
+ /** Free times to move the booking to (same services and person rules). */
4362
+ getManageSlots(token: string, query: BookingManageSlotsQuery): Promise<SdkResult<BookingSlots>>;
4363
+ /** Cancel the booking (optional reason for the business). */
4364
+ cancel(token: string, input?: {
4365
+ reason?: string | null;
4366
+ }): Promise<SdkResult<Booking>>;
4367
+ /** Move the booking to `startMs` of a slot from `getManageSlots`. */
4368
+ reschedule(token: string, input: {
4369
+ startMs: number;
4370
+ }): Promise<SdkResult<Booking>>;
4371
+ }
4112
4372
  /**
4113
4373
  * Merchant-defined forms (contact, demand, registration to an event...).
4114
4374
  * The definition is public and cacheable; a submit is validated server-side
@@ -4193,6 +4453,15 @@ declare class ReturnsModule {
4193
4453
  * quantities. POST so the email never appears in a URL.
4194
4454
  */
4195
4455
  lookupOrder(orderNumber: string, email: string): Promise<SdkResult<ReturnableOrder>>;
4456
+ /**
4457
+ * EU withdrawal function (Art. 11a Directive 2011/83/EU, 2.25.0). Two steps
4458
+ * in the template: the form (name, order number, e-mail), then a summary
4459
+ * with the "Confirm withdrawal" button that calls this. The result is the
4460
+ * acknowledgement to show; the same content with date and time goes out by
4461
+ * e-mail. Guests welcome, the order e-mail is the gate.
4462
+ */
4463
+ withdraw(input: SubmitWithdrawalInput): Promise<SdkResult<WithdrawalAcknowledgement>>;
4464
+ /** Return or complaint. Reason CHANGED_MIND is recorded as a withdrawal on the server. */
4196
4465
  submit(input: SubmitReturnInput): Promise<SdkResult<ReturnRequest>>;
4197
4466
  /** Email is the ownership gate; POST so it never lands in a URL / log. */
4198
4467
  getStatus(returnId: string, email: string): Promise<SdkResult<ReturnStatus>>;
@@ -4330,4 +4599,4 @@ declare function clearCartSummary(): void;
4330
4599
  /** Publish only authoritative current totals; server cart consumers call this after hydration and revalidation. */
4331
4600
  declare function publishCartSummary(summary: CartSummaryEvent): void;
4332
4601
 
4333
- export { type CourseCommentReply as $, type ActivePromotion as A, BehioStorefront as B, type CookieConsent as C, type Cart as D, type CartBundleLine as E, type CartBundleLineItem as F, type CartDiscount as G, type CartItem as H, type CartItemProduct as I, type CartLinkClaimed as J, type CartPromotion as K, type CartSummaryEvent as L, type Category as M, type CategoryDetail as N, type CertificateVerification as O, type ProductDetail as P, type CheckoutAddress as Q, type CheckoutInput as R, type SdkResult as S, type CheckoutPaymentMethod as T, type CheckoutPreview as U, type CheckoutResult as V, type CheckoutSettings as W, type CookieConsentInput as X, type CourseAttachment as Y, type CourseCertificate as Z, type CourseComment as _, type ProductVariant as a, type OrderPaymentInstructions as a$, type CourseCommentsList as a0, type CourseDetail as a1, type CourseLesson as a2, type CourseListItem as a3, type CourseModule as a4, type CoursePostedComment as a5, type CourseProgress as a6, type CourseTutorMessage as a7, type CourseTutorThread as a8, type CrossSellItem as a9, type LessonNote as aA, type LessonQuiz as aB, type LoginInput as aC, type LoyaltyBalance as aD, type LoyaltyNextTier as aE, type LoyaltyProgram as aF, type LoyaltyQuery as aG, type LoyaltyReferralResult as aH, type LoyaltySummary as aI, type LoyaltyTier as aJ, type LoyaltyTierPerks as aK, type LoyaltyTransaction as aL, type Menu as aM, type MenuItem as aN, type MenuItemRef as aO, type MenuItemType as aP, type MessageResponse as aQ, type NewsletterOptInDefault as aR, type NewsletterSubscribeInput as aS, type NewsletterSubscribeResult as aT, type NewsletterUnsubscribeResult as aU, type OrderAccessRequestResponse as aV, type OrderAccessVerifyResponse as aW, type OrderDetail as aX, type OrderDiscount as aY, type OrderItem as aZ, type OrderListItem as a_, type CurrencyDisplayFormat as aa, type CustomerAddress as ab, type CustomerBadge as ac, type CustomerChallenge as ad, type CustomerGamification as ae, type CustomerGamificationQuery as af, type CustomerProfile as ag, type DigitalDownload as ah, type DownloadUrl as ai, type Facet as aj, type FacetAvailability as ak, type FacetCategory as al, type FacetLabel as am, type FacetPriceRange as an, type FacetRange as ao, type FacetRatingBucket as ap, type FacetValue as aq, type FacetsResponse as ar, type FilterField as as, type FulfillmentStatus as at, FulfillmentStatuses as au, type GamificationRefreshResult as av, type GiftCardBalance as aw, type GiftCardPurchaseInput as ax, type GiftCardPurchaseResult as ay, type GiftCardSummary as az, type StorefrontFormFieldError as b, type ShopCommerce as b$, type OrderPickupPoint as b0, type OrderShipment as b1, type OrderStatus as b2, type OrderStatusHistory as b3, OrderStatuses as b4, type OrderTracking as b5, type Page as b6, type PageAttachment as b7, type PageDetail as b8, type PaginatedResponse as b9, type ProductSortValue as bA, type ProductVolumePrice as bB, type ProductsQuery as bC, type QuizAnswerInput as bD, type QuizAnswerResult as bE, type QuizQuestion as bF, type QuizResult as bG, type QuoteItem as bH, type QuoteRequest as bI, type RegisterInput as bJ, type RegisterResult as bK, type RequestInterceptor as bL, type RequestInterceptorConfig as bM, type ResponseInterceptor as bN, type ResponseInterceptorData as bO, type ReturnRequest as bP, type ReturnRequestItem as bQ, type ReturnStatus as bR, type ReturnStatusItem as bS, type ReturnableOrder as bT, type ReturnableOrderItem as bU, type SdkError as bV, type ShippingMethodSummary as bW, type ShippingPublicConfig as bX, type ShippingQuote as bY, type ShippingQuoteInput as bZ, type ShopAppearance as b_, type PaymentInstrument as ba, type PaymentStatus as bb, PaymentStatuses as bc, type PaymentSwift as bd, type PickupPoint as be, type PickupPointHours as bf, type PickupPointsInput as bg, type PickupWidgetConfig as bh, type PriceDisplay as bi, type ProductAssetGroup as bj, type ProductAssetItem as bk, type ProductAvailability as bl, type ProductGroup as bm, type ProductLabel as bn, type ProductListItem as bo, type ProductMedia as bp, type ProductMediaVariant as bq, type ProductParameter as br, type ProductParameterGroup as bs, type ProductParametersResponse as bt, type ProductPrice as bu, type ProductPromotionSummary as bv, type ProductReview as bw, type ProductReviewsResponse as bx, type ProductSibling as by, ProductSort as bz, type AddToCartInput as c, type ShopInfo as c0, type ShopScript as c1, type ShopScriptPlacement as c2, type ShopScriptType as c3, type ShopScripts as c4, type ShopSeo as c5, type ShopSeoIdentity as c6, type SiteFormField as c7, type SiteFormFieldOption as c8, type SiteFormFieldType as c9, type SubscriptionFrequency as cA, type SubscriptionItem as cB, type SubscriptionStatus as cC, type TaxBreakdownLine as cD, type VariantAxis as cE, type VariantAxisValue as cF, type WishlistItem as cG, clearCartSummary as cH, err as cI, ok as cJ, publishCartSummary as cK, toSdkError as cL, type Sitemap as ca, type SitemapEntry as cb, type StockBehavior as cc, type StockMode as cd, type StorefrontCollection as ce, type StorefrontCollectionField as cf, type StorefrontCollectionFieldType as cg, type StorefrontCollectionItem as ch, type StorefrontCollectionQuery as ci, type StorefrontFaqGroup as cj, type StorefrontFaqGroupSummary as ck, type StorefrontFaqGroups as cl, type StorefrontFaqItem as cm, type StorefrontFaqQuery as cn, type StorefrontForm as co, type StorefrontFormFieldErrorCode as cp, type StorefrontFormFile as cq, type StorefrontFormSettings as cr, type StorefrontFormSubmitInput as cs, type StorefrontFormSubmitResult as ct, type StorefrontFormUpload as cu, type SubmitQuoteInput as cv, type SubmitReturnInput as cw, type SubmitReviewInput as cx, type Subscription as cy, type SubscriptionAction as cz, type AddressDetail as d, type AddressSuggestion as e, type AddressType as f, AddressTypes as g, type AuthTokens as h, type BackInStockSubscription as i, type BadgeTone as j, BehioApiError as k, type BehioErrorCode as l, type BehioEventHandler as m, type BehioEventType as n, BehioNetworkError as o, type BehioStorefrontConfig as p, type Blog as q, type BlogPostDetail as r, type BlogPostListItem as s, type BlogPostsPage as t, type BlogPostsQuery as u, type BlogSettings as v, type BlogTag as w, type Bundle as x, type BundleCatalogQuery as y, type BundleItem as z };
4602
+ export { type CartSummaryEvent as $, type ActivePromotion as A, BehioStorefront as B, type CookieConsent as C, type BookingCreateInput as D, type BookingCreated as E, type BookingLocale as F, type BookingLocation as G, type BookingManageSlotsQuery as H, type BookingService as I, type BookingSlot as J, type BookingSlots as K, type BookingSlotsQuery as L, type BookingStaff as M, type BookingStatus as N, type Bundle as O, type ProductDetail as P, type BundleCatalogQuery as Q, type BundleItem as R, type SdkResult as S, type Cart as T, type CartBundleLine as U, type CartBundleLineItem as V, type CartDiscount as W, type CartItem as X, type CartItemProduct as Y, type CartLinkClaimed as Z, type CartPromotion as _, type ProductVariant as a, type MenuItem as a$, type Category as a0, type CategoryDetail as a1, type CertificateVerification as a2, type CheckoutAddress as a3, type CheckoutInput as a4, type CheckoutPaymentMethod as a5, type CheckoutPreview as a6, type CheckoutResult as a7, type CheckoutSettings as a8, type CookieConsentInput as a9, type FacetLabel as aA, type FacetPriceRange as aB, type FacetRange as aC, type FacetRatingBucket as aD, type FacetValue as aE, type FacetsResponse as aF, type FilterField as aG, type FulfillmentStatus as aH, FulfillmentStatuses as aI, type GamificationRefreshResult as aJ, type GiftCardBalance as aK, type GiftCardPurchaseInput as aL, type GiftCardPurchaseResult as aM, type GiftCardSummary as aN, type LessonNote as aO, type LessonQuiz as aP, type LoginInput as aQ, type LoyaltyBalance as aR, type LoyaltyNextTier as aS, type LoyaltyProgram as aT, type LoyaltyQuery as aU, type LoyaltyReferralResult as aV, type LoyaltySummary as aW, type LoyaltyTier as aX, type LoyaltyTierPerks as aY, type LoyaltyTransaction as aZ, type Menu as a_, type CourseAttachment as aa, type CourseCertificate as ab, type CourseComment as ac, type CourseCommentReply as ad, type CourseCommentsList as ae, type CourseDetail as af, type CourseLesson as ag, type CourseListItem as ah, type CourseModule as ai, type CoursePostedComment as aj, type CourseProgress as ak, type CourseTutorMessage as al, type CourseTutorThread as am, type CrossSellItem as an, type CurrencyDisplayFormat as ao, type CustomerAddress as ap, type CustomerBadge as aq, type CustomerChallenge as ar, type CustomerGamification as as, type CustomerGamificationQuery as at, type CustomerProfile as au, type DigitalDownload as av, type DownloadUrl as aw, type Facet as ax, type FacetAvailability as ay, type FacetCategory as az, type StorefrontFormFieldError as b, type ResponseInterceptor as b$, type MenuItemRef as b0, type MenuItemType as b1, type MessageResponse as b2, type NewsletterOptInDefault as b3, type NewsletterSubscribeInput as b4, type NewsletterSubscribeResult as b5, type NewsletterUnsubscribeResult as b6, type OrderAccessRequestResponse as b7, type OrderAccessVerifyResponse as b8, type OrderDetail as b9, type ProductGroup as bA, type ProductLabel as bB, type ProductListItem as bC, type ProductMedia as bD, type ProductMediaVariant as bE, type ProductParameter as bF, type ProductParameterGroup as bG, type ProductParametersResponse as bH, type ProductPrice as bI, type ProductPromotionSummary as bJ, type ProductReview as bK, type ProductReviewsResponse as bL, type ProductSibling as bM, ProductSort as bN, type ProductSortValue as bO, type ProductVolumePrice as bP, type ProductsQuery as bQ, type QuizAnswerInput as bR, type QuizAnswerResult as bS, type QuizQuestion as bT, type QuizResult as bU, type QuoteItem as bV, type QuoteRequest as bW, type RegisterInput as bX, type RegisterResult as bY, type RequestInterceptor as bZ, type RequestInterceptorConfig as b_, type OrderDiscount as ba, type OrderItem as bb, type OrderListItem as bc, type OrderPaymentInstructions as bd, type OrderPickupPoint as be, type OrderShipment as bf, type OrderStatus as bg, type OrderStatusHistory as bh, OrderStatuses as bi, type OrderTracking as bj, type Page as bk, type PageAttachment as bl, type PageDetail as bm, type PaginatedResponse as bn, type PaymentInstrument as bo, type PaymentStatus as bp, PaymentStatuses as bq, type PaymentSwift as br, type PickupPoint as bs, type PickupPointHours as bt, type PickupPointsInput as bu, type PickupWidgetConfig as bv, type PriceDisplay as bw, type ProductAssetGroup as bx, type ProductAssetItem as by, type ProductAvailability as bz, type AddToCartInput as c, err as c$, type ResponseInterceptorData as c0, type ReturnRequest as c1, type ReturnRequestItem as c2, type ReturnStatus as c3, type ReturnStatusItem as c4, type ReturnableOrder as c5, type ReturnableOrderItem as c6, type SdkError as c7, type ShippingMethodSummary as c8, type ShippingPublicConfig as c9, type StorefrontFaqItem as cA, type StorefrontFaqQuery as cB, type StorefrontForm as cC, type StorefrontFormFieldErrorCode as cD, type StorefrontFormFile as cE, type StorefrontFormSettings as cF, type StorefrontFormSubmitInput as cG, type StorefrontFormSubmitResult as cH, type StorefrontFormUpload as cI, type SubmitQuoteInput as cJ, type SubmitReturnInput as cK, type SubmitReviewInput as cL, type SubmitWithdrawalInput as cM, type Subscription as cN, type SubscriptionAction as cO, type SubscriptionFrequency as cP, type SubscriptionItem as cQ, type SubscriptionStatus as cR, type TaxBreakdownLine as cS, type VariantAxis as cT, type VariantAxisValue as cU, type WishlistItem as cV, type WithdrawalAcknowledgement as cW, type WithdrawalFlag as cX, type WithdrawalSettings as cY, type WithdrawalWindow as cZ, clearCartSummary as c_, type ShippingQuote as ca, type ShippingQuoteInput as cb, type ShopAppearance as cc, type ShopCommerce as cd, type ShopInfo as ce, type ShopScript as cf, type ShopScriptPlacement as cg, type ShopScriptType as ch, type ShopScripts as ci, type ShopSeo as cj, type ShopSeoIdentity as ck, type SiteFormField as cl, type SiteFormFieldOption as cm, type SiteFormFieldType as cn, type Sitemap as co, type SitemapEntry as cp, type StockBehavior as cq, type StockMode as cr, type StorefrontCollection as cs, type StorefrontCollectionField as ct, type StorefrontCollectionFieldType as cu, type StorefrontCollectionItem as cv, type StorefrontCollectionQuery as cw, type StorefrontFaqGroup as cx, type StorefrontFaqGroupSummary as cy, type StorefrontFaqGroups as cz, type AddressDetail as d, ok as d0, publishCartSummary as d1, toSdkError as d2, type AddressSuggestion as e, type AddressType as f, AddressTypes as g, type AuthTokens as h, type BackInStockSubscription as i, type BadgeTone as j, BehioApiError as k, type BehioErrorCode as l, type BehioEventHandler as m, type BehioEventType as n, BehioNetworkError as o, type BehioStorefrontConfig as p, type Blog as q, type BlogPostDetail as r, type BlogPostListItem as s, type BlogPostsPage as t, type BlogPostsQuery as u, type BlogSettings as v, type BlogTag as w, type Booking as x, type BookingCategory as y, type BookingConfig as z };