@vulog/aima-booking 1.2.21 → 1.2.22
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/dist/index.d.mts +128 -3
- package/dist/index.d.ts +128 -3
- package/dist/index.js +42 -1
- package/dist/index.mjs +41 -1
- package/package.json +3 -3
- package/src/getBookingRequests.ts +3 -0
- package/src/index.ts +1 -0
- package/src/triggerBRPayment.test.ts +192 -0
- package/src/triggerBRPayment.ts +52 -0
- package/src/types.ts +56 -0
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Client } from '@vulog/aima-client';
|
|
2
2
|
import { PaginableOptions, PaginableResponse } from '@vulog/aima-core';
|
|
3
|
-
import { z } from 'zod';
|
|
3
|
+
import z$1, { z } from 'zod';
|
|
4
4
|
import { UUID } from 'crypto';
|
|
5
5
|
|
|
6
6
|
type PaymentReceipts = {
|
|
@@ -18,6 +18,51 @@ type PaymentReceipts = {
|
|
|
18
18
|
scope: string;
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
|
+
/** Payment intent or receipt item as returned by trigger BR payment (and similar payment endpoints). */
|
|
22
|
+
type BRPaymentItem = {
|
|
23
|
+
id: string;
|
|
24
|
+
pspName: string;
|
|
25
|
+
pspReference: string;
|
|
26
|
+
pspPublishableKey: string;
|
|
27
|
+
amount: number;
|
|
28
|
+
currency: string;
|
|
29
|
+
date: string;
|
|
30
|
+
captureBefore: string;
|
|
31
|
+
status: string;
|
|
32
|
+
paymentMethodType: string;
|
|
33
|
+
paymentMethodPspReference: string;
|
|
34
|
+
paymentIntentPspReference: string;
|
|
35
|
+
number: number;
|
|
36
|
+
code?: string;
|
|
37
|
+
declineCode?: string;
|
|
38
|
+
pspClientSecret?: string;
|
|
39
|
+
reason?: string;
|
|
40
|
+
note?: string;
|
|
41
|
+
nextAction?: {
|
|
42
|
+
nextActionRedirectUrl: {
|
|
43
|
+
url: string;
|
|
44
|
+
method: string;
|
|
45
|
+
data: Record<string, string>;
|
|
46
|
+
};
|
|
47
|
+
type: string;
|
|
48
|
+
};
|
|
49
|
+
metadatas: Record<string, string>;
|
|
50
|
+
};
|
|
51
|
+
/** Credit entry in a booking request (e.g. trigger BR payment response). */
|
|
52
|
+
type BookingCredit = {
|
|
53
|
+
id: string;
|
|
54
|
+
fleetId: string;
|
|
55
|
+
amount: number;
|
|
56
|
+
availableAmount: number;
|
|
57
|
+
status: string;
|
|
58
|
+
walletId: string;
|
|
59
|
+
date: string;
|
|
60
|
+
};
|
|
61
|
+
/** Preferred payment method entry in request/response. */
|
|
62
|
+
type PreferredPaymentMethod = {
|
|
63
|
+
pspReference: string;
|
|
64
|
+
amount: number;
|
|
65
|
+
};
|
|
21
66
|
type CustomPrice = {
|
|
22
67
|
id: string;
|
|
23
68
|
fleetId: string;
|
|
@@ -105,6 +150,13 @@ type SATBookingRequest = BaseBookingRequest & {
|
|
|
105
150
|
trip: any | null;
|
|
106
151
|
warning: string | null;
|
|
107
152
|
};
|
|
153
|
+
/** Response of the trigger BR payment endpoint (booking request + payment intents/receipts). */
|
|
154
|
+
type TriggerBRPaymentResponse = Omit<SATBookingRequest, 'credits'> & {
|
|
155
|
+
paymentIntents: BRPaymentItem[];
|
|
156
|
+
paymentReceipts: BRPaymentItem[];
|
|
157
|
+
credits: BookingCredit[];
|
|
158
|
+
preferredPaymentMethods?: PreferredPaymentMethod[];
|
|
159
|
+
};
|
|
108
160
|
type GeoInfo = {
|
|
109
161
|
name: string;
|
|
110
162
|
coordinates: {
|
|
@@ -147,7 +199,7 @@ type Station = Partial<GeoInfo> & Partial<ServiceInfo> & {
|
|
|
147
199
|
[key: string]: any;
|
|
148
200
|
};
|
|
149
201
|
|
|
150
|
-
declare const BookingRequestStatusSchema: z.ZodEnum<["ALERT", "UPCOMING", "ONGOING", "COMPLETED", "CANCELLED", "PENDING_APPROVAL"]>;
|
|
202
|
+
declare const BookingRequestStatusSchema: z.ZodEnum<["ALERT", "UPCOMING", "ONGOING", "COMPLETED", "CANCELLED", "PENDING_APPROVAL", "CONFIRMED", "PENDING", "LATE"]>;
|
|
151
203
|
type BookingRequestStatus = z.infer<typeof BookingRequestStatusSchema>;
|
|
152
204
|
declare const ServiceTypeSchema: z.ZodEnum<["SUBSCRIPTION", "ROUND_TRIP_BOOKING", "SCHEDULED_BOOKING_STATION"]>;
|
|
153
205
|
type ServiceType = z.infer<typeof ServiceTypeSchema>;
|
|
@@ -202,4 +254,77 @@ declare const deallocateVehicle: (client: Client, bookingRequestId: UUID, vehicl
|
|
|
202
254
|
|
|
203
255
|
declare const updateScheduleBooking: (client: Client, bookingRequestId: string, updateData: Record<string, unknown>) => Promise<SATBookingRequest>;
|
|
204
256
|
|
|
205
|
-
|
|
257
|
+
declare const triggerBRPaymentSchema: z$1.ZodObject<{
|
|
258
|
+
bookingRequestId: z$1.ZodString;
|
|
259
|
+
body: z$1.ZodObject<{
|
|
260
|
+
scope: z$1.ZodEnum<["RENTAL", "DEPOSIT"]>;
|
|
261
|
+
requiresActionReturnURL: z$1.ZodOptional<z$1.ZodString>;
|
|
262
|
+
online: z$1.ZodBoolean;
|
|
263
|
+
amountType: z$1.ZodEnum<["FIXED", "PERCENTAGE"]>;
|
|
264
|
+
amountValue: z$1.ZodOptional<z$1.ZodNumber>;
|
|
265
|
+
preferredPaymentMethods: z$1.ZodOptional<z$1.ZodArray<z$1.ZodObject<{
|
|
266
|
+
pspReference: z$1.ZodString;
|
|
267
|
+
amount: z$1.ZodDefault<z$1.ZodNumber>;
|
|
268
|
+
}, "strip", z$1.ZodTypeAny, {
|
|
269
|
+
pspReference: string;
|
|
270
|
+
amount: number;
|
|
271
|
+
}, {
|
|
272
|
+
pspReference: string;
|
|
273
|
+
amount?: number | undefined;
|
|
274
|
+
}>, "many">>;
|
|
275
|
+
profileId: z$1.ZodString;
|
|
276
|
+
}, "strip", z$1.ZodTypeAny, {
|
|
277
|
+
profileId: string;
|
|
278
|
+
scope: "RENTAL" | "DEPOSIT";
|
|
279
|
+
online: boolean;
|
|
280
|
+
amountType: "FIXED" | "PERCENTAGE";
|
|
281
|
+
requiresActionReturnURL?: string | undefined;
|
|
282
|
+
amountValue?: number | undefined;
|
|
283
|
+
preferredPaymentMethods?: {
|
|
284
|
+
pspReference: string;
|
|
285
|
+
amount: number;
|
|
286
|
+
}[] | undefined;
|
|
287
|
+
}, {
|
|
288
|
+
profileId: string;
|
|
289
|
+
scope: "RENTAL" | "DEPOSIT";
|
|
290
|
+
online: boolean;
|
|
291
|
+
amountType: "FIXED" | "PERCENTAGE";
|
|
292
|
+
requiresActionReturnURL?: string | undefined;
|
|
293
|
+
amountValue?: number | undefined;
|
|
294
|
+
preferredPaymentMethods?: {
|
|
295
|
+
pspReference: string;
|
|
296
|
+
amount?: number | undefined;
|
|
297
|
+
}[] | undefined;
|
|
298
|
+
}>;
|
|
299
|
+
}, "strip", z$1.ZodTypeAny, {
|
|
300
|
+
body: {
|
|
301
|
+
profileId: string;
|
|
302
|
+
scope: "RENTAL" | "DEPOSIT";
|
|
303
|
+
online: boolean;
|
|
304
|
+
amountType: "FIXED" | "PERCENTAGE";
|
|
305
|
+
requiresActionReturnURL?: string | undefined;
|
|
306
|
+
amountValue?: number | undefined;
|
|
307
|
+
preferredPaymentMethods?: {
|
|
308
|
+
pspReference: string;
|
|
309
|
+
amount: number;
|
|
310
|
+
}[] | undefined;
|
|
311
|
+
};
|
|
312
|
+
bookingRequestId: string;
|
|
313
|
+
}, {
|
|
314
|
+
body: {
|
|
315
|
+
profileId: string;
|
|
316
|
+
scope: "RENTAL" | "DEPOSIT";
|
|
317
|
+
online: boolean;
|
|
318
|
+
amountType: "FIXED" | "PERCENTAGE";
|
|
319
|
+
requiresActionReturnURL?: string | undefined;
|
|
320
|
+
amountValue?: number | undefined;
|
|
321
|
+
preferredPaymentMethods?: {
|
|
322
|
+
pspReference: string;
|
|
323
|
+
amount?: number | undefined;
|
|
324
|
+
}[] | undefined;
|
|
325
|
+
};
|
|
326
|
+
bookingRequestId: string;
|
|
327
|
+
}>;
|
|
328
|
+
declare const triggerBRPayment: (client: Client, bookingRequestId: UUID, body: z$1.infer<typeof triggerBRPaymentSchema>["body"]) => Promise<TriggerBRPaymentResponse>;
|
|
329
|
+
|
|
330
|
+
export { type BRPaymentItem, type BaseBookingRequest, type BookingCredit, type BookingRequest, type BookingRequestFilters, type BookingRequestStatus, type CustomPrice, type DayOpeningHours, type Days, type GeoInfo, type Include, type IncludeStation, type OpeningHours, type PaymentReceipts, type PreferredPaymentMethod, type SATBookingRequest, type SATBookingRequestStatus, type Service, type ServiceInfo, type ServiceType, type Station, type Timetable, type TriggerBRPaymentResponse, allocateVehicle, deallocateVehicle, getBookingRequestById, getBookingRequestByTrip, getBookingRequests, getSATBookingRequests, getScheduleBookingRequests, getStationById, getStations, getSubscriptionBookingRequestById, getSubscriptionBookingRequests, triggerBRPayment, updateScheduleBooking };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Client } from '@vulog/aima-client';
|
|
2
2
|
import { PaginableOptions, PaginableResponse } from '@vulog/aima-core';
|
|
3
|
-
import { z } from 'zod';
|
|
3
|
+
import z$1, { z } from 'zod';
|
|
4
4
|
import { UUID } from 'crypto';
|
|
5
5
|
|
|
6
6
|
type PaymentReceipts = {
|
|
@@ -18,6 +18,51 @@ type PaymentReceipts = {
|
|
|
18
18
|
scope: string;
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
|
+
/** Payment intent or receipt item as returned by trigger BR payment (and similar payment endpoints). */
|
|
22
|
+
type BRPaymentItem = {
|
|
23
|
+
id: string;
|
|
24
|
+
pspName: string;
|
|
25
|
+
pspReference: string;
|
|
26
|
+
pspPublishableKey: string;
|
|
27
|
+
amount: number;
|
|
28
|
+
currency: string;
|
|
29
|
+
date: string;
|
|
30
|
+
captureBefore: string;
|
|
31
|
+
status: string;
|
|
32
|
+
paymentMethodType: string;
|
|
33
|
+
paymentMethodPspReference: string;
|
|
34
|
+
paymentIntentPspReference: string;
|
|
35
|
+
number: number;
|
|
36
|
+
code?: string;
|
|
37
|
+
declineCode?: string;
|
|
38
|
+
pspClientSecret?: string;
|
|
39
|
+
reason?: string;
|
|
40
|
+
note?: string;
|
|
41
|
+
nextAction?: {
|
|
42
|
+
nextActionRedirectUrl: {
|
|
43
|
+
url: string;
|
|
44
|
+
method: string;
|
|
45
|
+
data: Record<string, string>;
|
|
46
|
+
};
|
|
47
|
+
type: string;
|
|
48
|
+
};
|
|
49
|
+
metadatas: Record<string, string>;
|
|
50
|
+
};
|
|
51
|
+
/** Credit entry in a booking request (e.g. trigger BR payment response). */
|
|
52
|
+
type BookingCredit = {
|
|
53
|
+
id: string;
|
|
54
|
+
fleetId: string;
|
|
55
|
+
amount: number;
|
|
56
|
+
availableAmount: number;
|
|
57
|
+
status: string;
|
|
58
|
+
walletId: string;
|
|
59
|
+
date: string;
|
|
60
|
+
};
|
|
61
|
+
/** Preferred payment method entry in request/response. */
|
|
62
|
+
type PreferredPaymentMethod = {
|
|
63
|
+
pspReference: string;
|
|
64
|
+
amount: number;
|
|
65
|
+
};
|
|
21
66
|
type CustomPrice = {
|
|
22
67
|
id: string;
|
|
23
68
|
fleetId: string;
|
|
@@ -105,6 +150,13 @@ type SATBookingRequest = BaseBookingRequest & {
|
|
|
105
150
|
trip: any | null;
|
|
106
151
|
warning: string | null;
|
|
107
152
|
};
|
|
153
|
+
/** Response of the trigger BR payment endpoint (booking request + payment intents/receipts). */
|
|
154
|
+
type TriggerBRPaymentResponse = Omit<SATBookingRequest, 'credits'> & {
|
|
155
|
+
paymentIntents: BRPaymentItem[];
|
|
156
|
+
paymentReceipts: BRPaymentItem[];
|
|
157
|
+
credits: BookingCredit[];
|
|
158
|
+
preferredPaymentMethods?: PreferredPaymentMethod[];
|
|
159
|
+
};
|
|
108
160
|
type GeoInfo = {
|
|
109
161
|
name: string;
|
|
110
162
|
coordinates: {
|
|
@@ -147,7 +199,7 @@ type Station = Partial<GeoInfo> & Partial<ServiceInfo> & {
|
|
|
147
199
|
[key: string]: any;
|
|
148
200
|
};
|
|
149
201
|
|
|
150
|
-
declare const BookingRequestStatusSchema: z.ZodEnum<["ALERT", "UPCOMING", "ONGOING", "COMPLETED", "CANCELLED", "PENDING_APPROVAL"]>;
|
|
202
|
+
declare const BookingRequestStatusSchema: z.ZodEnum<["ALERT", "UPCOMING", "ONGOING", "COMPLETED", "CANCELLED", "PENDING_APPROVAL", "CONFIRMED", "PENDING", "LATE"]>;
|
|
151
203
|
type BookingRequestStatus = z.infer<typeof BookingRequestStatusSchema>;
|
|
152
204
|
declare const ServiceTypeSchema: z.ZodEnum<["SUBSCRIPTION", "ROUND_TRIP_BOOKING", "SCHEDULED_BOOKING_STATION"]>;
|
|
153
205
|
type ServiceType = z.infer<typeof ServiceTypeSchema>;
|
|
@@ -202,4 +254,77 @@ declare const deallocateVehicle: (client: Client, bookingRequestId: UUID, vehicl
|
|
|
202
254
|
|
|
203
255
|
declare const updateScheduleBooking: (client: Client, bookingRequestId: string, updateData: Record<string, unknown>) => Promise<SATBookingRequest>;
|
|
204
256
|
|
|
205
|
-
|
|
257
|
+
declare const triggerBRPaymentSchema: z$1.ZodObject<{
|
|
258
|
+
bookingRequestId: z$1.ZodString;
|
|
259
|
+
body: z$1.ZodObject<{
|
|
260
|
+
scope: z$1.ZodEnum<["RENTAL", "DEPOSIT"]>;
|
|
261
|
+
requiresActionReturnURL: z$1.ZodOptional<z$1.ZodString>;
|
|
262
|
+
online: z$1.ZodBoolean;
|
|
263
|
+
amountType: z$1.ZodEnum<["FIXED", "PERCENTAGE"]>;
|
|
264
|
+
amountValue: z$1.ZodOptional<z$1.ZodNumber>;
|
|
265
|
+
preferredPaymentMethods: z$1.ZodOptional<z$1.ZodArray<z$1.ZodObject<{
|
|
266
|
+
pspReference: z$1.ZodString;
|
|
267
|
+
amount: z$1.ZodDefault<z$1.ZodNumber>;
|
|
268
|
+
}, "strip", z$1.ZodTypeAny, {
|
|
269
|
+
pspReference: string;
|
|
270
|
+
amount: number;
|
|
271
|
+
}, {
|
|
272
|
+
pspReference: string;
|
|
273
|
+
amount?: number | undefined;
|
|
274
|
+
}>, "many">>;
|
|
275
|
+
profileId: z$1.ZodString;
|
|
276
|
+
}, "strip", z$1.ZodTypeAny, {
|
|
277
|
+
profileId: string;
|
|
278
|
+
scope: "RENTAL" | "DEPOSIT";
|
|
279
|
+
online: boolean;
|
|
280
|
+
amountType: "FIXED" | "PERCENTAGE";
|
|
281
|
+
requiresActionReturnURL?: string | undefined;
|
|
282
|
+
amountValue?: number | undefined;
|
|
283
|
+
preferredPaymentMethods?: {
|
|
284
|
+
pspReference: string;
|
|
285
|
+
amount: number;
|
|
286
|
+
}[] | undefined;
|
|
287
|
+
}, {
|
|
288
|
+
profileId: string;
|
|
289
|
+
scope: "RENTAL" | "DEPOSIT";
|
|
290
|
+
online: boolean;
|
|
291
|
+
amountType: "FIXED" | "PERCENTAGE";
|
|
292
|
+
requiresActionReturnURL?: string | undefined;
|
|
293
|
+
amountValue?: number | undefined;
|
|
294
|
+
preferredPaymentMethods?: {
|
|
295
|
+
pspReference: string;
|
|
296
|
+
amount?: number | undefined;
|
|
297
|
+
}[] | undefined;
|
|
298
|
+
}>;
|
|
299
|
+
}, "strip", z$1.ZodTypeAny, {
|
|
300
|
+
body: {
|
|
301
|
+
profileId: string;
|
|
302
|
+
scope: "RENTAL" | "DEPOSIT";
|
|
303
|
+
online: boolean;
|
|
304
|
+
amountType: "FIXED" | "PERCENTAGE";
|
|
305
|
+
requiresActionReturnURL?: string | undefined;
|
|
306
|
+
amountValue?: number | undefined;
|
|
307
|
+
preferredPaymentMethods?: {
|
|
308
|
+
pspReference: string;
|
|
309
|
+
amount: number;
|
|
310
|
+
}[] | undefined;
|
|
311
|
+
};
|
|
312
|
+
bookingRequestId: string;
|
|
313
|
+
}, {
|
|
314
|
+
body: {
|
|
315
|
+
profileId: string;
|
|
316
|
+
scope: "RENTAL" | "DEPOSIT";
|
|
317
|
+
online: boolean;
|
|
318
|
+
amountType: "FIXED" | "PERCENTAGE";
|
|
319
|
+
requiresActionReturnURL?: string | undefined;
|
|
320
|
+
amountValue?: number | undefined;
|
|
321
|
+
preferredPaymentMethods?: {
|
|
322
|
+
pspReference: string;
|
|
323
|
+
amount?: number | undefined;
|
|
324
|
+
}[] | undefined;
|
|
325
|
+
};
|
|
326
|
+
bookingRequestId: string;
|
|
327
|
+
}>;
|
|
328
|
+
declare const triggerBRPayment: (client: Client, bookingRequestId: UUID, body: z$1.infer<typeof triggerBRPaymentSchema>["body"]) => Promise<TriggerBRPaymentResponse>;
|
|
329
|
+
|
|
330
|
+
export { type BRPaymentItem, type BaseBookingRequest, type BookingCredit, type BookingRequest, type BookingRequestFilters, type BookingRequestStatus, type CustomPrice, type DayOpeningHours, type Days, type GeoInfo, type Include, type IncludeStation, type OpeningHours, type PaymentReceipts, type PreferredPaymentMethod, type SATBookingRequest, type SATBookingRequestStatus, type Service, type ServiceInfo, type ServiceType, type Station, type Timetable, type TriggerBRPaymentResponse, allocateVehicle, deallocateVehicle, getBookingRequestById, getBookingRequestByTrip, getBookingRequests, getSATBookingRequests, getScheduleBookingRequests, getStationById, getStations, getSubscriptionBookingRequestById, getSubscriptionBookingRequests, triggerBRPayment, updateScheduleBooking };
|
package/dist/index.js
CHANGED
|
@@ -41,6 +41,7 @@ __export(index_exports, {
|
|
|
41
41
|
getStations: () => getStations,
|
|
42
42
|
getSubscriptionBookingRequestById: () => getSubscriptionBookingRequestById,
|
|
43
43
|
getSubscriptionBookingRequests: () => getSubscriptionBookingRequests,
|
|
44
|
+
triggerBRPayment: () => triggerBRPayment,
|
|
44
45
|
updateScheduleBooking: () => updateScheduleBooking
|
|
45
46
|
});
|
|
46
47
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -55,7 +56,10 @@ var BookingRequestStatusSchema = import_zod.z.enum([
|
|
|
55
56
|
"ONGOING",
|
|
56
57
|
"COMPLETED",
|
|
57
58
|
"CANCELLED",
|
|
58
|
-
"PENDING_APPROVAL"
|
|
59
|
+
"PENDING_APPROVAL",
|
|
60
|
+
"CONFIRMED",
|
|
61
|
+
"PENDING",
|
|
62
|
+
"LATE"
|
|
59
63
|
]);
|
|
60
64
|
var ServiceTypeSchema = import_zod.z.enum(["SUBSCRIPTION", "ROUND_TRIP_BOOKING", "SCHEDULED_BOOKING_STATION"]);
|
|
61
65
|
var getBookingRequests = async (client, status, options) => {
|
|
@@ -495,6 +499,42 @@ var updateScheduleBooking = async (client, bookingRequestId, updateData) => {
|
|
|
495
499
|
updateData
|
|
496
500
|
).then(({ data }) => data);
|
|
497
501
|
};
|
|
502
|
+
|
|
503
|
+
// src/triggerBRPayment.ts
|
|
504
|
+
var import_zod9 = __toESM(require("zod"));
|
|
505
|
+
var triggerBRPaymentSchema = import_zod9.default.object({
|
|
506
|
+
bookingRequestId: import_zod9.default.string().uuid(),
|
|
507
|
+
body: import_zod9.default.object({
|
|
508
|
+
scope: import_zod9.default.enum(["RENTAL", "DEPOSIT"]),
|
|
509
|
+
requiresActionReturnURL: import_zod9.default.string().url().optional(),
|
|
510
|
+
online: import_zod9.default.boolean(),
|
|
511
|
+
amountType: import_zod9.default.enum(["FIXED", "PERCENTAGE"]),
|
|
512
|
+
amountValue: import_zod9.default.number().nonnegative().optional(),
|
|
513
|
+
preferredPaymentMethods: import_zod9.default.array(
|
|
514
|
+
import_zod9.default.object({
|
|
515
|
+
pspReference: import_zod9.default.string(),
|
|
516
|
+
amount: import_zod9.default.number().default(0)
|
|
517
|
+
})
|
|
518
|
+
).optional(),
|
|
519
|
+
profileId: import_zod9.default.string().uuid()
|
|
520
|
+
})
|
|
521
|
+
});
|
|
522
|
+
var triggerBRPayment = async (client, bookingRequestId, body) => {
|
|
523
|
+
const resultPayload = triggerBRPaymentSchema.safeParse({ bookingRequestId, body });
|
|
524
|
+
if (!resultPayload.success) {
|
|
525
|
+
throw new TypeError("Invalid args", {
|
|
526
|
+
cause: resultPayload.error.issues
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
return client.post(
|
|
530
|
+
`boapi/proxy/user/scheduledBooking/fleets/${client.clientOptions.fleetId}/bookingrequests/${bookingRequestId}/payment`,
|
|
531
|
+
resultPayload.data.body
|
|
532
|
+
).then(({ data }) => data).catch((error) => {
|
|
533
|
+
throw new TypeError("Failed to trigger booking request payment", {
|
|
534
|
+
cause: error
|
|
535
|
+
});
|
|
536
|
+
});
|
|
537
|
+
};
|
|
498
538
|
// Annotate the CommonJS export names for ESM import in node:
|
|
499
539
|
0 && (module.exports = {
|
|
500
540
|
allocateVehicle,
|
|
@@ -508,5 +548,6 @@ var updateScheduleBooking = async (client, bookingRequestId, updateData) => {
|
|
|
508
548
|
getStations,
|
|
509
549
|
getSubscriptionBookingRequestById,
|
|
510
550
|
getSubscriptionBookingRequests,
|
|
551
|
+
triggerBRPayment,
|
|
511
552
|
updateScheduleBooking
|
|
512
553
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -8,7 +8,10 @@ var BookingRequestStatusSchema = z.enum([
|
|
|
8
8
|
"ONGOING",
|
|
9
9
|
"COMPLETED",
|
|
10
10
|
"CANCELLED",
|
|
11
|
-
"PENDING_APPROVAL"
|
|
11
|
+
"PENDING_APPROVAL",
|
|
12
|
+
"CONFIRMED",
|
|
13
|
+
"PENDING",
|
|
14
|
+
"LATE"
|
|
12
15
|
]);
|
|
13
16
|
var ServiceTypeSchema = z.enum(["SUBSCRIPTION", "ROUND_TRIP_BOOKING", "SCHEDULED_BOOKING_STATION"]);
|
|
14
17
|
var getBookingRequests = async (client, status, options) => {
|
|
@@ -448,6 +451,42 @@ var updateScheduleBooking = async (client, bookingRequestId, updateData) => {
|
|
|
448
451
|
updateData
|
|
449
452
|
).then(({ data }) => data);
|
|
450
453
|
};
|
|
454
|
+
|
|
455
|
+
// src/triggerBRPayment.ts
|
|
456
|
+
import z9 from "zod";
|
|
457
|
+
var triggerBRPaymentSchema = z9.object({
|
|
458
|
+
bookingRequestId: z9.string().uuid(),
|
|
459
|
+
body: z9.object({
|
|
460
|
+
scope: z9.enum(["RENTAL", "DEPOSIT"]),
|
|
461
|
+
requiresActionReturnURL: z9.string().url().optional(),
|
|
462
|
+
online: z9.boolean(),
|
|
463
|
+
amountType: z9.enum(["FIXED", "PERCENTAGE"]),
|
|
464
|
+
amountValue: z9.number().nonnegative().optional(),
|
|
465
|
+
preferredPaymentMethods: z9.array(
|
|
466
|
+
z9.object({
|
|
467
|
+
pspReference: z9.string(),
|
|
468
|
+
amount: z9.number().default(0)
|
|
469
|
+
})
|
|
470
|
+
).optional(),
|
|
471
|
+
profileId: z9.string().uuid()
|
|
472
|
+
})
|
|
473
|
+
});
|
|
474
|
+
var triggerBRPayment = async (client, bookingRequestId, body) => {
|
|
475
|
+
const resultPayload = triggerBRPaymentSchema.safeParse({ bookingRequestId, body });
|
|
476
|
+
if (!resultPayload.success) {
|
|
477
|
+
throw new TypeError("Invalid args", {
|
|
478
|
+
cause: resultPayload.error.issues
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
return client.post(
|
|
482
|
+
`boapi/proxy/user/scheduledBooking/fleets/${client.clientOptions.fleetId}/bookingrequests/${bookingRequestId}/payment`,
|
|
483
|
+
resultPayload.data.body
|
|
484
|
+
).then(({ data }) => data).catch((error) => {
|
|
485
|
+
throw new TypeError("Failed to trigger booking request payment", {
|
|
486
|
+
cause: error
|
|
487
|
+
});
|
|
488
|
+
});
|
|
489
|
+
};
|
|
451
490
|
export {
|
|
452
491
|
allocateVehicle,
|
|
453
492
|
deallocateVehicle,
|
|
@@ -460,5 +499,6 @@ export {
|
|
|
460
499
|
getStations,
|
|
461
500
|
getSubscriptionBookingRequestById,
|
|
462
501
|
getSubscriptionBookingRequests,
|
|
502
|
+
triggerBRPayment,
|
|
463
503
|
updateScheduleBooking
|
|
464
504
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vulog/aima-booking",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.22",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"author": "Vulog",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@vulog/aima-client": "1.2.
|
|
23
|
-
"@vulog/aima-core": "1.2.
|
|
22
|
+
"@vulog/aima-client": "1.2.22",
|
|
23
|
+
"@vulog/aima-core": "1.2.22"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"es-toolkit": "^1.39.9",
|
package/src/index.ts
CHANGED
|
@@ -11,3 +11,4 @@ export type { IncludeStation } from './getStation';
|
|
|
11
11
|
export { allocateVehicle } from './allocateVehicle';
|
|
12
12
|
export { deallocateVehicle } from './deallocateVehicle';
|
|
13
13
|
export { updateScheduleBooking } from './updateScheduleBooking';
|
|
14
|
+
export { triggerBRPayment } from './triggerBRPayment';
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { describe, test, expect, vi, beforeEach } from 'vitest';
|
|
2
|
+
import { Client } from '@vulog/aima-client';
|
|
3
|
+
import { randomUUID } from 'crypto';
|
|
4
|
+
import { triggerBRPayment } from './triggerBRPayment';
|
|
5
|
+
import type { TriggerBRPaymentResponse } from './types';
|
|
6
|
+
|
|
7
|
+
describe('triggerBRPayment', () => {
|
|
8
|
+
const postMock = vi.fn();
|
|
9
|
+
const client = {
|
|
10
|
+
post: postMock,
|
|
11
|
+
clientOptions: {
|
|
12
|
+
fleetId: 'FLEET_ID',
|
|
13
|
+
},
|
|
14
|
+
} as unknown as Client;
|
|
15
|
+
|
|
16
|
+
const validBody = {
|
|
17
|
+
scope: 'RENTAL' as const,
|
|
18
|
+
online: true,
|
|
19
|
+
amountType: 'FIXED' as const,
|
|
20
|
+
amountValue: 0,
|
|
21
|
+
profileId: '16de5c48-3898-49c5-97c1-b8344c1db564',
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const minimalTriggerBRPaymentResponse: TriggerBRPaymentResponse = {
|
|
25
|
+
id: randomUUID(),
|
|
26
|
+
cityId: 'city-1',
|
|
27
|
+
completed: false,
|
|
28
|
+
creationDate: '2017-07-02T22:58:34Z',
|
|
29
|
+
customPrice: null,
|
|
30
|
+
fleetId: 'FLEET_ID',
|
|
31
|
+
pricingDetails: [],
|
|
32
|
+
productIds: [],
|
|
33
|
+
profileId: '9f0fd479-28a9-4754-9c77-611ea48bfb8f',
|
|
34
|
+
rollingContract: false,
|
|
35
|
+
serviceId: '9ed7d9d4-8c64-43ef-bb3d-e2b271fed682',
|
|
36
|
+
startDate: '2017-08-07T07:18:40Z',
|
|
37
|
+
status: 'CONFIRMED',
|
|
38
|
+
userId: '465d4067-5332-432f-ac2c-e45af2f85694',
|
|
39
|
+
cancellationDate: null,
|
|
40
|
+
cancelledBy: null,
|
|
41
|
+
endDate: null,
|
|
42
|
+
entityName: null,
|
|
43
|
+
journeyId: null,
|
|
44
|
+
modelId: null,
|
|
45
|
+
profileType: null,
|
|
46
|
+
realStartDate: null,
|
|
47
|
+
returnedDate: null,
|
|
48
|
+
station: null,
|
|
49
|
+
vehicleId: null,
|
|
50
|
+
cancellationFeeAmount: null,
|
|
51
|
+
credits: [],
|
|
52
|
+
earlyCancelledByUser: false,
|
|
53
|
+
email: null,
|
|
54
|
+
failureReason: null,
|
|
55
|
+
latitude: 43.68,
|
|
56
|
+
longitude: 7.2,
|
|
57
|
+
parentId: null,
|
|
58
|
+
planName: null,
|
|
59
|
+
preallocatedVehicleId: null,
|
|
60
|
+
previous: null,
|
|
61
|
+
price: null,
|
|
62
|
+
radius: 30,
|
|
63
|
+
requiresActionReturnURL: null,
|
|
64
|
+
thresholdDateLimit: null,
|
|
65
|
+
trip: null,
|
|
66
|
+
warning: null,
|
|
67
|
+
paymentIntents: [
|
|
68
|
+
{
|
|
69
|
+
id: '0009ca58-c698-4a08-9a91-6116da1a932e',
|
|
70
|
+
pspName: 'STRIPE',
|
|
71
|
+
pspReference: 'pi_1H4QuyCOd50lRjiuhiCUMi9e',
|
|
72
|
+
pspPublishableKey: 'pk_test_xxx',
|
|
73
|
+
amount: 215.5,
|
|
74
|
+
currency: 'EUR',
|
|
75
|
+
date: '2024-05-01T12:55:02',
|
|
76
|
+
captureBefore: '2024-05-01T12:55:02',
|
|
77
|
+
status: 'PAID',
|
|
78
|
+
paymentMethodType: 'CREDIT_CARD',
|
|
79
|
+
paymentMethodPspReference: 'pm_xxx',
|
|
80
|
+
paymentIntentPspReference: 'pi_xxx',
|
|
81
|
+
number: 4564456465,
|
|
82
|
+
metadatas: {},
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
paymentReceipts: [],
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
beforeEach(() => {
|
|
89
|
+
postMock.mockReset();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('throws Invalid args when bookingRequestId is not a valid UUID', async () => {
|
|
93
|
+
await expect(
|
|
94
|
+
triggerBRPayment(client, 'not-a-uuid' as any, validBody)
|
|
95
|
+
).rejects.toThrow(TypeError);
|
|
96
|
+
|
|
97
|
+
await expect(
|
|
98
|
+
triggerBRPayment(client, 'not-a-uuid' as any, validBody)
|
|
99
|
+
).rejects.toMatchObject({ message: 'Invalid args' });
|
|
100
|
+
|
|
101
|
+
expect(postMock).not.toHaveBeenCalled();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('throws Invalid args when body.scope is invalid', async () => {
|
|
105
|
+
await expect(
|
|
106
|
+
triggerBRPayment(client, randomUUID(), {
|
|
107
|
+
...validBody,
|
|
108
|
+
scope: 'INVALID' as any,
|
|
109
|
+
})
|
|
110
|
+
).rejects.toThrow(TypeError);
|
|
111
|
+
|
|
112
|
+
expect(postMock).not.toHaveBeenCalled();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test('throws Invalid args when body.profileId is not a valid UUID', async () => {
|
|
116
|
+
await expect(
|
|
117
|
+
triggerBRPayment(client, randomUUID(), {
|
|
118
|
+
...validBody,
|
|
119
|
+
profileId: 'not-a-uuid',
|
|
120
|
+
})
|
|
121
|
+
).rejects.toThrow(TypeError);
|
|
122
|
+
|
|
123
|
+
expect(postMock).not.toHaveBeenCalled();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test('throws Invalid args when body.amountType is invalid', async () => {
|
|
127
|
+
await expect(
|
|
128
|
+
triggerBRPayment(client, randomUUID(), {
|
|
129
|
+
...validBody,
|
|
130
|
+
amountType: 'INVALID' as any,
|
|
131
|
+
})
|
|
132
|
+
).rejects.toThrow(TypeError);
|
|
133
|
+
|
|
134
|
+
expect(postMock).not.toHaveBeenCalled();
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
test('calls POST with correct URL and body and returns data', async () => {
|
|
138
|
+
const bookingRequestId = randomUUID();
|
|
139
|
+
postMock.mockResolvedValueOnce({ data: minimalTriggerBRPaymentResponse });
|
|
140
|
+
|
|
141
|
+
const result = await triggerBRPayment(client, bookingRequestId, validBody);
|
|
142
|
+
|
|
143
|
+
expect(postMock).toHaveBeenCalledTimes(1);
|
|
144
|
+
expect(postMock).toHaveBeenCalledWith(
|
|
145
|
+
`boapi/proxy/user/scheduledBooking/fleets/FLEET_ID/bookingrequests/${bookingRequestId}/payment`,
|
|
146
|
+
validBody
|
|
147
|
+
);
|
|
148
|
+
expect(result).toEqual(minimalTriggerBRPaymentResponse);
|
|
149
|
+
expect(result.paymentIntents).toHaveLength(1);
|
|
150
|
+
expect(result.paymentIntents[0].pspName).toBe('STRIPE');
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test('sends optional requiresActionReturnURL and preferredPaymentMethods when provided', async () => {
|
|
154
|
+
const bookingRequestId = randomUUID();
|
|
155
|
+
const bodyWithOptionals = {
|
|
156
|
+
...validBody,
|
|
157
|
+
requiresActionReturnURL: 'https://example.com/return',
|
|
158
|
+
preferredPaymentMethods: [{ pspReference: 'pm_xxx', amount: 100 }],
|
|
159
|
+
};
|
|
160
|
+
postMock.mockResolvedValueOnce({ data: minimalTriggerBRPaymentResponse });
|
|
161
|
+
|
|
162
|
+
await triggerBRPayment(client, bookingRequestId, bodyWithOptionals);
|
|
163
|
+
|
|
164
|
+
expect(postMock).toHaveBeenCalledWith(
|
|
165
|
+
`boapi/proxy/user/scheduledBooking/fleets/FLEET_ID/bookingrequests/${bookingRequestId}/payment`,
|
|
166
|
+
bodyWithOptionals
|
|
167
|
+
);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
test('throws when client.post rejects', async () => {
|
|
171
|
+
const bookingRequestId = randomUUID();
|
|
172
|
+
const networkError = new Error('Network error');
|
|
173
|
+
postMock.mockRejectedValueOnce(networkError);
|
|
174
|
+
|
|
175
|
+
let thrown: unknown;
|
|
176
|
+
try {
|
|
177
|
+
await triggerBRPayment(client, bookingRequestId, validBody);
|
|
178
|
+
} catch (e) {
|
|
179
|
+
thrown = e;
|
|
180
|
+
}
|
|
181
|
+
expect(thrown).toBeDefined();
|
|
182
|
+
const err = thrown as Error & { cause?: unknown };
|
|
183
|
+
expect(err instanceof Error).toBe(true);
|
|
184
|
+
// Implementation may wrap in TypeError('Failed to trigger booking request payment', { cause })
|
|
185
|
+
const isWrapped =
|
|
186
|
+
err.name === 'TypeError' &&
|
|
187
|
+
err.message === 'Failed to trigger booking request payment' &&
|
|
188
|
+
err.cause === networkError;
|
|
189
|
+
const isPropagated = err.message === 'Network error';
|
|
190
|
+
expect(isWrapped || isPropagated).toBe(true);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { UUID } from 'crypto';
|
|
2
|
+
|
|
3
|
+
import { Client } from '@vulog/aima-client';
|
|
4
|
+
|
|
5
|
+
import z from 'zod';
|
|
6
|
+
|
|
7
|
+
import { TriggerBRPaymentResponse } from './types';
|
|
8
|
+
|
|
9
|
+
const triggerBRPaymentSchema = z.object({
|
|
10
|
+
bookingRequestId: z.string().uuid(),
|
|
11
|
+
body: z.object({
|
|
12
|
+
scope: z.enum(['RENTAL', 'DEPOSIT']),
|
|
13
|
+
requiresActionReturnURL: z.string().url().optional(),
|
|
14
|
+
online: z.boolean(),
|
|
15
|
+
amountType: z.enum(['FIXED', 'PERCENTAGE']),
|
|
16
|
+
amountValue: z.number().nonnegative().optional(),
|
|
17
|
+
preferredPaymentMethods: z
|
|
18
|
+
.array(
|
|
19
|
+
z.object({
|
|
20
|
+
pspReference: z.string(),
|
|
21
|
+
amount: z.number().default(0),
|
|
22
|
+
})
|
|
23
|
+
)
|
|
24
|
+
.optional(),
|
|
25
|
+
profileId: z.string().uuid(),
|
|
26
|
+
}),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// /scheduledBooking/fleets/{fleetId}/bookingrequests/{id}/payment
|
|
30
|
+
export const triggerBRPayment = async (
|
|
31
|
+
client: Client,
|
|
32
|
+
bookingRequestId: UUID,
|
|
33
|
+
body: z.infer<typeof triggerBRPaymentSchema>['body']
|
|
34
|
+
): Promise<TriggerBRPaymentResponse> => {
|
|
35
|
+
const resultPayload = triggerBRPaymentSchema.safeParse({ bookingRequestId, body });
|
|
36
|
+
if (!resultPayload.success) {
|
|
37
|
+
throw new TypeError('Invalid args', {
|
|
38
|
+
cause: resultPayload.error.issues,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return client
|
|
42
|
+
.post<TriggerBRPaymentResponse>(
|
|
43
|
+
`boapi/proxy/user/scheduledBooking/fleets/${client.clientOptions.fleetId}/bookingrequests/${bookingRequestId}/payment`,
|
|
44
|
+
resultPayload.data.body
|
|
45
|
+
)
|
|
46
|
+
.then(({ data }) => data)
|
|
47
|
+
.catch((error) => {
|
|
48
|
+
throw new TypeError('Failed to trigger booking request payment', {
|
|
49
|
+
cause: error,
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
};
|
package/src/types.ts
CHANGED
|
@@ -15,6 +15,54 @@ export type PaymentReceipts = {
|
|
|
15
15
|
};
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
/** Payment intent or receipt item as returned by trigger BR payment (and similar payment endpoints). */
|
|
19
|
+
export type BRPaymentItem = {
|
|
20
|
+
id: string;
|
|
21
|
+
pspName: string;
|
|
22
|
+
pspReference: string;
|
|
23
|
+
pspPublishableKey: string;
|
|
24
|
+
amount: number;
|
|
25
|
+
currency: string;
|
|
26
|
+
date: string;
|
|
27
|
+
captureBefore: string;
|
|
28
|
+
status: string;
|
|
29
|
+
paymentMethodType: string;
|
|
30
|
+
paymentMethodPspReference: string;
|
|
31
|
+
paymentIntentPspReference: string;
|
|
32
|
+
number: number;
|
|
33
|
+
code?: string;
|
|
34
|
+
declineCode?: string;
|
|
35
|
+
pspClientSecret?: string;
|
|
36
|
+
reason?: string;
|
|
37
|
+
note?: string;
|
|
38
|
+
nextAction?: {
|
|
39
|
+
nextActionRedirectUrl: {
|
|
40
|
+
url: string;
|
|
41
|
+
method: string;
|
|
42
|
+
data: Record<string, string>;
|
|
43
|
+
};
|
|
44
|
+
type: string;
|
|
45
|
+
};
|
|
46
|
+
metadatas: Record<string, string>;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/** Credit entry in a booking request (e.g. trigger BR payment response). */
|
|
50
|
+
export type BookingCredit = {
|
|
51
|
+
id: string;
|
|
52
|
+
fleetId: string;
|
|
53
|
+
amount: number;
|
|
54
|
+
availableAmount: number;
|
|
55
|
+
status: string;
|
|
56
|
+
walletId: string;
|
|
57
|
+
date: string;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/** Preferred payment method entry in request/response. */
|
|
61
|
+
export type PreferredPaymentMethod = {
|
|
62
|
+
pspReference: string;
|
|
63
|
+
amount: number;
|
|
64
|
+
};
|
|
65
|
+
|
|
18
66
|
export type CustomPrice = {
|
|
19
67
|
id: string;
|
|
20
68
|
fleetId: string;
|
|
@@ -104,6 +152,14 @@ export type SATBookingRequest = BaseBookingRequest & {
|
|
|
104
152
|
warning: string | null;
|
|
105
153
|
};
|
|
106
154
|
|
|
155
|
+
/** Response of the trigger BR payment endpoint (booking request + payment intents/receipts). */
|
|
156
|
+
export type TriggerBRPaymentResponse = Omit<SATBookingRequest, 'credits'> & {
|
|
157
|
+
paymentIntents: BRPaymentItem[];
|
|
158
|
+
paymentReceipts: BRPaymentItem[];
|
|
159
|
+
credits: BookingCredit[];
|
|
160
|
+
preferredPaymentMethods?: PreferredPaymentMethod[];
|
|
161
|
+
};
|
|
162
|
+
|
|
107
163
|
// Station types
|
|
108
164
|
export type GeoInfo = {
|
|
109
165
|
name: string;
|