@voyant-travel/finance 0.190.0 → 0.192.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.
Files changed (45) hide show
  1. package/dist/card-payment.d.ts +15 -0
  2. package/dist/card-payment.js +74 -41
  3. package/dist/checkout-routes.d.ts +6 -0
  4. package/dist/checkout-routes.js +10 -1
  5. package/dist/checkout-service-plan.d.ts +2 -0
  6. package/dist/checkout-service.js +24 -7
  7. package/dist/checkout-validation.d.ts +13 -3
  8. package/dist/checkout-validation.js +6 -1
  9. package/dist/index.d.ts +4 -3
  10. package/dist/index.js +7 -3
  11. package/dist/payment-adapter-events.d.ts +96 -2
  12. package/dist/payment-adapter-events.js +150 -24
  13. package/dist/payment-adapter-session-guard.d.ts +18 -0
  14. package/dist/payment-adapter-session-guard.js +64 -0
  15. package/dist/payment-adapter-status.d.ts +61 -0
  16. package/dist/payment-adapter-status.js +49 -0
  17. package/dist/payment-link.js +29 -3
  18. package/dist/routes-booking-billing.d.ts +10 -0
  19. package/dist/routes-invoice-core.d.ts +5 -0
  20. package/dist/routes-invoice-schemas.d.ts +1 -0
  21. package/dist/routes-invoice-schemas.js +1 -0
  22. package/dist/routes-payment-processing.d.ts +18 -0
  23. package/dist/routes-payment-processing.js +1 -0
  24. package/dist/routes-public.d.ts +34 -0
  25. package/dist/routes-public.js +16 -1
  26. package/dist/routes.d.ts +33 -0
  27. package/dist/runtime.d.ts +2 -1
  28. package/dist/runtime.js +96 -1
  29. package/dist/schema/payment-sessions.d.ts +17 -0
  30. package/dist/schema/payment-sessions.js +2 -0
  31. package/dist/service-booking-billing.d.ts +3 -0
  32. package/dist/service-booking-guarantees.d.ts +1 -0
  33. package/dist/service-booking-payment-schedules.d.ts +2 -0
  34. package/dist/service-payment-processing.d.ts +10 -1
  35. package/dist/service-payment-session-completion.d.ts +10 -1
  36. package/dist/service-payment-session-completion.js +104 -24
  37. package/dist/service-payment-sessions.d.ts +8 -0
  38. package/dist/service-payment-sessions.js +27 -8
  39. package/dist/service-public.d.ts +4 -0
  40. package/dist/service-public.js +1 -0
  41. package/dist/service.d.ts +13 -1
  42. package/dist/voyant.js +2 -0
  43. package/migrations/20260722053500_payment_session_provider_connection.sql +2 -0
  44. package/migrations/meta/_journal.json +8 -1
  45. package/package.json +4 -4
@@ -41,6 +41,9 @@ export interface CardPaymentStartArgs {
41
41
  billing: CardPaymentBilling;
42
42
  description?: string;
43
43
  returnUrl?: string;
44
+ cancelUrl?: string;
45
+ shipping?: Record<string, unknown>;
46
+ metadata?: Record<string, unknown>;
44
47
  }
45
48
  /** Result of a card-payment start: the hosted-payment URL to redirect to. */
