@wix/headless-bookings 1.0.17 → 1.0.19
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/cjs/dist/__mocks__/booking/booking-client-service.js +4 -1
- package/cjs/dist/__mocks__/services/services-mocks.d.ts +13 -0
- package/cjs/dist/__mocks__/services/services-mocks.js +92 -1
- package/cjs/dist/react/core/booking/Booking.d.ts +6 -0
- package/cjs/dist/react/core/booking/Booking.js +2 -0
- package/cjs/dist/react/core/payment/Payment.d.ts +2 -1
- package/cjs/dist/react/core/payment/Payment.js +11 -8
- package/cjs/dist/react/payment/Payment.d.ts +3 -2
- package/cjs/dist/react/payment/Payment.js +11 -5
- package/cjs/dist/services/booking/book-action/buildBookingRequest.js +13 -4
- package/cjs/dist/services/booking/book-action/types.d.ts +6 -0
- package/cjs/dist/services/booking/booking.d.ts +17 -0
- package/cjs/dist/services/booking/booking.js +8 -0
- package/cjs/dist/services/index.d.ts +1 -1
- package/cjs/dist/services/payment/payment.d.ts +4 -1
- package/cjs/dist/services/payment/payment.def.d.ts +49 -1
- package/cjs/dist/services/payment/payment.js +107 -69
- package/cjs/dist/services/servicePayment.d.ts +26 -0
- package/cjs/dist/services/servicePayment.js +46 -0
- package/cjs/dist/utils/money.d.ts +12 -2
- package/cjs/dist/utils/money.js +30 -18
- package/dist/__mocks__/booking/booking-client-service.js +4 -1
- package/dist/__mocks__/services/services-mocks.d.ts +13 -0
- package/dist/__mocks__/services/services-mocks.js +91 -0
- package/dist/react/core/booking/Booking.d.ts +6 -0
- package/dist/react/core/booking/Booking.js +2 -0
- package/dist/react/core/payment/Payment.d.ts +2 -1
- package/dist/react/core/payment/Payment.js +11 -8
- package/dist/react/payment/Payment.d.ts +3 -2
- package/dist/react/payment/Payment.js +11 -5
- package/dist/services/booking/book-action/buildBookingRequest.js +13 -4
- package/dist/services/booking/book-action/types.d.ts +6 -0
- package/dist/services/booking/booking.d.ts +17 -0
- package/dist/services/booking/booking.js +8 -0
- package/dist/services/index.d.ts +1 -1
- package/dist/services/payment/payment.d.ts +4 -1
- package/dist/services/payment/payment.def.d.ts +49 -1
- package/dist/services/payment/payment.js +107 -69
- package/dist/services/servicePayment.d.ts +26 -0
- package/dist/services/servicePayment.js +40 -0
- package/dist/utils/money.d.ts +12 -2
- package/dist/utils/money.js +30 -18
- package/package.json +4 -4
|
@@ -535,6 +535,97 @@ export const mockServiceWithDeposit = {
|
|
|
535
535
|
},
|
|
536
536
|
},
|
|
537
537
|
};
|
|
538
|
+
/** Deposit set as a fixed amount under `depositDetails`, the newer field. */
|
|
539
|
+
export const mockServiceDepositDetailsAmount = {
|
|
540
|
+
...mockService,
|
|
541
|
+
_id: 'test-service-deposit-details-amount',
|
|
542
|
+
name: 'Deposit Details Amount Service',
|
|
543
|
+
payment: {
|
|
544
|
+
rateType: RateType.FIXED,
|
|
545
|
+
fixed: {
|
|
546
|
+
price: {
|
|
547
|
+
value: '100.00',
|
|
548
|
+
currency: 'USD',
|
|
549
|
+
},
|
|
550
|
+
depositDetails: {
|
|
551
|
+
amount: {
|
|
552
|
+
value: '25.00',
|
|
553
|
+
currency: 'USD',
|
|
554
|
+
},
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
options: {
|
|
558
|
+
online: true,
|
|
559
|
+
deposit: true,
|
|
560
|
+
},
|
|
561
|
+
},
|
|
562
|
+
};
|
|
563
|
+
/** Percentage deposit: `options.deposit` set, no amount anywhere on the entity. */
|
|
564
|
+
export const mockServicePercentageDeposit = {
|
|
565
|
+
...mockService,
|
|
566
|
+
_id: 'test-service-percentage-deposit',
|
|
567
|
+
name: 'Percentage Deposit Service',
|
|
568
|
+
payment: {
|
|
569
|
+
rateType: RateType.FIXED,
|
|
570
|
+
fixed: {
|
|
571
|
+
price: {
|
|
572
|
+
value: '10',
|
|
573
|
+
currency: 'USD',
|
|
574
|
+
},
|
|
575
|
+
fullUpfrontPaymentAllowed: true,
|
|
576
|
+
},
|
|
577
|
+
options: {
|
|
578
|
+
online: true,
|
|
579
|
+
inPerson: false,
|
|
580
|
+
deposit: true,
|
|
581
|
+
},
|
|
582
|
+
},
|
|
583
|
+
};
|
|
584
|
+
/**
|
|
585
|
+
* Mock service with a deposit that may also be paid in full upfront — the only
|
|
586
|
+
* configuration where `booking.depositSelected` may be `false`.
|
|
587
|
+
*/
|
|
588
|
+
export const mockServiceWithDepositFullUpfront = {
|
|
589
|
+
...mockService,
|
|
590
|
+
_id: 'test-service-deposit-full-upfront',
|
|
591
|
+
name: 'Service with Deposit and Full Upfront Allowed',
|
|
592
|
+
payment: {
|
|
593
|
+
rateType: RateType.FIXED,
|
|
594
|
+
fixed: {
|
|
595
|
+
price: {
|
|
596
|
+
value: '100.00',
|
|
597
|
+
currency: 'USD',
|
|
598
|
+
},
|
|
599
|
+
deposit: {
|
|
600
|
+
value: '30.00',
|
|
601
|
+
currency: 'USD',
|
|
602
|
+
},
|
|
603
|
+
fullUpfrontPaymentAllowed: true,
|
|
604
|
+
},
|
|
605
|
+
},
|
|
606
|
+
};
|
|
607
|
+
/**
|
|
608
|
+
* Mock VARIED-rate service with a deposit (both under `payment.varied`).
|
|
609
|
+
*/
|
|
610
|
+
export const mockServiceVariedWithDeposit = {
|
|
611
|
+
...mockService,
|
|
612
|
+
_id: 'test-service-varied-deposit',
|
|
613
|
+
name: 'Varied Service with Deposit',
|
|
614
|
+
payment: {
|
|
615
|
+
rateType: RateType.VARIED,
|
|
616
|
+
varied: {
|
|
617
|
+
defaultPrice: {
|
|
618
|
+
value: '80.00',
|
|
619
|
+
currency: 'USD',
|
|
620
|
+
},
|
|
621
|
+
deposit: {
|
|
622
|
+
value: '20.00',
|
|
623
|
+
currency: 'USD',
|
|
624
|
+
},
|
|
625
|
+
fullUpfrontPaymentAllowed: true,
|
|
626
|
+
},
|
|
627
|
+
},
|
|
628
|
+
};
|
|
538
629
|
/**
|
|
539
630
|
* Mock service with in-person payment option
|
|
540
631
|
*/
|
|
@@ -45,6 +45,12 @@ export interface BookingData {
|
|
|
45
45
|
* heuristic applies. Set via `actions.setSelectedPaymentOption`.
|
|
46
46
|
*/
|
|
47
47
|
selectedPaymentOption: SelectedPaymentOption | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Deposit-vs-full-upfront choice. `true` pays only the deposit now, `false`
|
|
50
|
+
* pays the full price now, `undefined` means not chosen. Set via
|
|
51
|
+
* `actions.setDepositSelected`.
|
|
52
|
+
*/
|
|
53
|
+
depositSelected: boolean | undefined;
|
|
48
54
|
actions: BookingServiceActions;
|
|
49
55
|
}
|
|
50
56
|
/**
|
|
@@ -106,6 +106,7 @@ export function Data(props) {
|
|
|
106
106
|
const timezone = bookingService.timezone.get();
|
|
107
107
|
const formSubmission = bookingService.formSubmission.get();
|
|
108
108
|
const selectedPaymentOption = bookingService.selectedPaymentOption.get();
|
|
109
|
+
const depositSelected = bookingService.depositSelected.get();
|
|
109
110
|
const { actions } = bookingService;
|
|
110
111
|
const location = resolveLocation(bookingLocation, serviceSelections);
|
|
111
112
|
return children({
|
|
@@ -114,6 +115,7 @@ export function Data(props) {
|
|
|
114
115
|
timezone,
|
|
115
116
|
formSubmission,
|
|
116
117
|
selectedPaymentOption,
|
|
118
|
+
depositSelected,
|
|
117
119
|
actions,
|
|
118
120
|
});
|
|
119
121
|
}
|
|
@@ -172,7 +172,8 @@ export interface ServiceOptionsProps {
|
|
|
172
172
|
}
|
|
173
173
|
/**
|
|
174
174
|
* Core component that exposes service payment options via render props.
|
|
175
|
-
* Reads isOnline, isInPerson, isDeposit from the payment
|
|
175
|
+
* Reads isOnline, isInPerson, isDeposit, canPayFullUpfront from the payment
|
|
176
|
+
* service signal.
|
|
176
177
|
*
|
|
177
178
|
* @component
|
|
178
179
|
*/
|
|
@@ -81,10 +81,12 @@ export function Data(props) {
|
|
|
81
81
|
const additionalInfoList = paymentDetails?.additionalInfo?.lineItems || [];
|
|
82
82
|
const firstLineItemInfo = additionalInfoList[0];
|
|
83
83
|
const customPrice = firstLineItemInfo?.customPrice || null;
|
|
84
|
-
// Computed flags
|
|
85
|
-
const hasTax = tax !== null && tax.amount > 0;
|
|
86
|
-
const hasDiscount = discount !== null && discount.amount > 0;
|
|
87
|
-
const isDeposit = payNow !== null &&
|
|
84
|
+
// Computed flags (amounts may be strings — compare numerically)
|
|
85
|
+
const hasTax = tax !== null && Number(tax.amount) > 0;
|
|
86
|
+
const hasDiscount = discount !== null && Number(discount.amount) > 0;
|
|
87
|
+
const isDeposit = payNow !== null &&
|
|
88
|
+
total !== null &&
|
|
89
|
+
Number(payNow.amount) < Number(total.amount);
|
|
88
90
|
return props.children({
|
|
89
91
|
subtotal,
|
|
90
92
|
total,
|
|
@@ -190,7 +192,8 @@ export function LineItemProvider(props) {
|
|
|
190
192
|
}
|
|
191
193
|
/**
|
|
192
194
|
* Core component that exposes service payment options via render props.
|
|
193
|
-
* Reads isOnline, isInPerson, isDeposit from the payment
|
|
195
|
+
* Reads isOnline, isInPerson, isDeposit, canPayFullUpfront from the payment
|
|
196
|
+
* service signal.
|
|
194
197
|
*
|
|
195
198
|
* @component
|
|
196
199
|
*/
|
|
@@ -217,9 +220,9 @@ export function ServiceOptions(props) {
|
|
|
217
220
|
*/
|
|
218
221
|
export function LineItemInfo(props) {
|
|
219
222
|
const { lineItem, currency } = useLineItemContext();
|
|
220
|
-
// Computed flags
|
|
221
|
-
const hasDiscount = lineItem.discount !== null && lineItem.discount.amount > 0;
|
|
222
|
-
const hasDeposit = lineItem.deposit !== null && lineItem.deposit.amount > 0;
|
|
223
|
+
// Computed flags (amounts may be strings — compare numerically)
|
|
224
|
+
const hasDiscount = lineItem.discount !== null && Number(lineItem.discount.amount) > 0;
|
|
225
|
+
const hasDeposit = lineItem.deposit !== null && Number(lineItem.deposit.amount) > 0;
|
|
223
226
|
return props.children({
|
|
224
227
|
lineItem,
|
|
225
228
|
currency,
|
|
@@ -210,7 +210,8 @@ export interface ServiceOptionsProps {
|
|
|
210
210
|
*
|
|
211
211
|
* Payment scenarios:
|
|
212
212
|
* - `isOnline=true, isInPerson=false, isDeposit=false` → Pay now only (Due now = total)
|
|
213
|
-
* - `isOnline=true, isInPerson=false, isDeposit=true` → Pay now + security deposit
|
|
213
|
+
* - `isOnline=true, isInPerson=false, isDeposit=true, canPayFullUpfront=false` → Pay now + security deposit
|
|
214
|
+
* - `isOnline=true, isInPerson=false, isDeposit=true, canPayFullUpfront=true` → Radio: Pay deposit now / Pay in full now
|
|
214
215
|
* - `isOnline=true, isInPerson=true` → Radio: Pay Online / Pay on Arrival
|
|
215
216
|
* - `isOnline=false, isInPerson=true` → Pay on arrival only
|
|
216
217
|
*
|
|
@@ -223,7 +224,7 @@ export interface ServiceOptionsProps {
|
|
|
223
224
|
* @example
|
|
224
225
|
* ```tsx
|
|
225
226
|
* <Payment.ServiceOptions asChild>
|
|
226
|
-
* {({ isOnline, isInPerson, isDeposit }) => (
|
|
227
|
+
* {({ isOnline, isInPerson, isDeposit, canPayFullUpfront }) => (
|
|
227
228
|
* // render the correct payment scenario
|
|
228
229
|
* )}
|
|
229
230
|
* </Payment.ServiceOptions>
|
|
@@ -144,7 +144,7 @@ Total.displayName = 'Payment.Total';
|
|
|
144
144
|
*/
|
|
145
145
|
export const PayNow = React.forwardRef((props, ref) => {
|
|
146
146
|
const { asChild, children, className } = props;
|
|
147
|
-
return (_jsx(CorePayment.Data, { children: ({ payNow, isDeposit }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, customElement: children, customElementProps: { payNow, isDeposit }, "data-testid": TestIds.paymentPayNow, "data-has-deposit": isDeposit, children: isDeposit && payNow && payNow.amount > 0 && (_jsx(Money, { money: payNow })) })) }));
|
|
147
|
+
return (_jsx(CorePayment.Data, { children: ({ payNow, isDeposit }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, customElement: children, customElementProps: { payNow, isDeposit }, "data-testid": TestIds.paymentPayNow, "data-has-deposit": isDeposit, children: isDeposit && payNow && Number(payNow.amount) > 0 && (_jsx(Money, { money: payNow })) })) }));
|
|
148
148
|
});
|
|
149
149
|
PayNow.displayName = 'Payment.PayNow';
|
|
150
150
|
/**
|
|
@@ -159,7 +159,7 @@ PayNow.displayName = 'Payment.PayNow';
|
|
|
159
159
|
*/
|
|
160
160
|
export const PayLater = React.forwardRef((props, ref) => {
|
|
161
161
|
const { asChild, children, className } = props;
|
|
162
|
-
return (_jsx(CorePayment.Data, { children: ({ payLater, isDeposit }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, customElement: children, customElementProps: { payLater, isDeposit }, "data-testid": TestIds.paymentPayLater, "data-has-deposit": isDeposit, children: isDeposit && payLater && payLater.amount > 0 && (_jsx(Money, { money: payLater })) })) }));
|
|
162
|
+
return (_jsx(CorePayment.Data, { children: ({ payLater, isDeposit }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, customElement: children, customElementProps: { payLater, isDeposit }, "data-testid": TestIds.paymentPayLater, "data-has-deposit": isDeposit, children: isDeposit && payLater && Number(payLater.amount) > 0 && (_jsx(Money, { money: payLater })) })) }));
|
|
163
163
|
});
|
|
164
164
|
PayLater.displayName = 'Payment.PayLater';
|
|
165
165
|
/**
|
|
@@ -168,7 +168,8 @@ PayLater.displayName = 'Payment.PayLater';
|
|
|
168
168
|
*
|
|
169
169
|
* Payment scenarios:
|
|
170
170
|
* - `isOnline=true, isInPerson=false, isDeposit=false` → Pay now only (Due now = total)
|
|
171
|
-
* - `isOnline=true, isInPerson=false, isDeposit=true` → Pay now + security deposit
|
|
171
|
+
* - `isOnline=true, isInPerson=false, isDeposit=true, canPayFullUpfront=false` → Pay now + security deposit
|
|
172
|
+
* - `isOnline=true, isInPerson=false, isDeposit=true, canPayFullUpfront=true` → Radio: Pay deposit now / Pay in full now
|
|
172
173
|
* - `isOnline=true, isInPerson=true` → Radio: Pay Online / Pay on Arrival
|
|
173
174
|
* - `isOnline=false, isInPerson=true` → Pay on arrival only
|
|
174
175
|
*
|
|
@@ -181,7 +182,7 @@ PayLater.displayName = 'Payment.PayLater';
|
|
|
181
182
|
* @example
|
|
182
183
|
* ```tsx
|
|
183
184
|
* <Payment.ServiceOptions asChild>
|
|
184
|
-
* {({ isOnline, isInPerson, isDeposit }) => (
|
|
185
|
+
* {({ isOnline, isInPerson, isDeposit, canPayFullUpfront }) => (
|
|
185
186
|
* // render the correct payment scenario
|
|
186
187
|
* )}
|
|
187
188
|
* </Payment.ServiceOptions>
|
|
@@ -189,7 +190,12 @@ PayLater.displayName = 'Payment.PayLater';
|
|
|
189
190
|
*/
|
|
190
191
|
export const ServiceOptions = React.forwardRef((props, ref) => {
|
|
191
192
|
const { asChild, children } = props;
|
|
192
|
-
return (_jsx(CorePayment.ServiceOptions, { children: ({ isOnline, isInPerson, isDeposit }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, customElement: children, customElementProps: {
|
|
193
|
+
return (_jsx(CorePayment.ServiceOptions, { children: ({ isOnline, isInPerson, isDeposit, canPayFullUpfront }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, customElement: children, customElementProps: {
|
|
194
|
+
isOnline,
|
|
195
|
+
isInPerson,
|
|
196
|
+
isDeposit,
|
|
197
|
+
canPayFullUpfront,
|
|
198
|
+
}, "data-testid": TestIds.paymentServiceOptions, "data-is-online": isOnline, "data-is-in-person": isInPerson, "data-is-deposit": isDeposit, "data-can-pay-full-upfront": canPayFullUpfront, children: null })) }));
|
|
193
199
|
});
|
|
194
200
|
ServiceOptions.displayName = 'Payment.ServiceOptions';
|
|
195
201
|
/**
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { LocationType as TimeSlotLocationType } from '@wix/auto_sdk_bookings_availability-time-slots';
|
|
5
5
|
import { LocationType as BookingLocationType, SelectionMethod, } from '@wix/auto_sdk_bookings_bookings';
|
|
6
6
|
import { STAFF_MEMBER_RESOURCE_TYPE_ID } from '../../constants.js';
|
|
7
|
+
import { isFullUpfrontPaymentAllowed, requiresDeposit, } from '../../servicePayment.js';
|
|
7
8
|
/**
|
|
8
9
|
* Derives the selected payment option from service payment settings.
|
|
9
10
|
* Maps service.payment.options to booking API's selectedPaymentOption.
|
|
@@ -53,12 +54,20 @@ export function buildBookingRequest(params) {
|
|
|
53
54
|
const resource = item.timeSlot.resources?.[0] ?? item.resources?.[0];
|
|
54
55
|
// Get location: prefer timeSlot.location, fallback to params.location
|
|
55
56
|
const slotLocation = item.timeSlot.location ?? location;
|
|
57
|
+
// Consumer override (if set) wins over the service-config heuristic.
|
|
58
|
+
const selectedPaymentOption = params.selectedPaymentOption ?? deriveSelectedPaymentOption(item.service);
|
|
59
|
+
// The only state where the schema allows `false`. Outside it, omitting the key
|
|
60
|
+
// leaves the server default in place.
|
|
61
|
+
const depositSelectedApplies = params.depositSelected !== undefined &&
|
|
62
|
+
selectedPaymentOption === 'ONLINE' &&
|
|
63
|
+
requiresDeposit(item.service) &&
|
|
64
|
+
isFullUpfrontPaymentAllowed(item.service);
|
|
56
65
|
return {
|
|
57
66
|
booking: {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
67
|
+
selectedPaymentOption,
|
|
68
|
+
...(depositSelectedApplies && {
|
|
69
|
+
depositSelected: params.depositSelected,
|
|
70
|
+
}),
|
|
62
71
|
// Participants
|
|
63
72
|
totalParticipants: item.totalParticipants || 1,
|
|
64
73
|
// App that created the booking (used to filter bookings by source app).
|
|
@@ -59,6 +59,12 @@ export interface BookActionParams {
|
|
|
59
59
|
* service. When omitted, the existing service-config heuristic applies.
|
|
60
60
|
*/
|
|
61
61
|
selectedPaymentOption?: SelectedPaymentOption;
|
|
62
|
+
/**
|
|
63
|
+
* Optional consumer choice: `true` pays only the deposit now, `false` pays the
|
|
64
|
+
* full price now. Dropped unless the booking is ONLINE and the service has a
|
|
65
|
+
* deposit with `fullUpfrontPaymentAllowed`. Omit to keep the server default.
|
|
66
|
+
*/
|
|
67
|
+
depositSelected?: boolean;
|
|
62
68
|
/**
|
|
63
69
|
* DAY-range only. When `true`, the picked per-day slots are collapsed into a
|
|
64
70
|
* single Booking spanning the whole range (`firstSlot.startDate ->
|
|
@@ -89,6 +89,12 @@ export interface BookingServiceActions {
|
|
|
89
89
|
* is cleared and the heuristic applies again.
|
|
90
90
|
*/
|
|
91
91
|
setSelectedPaymentOption(value: SelectedPaymentOption | null): void;
|
|
92
|
+
/**
|
|
93
|
+
* Set (or clear with `undefined`) the deposit-vs-full-upfront choice. `true`
|
|
94
|
+
* charges only the deposit now, `false` charges the full price now. Gate the UI
|
|
95
|
+
* on `Payment.ServiceOptions`' `isDeposit && canPayFullUpfront`.
|
|
96
|
+
*/
|
|
97
|
+
setDepositSelected(value: boolean | undefined): void;
|
|
92
98
|
/**
|
|
93
99
|
* Toggle the DAY-range `allDay` flag. When `true`, `book()` collapses the
|
|
94
100
|
* picked per-day slots into one range-spanning Booking created via
|
|
@@ -117,6 +123,12 @@ export interface BookingService {
|
|
|
117
123
|
* service-config heuristic. Set to `'ONLINE'` or `'OFFLINE'` to override.
|
|
118
124
|
*/
|
|
119
125
|
selectedPaymentOption: Signal<SelectedPaymentOption | undefined>;
|
|
126
|
+
/**
|
|
127
|
+
* Signal containing the deposit-vs-full-upfront choice. `true` pays only the
|
|
128
|
+
* deposit now, `false` pays the full price now. `undefined` means "not chosen"
|
|
129
|
+
* — `book()` omits the field and the preview keeps its deposit default.
|
|
130
|
+
*/
|
|
131
|
+
depositSelected: Signal<boolean | undefined>;
|
|
120
132
|
/** Actions for modifying booking state */
|
|
121
133
|
actions: BookingServiceActions;
|
|
122
134
|
}
|
|
@@ -146,6 +158,11 @@ export interface BookingServiceConfig {
|
|
|
146
158
|
* service-config heuristic; set to `'ONLINE'` or `'OFFLINE'` to override.
|
|
147
159
|
*/
|
|
148
160
|
selectedPaymentOption?: SelectedPaymentOption;
|
|
161
|
+
/**
|
|
162
|
+
* Optional initial deposit-vs-full-upfront choice. Omit to keep the server's
|
|
163
|
+
* default.
|
|
164
|
+
*/
|
|
165
|
+
depositSelected?: boolean;
|
|
149
166
|
/** Optional app ID override for the catalog reference. Defaults to the bookings app ID. */
|
|
150
167
|
appId?: string;
|
|
151
168
|
/**
|
|
@@ -71,6 +71,7 @@ export const BookingService = implementService.withConfig()(BookingServiceDefini
|
|
|
71
71
|
const timezoneSignal = signalsService.signal(config.timezone ?? getClientTimezone());
|
|
72
72
|
const formSubmissionSignal = signalsService.signal(config.formSubmission || null);
|
|
73
73
|
const selectedPaymentOptionSignal = signalsService.signal(config.selectedPaymentOption);
|
|
74
|
+
const depositSelectedSignal = signalsService.signal(config.depositSelected);
|
|
74
75
|
// Internal-only signal: set via `setAllDay`, read by `book()`. Not
|
|
75
76
|
// exposed on the service surface — consumers derive and push the value
|
|
76
77
|
// (e.g. from the picker's selection mode), so there's no read-back.
|
|
@@ -173,6 +174,10 @@ export const BookingService = implementService.withConfig()(BookingServiceDefini
|
|
|
173
174
|
setSelectedPaymentOption(value) {
|
|
174
175
|
selectedPaymentOptionSignal.set(value ?? undefined);
|
|
175
176
|
},
|
|
177
|
+
// Deposit vs full upfront action
|
|
178
|
+
setDepositSelected(value) {
|
|
179
|
+
depositSelectedSignal.set(value);
|
|
180
|
+
},
|
|
176
181
|
// All-day (DAY-range) action
|
|
177
182
|
setAllDay(value) {
|
|
178
183
|
allDaySignal.set(value);
|
|
@@ -192,6 +197,7 @@ export const BookingService = implementService.withConfig()(BookingServiceDefini
|
|
|
192
197
|
const location = locationSignal.get();
|
|
193
198
|
const timezone = timezoneSignal.get();
|
|
194
199
|
const selectedPaymentOption = selectedPaymentOptionSignal.get();
|
|
200
|
+
const depositSelected = depositSelectedSignal.get();
|
|
195
201
|
const allDay = allDaySignal.get();
|
|
196
202
|
// Validation happens inside executeBookAction
|
|
197
203
|
return executeBookAction({
|
|
@@ -202,6 +208,7 @@ export const BookingService = implementService.withConfig()(BookingServiceDefini
|
|
|
202
208
|
appId: config.appId,
|
|
203
209
|
sourceAppId: config.sourceAppId,
|
|
204
210
|
selectedPaymentOption,
|
|
211
|
+
depositSelected,
|
|
205
212
|
allDay,
|
|
206
213
|
});
|
|
207
214
|
},
|
|
@@ -212,6 +219,7 @@ export const BookingService = implementService.withConfig()(BookingServiceDefini
|
|
|
212
219
|
timezone: timezoneSignal,
|
|
213
220
|
formSubmission: formSubmissionSignal,
|
|
214
221
|
selectedPaymentOption: selectedPaymentOptionSignal,
|
|
222
|
+
depositSelected: depositSelectedSignal,
|
|
215
223
|
actions,
|
|
216
224
|
};
|
|
217
225
|
});
|
package/dist/services/index.d.ts
CHANGED
|
@@ -9,6 +9,6 @@ export { ServiceListService, ServiceListServiceDefinition, type ServiceListServi
|
|
|
9
9
|
export { SYNTHETIC_CUSTOM_ID, SYNTHETIC_CUSTOMER_ID, AvailabilityLocationType, type ServiceWithAvailabilityItem, type AvailabilityFilter, type Attribute, type AvailabilityLocation, } from '../api/query-services/index.js';
|
|
10
10
|
export { executeBookAction, canBook, buildBookingRequest, buildCartRequest, buildDayRangeBookingRequest, createBookingsForCart, isDayRangeService, getDayRangeBounds, type CanBookParams, type BookResult, type BookingError, type BookActionParams, type BookChildProps, type BookProps, type BuildCartParams, type BuildDayRangeBookingRequest, type CreatedBookings, type DayRangeBounds, } from './booking/book-action/index.js';
|
|
11
11
|
export { BookingFormService, BookingFormServiceDefinition, type BookingFormServiceAPI, type BookingFormServiceConfig, } from './booking-form/booking-form.js';
|
|
12
|
-
export { PaymentService, PaymentServiceDefinition, type PaymentServiceAPI, type PaymentServiceConfig, type PaymentDetails, type PricingServiceSelection, type LineItemAdditionalInfo, type ServicePaymentOptions, loadPaymentConfig, type SuccessPaymentConfigResult, type ErrorPaymentConfigResult, } from './payment/payment.js';
|
|
12
|
+
export { PaymentService, PaymentServiceDefinition, type PaymentServiceAPI, type PaymentServiceConfig, type PaymentDetails, type PricingServiceSelection, type LineItemAdditionalInfo, type AppliedAdditionalFee, type PreviewPriceInfo, type ServicePaymentOptions, loadPaymentConfig, type SuccessPaymentConfigResult, type ErrorPaymentConfigResult, } from './payment/payment.js';
|
|
13
13
|
export { LocationListService, LocationListServiceDefinition, LocationType, loadLocationListServiceInitialData, locationListServiceBinding, type LocationListServiceAPI, type LocationListServiceConfig, type LocationListActions, type Location, type LoadLocationListServiceResult, getLocationById, } from './location-list/location-list.js';
|
|
14
14
|
export { StaffMemberListService, StaffMemberListServiceDefinition, loadStaffMemberListServiceInitialData, staffMemberListServiceBinding, type StaffMemberListServiceAPI, type StaffMemberListServiceConfig, type StaffMemberListActions, type StaffMemberData, type LoadStaffMemberListServiceResult, } from './staff-member-list/staff-member-list.js';
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { type PaymentServiceConfig, type PaymentServiceInternalConfig, type PricingServiceSelection } from './payment.def.js';
|
|
7
7
|
import type { SelectedPaymentOption } from '../booking/book-action/types.js';
|
|
8
|
-
export { PaymentServiceDefinition, type PaymentServiceConfig, type PaymentDetails, type LineItemAdditionalInfo, type PricingServiceSelection, type ServicePaymentOptions, } from './payment.def.js';
|
|
8
|
+
export { PaymentServiceDefinition, type PaymentServiceConfig, type PaymentDetails, type LineItemAdditionalInfo, type AppliedAdditionalFee, type PreviewPriceInfo, type PricingServiceSelection, type ServicePaymentOptions, } from './payment.def.js';
|
|
9
9
|
export type { PaymentServiceAPI, PaymentServiceInternalConfig, } from './payment.def.js';
|
|
10
10
|
export declare const PaymentService: import("@wix/services-definitions").ServiceFactory<string & {
|
|
11
11
|
__api: import("./payment.def.js").PaymentServiceAPI;
|
|
@@ -28,9 +28,12 @@ export type ErrorPaymentConfigResult = {
|
|
|
28
28
|
* @param params.totalParticipants - Number of participants (default: 1)
|
|
29
29
|
* @param params.selectedPaymentOption - Optional consumer-selected payment option;
|
|
30
30
|
* overrides the service-config heuristic on each line item's `paymentOption`.
|
|
31
|
+
* @param params.depositSelected - Optional deposit-vs-full-upfront choice; `false`
|
|
32
|
+
* resolves a deposit service to full payment. Omit to keep the deposit default.
|
|
31
33
|
*/
|
|
32
34
|
export declare function loadPaymentConfig(params: {
|
|
33
35
|
pricingServiceSelections: PricingServiceSelection[];
|
|
34
36
|
totalParticipants?: number;
|
|
35
37
|
selectedPaymentOption?: SelectedPaymentOption;
|
|
38
|
+
depositSelected?: boolean;
|
|
36
39
|
}): Promise<SuccessPaymentConfigResult | ErrorPaymentConfigResult>;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import type { Signal } from '@wix/services-definitions/core-services/signals';
|
|
6
6
|
import type { CalculateTotalsResponse } from '@wix/auto_sdk_ecom_totals-calculator';
|
|
7
7
|
import type { Service } from '@wix/auto_sdk_bookings_services';
|
|
8
|
+
import type { BookingLineItem, PriceInfo } from '@wix/auto_sdk_bookings_pricing';
|
|
8
9
|
import type { SelectedPaymentOption } from '../booking/book-action/types.js';
|
|
9
10
|
import type { ServiceSelectionTimeSlot } from '../booking/booking.js';
|
|
10
11
|
/**
|
|
@@ -16,13 +17,47 @@ export interface ServicePaymentOptions {
|
|
|
16
17
|
isOnline: boolean;
|
|
17
18
|
/** Customer can pay in person (on arrival) */
|
|
18
19
|
isInPerson: boolean;
|
|
19
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* A deposit is required at booking time — including percentage deposits, which
|
|
22
|
+
* set no amount. For the amount use `Payment.PayNow` / `Payment.PayLater`.
|
|
23
|
+
*/
|
|
20
24
|
isDeposit: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Customers may pay the full price upfront instead of only the deposit.
|
|
27
|
+
* Meaningful only with `isDeposit`; together they gate the
|
|
28
|
+
* deposit-vs-pay-in-full toggle.
|
|
29
|
+
*/
|
|
30
|
+
canPayFullUpfront: boolean;
|
|
21
31
|
}
|
|
22
32
|
/**
|
|
23
33
|
* Payment option for line items
|
|
24
34
|
*/
|
|
25
35
|
export type PaymentOption = 'FULL_PAYMENT_ONLINE' | 'FULL_PAYMENT_OFFLINE' | 'DEPOSIT_ONLINE';
|
|
36
|
+
/**
|
|
37
|
+
* An additional fee pricing applied to a booking line, as served.
|
|
38
|
+
*/
|
|
39
|
+
export interface AppliedAdditionalFee {
|
|
40
|
+
/** The service's additional fee ID. */
|
|
41
|
+
feeId?: string;
|
|
42
|
+
/** Units the fee was charged for (1 for a per-reservation fee). */
|
|
43
|
+
units?: number;
|
|
44
|
+
/** The fee amount for this line. */
|
|
45
|
+
amount?: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* `PriceInfo` with the additional-fee fields `previewPrice` serves, which the
|
|
49
|
+
* public pricing SDK types don't declare (they are `@internal` there). Types
|
|
50
|
+
* only: the values are the response as served.
|
|
51
|
+
*/
|
|
52
|
+
export interface PreviewPriceInfo extends PriceInfo {
|
|
53
|
+
bookingLineItems?: (BookingLineItem & {
|
|
54
|
+
additionalFees?: AppliedAdditionalFee[];
|
|
55
|
+
})[];
|
|
56
|
+
/** Sum of all lines' additional fees. */
|
|
57
|
+
totalAdditionalFees?: number | null;
|
|
58
|
+
/** `calculatedPrice` plus `totalAdditionalFees`. */
|
|
59
|
+
calculatedPriceWithFees?: number | null;
|
|
60
|
+
}
|
|
26
61
|
/**
|
|
27
62
|
* Additional computed info for a line item (not in SDK response)
|
|
28
63
|
*/
|
|
@@ -31,6 +66,14 @@ export interface LineItemAdditionalInfo {
|
|
|
31
66
|
lineItemId: string;
|
|
32
67
|
/** Custom price (for CUSTOM rate type services) */
|
|
33
68
|
customPrice?: string;
|
|
69
|
+
/**
|
|
70
|
+
* The raw `previewPrice` response for this line, as served — for fields the
|
|
71
|
+
* payment service does not read. Not the amounts charged: those (including
|
|
72
|
+
* a capped deposit) come from `response`. Set only when the line was priced
|
|
73
|
+
* by `previewPrice` (duration-range services, or a deposit the server
|
|
74
|
+
* resolves).
|
|
75
|
+
*/
|
|
76
|
+
priceInfo?: PreviewPriceInfo;
|
|
34
77
|
}
|
|
35
78
|
/**
|
|
36
79
|
* Payment calculation result with SDK response and additional computed info
|
|
@@ -83,6 +126,11 @@ export interface PaymentServiceInternalConfig extends PaymentServiceConfig {
|
|
|
83
126
|
* set, overrides the service-config heuristic in line item `paymentOption`.
|
|
84
127
|
*/
|
|
85
128
|
selectedPaymentOption?: SelectedPaymentOption;
|
|
129
|
+
/**
|
|
130
|
+
* Deposit-vs-full-upfront choice for lazy loading. `false` resolves a deposit
|
|
131
|
+
* service to full payment instead of `DEPOSIT_ONLINE`.
|
|
132
|
+
*/
|
|
133
|
+
depositSelected?: boolean;
|
|
86
134
|
}
|
|
87
135
|
export interface PaymentServiceAPI {
|
|
88
136
|
paymentDetailsSignal: Signal<PaymentDetails | null>;
|