46
49
  export interface CardPaymentStartResult {
@@ -68,4 +71,16 @@ export interface PaymentAdapterCardPaymentStarterOptions {
68
71
  */
69
72
  resolveNotifyUrl?(c: Context): string | undefined;
70
73
  }
74
+ export interface PaymentAdapterCardPaymentExecution {
75
+ context: PaymentAdapterRuntimeContext;
76
+ runtime?: FinanceServiceRuntime;
77
+ notifyUrl?: string;
78
+ idempotencyKey?: string;
79
+ }
80
+ /**
81
+ * Start a payment through a selected adapter without requiring an HTTP
82
+ * framework context. Package runtimes use this function; the Hono-oriented
83
+ * starter below remains the checkout-surface convenience wrapper.
84
+ */
85
+ export declare function startPaymentAdapterCardPayment(adapter: PaymentAdapter, args: CardPaymentStartArgs, execution: PaymentAdapterCardPaymentExecution): Promise<CardPaymentStartResult | null>;
71
86
  export declare function createPaymentAdapterCardPaymentStarter(adapter: PaymentAdapter, options?: PaymentAdapterCardPaymentStarterOptions): CardPaymentStarter;
@@ -1,23 +1,56 @@
1
- import { eq } from "drizzle-orm";
1
+ import { and, eq, isNull, sql } from "drizzle-orm";
2
+ import { applyPaymentAdapterInitiationResult } from "./payment-adapter-events.js";
2
3
  import { paymentSessions } from "./schema/payment-sessions.js";
3
- import { financePaymentSessionCompletionService } from "./service-payment-session-completion.js";
4
- import { financePaymentSessionService } from "./service-payment-sessions.js";
5
- export function createPaymentAdapterCardPaymentStarter(adapter, options = {}) {
6
- return async (c, args) => {
7
- const [session] = await args.db
8
- .select()
4
+ const PAYMENT_ADAPTER_INITIATION_CLAIM_KEY = "paymentAdapterInitiationClaim";
5
+ const PAYMENT_ADAPTER_INITIATION_STATE_KEY = "paymentAdapterInitiationState";
6
+ /**
7
+ * Start a payment through a selected adapter without requiring an HTTP
8
+ * framework context. Package runtimes use this function; the Hono-oriented
9
+ * starter below remains the checkout-surface convenience wrapper.
10
+ */
11
+ export async function startPaymentAdapterCardPayment(adapter, args, execution) {
12
+ const [initialSession] = await args.db
13
+ .select()
14
+ .from(paymentSessions)
15
+ .where(eq(paymentSessions.id, args.sessionId))
16
+ .limit(1);
17
+ if (!initialSession)
18
+ return null;
19
+ const idempotencyKey = initialSession.idempotencyKey ?? execution.idempotencyKey ?? `payment:${initialSession.id}`;
20
+ const [session] = await args.db
21
+ .update(paymentSessions)
22
+ .set({
23
+ status: "processing",
24
+ idempotencyKey,
25
+ metadata: sql `coalesce(${paymentSessions.metadata}, '{}'::jsonb) || ${JSON.stringify({
26
+ [PAYMENT_ADAPTER_INITIATION_CLAIM_KEY]: idempotencyKey,
27
+ [PAYMENT_ADAPTER_INITIATION_STATE_KEY]: "in_flight",
28
+ })}::jsonb`,
29
+ updatedAt: new Date(),
30
+ })
31
+ .where(and(eq(paymentSessions.id, args.sessionId), eq(paymentSessions.status, "pending"), isNull(paymentSessions.providerConnectionId), isNull(paymentSessions.providerSessionId), isNull(paymentSessions.providerPaymentId)))
32
+ .returning();
33
+ if (!session) {
34
+ const [continuation] = await args.db
35
+ .select({ redirectUrl: paymentSessions.redirectUrl })
9
36
  .from(paymentSessions)
10
37
  .where(eq(paymentSessions.id, args.sessionId))
11
38
  .limit(1);
12
- if (!session)
13
- return null;
14
- const idempotencyKey = session.idempotencyKey ?? options.idempotencyKey?.(session.id) ?? `payment:${session.id}`;
15
- const notifyUrl = options.resolveNotifyUrl?.(c);
16
- const result = await adapter.initiate(options.resolveContext?.(c) ?? { env: c.env }, {
39
+ return continuation ? { redirectUrl: continuation.redirectUrl } : null;
40
+ }
41
+ const metadata = {
42
+ ...(args.metadata ?? {}),
43
+ billing: args.billing,
44
+ ...(execution.notifyUrl ? { notifyUrl: execution.notifyUrl } : {}),
45
+ };
46
+ let result;
47
+ try {
48
+ result = await adapter.initiate(execution.context, {
17
49
  paymentSessionId: session.id,
18
50
  money: { amountMinor: session.amountCents, currency: session.currency },
19
51
  description: args.description ?? session.notes ?? undefined,
20
52
  returnUrl: args.returnUrl ?? session.returnUrl ?? undefined,
53
+ cancelUrl: args.cancelUrl ?? session.cancelUrl ?? undefined,
21
54
  idempotencyKey,
22
55
  customer: {
23
56
  email: args.billing.email,
@@ -25,35 +58,35 @@ export function createPaymentAdapterCardPaymentStarter(adapter, options = {}) {
25
58
  firstName: args.billing.firstName,
26
59
  lastName: args.billing.lastName ?? null,
27
60
  },
28
- ...(notifyUrl ? { metadata: { notifyUrl } } : {}),
61
+ shipping: args.shipping,
62
+ metadata,
63
+ });
64
+ await applyPaymentAdapterInitiationResult(args.db, session.id, adapter.id, result, { idempotencyKey, claimedAt: session.updatedAt }, execution.runtime);
65
+ }
66
+ catch (error) {
67
+ const retrySafe = adapter.capabilities.idempotencyKeys && adapter.capabilities.retrySafeInitiation;
68
+ await args.db
69
+ .update(paymentSessions)
70
+ .set({
71
+ status: retrySafe ? "pending" : "processing",
72
+ metadata: sql `coalesce(${paymentSessions.metadata}, '{}'::jsonb) || ${JSON.stringify({
73
+ [PAYMENT_ADAPTER_INITIATION_CLAIM_KEY]: retrySafe ? null : idempotencyKey,
74
+ [PAYMENT_ADAPTER_INITIATION_STATE_KEY]: retrySafe ? "retryable" : "uncertain",
75
+ })}::jsonb`,
76
+ updatedAt: new Date(),
77
+ })
78
+ .where(and(eq(paymentSessions.id, session.id), eq(paymentSessions.status, "processing"), eq(paymentSessions.idempotencyKey, idempotencyKey), eq(paymentSessions.updatedAt, session.updatedAt), isNull(paymentSessions.providerConnectionId), isNull(paymentSessions.providerSessionId), isNull(paymentSessions.providerPaymentId), sql `${paymentSessions.metadata}->>${PAYMENT_ADAPTER_INITIATION_CLAIM_KEY} = ${idempotencyKey}`));
79
+ throw error;
80
+ }
81
+ return { redirectUrl: result.checkout?.url ?? null };
82
+ }
83
+ export function createPaymentAdapterCardPaymentStarter(adapter, options = {}) {
84
+ return async (c, args) => {
85
+ return startPaymentAdapterCardPayment(adapter, args, {
86
+ context: options.resolveContext?.(c) ?? { env: c.env },
87
+ runtime: options.resolveRuntime?.(c),
88
+ notifyUrl: options.resolveNotifyUrl?.(c),
89
+ idempotencyKey: options.idempotencyKey?.(args.sessionId),
29
90
  });
30
- const providerData = {
31
- providerSessionId: result.processorSessionId ?? undefined,
32
- providerPaymentId: result.processorPaymentId ?? undefined,
33
- providerPayload: result.raw === undefined ? undefined : { initiation: result.raw },
34
- metadata: { paymentAdapterInitiationIdempotencyKey: result.idempotencyKey },
35
- };
36
- if (result.nextState === "paid" || result.nextState === "authorized") {
37
- await financePaymentSessionService.updatePaymentSession(args.db, session.id, {
38
- provider: adapter.id,
39
- redirectUrl: result.checkout?.url ?? undefined,
40
- idempotencyKey,
41
- });
42
- await financePaymentSessionCompletionService.completePaymentSession(args.db, session.id, {
43
- status: result.nextState,
44
- captureMode: "automatic",
45
- ...providerData,
46
- }, options.resolveRuntime?.(c));
47
- }
48
- else {
49
- await financePaymentSessionService.updatePaymentSession(args.db, session.id, {
50
- provider: adapter.id,
51
- status: result.nextState,
52
- redirectUrl: result.checkout?.url ?? undefined,
53
- idempotencyKey,
54
- ...providerData,
55
- });
56
- }
57
- return { redirectUrl: result.checkout?.url ?? null };
58
91
  };
59
92
  }
@@ -15,6 +15,7 @@ export type CheckoutRoutesOptions = {
15
15
  notificationDispatcher?: CheckoutNotificationDispatcher | null;
16
16
  resolveNotificationDispatcher?: (bindings: Record<string, unknown>) => CheckoutNotificationDispatcher | null;
17
17
  paymentStarters?: Record<string, CheckoutPaymentStarter>;
18
+ resolveSelectedPaymentStarter?: (bindings: Record<string, unknown>) => CheckoutPaymentStarter | null;
18
19
  resolvePaymentStarters?: (bindings: Record<string, unknown>) => Record<string, CheckoutPaymentStarter>;
19
20
  bankTransferDetails?: CheckoutBankTransferDetails | null;
20
21
  resolveBankTransferDetails?: (bindings: Record<string, unknown>) => CheckoutBankTransferDetails | null;
@@ -31,6 +32,7 @@ export interface CheckoutReminderRunList {
31
32
  export type CheckoutRouteRuntime = {
32
33
  bindings: Record<string, unknown>;
33
34
  notificationDispatcher: CheckoutNotificationDispatcher | null;
35
+ selectedPaymentStarter: CheckoutPaymentStarter | null;
34
36
  paymentStarters: Record<string, CheckoutPaymentStarter>;
35
37
  bankTransferDetails: CheckoutBankTransferDetails | null;
36
38
  publicCheckoutBaseUrl?: string | null;
@@ -279,6 +281,7 @@ export declare function createCheckoutRoutes(options?: CheckoutRoutesOptions): i
279
281
  targetType: "other" | "booking" | "order" | "invoice" | "booking_payment_schedule" | "booking_guarantee" | "flight_order";
280
282
  targetId: string | null;
281
283
  paymentId: string | null;
284
+ providerConnectionId: string | null;
282
285
  providerSessionId: string | null;
283
286
  providerPaymentId: string | null;
284
287
  externalReference: string | null;
@@ -518,6 +521,7 @@ export declare function createCheckoutRoutes(options?: CheckoutRoutesOptions): i
518
521
  targetType: "other" | "booking" | "order" | "invoice" | "booking_payment_schedule" | "booking_guarantee" | "flight_order";
519
522
  targetId: string | null;
520
523
  paymentId: string | null;
524
+ providerConnectionId: string | null;
521
525
  providerSessionId: string | null;
522
526
  providerPaymentId: string | null;
523
527
  externalReference: string | null;
@@ -851,6 +855,7 @@ export declare function createCheckoutAdminRoutes(options?: CheckoutRoutesOption
851
855
  targetType: "other" | "booking" | "order" | "invoice" | "booking_payment_schedule" | "booking_guarantee" | "flight_order";
852
856
  targetId: string | null;
853
857
  paymentId: string | null;
858
+ providerConnectionId: string | null;
854
859
  providerSessionId: string | null;
855
860
  providerPaymentId: string | null;
856
861
  externalReference: string | null;
@@ -1090,6 +1095,7 @@ export declare function createCheckoutAdminRoutes(options?: CheckoutRoutesOption
1090
1095
  targetType: "other" | "booking" | "order" | "invoice" | "booking_payment_schedule" | "booking_guarantee" | "flight_order";
1091
1096
  targetId: string | null;
1092
1097
  paymentId: string | null;
1098
+ providerConnectionId: string | null;
1093
1099
  providerSessionId: string | null;
1094
1100
  providerPaymentId: string | null;
1095
1101
  externalReference: string | null;
@@ -121,7 +121,15 @@ function resolveCheckoutRouteRuntime(bindings, options, container) {
121
121
  return buildCheckoutRouteRuntime(bindings, options);
122
122
  }
123
123
  function assertCheckoutRuntimeSupportsCollection(runtime, input) {
124
- if (input.method === "card" && Object.keys(runtime.paymentStarters).length === 0) {
124
+ if (input.method === "card" && input.startProvider && !input.startProvider.provider) {
125
+ if (!runtime.selectedPaymentStarter) {
126
+ throw new CheckoutRouteRuntimeNotConfiguredError();
127
+ }
128
+ return;
129
+ }
130
+ if (input.method === "card" &&
131
+ !runtime.selectedPaymentStarter &&
132
+ Object.keys(runtime.paymentStarters).length === 0) {
125
133
  throw new CheckoutRouteRuntimeNotConfiguredError();
126
134
  }
127
135
  }
@@ -129,6 +137,7 @@ export function buildCheckoutRouteRuntime(bindings, options = {}) {
129
137
  return {
130
138
  bindings,
131
139
  notificationDispatcher: options.resolveNotificationDispatcher?.(bindings) ?? options.notificationDispatcher ?? null,
140
+ selectedPaymentStarter: options.resolveSelectedPaymentStarter?.(bindings) ?? null,
132
141
  paymentStarters: options.resolvePaymentStarters?.(bindings) ?? options.paymentStarters ?? {},
133
142
  bankTransferDetails: options.resolveBankTransferDetails?.(bindings) ?? options.bankTransferDetails ?? null,
134
143
  publicCheckoutBaseUrl: options.resolvePublicCheckoutBaseUrl?.(bindings) ?? options.publicCheckoutBaseUrl ?? null,
@@ -105,6 +105,8 @@ export interface CheckoutRuntimeOptions {
105
105
  bindings?: Record<string, unknown>;
106
106
  bankTransferDetails?: CheckoutBankTransferDetails | null;
107
107
  notificationDispatcher?: CheckoutNotificationDispatcher | null;
108
+ /** Deployment-selected PaymentAdapter bridge. Takes precedence over legacy keyed starters. */
109
+ selectedPaymentStarter?: CheckoutPaymentStarter | null;
108
110
  paymentStarters?: Record<string, CheckoutPaymentStarter>;
109
111
  publicCheckoutBaseUrl?: string | null;
110
112
  }
@@ -190,6 +190,27 @@ async function createCollectionInvoice(db, context, plan, notes) {
190
190
  return invoice;
191
191
  }
192
192
  export async function initiateCheckoutCollection(db, bookingId, input, options = {}, runtime = {}) {
193
+ let providerStarter = null;
194
+ if (input.startProvider) {
195
+ if (input.method !== "card") {
196
+ throw new Error("Provider start is only available for card collections");
197
+ }
198
+ // Resolve deployment-owned processor readiness before any checkout read
199
+ // that may materialize a default payment plan. The selected PaymentAdapter
200
+ // wins over legacy provider hints; keyed starters remain only for explicit
201
+ // self-hosted provider requests. A missing adapter is a zero-mutation
202
+ // failure.
203
+ const requestedProvider = input.startProvider.provider;
204
+ providerStarter =
205
+ runtime.selectedPaymentStarter ??
206
+ (requestedProvider ? runtime.paymentStarters?.[requestedProvider] : undefined) ??
207
+ null;
208
+ if (!providerStarter) {
209
+ throw new Error(requestedProvider
210
+ ? `Payment provider "${requestedProvider}" is not configured`
211
+ : "No payment adapter is selected for card collection");
212
+ }
213
+ }
193
214
  const context = await loadBookingContext(db, bookingId);
194
215
  if (!context)
195
216
  return null;
@@ -250,17 +271,13 @@ export async function initiateCheckoutCollection(db, bookingId, input, options =
250
271
  }
251
272
  }
252
273
  if (input.startProvider) {
253
- if (input.method !== "card") {
254
- throw new Error("Provider start is only available for card collections");
255
- }
256
274
  if (!paymentSession) {
257
275
  throw new Error("No payment session available for provider start");
258
276
  }
259
- const starter = runtime.paymentStarters?.[input.startProvider.provider];
260
- if (!starter) {
261
- throw new Error(`Payment provider "${input.startProvider.provider}" is not configured`);
277
+ if (!providerStarter) {
278
+ throw new Error("No payment adapter is selected for card collection");
262
279
  }
263
- providerStart = await starter({
280
+ providerStart = await providerStarter({
264
281
  db,
265
282
  bookingId,
266
283
  plan,
@@ -46,7 +46,7 @@ export declare const checkoutReminderTargetTypeSchema: z.ZodEnum<{
46
46
  booking_cancelled_non_payment: "booking_cancelled_non_payment";
47
47
  }>;
48
48
  export declare const checkoutProviderStartInputSchema: z.ZodObject<{
49
- provider: z.ZodString;
49
+ provider: z.ZodOptional<z.ZodString>;
50
50
  payload: z.ZodNullable<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
51
51
  }, z.core.$strip>;
52
52
  export declare const checkoutNotificationAttachmentSchema: z.ZodObject<{
@@ -249,6 +249,7 @@ export declare const initiateCheckoutCollectionSchema: z.ZodObject<{
249
249
  idempotencyKey: z.ZodNullable<z.ZodOptional<z.ZodString>>;
250
250
  }, z.core.$strip>>;
251
251
  provider: z.ZodNullable<z.ZodOptional<z.ZodString>>;
252
+ providerConnectionId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
252
253
  paymentMethod: z.ZodNullable<z.ZodOptional<z.ZodEnum<{
253
254
  bank_transfer: "bank_transfer";
254
255
  credit_card: "credit_card";
@@ -322,6 +323,7 @@ export declare const initiateCheckoutCollectionSchema: z.ZodObject<{
322
323
  idempotencyKey: z.ZodNullable<z.ZodOptional<z.ZodString>>;
323
324
  }, z.core.$strip>>;
324
325
  provider: z.ZodNullable<z.ZodOptional<z.ZodString>>;
326
+ providerConnectionId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
325
327
  paymentMethod: z.ZodNullable<z.ZodOptional<z.ZodEnum<{
326
328
  bank_transfer: "bank_transfer";
327
329
  credit_card: "credit_card";
@@ -407,7 +409,7 @@ export declare const initiateCheckoutCollectionSchema: z.ZodObject<{
407
409
  paymentLinkBaseUrl: z.ZodNullable<z.ZodOptional<z.ZodString>>;
408
410
  }, z.core.$strip>>;
409
411
  startProvider: z.ZodOptional<z.ZodObject<{
410
- provider: z.ZodString;
412
+ provider: z.ZodOptional<z.ZodString>;
411
413
  payload: z.ZodNullable<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
412
414
  }, z.core.$strip>>;
413
415
  notes: z.ZodNullable<z.ZodOptional<z.ZodString>>;
@@ -501,6 +503,7 @@ export declare const bootstrapCheckoutCollectionSchema: z.ZodObject<{
501
503
  idempotencyKey: z.ZodNullable<z.ZodOptional<z.ZodString>>;
502
504
  }, z.core.$strip>>;
503
505
  provider: z.ZodNullable<z.ZodOptional<z.ZodString>>;
506
+ providerConnectionId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
504
507
  paymentMethod: z.ZodNullable<z.ZodOptional<z.ZodEnum<{
505
508
  bank_transfer: "bank_transfer";
506
509
  credit_card: "credit_card";
@@ -574,6 +577,7 @@ export declare const bootstrapCheckoutCollectionSchema: z.ZodObject<{
574
577
  idempotencyKey: z.ZodNullable<z.ZodOptional<z.ZodString>>;
575
578
  }, z.core.$strip>>;
576
579
  provider: z.ZodNullable<z.ZodOptional<z.ZodString>>;
580
+ providerConnectionId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
577
581
  paymentMethod: z.ZodNullable<z.ZodOptional<z.ZodEnum<{
578
582
  bank_transfer: "bank_transfer";
579
583
  credit_card: "credit_card";
@@ -659,7 +663,7 @@ export declare const bootstrapCheckoutCollectionSchema: z.ZodObject<{
659
663
  paymentLinkBaseUrl: z.ZodNullable<z.ZodOptional<z.ZodString>>;
660
664
  }, z.core.$strip>>;
661
665
  startProvider: z.ZodOptional<z.ZodObject<{
662
- provider: z.ZodString;
666
+ provider: z.ZodOptional<z.ZodString>;
663
667
  payload: z.ZodNullable<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
664
668
  }, z.core.$strip>>;
665
669
  notes: z.ZodNullable<z.ZodOptional<z.ZodString>>;
@@ -954,6 +958,7 @@ export declare const initiatedCheckoutCollectionSchema: z.ZodObject<{
954
958
  expired: "expired";
955
959
  }>;
956
960
  provider: z.ZodNullable<z.ZodString>;
961
+ providerConnectionId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
957
962
  providerSessionId: z.ZodNullable<z.ZodString>;
958
963
  providerPaymentId: z.ZodNullable<z.ZodString>;
959
964
  externalReference: z.ZodNullable<z.ZodString>;
@@ -983,6 +988,7 @@ export declare const initiatedCheckoutCollectionSchema: z.ZodObject<{
983
988
  notes: z.ZodNullable<z.ZodString>;
984
989
  }, z.core.$strip>, z.ZodTransform<{
985
990
  legacyOrderId: string | null;
991
+ providerConnectionId: string | null;
986
992
  target: {
987
993
  type: "booking";
988
994
  bookingId: string;
@@ -1113,6 +1119,7 @@ export declare const initiatedCheckoutCollectionSchema: z.ZodObject<{
1113
1119
  idempotencyKey?: string | null | undefined;
1114
1120
  } | null | undefined;
1115
1121
  legacyOrderId?: string | null | undefined;
1122
+ providerConnectionId?: string | null | undefined;
1116
1123
  }>>>;
1117
1124
  invoiceNotification: z.ZodNullable<z.ZodObject<{
1118
1125
  id: z.ZodString;
@@ -1331,6 +1338,7 @@ export declare const bootstrappedCheckoutCollectionSchema: z.ZodObject<{
1331
1338
  expired: "expired";
1332
1339
  }>;
1333
1340
  provider: z.ZodNullable<z.ZodString>;
1341
+ providerConnectionId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1334
1342
  providerSessionId: z.ZodNullable<z.ZodString>;
1335
1343
  providerPaymentId: z.ZodNullable<z.ZodString>;
1336
1344
  externalReference: z.ZodNullable<z.ZodString>;
@@ -1360,6 +1368,7 @@ export declare const bootstrappedCheckoutCollectionSchema: z.ZodObject<{
1360
1368
  notes: z.ZodNullable<z.ZodString>;
1361
1369
  }, z.core.$strip>, z.ZodTransform<{
1362
1370
  legacyOrderId: string | null;
1371
+ providerConnectionId: string | null;
1363
1372
  target: {
1364
1373
  type: "booking";
1365
1374
  bookingId: string;
@@ -1490,6 +1499,7 @@ export declare const bootstrappedCheckoutCollectionSchema: z.ZodObject<{
1490
1499
  idempotencyKey?: string | null | undefined;
1491
1500
  } | null | undefined;
1492
1501
  legacyOrderId?: string | null | undefined;
1502
+ providerConnectionId?: string | null | undefined;
1493
1503
  }>>>;
1494
1504
  invoiceNotification: z.ZodNullable<z.ZodObject<{
1495
1505
  id: z.ZodString;
@@ -28,7 +28,12 @@ export const checkoutReminderTargetTypeSchema = z.enum([
28
28
  "invoice",
29
29
  ]);
30
30
  export const checkoutProviderStartInputSchema = z.object({
31
- provider: z.string().min(1).max(255),
31
+ /**
32
+ * Legacy provider hint. Deployments with a selected PaymentAdapter ignore
33
+ * this value and always use their selected adapter. New clients should omit
34
+ * it so processor selection remains deployment-owned.
35
+ */
36
+ provider: z.string().min(1).max(255).optional(),
32
37
  payload: z.record(z.string(), z.unknown()).optional().nullable(),
33
38
  });
34
39
  export const checkoutNotificationAttachmentSchema = z
package/dist/index.d.ts CHANGED
@@ -28,12 +28,13 @@ export { PAYMENT_ADAPTER_CONTRACT_VERSION, PAYMENT_ADAPTER_RUNTIME_PORT_ID, paym
28
28
  export { type BookingCancellationSettlementInput, buildPaidBookingCancellationSettlementNote, closeTerminalBookingPaymentSchedules, financeBookingLifecycle, recordPaidBookingCancellationSettlement, } from "./booking-lifecycle.js";
29
29
  export { type BookingTaxRouteOptions, type BookingTaxSettings, computeBookingItemTaxLine, createBookingTaxPreviewApiExtension, createBookingTaxPreviewRoutes, createBookingTaxSettingsApiExtension, createBookingTaxSettingsRoutes, loadProductTaxFacts, matchesTaxPolicyCondition, mountBookingTaxPreviewRoutes, mountBookingTaxSettingsRoutes, type ProductTaxFacts, type ResolveBookingSellTaxRateOptions, type ResolveBookingTaxSettings, type ResolvedBookingSellTaxRate, resolveBookingSellTaxRate, type TaxPolicyCondition, type UpdateBookingTaxSettings, } from "./booking-tax.js";
30
30
  export { BOOKING_TAX_PREVIEW_RUNTIME_KEY, BOOKING_TAX_SETTINGS_RUNTIME_KEY, type BookingTaxRuntime, createBookingTaxPreviewVoyantRuntime, createBookingTaxSettingsVoyantRuntime, } from "./booking-tax-runtime.js";
31
- export type { CardPaymentBilling, CardPaymentStartArgs, CardPaymentStarter, CardPaymentStartResult, PaymentAdapterCardPaymentStarterOptions, } from "./card-payment.js";
32
- export { createPaymentAdapterCardPaymentStarter } from "./card-payment.js";
31
+ export type { CardPaymentBilling, CardPaymentStartArgs, CardPaymentStarter, CardPaymentStartResult, PaymentAdapterCardPaymentExecution, PaymentAdapterCardPaymentStarterOptions, } from "./card-payment.js";
32
+ export { createPaymentAdapterCardPaymentStarter, startPaymentAdapterCardPayment, } from "./card-payment.js";
33
33
  export { type DocumentDownloadEnvelope, type DocumentDownloadResolution, type DocumentDownloadResolver, resolveStoredDocumentDownload, type StoredDocumentReference, } from "./document-download.js";
34
34
  export { createInvoiceFxApiExtension, createInvoiceFxRoutes, createVoyantDataFxExchangeRateResolver, type InvoiceExchangeRateResolution, type InvoiceFxContext, type InvoiceFxOptions, type InvoiceFxRouteOptions, type InvoiceFxSettings, mountInvoiceFxRoutes, type ResolvedInvoiceFxSettings, type ResolveInvoiceExchangeRate, type ResolveInvoiceExchangeRateInput, type ResolveInvoiceFxSettings, resolveInvoiceFxContext, resolveInvoiceFxSettingsOrDefault, type UpdateInvoiceFxSettings, type VoyantDataFxResolverOptions, } from "./invoice-fx.js";
35
35
  export { type CreateOrderPaymentSessionsOptions, createOrderPaymentSessions, type EnsureOrderSessionParams, type OrderPaymentSessionSummary, type OrderPaymentSessions, type OrderPaymentSessionTargetType, type StartOrderPaymentProvider, } from "./order-payment-sessions.js";
36
- export { applyPaymentAdapterCallbackEvent } from "./payment-adapter-events.js";
36
+ export { applyPaymentAdapterCallbackEvent, applyPaymentAdapterInitiationResult, applyPaymentAdapterStatusResult, } from "./payment-adapter-events.js";
37
+ export { type PaymentAdapterStatusRefreshExecution, refreshPaymentAdapterStatus, } from "./payment-adapter-status.js";
37
38
  export type { ComputedScheduleEntry, ComputeScheduleInput, DepositKind, DepositRule, PaymentPolicy, PaymentPolicyCascadeLayers, PaymentPolicySource, PaymentScheduleEntryType, ResolvedPaymentPolicy, } from "./payment-policy.js";
38
39
  export { computePaymentSchedule, isPaymentPolicyEmpty, noDepositPolicy, normalizePaymentPolicy, policyShouldRequireFullPayment, resolveEffectivePaymentPolicy, } from "./payment-policy.js";
39
40
  export { createPaymentPolicyCascade, type PaymentPolicyCascade, type PaymentPolicyCascadeOptions, type PaymentPolicyCascadeReaders, readPolicySourceFromInternalNotes, stampPolicySourceOnBooking, } from "./payment-policy-cascade.js";
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ import { registerBookingFinancialLifecycle } from "@voyant-travel/bookings";
4
4
  import { customFieldsRuntimePort } from "@voyant-travel/core/custom-fields";
5
5
  import { defineGraphRuntimeFactory } from "@voyant-travel/core/project";
6
6
  import { stampOpenApiRegistryApiId } from "@voyant-travel/hono";
7
+ import { paymentAdapterRuntimePort } from "@voyant-travel/payments";
7
8
  import { financeBookingLifecycle } from "./booking-lifecycle.js";
8
9
  import { createBookingTaxSettingsRoutes } from "./booking-tax.js";
9
10
  import { buildFinanceCheckoutRouteRuntime, createFinanceCheckoutAdminRoutes, createFinanceCheckoutRoutes, FINANCE_CHECKOUT_ROUTE_RUNTIME_CONTAINER_KEY, } from "./checkout-routes.js";
@@ -68,7 +69,9 @@ export const financeApiModule = createFinanceApiModule();
68
69
  export const createFinanceVoyantRuntime = defineGraphRuntimeFactory(async ({ api, getPort, getPorts, hasPort }) => {
69
70
  const configured = createFinanceApiModule(createFinanceRuntime(await getPort(financeHostRuntimePort), await getPort(customFieldsRuntimePort), await getPort(financeNotificationsRuntimePort), hasPort(financeCheckoutPaymentStartersRuntimePort)
70
71
  ? await getPort(financeCheckoutPaymentStartersRuntimePort)
71
- : undefined, await getPorts(financeInvoiceSettlementPollerRuntimePort)));
72
+ : undefined, await getPorts(financeInvoiceSettlementPollerRuntimePort), hasPort(paymentAdapterRuntimePort)
73
+ ? await getPort(paymentAdapterRuntimePort)
74
+ : undefined));
72
75
  const bootstrap = configured.module.bootstrap;
73
76
  const selected = {
74
77
  module: {
@@ -91,11 +94,12 @@ export { PAYMENT_ADAPTER_CONTRACT_VERSION, PAYMENT_ADAPTER_RUNTIME_PORT_ID, paym
91
94
  export { buildPaidBookingCancellationSettlementNote, closeTerminalBookingPaymentSchedules, financeBookingLifecycle, recordPaidBookingCancellationSettlement, } from "./booking-lifecycle.js";
92
95
  export { computeBookingItemTaxLine, createBookingTaxPreviewApiExtension, createBookingTaxPreviewRoutes, createBookingTaxSettingsApiExtension, createBookingTaxSettingsRoutes, loadProductTaxFacts, matchesTaxPolicyCondition, mountBookingTaxPreviewRoutes, mountBookingTaxSettingsRoutes, resolveBookingSellTaxRate, } from "./booking-tax.js";
93
96
  export { BOOKING_TAX_PREVIEW_RUNTIME_KEY, BOOKING_TAX_SETTINGS_RUNTIME_KEY, createBookingTaxPreviewVoyantRuntime, createBookingTaxSettingsVoyantRuntime, } from "./booking-tax-runtime.js";
94
- export { createPaymentAdapterCardPaymentStarter } from "./card-payment.js";
97
+ export { createPaymentAdapterCardPaymentStarter, startPaymentAdapterCardPayment, } from "./card-payment.js";
95
98
  export { resolveStoredDocumentDownload, } from "./document-download.js";
96
99
  export { createInvoiceFxApiExtension, createInvoiceFxRoutes, createVoyantDataFxExchangeRateResolver, mountInvoiceFxRoutes, resolveInvoiceFxContext, resolveInvoiceFxSettingsOrDefault, } from "./invoice-fx.js";
97
100
  export { createOrderPaymentSessions, } from "./order-payment-sessions.js";
98
- export { applyPaymentAdapterCallbackEvent } from "./payment-adapter-events.js";
101
+ export { applyPaymentAdapterCallbackEvent, applyPaymentAdapterInitiationResult, applyPaymentAdapterStatusResult, } from "./payment-adapter-events.js";
102
+ export { refreshPaymentAdapterStatus, } from "./payment-adapter-status.js";
99
103
  export { computePaymentSchedule, isPaymentPolicyEmpty, noDepositPolicy, normalizePaymentPolicy, policyShouldRequireFullPayment, resolveEffectivePaymentPolicy, } from "./payment-policy.js";
100
104
  export { createPaymentPolicyCascade, readPolicySourceFromInternalNotes, stampPolicySourceOnBooking, } from "./payment-policy-cascade.js";
101
105
  export { createBookingScheduleAdminRoutes, createBookingScheduleApiExtension, createBookingScheduleVoyantRuntime, createPaymentPolicyPublicRoutes, generatePaymentScheduleForBooking, } from "./payment-schedule/routes.js";
@@ -1,6 +1,54 @@
1
- import type { PaymentCallbackEvent } from "@voyant-travel/payments";
1
+ import type { PaymentCallbackEvent, PaymentInitiationResult, PaymentStatusResult } from "@voyant-travel/payments";
2
2
  import type { PostgresJsDatabase } from "drizzle-orm/postgres-js";
3
- import type { FinanceServiceRuntime } from "./service-shared.js";
3
+ import { type FinanceServiceRuntime } from "./service-shared.js";
4
+ export declare function applyPaymentAdapterInitiationResult(db: PostgresJsDatabase, paymentSessionId: string, adapterId: string, result: PaymentInitiationResult, claim: {
5
+ idempotencyKey: string;
6
+ claimedAt: Date;
7
+ }, runtime?: FinanceServiceRuntime): Promise<{
8
+ id: string;
9
+ targetType: "other" | "booking" | "order" | "invoice" | "booking_payment_schedule" | "booking_guarantee" | "flight_order";
10
+ targetId: string | null;
11
+ bookingId: string | null;
12
+ orderId: string | null;
13
+ invoiceId: string | null;
14
+ bookingPaymentScheduleId: string | null;
15
+ bookingGuaranteeId: string | null;
16
+ paymentInstrumentId: string | null;
17
+ paymentAuthorizationId: string | null;
18
+ paymentCaptureId: string | null;
19
+ paymentId: string | null;
20
+ status: "paid" | "pending" | "failed" | "requires_redirect" | "processing" | "authorized" | "cancelled" | "expired";
21
+ provider: string | null;
22
+ providerConnectionId: string | null;
23
+ providerSessionId: string | null;
24
+ providerPaymentId: string | null;
25
+ externalReference: string | null;
26
+ idempotencyKey: string | null;
27
+ clientReference: string | null;
28
+ currency: string;
29
+ amountCents: number;
30
+ paymentMethod: "bank_transfer" | "credit_card" | "debit_card" | "cash" | "cheque" | "wallet" | "direct_bill" | "travel_credit" | "other" | null;
31
+ payerPersonId: string | null;
32
+ payerOrganizationId: string | null;
33
+ payerEmail: string | null;
34
+ payerName: string | null;
35
+ redirectUrl: string | null;
36
+ returnUrl: string | null;
37
+ cancelUrl: string | null;
38
+ callbackUrl: string | null;
39
+ expiresAt: Date | null;
40
+ completedAt: Date | null;
41
+ failedAt: Date | null;
42
+ cancelledAt: Date | null;
43
+ expiredAt: Date | null;
44
+ failureCode: string | null;
45
+ failureMessage: string | null;
46
+ notes: string | null;
47
+ providerPayload: Record<string, unknown> | null;
48
+ metadata: Record<string, unknown> | null;
49
+ createdAt: Date;
50
+ updatedAt: Date;
51
+ } | null>;
4
52
  export declare function applyPaymentAdapterCallbackEvent(db: PostgresJsDatabase, event: PaymentCallbackEvent, runtime?: FinanceServiceRuntime): Promise<{
5
53
  id: string;
6
54
  targetType: "other" | "booking" | "order" | "invoice" | "booking_payment_schedule" | "booking_guarantee" | "flight_order";
@@ -16,6 +64,52 @@ export declare function applyPaymentAdapterCallbackEvent(db: PostgresJsDatabase,
16
64
  paymentId: string | null;
17
65
  status: "paid" | "pending" | "failed" | "requires_redirect" | "processing" | "authorized" | "cancelled" | "expired";
18
66
  provider: string | null;
67
+ providerConnectionId: string | null;
68
+ providerSessionId: string | null;
69
+ providerPaymentId: string | null;
70
+ externalReference: string | null;
71
+ idempotencyKey: string | null;
72
+ clientReference: string | null;
73
+ currency: string;
74
+ amountCents: number;
75
+ paymentMethod: "bank_transfer" | "credit_card" | "debit_card" | "cash" | "cheque" | "wallet" | "direct_bill" | "travel_credit" | "other" | null;
76
+ payerPersonId: string | null;
77
+ payerOrganizationId: string | null;
78
+ payerEmail: string | null;
79
+ payerName: string | null;
80
+ redirectUrl: string | null;
81
+ returnUrl: string | null;
82
+ cancelUrl: string | null;
83
+ callbackUrl: string | null;
84
+ expiresAt: Date | null;
85
+ completedAt: Date | null;
86
+ failedAt: Date | null;
87
+ cancelledAt: Date | null;
88
+ expiredAt: Date | null;
89
+ failureCode: string | null;
90
+ failureMessage: string | null;
91
+ notes: string | null;
92
+ providerPayload: Record<string, unknown> | null;
93
+ metadata: Record<string, unknown> | null;
94
+ createdAt: Date;
95
+ updatedAt: Date;
96
+ } | null>;
97
+ export declare function applyPaymentAdapterStatusResult(db: PostgresJsDatabase, paymentSessionId: string, result: PaymentStatusResult, statusLeaseToken: string, runtime?: FinanceServiceRuntime, checkedAt?: Date): Promise<{
98
+ id: string;
99
+ targetType: "other" | "booking" | "order" | "invoice" | "booking_payment_schedule" | "booking_guarantee" | "flight_order";
100
+ targetId: string | null;
101
+ bookingId: string | null;
102
+ orderId: string | null;
103
+ invoiceId: string | null;
104
+ bookingPaymentScheduleId: string | null;
105
+ bookingGuaranteeId: string | null;
106
+ paymentInstrumentId: string | null;
107
+ paymentAuthorizationId: string | null;
108
+ paymentCaptureId: string | null;
109
+ paymentId: string | null;
110
+ status: "paid" | "pending" | "failed" | "requires_redirect" | "processing" | "authorized" | "cancelled" | "expired";
111
+ provider: string | null;
112
+ providerConnectionId: string | null;
19
113
  providerSessionId: string | null;
20
114
  providerPaymentId: string | null;
21
115
  externalReference: string | null;