@antelopejs/dms-saas 0.3.9 → 0.3.10

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 (32) hide show
  1. package/dist/routes/tenant/index.d.ts +1 -0
  2. package/dist/routes/tenant/index.js +1 -0
  3. package/dist/routes/tenant/index.js.map +1 -1
  4. package/dist/routes/tenant/tenant-plan-checkout-recovery.d.ts +21 -0
  5. package/dist/routes/tenant/tenant-plan-checkout-recovery.js +140 -0
  6. package/dist/routes/tenant/tenant-plan-checkout-recovery.js.map +1 -0
  7. package/dist/routes/tenant/tenant-plan-checkout.d.ts +0 -3
  8. package/dist/routes/tenant/tenant-plan-checkout.js +4 -44
  9. package/dist/routes/tenant/tenant-plan-checkout.js.map +1 -1
  10. package/dist/routes/tenant/tenant-plan.d.ts +3 -0
  11. package/dist/routes/tenant/tenant-plan.js +27 -0
  12. package/dist/routes/tenant/tenant-plan.js.map +1 -1
  13. package/dist/stripe/webhook-checkout.js +2 -0
  14. package/dist/stripe/webhook-checkout.js.map +1 -1
  15. package/dist/stripe/workspace-checkout.d.ts +5 -0
  16. package/dist/stripe/workspace-checkout.js +25 -1
  17. package/dist/stripe/workspace-checkout.js.map +1 -1
  18. package/frontend-vue/app/components/PendingCheckoutModal.vue +78 -0
  19. package/frontend-vue/app/components/PlanComparisonModal.vue +5 -0
  20. package/frontend-vue/app/components/PlanUpgradeModal.vue +5 -0
  21. package/frontend-vue/app/components/TenantPlanCard.vue +27 -1
  22. package/frontend-vue/app/components/WorkspaceCreateModal.vue +2 -0
  23. package/frontend-vue/app/composables/useApiErrorMessage.ts +9 -8
  24. package/frontend-vue/app/composables/usePendingCheckout.ts +88 -0
  25. package/frontend-vue/app/composables/useSaasRegistration.ts +1 -0
  26. package/frontend-vue/app/composables/useStripePaymentElement.ts +90 -13
  27. package/frontend-vue/app/composables/useTenantPlan.ts +41 -1
  28. package/frontend-vue/app/custom-pages/auth/no-workspace.vue +1 -0
  29. package/frontend-vue/i18n/locales/saas-en-GB.json +12 -0
  30. package/frontend-vue/i18n/locales/saas-fr-FR.json +12 -0
  31. package/frontend-vue/package.json +3 -0
  32. package/package.json +1 -1
@@ -4,6 +4,7 @@ export * from "./data-export";
4
4
  export * from "./tenant-billing";
5
5
  export * from "./tenant-plan";
6
6
  export * from "./tenant-plan-checkout";
7
+ export * from "./tenant-plan-checkout-recovery";
7
8
  export * from "./tenant-plan-ops";
8
9
  export * from "./tenant-seats";
9
10
  export * from "./workspaces";
@@ -20,6 +20,7 @@ __exportStar(require("./data-export"), exports);
20
20
  __exportStar(require("./tenant-billing"), exports);
21
21
  __exportStar(require("./tenant-plan"), exports);
22
22
  __exportStar(require("./tenant-plan-checkout"), exports);
23
+ __exportStar(require("./tenant-plan-checkout-recovery"), exports);
23
24
  __exportStar(require("./tenant-plan-ops"), exports);
24
25
  __exportStar(require("./tenant-seats"), exports);
25
26
  __exportStar(require("./workspaces"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/routes/tenant/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,wDAAsC;AACtC,gDAA8B;AAC9B,mDAAiC;AACjC,gDAA8B;AAC9B,yDAAuC;AACvC,oDAAkC;AAClC,iDAA+B;AAC/B,+CAA6B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/routes/tenant/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,wDAAsC;AACtC,gDAA8B;AAC9B,mDAAiC;AACjC,gDAA8B;AAC9B,yDAAuC;AACvC,kEAAgD;AAChD,oDAAkC;AAClC,iDAA+B;AAC/B,+CAA6B"}
@@ -0,0 +1,21 @@
1
+ import type { TenantSubscription, TenantSubscriptionModel } from "../../db";
2
+ export declare const UNRECORDED_CHECKOUT_TTL_MS: number;
3
+ export declare const CHECKOUT_CANCELLED_PARAM = "checkout";
4
+ export declare const CHECKOUT_CANCELLED_VALUE = "cancelled";
5
+ export declare const CHECKOUT_OPERATION_PARAM = "checkoutOperation";
6
+ export interface PendingCheckout {
7
+ targetPlanId: string | null;
8
+ checkoutUrl: string | null;
9
+ expiresAt: Date | null;
10
+ isPaid: boolean;
11
+ }
12
+ export interface PendingCheckoutResult {
13
+ pending: PendingCheckout | null;
14
+ }
15
+ export interface CancelCheckoutResult {
16
+ released: boolean;
17
+ }
18
+ export declare function withCheckoutCancelMarker(cancelUrl: string, operationId: string): string;
19
+ export declare function releaseAbandonedCheckout(subscription: TenantSubscription, model: TenantSubscriptionModel, now?: Date): Promise<TenantSubscription>;
20
+ export declare function describePendingCheckout(subscription: TenantSubscription | undefined): Promise<PendingCheckoutResult>;
21
+ export declare function cancelPendingCheckout(subscription: TenantSubscription | undefined, model: TenantSubscriptionModel, operationId: string | null, now?: Date): Promise<CancelCheckoutResult>;
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CHECKOUT_OPERATION_PARAM = exports.CHECKOUT_CANCELLED_VALUE = exports.CHECKOUT_CANCELLED_PARAM = exports.UNRECORDED_CHECKOUT_TTL_MS = void 0;
7
+ exports.withCheckoutCancelMarker = withCheckoutCancelMarker;
8
+ exports.releaseAbandonedCheckout = releaseAbandonedCheckout;
9
+ exports.describePendingCheckout = describePendingCheckout;
10
+ exports.cancelPendingCheckout = cancelPendingCheckout;
11
+ const interface_api_1 = require("@antelopejs/interface-api");
12
+ const logging_1 = require("@antelopejs/interface-core/logging");
13
+ const stripe_1 = __importDefault(require("stripe"));
14
+ const client_1 = require("../../stripe/client");
15
+ const workspace_checkout_1 = require("../../stripe/workspace-checkout");
16
+ const tenant_plan_ops_1 = require("./tenant-plan-ops");
17
+ const CHECKOUT_KIND = "checkout";
18
+ const MS_PER_MINUTE = 60_000;
19
+ const MS_PER_SECOND = 1000;
20
+ const LOG_PREFIX = "[dms-saas:checkout]";
21
+ const CHECKOUT_IN_PROGRESS_KEY = "saas.errors.plan.checkout_in_progress";
22
+ const CHECKOUT_ALREADY_PAID_KEY = "saas.errors.plan.checkout_already_paid";
23
+ exports.UNRECORDED_CHECKOUT_TTL_MS = 15 * MS_PER_MINUTE;
24
+ exports.CHECKOUT_CANCELLED_PARAM = "checkout";
25
+ exports.CHECKOUT_CANCELLED_VALUE = "cancelled";
26
+ exports.CHECKOUT_OPERATION_PARAM = "checkoutOperation";
27
+ function withCheckoutCancelMarker(cancelUrl, operationId) {
28
+ const url = new URL(cancelUrl);
29
+ url.searchParams.set(exports.CHECKOUT_CANCELLED_PARAM, exports.CHECKOUT_CANCELLED_VALUE);
30
+ url.searchParams.set(exports.CHECKOUT_OPERATION_PARAM, operationId);
31
+ return url.toString();
32
+ }
33
+ function pendingCheckoutTransition(subscription) {
34
+ const transition = subscription?.domainTransition;
35
+ return transition?.kind === CHECKOUT_KIND ? transition : null;
36
+ }
37
+ async function retrieveRecordedSession(subscription, transition) {
38
+ if (!subscription.stripeCheckoutSessionId)
39
+ return null;
40
+ const session = await (0, client_1.getStripeClient)().checkout.sessions.retrieve(subscription.stripeCheckoutSessionId);
41
+ return session.metadata?.operationId === transition.operationId
42
+ ? session
43
+ : null;
44
+ }
45
+ function isUnrecordedPastTtl(transition, now) {
46
+ const age = now.getTime() - new Date(transition.requestedAt).getTime();
47
+ return age >= exports.UNRECORDED_CHECKOUT_TTL_MS;
48
+ }
49
+ async function releaseCheckoutTransition(subscription, model, session) {
50
+ const operationId = subscription.domainTransition?.operationId;
51
+ logging_1.Logging.Warn(`${LOG_PREFIX} releasing abandoned checkout ${operationId} of tenant ${subscription._id}`);
52
+ const outcome = await model.mutateRevision(subscription, {
53
+ domainTransition: null,
54
+ stripeCheckoutSessionId: null,
55
+ });
56
+ const released = await model.get(subscription._id);
57
+ if (!released)
58
+ throw new Error("Subscription vanished during release");
59
+ const isStillPending = released.domainTransition?.operationId === operationId;
60
+ if (outcome !== "applied" && isStillPending)
61
+ throw new Error(`Checkout release ${outcome}; reload before retry`);
62
+ if (session)
63
+ await (0, workspace_checkout_1.releaseCheckoutTrialReservation)(session, released._id);
64
+ return released;
65
+ }
66
+ async function findAbandonment(subscription, transition, now) {
67
+ const session = await retrieveRecordedSession(subscription, transition);
68
+ if (session)
69
+ return { isAbandoned: session.status === "expired", session };
70
+ return { isAbandoned: isUnrecordedPastTtl(transition, now), session };
71
+ }
72
+ async function releaseAbandonedCheckout(subscription, model, now = new Date()) {
73
+ const transition = pendingCheckoutTransition(subscription);
74
+ if (!transition)
75
+ return subscription;
76
+ const { isAbandoned, session } = await findAbandonment(subscription, transition, now);
77
+ if (!isAbandoned)
78
+ return subscription;
79
+ return releaseCheckoutTransition(subscription, model, session);
80
+ }
81
+ function describeSession(transition, session) {
82
+ if (session?.status === "expired")
83
+ return null;
84
+ const isOpen = session?.status === "open";
85
+ return {
86
+ targetPlanId: transition.targetPlanId,
87
+ checkoutUrl: isOpen ? (session.url ?? null) : null,
88
+ expiresAt: isOpen && session.expires_at
89
+ ? new Date(session.expires_at * MS_PER_SECOND)
90
+ : null,
91
+ isPaid: session?.status === "complete",
92
+ };
93
+ }
94
+ async function describePendingCheckout(subscription) {
95
+ const transition = pendingCheckoutTransition(subscription);
96
+ if (!subscription || !transition)
97
+ return { pending: null };
98
+ const session = await retrieveRecordedSession(subscription, transition);
99
+ return { pending: describeSession(transition, session) };
100
+ }
101
+ async function expireOpenSession(session) {
102
+ if (session.status !== "open")
103
+ return session;
104
+ const sessions = (0, client_1.getStripeClient)().checkout.sessions;
105
+ try {
106
+ return await sessions.expire(session.id);
107
+ }
108
+ catch (error) {
109
+ if (!(error instanceof stripe_1.default.errors.StripeInvalidRequestError))
110
+ throw error;
111
+ return sessions.retrieve(session.id);
112
+ }
113
+ }
114
+ const CANCELLATION_REFUSALS = {
115
+ open: CHECKOUT_IN_PROGRESS_KEY,
116
+ complete: CHECKOUT_ALREADY_PAID_KEY,
117
+ };
118
+ async function cancelRecordedSession(subscription, model, session) {
119
+ const settled = await expireOpenSession(session);
120
+ const refusal = settled.status && CANCELLATION_REFUSALS[settled.status];
121
+ if (refusal)
122
+ throw new interface_api_1.HTTPResult(tenant_plan_ops_1.HTTP_CONFLICT, refusal);
123
+ await releaseCheckoutTransition(subscription, model, settled);
124
+ return { released: true };
125
+ }
126
+ async function cancelPendingCheckout(subscription, model, operationId, now = new Date()) {
127
+ const transition = pendingCheckoutTransition(subscription);
128
+ if (!subscription || !transition)
129
+ return { released: false };
130
+ if (operationId && operationId !== transition.operationId)
131
+ return { released: false };
132
+ const session = await retrieveRecordedSession(subscription, transition);
133
+ if (session)
134
+ return cancelRecordedSession(subscription, model, session);
135
+ if (!isUnrecordedPastTtl(transition, now))
136
+ throw new interface_api_1.HTTPResult(tenant_plan_ops_1.HTTP_CONFLICT, CHECKOUT_IN_PROGRESS_KEY);
137
+ await releaseCheckoutTransition(subscription, model, null);
138
+ return { released: true };
139
+ }
140
+ //# sourceMappingURL=tenant-plan-checkout-recovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tenant-plan-checkout-recovery.js","sourceRoot":"","sources":["../../../src/routes/tenant/tenant-plan-checkout-recovery.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,2 @@
1
- import { type TenantSubscription, type TenantSubscriptionModel } from "../../db";
2
1
  import { type ChangePlanResult, type PlanChangeRequest } from "./tenant-plan-ops";
3
- export declare const UNRECORDED_CHECKOUT_TTL_MS: number;
4
- export declare function releaseAbandonedCheckout(subscription: TenantSubscription, model: TenantSubscriptionModel, now?: Date): Promise<TenantSubscription>;
5
2
  export declare function startPaidCheckout(request: PlanChangeRequest): Promise<ChangePlanResult>;
@@ -1,7 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.UNRECORDED_CHECKOUT_TTL_MS = void 0;
4
- exports.releaseAbandonedCheckout = releaseAbandonedCheckout;
5
3
  exports.startPaidCheckout = startPaidCheckout;
6
4
  const node_crypto_1 = require("node:crypto");
7
5
  const interface_api_1 = require("@antelopejs/interface-api");
@@ -18,15 +16,13 @@ const utils_1 = require("../../utils");
18
16
  const complimentary_1 = require("../../workspaces/complimentary");
19
17
  const trial_identity_model_1 = require("../../workspaces/db/trial-identity.model");
20
18
  const tenant_plan_ops_1 = require("./tenant-plan-ops");
19
+ const tenant_plan_checkout_recovery_1 = require("./tenant-plan-checkout-recovery");
21
20
  const HTTP_UNPROCESSABLE = 422;
22
21
  const HTTP_SERVICE_UNAVAILABLE = 503;
23
22
  const PENDING_PAYMENT_STATUS = "pending_payment";
24
23
  const PLACEHOLDER_PLAN_ID = null;
25
24
  const CHECKOUT_KIND = "checkout";
26
- const EXPIRED_SESSION_STATUS = "expired";
27
- const MS_PER_MINUTE = 60_000;
28
25
  const LOG_PREFIX = "[dms-saas:checkout]";
29
- exports.UNRECORDED_CHECKOUT_TTL_MS = 15 * MS_PER_MINUTE;
30
26
  const NO_TRIAL = { days: 0, reservedIdentityId: null };
31
27
  function asNonEmptyString(value) {
32
28
  return typeof value === "string" && value.trim().length > 0
@@ -78,43 +74,6 @@ async function initializeCheckoutSubscription(request) {
78
74
  throw new Error("Checkout subscription acknowledgement requires reconciliation");
79
75
  return subscription;
80
76
  }
81
- async function retrieveRecordedSession(subscription, transition) {
82
- if (!subscription.stripeCheckoutSessionId)
83
- return null;
84
- const session = await (0, client_1.getStripeClient)().checkout.sessions.retrieve(subscription.stripeCheckoutSessionId);
85
- return session.metadata?.operationId === transition.operationId
86
- ? session
87
- : null;
88
- }
89
- function isUnrecordedPastTtl(transition, now) {
90
- const age = now.getTime() - new Date(transition.requestedAt).getTime();
91
- return age >= exports.UNRECORDED_CHECKOUT_TTL_MS;
92
- }
93
- async function isAbandonedCheckout(subscription, transition, now) {
94
- const session = await retrieveRecordedSession(subscription, transition);
95
- if (session)
96
- return session.status === EXPIRED_SESSION_STATUS;
97
- return isUnrecordedPastTtl(transition, now);
98
- }
99
- async function releaseAbandonedCheckout(subscription, model, now = new Date()) {
100
- const transition = subscription.domainTransition;
101
- if (transition?.kind !== CHECKOUT_KIND)
102
- return subscription;
103
- if (!(await isAbandonedCheckout(subscription, transition, now))) {
104
- return subscription;
105
- }
106
- logging_1.Logging.Warn(`${LOG_PREFIX} releasing abandoned checkout ${transition.operationId} of tenant ${subscription._id}`);
107
- const outcome = await model.mutateRevision(subscription, {
108
- domainTransition: null,
109
- stripeCheckoutSessionId: null,
110
- });
111
- if (outcome !== "applied")
112
- throw new Error(`Checkout release ${outcome}; reload before retry`);
113
- const released = await model.get(subscription._id);
114
- if (!released)
115
- throw new Error("Subscription vanished during release");
116
- return released;
117
- }
118
77
  async function attachCheckoutSession(checkout, subscription, model, operationId) {
119
78
  await model.updateDuringTransition(subscription._id, operationId, {
120
79
  isComplimentary: (0, complimentary_1.isComplimentarySubscription)(subscription),
@@ -151,7 +110,7 @@ async function failCheckoutAttempt(error, attempt, model) {
151
110
  }
152
111
  async function admitCheckout(request) {
153
112
  const model = request.tenantSubscriptionModel;
154
- const subscription = await releaseAbandonedCheckout(await initializeCheckoutSubscription(request), model);
113
+ const subscription = await (0, tenant_plan_checkout_recovery_1.releaseAbandonedCheckout)(await initializeCheckoutSubscription(request), model);
155
114
  (0, interface_api_util_1.assert)(!subscription.domainTransition, tenant_plan_ops_1.HTTP_CONFLICT, subscription.domainTransition?.kind === CHECKOUT_KIND
156
115
  ? "saas.errors.plan.checkout_in_progress"
157
116
  : "saas.errors.plan.change_in_progress");
@@ -190,9 +149,10 @@ async function openCheckoutSession(request, attempt, target) {
190
149
  stripePriceId: target.stripePriceId,
191
150
  trialDays: trial.days,
192
151
  successUrl: redirect.successUrl,
193
- cancelUrl: redirect.cancelUrl,
152
+ cancelUrl: (0, tenant_plan_checkout_recovery_1.withCheckoutCancelMarker)(redirect.cancelUrl, attempt.operationId),
194
153
  planId: request.newPlan._id,
195
154
  existingCustomerId: customerId,
155
+ reservedTrialIdentityId: trial.reservedIdentityId,
196
156
  });
197
157
  }
198
158
  async function createAdmittedCheckout(request) {
@@ -1 +1 @@
1
- {"version":3,"file":"tenant-plan-checkout.js","sourceRoot":"","sources":["../../../src/routes/tenant/tenant-plan-checkout.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tenant-plan-checkout.js","sourceRoot":"","sources":["../../../src/routes/tenant/tenant-plan-checkout.ts"],"names":[],"mappings":";;AAoVA,8CAMC;AA/UD,6CAAyC;AACzC,6DAAuD;AACvD,uEAAwD;AACxD,gEAA6D;AAC7D,6FAAqE;AACrE,iFAAyF;AACzF,uDAAkE;AAClE,yCAAoD;AACpD,iCAIkB;AAClB,gDAAsD;AACtD,wEAOyC;AACzC,uCAAwC;AACxC,kEAA6E;AAC7E,mFAGkD;AAClD,uDAO2B;AAC3B,mFAGyC;AAEzC,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAC/B,MAAM,wBAAwB,GAAG,GAAG,CAAC;AACrC,MAAM,sBAAsB,GAAG,iBAA0B,CAAC;AAC1D,MAAM,mBAAmB,GAAkB,IAAI,CAAC;AAChD,MAAM,aAAa,GAAG,UAAmB,CAAC;AAC1C,MAAM,UAAU,GAAG,qBAAqB,CAAC;AAgCzC,MAAM,QAAQ,GAAe,EAAE,IAAI,EAAE,CAAC,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC;AAEnE,SAAS,gBAAgB,CAAC,KAAc;IACtC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;QACzD,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE;QACd,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,SAAS,6BAA6B,CACpC,IAAoB;IAEpB,MAAM,UAAU,GAAG,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACnD,IAAA,2BAAM,EACJ,UAAU,IAAI,IAAA,6BAAoB,EAAC,UAAU,CAAC,EAC9C,kCAAgB,EAChB,wCAAwC,CACzC,CAAC;IACF,IAAA,2BAAM,EACJ,SAAS,IAAI,IAAA,6BAAoB,EAAC,SAAS,CAAC,EAC5C,kCAAgB,EAChB,wCAAwC,CACzC,CAAC;IACF,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;AACnC,CAAC;AAED,KAAK,UAAU,oBAAoB,CACjC,OAA0B;IAE1B,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC5C,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IAClE,MAAM,qBAAqB,GAAG,IAAA,wCAAQ,EAAC,0BAAqB,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,IAAA,iBAAS,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxC,IAAI,MAAM,qBAAqB,CAAC,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC;QACnE,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,MAAM,UAAU,GAAG,IAAA,wCAAQ,EAAC,yCAAkB,CAAC,CAAC;IAChD,MAAM,EAAE,GAAG,IAAA,sCAAe,EAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC1D,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC/D,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE,kBAAkB,EAAE,EAAE,EAAE,CAAC;AAC7D,CAAC;AAED,KAAK,UAAU,8BAA8B,CAC3C,OAA0B;IAE1B,IAAI,OAAO,CAAC,YAAY;QAAE,OAAO,OAAO,CAAC,YAAY,CAAC;IACtD,MAAM,OAAO,CAAC,uBAAuB,CAAC,MAAM,CAAC;QAC3C,GAAG,EAAE,OAAO,CAAC,QAAQ;QACrB,MAAM,EAAE,mBAAmB;QAC3B,MAAM,EAAE,sBAAsB;QAC9B,eAAe,EAAE,KAAK;QACtB,gBAAgB,EAAE,EAAE;QACpB,gBAAgB,EAAE,IAAI;QACtB,oBAAoB,EAAE,IAAI;QAC1B,uBAAuB,EAAE,IAAI;QAC7B,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG;QAC3B,SAAS,EAAE,IAAI,IAAI,EAAE;QACrB,SAAS,EAAE,IAAI,IAAI,EAAE;KACtB,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,uBAAuB,CAAC,GAAG,CAC5D,OAAO,CAAC,QAAQ,CACjB,CAAC;IACF,IAAI,CAAC,YAAY;QACf,MAAM,IAAI,KAAK,CACb,+DAA+D,CAChE,CAAC;IACJ,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,KAAK,UAAU,qBAAqB,CAClC,QAAkC,EAClC,YAAgC,EAChC,KAA8B,EAC9B,WAAmB;IAEnB,MAAM,KAAK,CAAC,sBAAsB,CAAC,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE;QAChE,eAAe,EAAE,IAAA,2CAA2B,EAAC,YAAY,CAAC;QAC1D,gBAAgB,EAAE,QAAQ,CAAC,UAAU;QACrC,uBAAuB,EAAE,QAAQ,CAAC,SAAS;QAC3C,SAAS,EAAE,IAAI,IAAI,EAAE;KACtB,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,qBAAqB,CAAC,KAAc;IACjD,IAAI,CAAC,CAAC,KAAK,YAAY,iDAA4B,CAAC;QAAE,OAAO;IAC7D,MAAM,IAAA,wBAAe,GAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;AACpE,CAAC;AAQD,KAAK,UAAU,uBAAuB,CACpC,OAAwB,EACxB,KAA8B;IAE9B,MAAM,KAAK,CAAC,kBAAkB,CAC5B,OAAO,CAAC,cAAc,EACtB,OAAO,CAAC,WAAW,EACnB,EAAE,CACH,CAAC;IACF,IAAI,OAAO,CAAC,uBAAuB,EAAE,CAAC;QACpC,MAAM,IAAA,wCAAQ,EAAC,yCAAkB,CAAC;aAC/B,aAAa,CAAC,OAAO,CAAC,uBAAuB,EAAE,OAAO,CAAC,QAAQ,CAAC;aAChE,KAAK,CAAC,CAAC,YAAY,EAAE,EAAE,CACtB,iBAAO,CAAC,IAAI,CACV,GAAG,UAAU,qDAAqD,OAAO,CAAC,WAAW,EAAE,EACvF,YAAY,CACb,CACF,CAAC;IACN,CAAC;IACD,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;QAC9B,MAAM,IAAA,iDAA4B,EAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,KAAK,CACjE,CAAC,YAAY,EAAE,EAAE,CACf,iBAAO,CAAC,IAAI,CACV,GAAG,UAAU,4CAA4C,OAAO,CAAC,iBAAiB,EAAE,EACpF,YAAY,CACb,CACJ,CAAC;IACJ,CAAC;AACH,CAAC;AAOD,KAAK,UAAU,mBAAmB,CAChC,KAAc,EACd,OAAwB,EACxB,KAA8B;IAE9B,iBAAO,CAAC,KAAK,CACX,GAAG,UAAU,sCAAsC,OAAO,CAAC,QAAQ,EAAE,EACrE,KAAK,CACN,CAAC;IACF,MAAM,iBAAiB,GAAG,KAAK,YAAY,iDAA4B,CAAC;IACxE,IAAI,CAAC,IAAA,gDAA2B,EAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC9D,MAAM,IAAI,0BAAU,CAClB,wBAAwB,EACxB,0CAA0C,CAC3C,CAAC;IACJ,CAAC;IACD,MAAM,qBAAqB,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,uBAAuB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,IAAI,0BAAU,CAClB,kBAAkB,EAClB,uCAAuC,CACxC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,OAA0B;IAE1B,MAAM,KAAK,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAC9C,MAAM,YAAY,GAAG,MAAM,IAAA,wDAAwB,EACjD,MAAM,8BAA8B,CAAC,OAAO,CAAC,EAC7C,KAAK,CACN,CAAC;IACF,IAAA,2BAAM,EACJ,CAAC,YAAY,CAAC,gBAAgB,EAC9B,+BAAa,EACb,YAAY,CAAC,gBAAgB,EAAE,IAAI,KAAK,aAAa;QACnD,CAAC,CAAC,uCAAuC;QACzC,CAAC,CAAC,qCAAqC,CAC1C,CAAC;IACF,MAAM,WAAW,GAAG,IAAA,wBAAU,GAAE,CAAC;IACjC,MAAM,KAAK,CAAC,eAAe,CAAC,YAAY,EAAE;QACxC,WAAW;QACX,IAAI,EAAE,aAAa;QACnB,YAAY,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG;QACjC,WAAW,EAAE,IAAI,IAAI,EAAE;KACxB,CAAC,CAAC;IACH,OAAO;QACL,YAAY;QACZ,WAAW;QACX,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,cAAc,EAAE,YAAY,CAAC,GAAG;QAChC,iBAAiB,EAAE,IAAI;QACvB,uBAAuB,EAAE,IAAI;KAC9B,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,OAA0B,EAC1B,OAAwB,EACxB,MAA6B;IAE7B,MAAM,EAAE,kBAAkB,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IAChD,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAClD,OAAO,CAAC,uBAAuB,GAAG,KAAK,CAAC,kBAAkB,CAAC;IAG3D,MAAM,UAAU,GACd,kBAAkB;QAClB,CAAC,MAAM,IAAA,iDAA4B,EAAC;YAClC,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK;SAC/B,CAAC,CAAC,CAAC;IACN,IAAI,CAAC,kBAAkB;QAAE,OAAO,CAAC,iBAAiB,GAAG,UAAU,CAAC;IAChE,OAAO,IAAA,mDAA8B,EAAC;QACpC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK;QAC9B,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,SAAS,EAAE,KAAK,CAAC,IAAI;QACrB,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,SAAS,EAAE,IAAA,wDAAwB,EACjC,QAAQ,CAAC,SAAS,EAClB,OAAO,CAAC,WAAW,CACpB;QACD,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG;QAC3B,kBAAkB,EAAE,UAAU;QAC9B,uBAAuB,EAAE,KAAK,CAAC,kBAAkB;KAClD,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,sBAAsB,CACnC,OAA0B;IAE1B,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,uBAAuB,EAAE,GAAG,OAAO,CAAC;IACrE,MAAM,QAAQ,GAAG,6BAA6B,CAAC,IAAI,CAAC,CAAC;IACrD,MAAM,aAAa,GAAG,OAAO,CAAC,mBAAmB,EAAE,aAAa,CAAC;IACjE,IAAA,2BAAM,EAAC,aAAa,EAAE,kCAAgB,EAAE,kCAAkC,CAAC,CAAC;IAC5E,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,CAAC;IAClE,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE;QAC3D,aAAa;QACb,kBAAkB,EAAE,YAAY,CAAC,gBAAgB,IAAI,IAAI;QACzD,QAAQ;KACT,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAC1B,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,uBAAuB,CAAC,CAC7D,CAAC;IACF,MAAM,qBAAqB,CACzB,QAAQ,EACR,YAAY,EACZ,uBAAuB,EACvB,OAAO,CAAC,WAAW,CACpB,CAAC;IACF,MAAM,IAAA,2CAA2B,EAAC,QAAQ,CAAC,CAAC;IAC5C,OAAO;QACL,GAAG,uCAAqB;QACxB,MAAM,EAAE,OAAO,CAAC,GAAG;QACnB,WAAW,EAAE,QAAQ,CAAC,GAAG;KAC1B,CAAC;AACJ,CAAC;AAGM,KAAK,UAAU,iBAAiB,CACrC,OAA0B;IAE1B,OAAO,IAAA,8CAA2B,EAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,CACxD,sBAAsB,CAAC,OAAO,CAAC,CAChC,CAAC;AACJ,CAAC"}
@@ -2,6 +2,7 @@ import { TenantModel } from "@antelopejs/interface-dms/db";
2
2
  import type { User } from "@antelopejs/interface-dms/auth/db";
3
3
  import { FeatureModel, PlanModel, TenantBillingInfoModel, TenantSubscriptionModel } from "../../db";
4
4
  import { type ChangePlanBody, type ChangePlanResult, type CurrentPlanResult } from "./tenant-plan-ops";
5
+ import { type CancelCheckoutResult, type PendingCheckoutResult } from "./tenant-plan-checkout-recovery";
5
6
  declare const SaasTenantPlanController_base: import("@antelopejs/interface-api").ControllerClass<object>;
6
7
  export declare class SaasTenantPlanController extends SaasTenantPlanController_base {
7
8
  tenantModel: TenantModel;
@@ -11,6 +12,8 @@ export declare class SaasTenantPlanController extends SaasTenantPlanController_b
11
12
  private loadSubscription;
12
13
  getCurrentPlan(_user: User, ctx: any, tenantSubscriptionModel: TenantSubscriptionModel): Promise<CurrentPlanResult>;
13
14
  cancelPendingChange(user: User, ctx: any, tenantSubscriptionModel: TenantSubscriptionModel): Promise<ChangePlanResult>;
15
+ getPendingCheckout(_user: User, tenantSubscriptionModel: TenantSubscriptionModel): Promise<PendingCheckoutResult>;
16
+ cancelCheckout(_user: User, operationId: unknown, ctx: any, tenantSubscriptionModel: TenantSubscriptionModel): Promise<CancelCheckoutResult>;
14
17
  changePlan(user: User, body: ChangePlanBody, ctx: any, tenantSubscriptionModel: TenantSubscriptionModel, tenantBillingInfoModel: TenantBillingInfoModel): Promise<ChangePlanResult>;
15
18
  private assertPlanChangeAllowed;
16
19
  private resolveSamePlanRequest;
@@ -18,6 +18,7 @@ const interface_api_util_1 = require("@antelopejs/interface-api-util");
18
18
  const interface_database_decorators_1 = require("@antelopejs/interface-database-decorators");
19
19
  const db_1 = require("@antelopejs/interface-dms/db");
20
20
  const guards_1 = require("@antelopejs/interface-dms/guards");
21
+ const tenant_lifecycle_1 = require("@antelopejs/interface-dms/tenant-lifecycle");
21
22
  const request_tenant_1 = require("@antelopejs/interface-dms/request-tenant");
22
23
  const tenant_scoped_model_1 = require("@antelopejs/interface-dms/tenant-scoped-model");
23
24
  const tenant_access_1 = require("@antelopejs/interface-dms/tenant-access");
@@ -29,6 +30,7 @@ const complimentary_1 = require("../../workspaces/complimentary");
29
30
  const default_plan_1 = require("../../workspaces/default-plan");
30
31
  const tenant_plan_ops_1 = require("./tenant-plan-ops");
31
32
  const tenant_plan_checkout_1 = require("./tenant-plan-checkout");
33
+ const tenant_plan_checkout_recovery_1 = require("./tenant-plan-checkout-recovery");
32
34
  function startsPaidCheckout(newPlan, subscription) {
33
35
  return (0, tenant_plan_ops_1.isPaidPlan)(newPlan) && !subscription?.stripeSubscriptionId;
34
36
  }
@@ -92,6 +94,13 @@ class SaasTenantPlanController extends (0, interface_api_1.Controller)("/api/saa
92
94
  (0, interface_api_util_1.assert)(subscription?.pendingPlanId, tenant_plan_ops_1.HTTP_BAD_REQUEST, "saas.errors.plan.no_pending_change");
93
95
  return (0, tenant_plan_ops_1.dropPendingChange)(tenantId, subscription);
94
96
  }
97
+ async getPendingCheckout(_user, tenantSubscriptionModel) {
98
+ return (0, tenant_plan_checkout_recovery_1.describePendingCheckout)(await tenantSubscriptionModel.findOne());
99
+ }
100
+ async cancelCheckout(_user, operationId, ctx, tenantSubscriptionModel) {
101
+ const tenantId = (0, request_tenant_1.getRequestTenantId)(ctx);
102
+ return (0, tenant_lifecycle_1.runTenantLifecycleOperation)(tenantId, async () => (0, tenant_plan_checkout_recovery_1.cancelPendingCheckout)(await tenantSubscriptionModel.findOne(), tenantSubscriptionModel, typeof operationId === "string" && operationId ? operationId : null));
103
+ }
95
104
  async changePlan(user, body, ctx, tenantSubscriptionModel, tenantBillingInfoModel) {
96
105
  const tenantId = (0, request_tenant_1.getRequestTenantId)(ctx);
97
106
  const tenant = await this.tenantModel.get(tenantId);
@@ -184,6 +193,24 @@ __decorate([
184
193
  __metadata("design:paramtypes", [Function, Object, db_2.TenantSubscriptionModel]),
185
194
  __metadata("design:returntype", Promise)
186
195
  ], SaasTenantPlanController.prototype, "cancelPendingChange", null);
196
+ __decorate([
197
+ (0, interface_api_1.Get)("/checkout"),
198
+ __param(0, (0, guards_1.AuthTenantOwner)({ bypassTenantAccessGate: true })),
199
+ __param(1, (0, tenant_scoped_model_1.TenantScopedModel)(db_2.TenantSubscriptionModel)),
200
+ __metadata("design:type", Function),
201
+ __metadata("design:paramtypes", [Function, db_2.TenantSubscriptionModel]),
202
+ __metadata("design:returntype", Promise)
203
+ ], SaasTenantPlanController.prototype, "getPendingCheckout", null);
204
+ __decorate([
205
+ (0, interface_api_1.Delete)("/checkout"),
206
+ __param(0, (0, guards_1.AuthTenantOwner)({ bypassTenantAccessGate: true })),
207
+ __param(1, (0, interface_api_1.Parameter)(tenant_plan_checkout_recovery_1.CHECKOUT_OPERATION_PARAM, "query")),
208
+ __param(2, (0, interface_api_1.Context)()),
209
+ __param(3, (0, tenant_scoped_model_1.TenantScopedModel)(db_2.TenantSubscriptionModel)),
210
+ __metadata("design:type", Function),
211
+ __metadata("design:paramtypes", [Function, Object, Object, db_2.TenantSubscriptionModel]),
212
+ __metadata("design:returntype", Promise)
213
+ ], SaasTenantPlanController.prototype, "cancelCheckout", null);
187
214
  __decorate([
188
215
  (0, interface_api_1.Put)("/"),
189
216
  __param(0, (0, guards_1.AuthTenantOwner)({ bypassTenantAccessGate: true })),
@@ -1 +1 @@
1
- {"version":3,"file":"tenant-plan.js","sourceRoot":"","sources":["../../../src/routes/tenant/tenant-plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tenant-plan.js","sourceRoot":"","sources":["../../../src/routes/tenant/tenant-plan.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,7 @@ const complimentary_1 = require("../workspaces/complimentary");
12
12
  const client_1 = require("./client");
13
13
  const payload_shapes_1 = require("./payload-shapes");
14
14
  const webhook_shared_1 = require("./webhook-shared");
15
+ const workspace_checkout_1 = require("./workspace-checkout");
15
16
  async function promoteSubscriptionPaymentMethod(subscription) {
16
17
  const customerId = (0, webhook_shared_1.asCustomerId)(subscription.customer);
17
18
  const paymentMethodId = typeof subscription.default_payment_method === "string"
@@ -134,6 +135,7 @@ async function handleCheckoutSessionExpired(event) {
134
135
  });
135
136
  if (outcome !== "applied")
136
137
  throw new Error(`Checkout expiration ${outcome}; reconciliation required`);
138
+ await (0, workspace_checkout_1.releaseCheckoutTrialReservation)(session, tenantId);
137
139
  }
138
140
  async function recordCheckoutTrialConsumption(session, createdBy, planId) {
139
141
  const email = session.customer_details?.email;
@@ -1 +1 @@
1
- {"version":3,"file":"webhook-checkout.js","sourceRoot":"","sources":["../../src/stripe/webhook-checkout.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webhook-checkout.js","sourceRoot":"","sources":["../../src/stripe/webhook-checkout.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,6 @@
1
+ import Stripe from "stripe";
2
+ export declare const CHECKOUT_SESSION_LIFETIME_MS: number;
3
+ export declare const TRIAL_IDENTITY_METADATA_KEY = "trialIdentityId";
1
4
  export interface WorkspaceCheckoutSessionInput {
2
5
  operationId?: string;
3
6
  tenantId: string;
@@ -8,6 +11,7 @@ export interface WorkspaceCheckoutSessionInput {
8
11
  cancelUrl: string;
9
12
  planId?: string;
10
13
  existingCustomerId?: string;
14
+ reservedTrialIdentityId?: string | null;
11
15
  }
12
16
  export interface WorkspaceCheckoutSession {
13
17
  sessionId: string;
@@ -27,4 +31,5 @@ export interface TenantCheckoutCustomerInput {
27
31
  export declare function createTenantCheckoutCustomer(input: TenantCheckoutCustomerInput): Promise<string>;
28
32
  export declare function isDefinitiveStripeRejection(error: unknown): boolean;
29
33
  export declare function deleteStripeCustomerIfExists(customerId: string): Promise<void>;
34
+ export declare function releaseCheckoutTrialReservation(session: Stripe.Checkout.Session, tenantId: string): Promise<void>;
30
35
  export declare function createWorkspaceCheckoutSession(input: WorkspaceCheckoutSessionInput): Promise<WorkspaceCheckoutSession>;
@@ -3,19 +3,27 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.UnusableCheckoutSessionError = void 0;
6
+ exports.UnusableCheckoutSessionError = exports.TRIAL_IDENTITY_METADATA_KEY = exports.CHECKOUT_SESSION_LIFETIME_MS = void 0;
7
7
  exports.createTenantCheckoutCustomer = createTenantCheckoutCustomer;
8
8
  exports.isDefinitiveStripeRejection = isDefinitiveStripeRejection;
9
9
  exports.deleteStripeCustomerIfExists = deleteStripeCustomerIfExists;
10
+ exports.releaseCheckoutTrialReservation = releaseCheckoutTrialReservation;
10
11
  exports.createWorkspaceCheckoutSession = createWorkspaceCheckoutSession;
11
12
  const logging_1 = require("@antelopejs/interface-core/logging");
12
13
  const stripe_1 = __importDefault(require("stripe"));
14
+ const interface_database_decorators_1 = require("@antelopejs/interface-database-decorators");
15
+ const trial_identity_model_1 = require("../workspaces/db/trial-identity.model");
13
16
  const client_1 = require("./client");
14
17
  const MISSING_RESOURCE_CODE = "resource_missing";
15
18
  const HTTP_CLIENT_ERROR_MIN = 400;
16
19
  const HTTP_SERVER_ERROR_MIN = 500;
17
20
  const MANAGED_PAYMENTS_PARAM = "managed_payments";
18
21
  const LOG_PREFIX = "[dms-saas:checkout]";
22
+ const MS_PER_SECOND = 1000;
23
+ const MS_PER_MINUTE = 60 * MS_PER_SECOND;
24
+ exports.CHECKOUT_SESSION_LIFETIME_MS = 30 * MS_PER_MINUTE;
25
+ const CHECKOUT_EXPIRY_MARGIN_MS = MS_PER_MINUTE;
26
+ exports.TRIAL_IDENTITY_METADATA_KEY = "trialIdentityId";
19
27
  const MANAGED_PAYMENTS_OPT_OUT = { enabled: false };
20
28
  class UnusableCheckoutSessionError extends Error {
21
29
  sessionId;
@@ -74,6 +82,18 @@ async function resolveCheckoutCustomerId(input) {
74
82
  ownerEmail: input.ownerEmail,
75
83
  });
76
84
  }
85
+ function checkoutSessionExpiry() {
86
+ const expiresAt = Date.now() + exports.CHECKOUT_SESSION_LIFETIME_MS + CHECKOUT_EXPIRY_MARGIN_MS;
87
+ return Math.floor(expiresAt / MS_PER_SECOND);
88
+ }
89
+ async function releaseCheckoutTrialReservation(session, tenantId) {
90
+ const identityId = session.metadata?.[exports.TRIAL_IDENTITY_METADATA_KEY];
91
+ if (!identityId)
92
+ return;
93
+ await (0, interface_database_decorators_1.GetModel)(trial_identity_model_1.TrialIdentityModel)
94
+ .releaseUnused(identityId, tenantId)
95
+ .catch((error) => logging_1.Logging.Warn(`${LOG_PREFIX} failed to release the trial reserved by checkout session ${session.id}`, error));
96
+ }
77
97
  function buildCheckoutSubscriptionData(metadata, trialDays) {
78
98
  const subscriptionData = {
79
99
  metadata,
@@ -107,6 +127,9 @@ async function createWorkspaceCheckoutSession(input) {
107
127
  sessionMetadata.planId = input.planId;
108
128
  if (input.operationId)
109
129
  sessionMetadata.operationId = input.operationId;
130
+ if (input.reservedTrialIdentityId)
131
+ sessionMetadata[exports.TRIAL_IDENTITY_METADATA_KEY] =
132
+ input.reservedTrialIdentityId;
110
133
  const session = await createSessionOptingOutOfManagedPayments({
111
134
  mode: "subscription",
112
135
  customer: customerId,
@@ -119,6 +142,7 @@ async function createWorkspaceCheckoutSession(input) {
119
142
  tax_id_collection: { enabled: true },
120
143
  billing_address_collection: "required",
121
144
  customer_update: { address: "auto", name: "auto" },
145
+ expires_at: checkoutSessionExpiry(),
122
146
  }, input.operationId
123
147
  ? { idempotencyKey: `checkout-session:${input.operationId}` }
124
148
  : undefined);
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-checkout.js","sourceRoot":"","sources":["../../src/stripe/workspace-checkout.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workspace-checkout.js","sourceRoot":"","sources":["../../src/stripe/workspace-checkout.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ <script setup lang="ts">
2
+ import { computed, ref } from "vue";
3
+
4
+ const KEY_PREFIX = "saas.workspace.plan.checkout_pending";
5
+
6
+ const toast = useToast();
7
+ const { resolveApiError } = useApiErrorMessage();
8
+ const { prompt, resume, startOver } = usePendingCheckout();
9
+
10
+ const isRestarting = ref(false);
11
+
12
+ const open = computed({
13
+ get: () => prompt.value !== null,
14
+ set: (isOpen: boolean) => {
15
+ if (!isOpen) prompt.value = null;
16
+ },
17
+ });
18
+
19
+ const pending = computed(() => prompt.value?.pending ?? null);
20
+ const canResume = computed(() => !!pending.value?.checkoutUrl);
21
+
22
+ /** A paid checkout only waits for Stripe; one still opening only for time. */
23
+ const descriptionKey = computed(() => {
24
+ if (pending.value?.isPaid) return `${KEY_PREFIX}.description_paid`;
25
+ return canResume.value
26
+ ? `${KEY_PREFIX}.description`
27
+ : `${KEY_PREFIX}.description_opening`;
28
+ });
29
+
30
+ async function restart(): Promise<void> {
31
+ isRestarting.value = true;
32
+ try {
33
+ await startOver();
34
+ } catch (error) {
35
+ toast.add({
36
+ title: resolveApiError(error, `${KEY_PREFIX}.restart_error`),
37
+ color: "error",
38
+ icon: "i-ph-warning-circle",
39
+ });
40
+ isRestarting.value = false;
41
+ }
42
+ }
43
+ </script>
44
+
45
+ <template>
46
+ <UModal
47
+ v-model:open="open"
48
+ :title="$t(`${KEY_PREFIX}.title`)"
49
+ :description="$t(descriptionKey)"
50
+ >
51
+ <template #footer>
52
+ <div class="flex w-full flex-wrap justify-end gap-2">
53
+ <UButton color="neutral" variant="subtle" @click="open = false">
54
+ {{ $t(`${KEY_PREFIX}.close`) }}
55
+ </UButton>
56
+ <UButton
57
+ v-if="canResume"
58
+ color="neutral"
59
+ variant="outline"
60
+ icon="i-ph-arrow-counter-clockwise"
61
+ :loading="isRestarting"
62
+ @click="restart"
63
+ >
64
+ {{ $t(`${KEY_PREFIX}.restart`) }}
65
+ </UButton>
66
+ <UButton
67
+ v-if="canResume"
68
+ color="primary"
69
+ icon="i-ph-lock-simple"
70
+ :disabled="isRestarting"
71
+ @click="resume"
72
+ >
73
+ {{ $t(`${KEY_PREFIX}.resume`) }}
74
+ </UButton>
75
+ </div>
76
+ </template>
77
+ </UModal>
78
+ </template>
@@ -20,6 +20,7 @@ const { t } = useI18n();
20
20
  const toast = useToast();
21
21
  const { resolveApiError } = useApiErrorMessage();
22
22
  const { changePlan } = useTenantPlan();
23
+ const { offerFor: offerPendingCheckout } = usePendingCheckout();
23
24
  const { formatFeatureValue } = usePlanFeatureFormat();
24
25
  const { featureLabel, featureTooltip } = usePlanFeatureLabel();
25
26
  const { formatMajorUnits } = useMoneyFormat();
@@ -102,6 +103,10 @@ async function select(plan: TenantPlanView): Promise<void> {
102
103
  open.value = false;
103
104
  emit("changed");
104
105
  } catch (error) {
106
+ if (await offerPendingCheckout(error, plan._id)) {
107
+ open.value = false;
108
+ return;
109
+ }
105
110
  toast.add({
106
111
  title: resolveApiError(error, "saas.workspace.plan.change_error"),
107
112
  color: "error",
@@ -16,6 +16,7 @@ const { t } = useI18n();
16
16
  const { resolveApiError } = useApiErrorMessage();
17
17
  const identity = useBillingIdentity();
18
18
  const { changePlan } = useTenantPlan();
19
+ const { offerFor: offerPendingCheckout } = usePendingCheckout();
19
20
  const { formatMajorUnits } = useMoneyFormat();
20
21
  const planIntervalLabel = usePlanIntervalLabel("saas.workspace.plan.interval");
21
22
 
@@ -87,6 +88,10 @@ async function confirm(): Promise<void> {
87
88
  open.value = false;
88
89
  emit("changed");
89
90
  } catch (error) {
91
+ if (await offerPendingCheckout(error, plan._id)) {
92
+ open.value = false;
93
+ return;
94
+ }
90
95
  notifyError(resolveApiError(error, "saas.workspace.plan.change_error"));
91
96
  } finally {
92
97
  isSubmitting.value = false;
@@ -25,6 +25,7 @@ const { featureLabel } = usePlanFeatureLabel();
25
25
  const planDescription = usePlanDescription();
26
26
  const { workspace, load: loadWorkspace } = useCurrentWorkspace();
27
27
  const { isOpen: isComparisonOpen } = usePlanComparison();
28
+ const { consumeCancelledCheckout } = usePendingCheckout();
28
29
  const planIntervalLabel = usePlanIntervalLabel("saas.workspace.plan.interval");
29
30
 
30
31
  const data = ref<TenantPlanResponse | null>(null);
@@ -164,8 +165,32 @@ async function loadWorkspaceForOwner(): Promise<void> {
164
165
  if (status?.isTenantOwner) await loadWorkspace().catch(() => undefined);
165
166
  }
166
167
 
167
- onMounted(() => {
168
+ /** Back from Stripe's cancel link: the checkout left behind is released
169
+ * before the card loads, so the plan buttons work straight away. */
170
+ async function releaseCancelledCheckout(): Promise<void> {
171
+ try {
172
+ const { released } = await consumeCancelledCheckout();
173
+ if (!released) return;
174
+ toast.add({
175
+ title: t("saas.workspace.plan.checkout_pending.cancelled"),
176
+ color: "info",
177
+ icon: "i-ph-info",
178
+ });
179
+ } catch (error) {
180
+ toast.add({
181
+ title: resolveApiError(
182
+ error,
183
+ "saas.workspace.plan.checkout_pending.restart_error",
184
+ ),
185
+ color: "error",
186
+ icon: "i-ph-warning-circle",
187
+ });
188
+ }
189
+ }
190
+
191
+ onMounted(async () => {
168
192
  void loadWorkspaceForOwner();
193
+ await releaseCancelledCheckout();
169
194
  return fetchPlan(false);
170
195
  });
171
196
  </script>
@@ -279,6 +304,7 @@ onMounted(() => {
279
304
  :plan="upgradeTarget"
280
305
  @changed="refresh"
281
306
  />
307
+ <DmsSaasPendingCheckoutModal />
282
308
  </div>
283
309
  </UCard>
284
310
  </template>
@@ -39,6 +39,7 @@ const planIntervalLabel = usePlanIntervalLabel(
39
39
  );
40
40
  const planDescription = usePlanDescription();
41
41
  const config = useDmsRuntimeConfig();
42
+ const { user } = useCurrentUser();
42
43
 
43
44
  const stripePublishableKey = computed<string>(
44
45
  () => (config.public.dmsSaas as any)?.stripePublishableKey ?? "",
@@ -121,6 +122,7 @@ async function initStripeElement(): Promise<void> {
121
122
  publishableKey: stripePublishableKey.value,
122
123
  clientSecret: setup.clientSecret,
123
124
  containerId: PAYMENT_ELEMENT_ID,
125
+ billingEmail: () => user.value?.email ?? "",
124
126
  });
125
127
  }
126
128
 
@@ -1,3 +1,11 @@
1
+ /** The i18n key the server answered a failed `$authFetch` with, if any. */
2
+ export function readApiErrorKey(error: unknown): string | undefined {
3
+ const data = (error as { data?: unknown } | undefined)?.data;
4
+ if (typeof data === "string") return data;
5
+ const message = (data as { message?: unknown } | undefined)?.message;
6
+ return typeof message === "string" ? message : undefined;
7
+ }
8
+
1
9
  /**
2
10
  * Resolves an unknown error thrown by `$authFetch` into a human-readable,
3
11
  * translated message.
@@ -12,17 +20,10 @@
12
20
  export function useApiErrorMessage() {
13
21
  const nuxtApp = useDmsApp();
14
22
 
15
- function extractServerKey(error: unknown): string | undefined {
16
- const data = (error as { data?: unknown } | undefined)?.data;
17
- if (typeof data === "string") return data;
18
- const message = (data as { message?: unknown } | undefined)?.message;
19
- return typeof message === "string" ? message : undefined;
20
- }
21
-
22
23
  /** Translated server message, or `undefined` when the server sent no usable key. */
23
24
  function resolveServerMessage(error: unknown): string | undefined {
24
25
  const { t, te } = nuxtApp.$i18n;
25
- const key = extractServerKey(error);
26
+ const key = readApiErrorKey(error);
26
27
  return key && te(key) ? t(key) : undefined;
27
28
  }
28
29
 
@@ -0,0 +1,88 @@
1
+ const CHECKOUT_IN_PROGRESS_KEY = "saas.errors.plan.checkout_in_progress";
2
+ const PROMPT_STATE_KEY = "saas-pending-checkout-prompt";
3
+ const CHECKOUT_CANCELLED_PARAM = "checkout";
4
+ const CHECKOUT_CANCELLED_VALUE = "cancelled";
5
+
6
+ /** A plan change refused because an earlier checkout is still pending. */
7
+ export interface PendingCheckoutPrompt {
8
+ /** The plan the owner just chose, which starting over checks out. */
9
+ planId: string;
10
+ pending: PendingCheckout | null;
11
+ }
12
+
13
+ export function isCheckoutInProgressError(error: unknown): boolean {
14
+ return readApiErrorKey(error) === CHECKOUT_IN_PROGRESS_KEY;
15
+ }
16
+
17
+ /**
18
+ * The owner's way out of a checkout they left unpaid: resume it, or give it
19
+ * up and start over. The prompt state is shared so the plan modals can raise
20
+ * it and the plan card, which outlives them, can host it.
21
+ */
22
+ export function usePendingCheckout() {
23
+ const prompt = useDmsState<PendingCheckoutPrompt | null>(
24
+ PROMPT_STATE_KEY,
25
+ () => null,
26
+ );
27
+ const route = useDmsRoute();
28
+ const router = useDmsRouter();
29
+ const { loadPendingCheckout, cancelCheckout, changePlan } = useTenantPlan();
30
+
31
+ /** Raises the prompt when `error` is a pending-checkout refusal. */
32
+ async function offerFor(error: unknown, planId: string): Promise<boolean> {
33
+ if (!isCheckoutInProgressError(error)) return false;
34
+ const { pending } = await loadPendingCheckout().catch(() => ({
35
+ pending: null,
36
+ }));
37
+ prompt.value = { planId, pending };
38
+ return true;
39
+ }
40
+
41
+ function resume(): void {
42
+ const url = prompt.value?.pending?.checkoutUrl;
43
+ if (url && typeof window !== "undefined") window.location.href = url;
44
+ }
45
+
46
+ /** Gives up the pending checkout, then opens one for the chosen plan. */
47
+ async function startOver(): Promise<void> {
48
+ const planId = prompt.value?.planId;
49
+ if (!planId) return;
50
+ await cancelCheckout();
51
+ const result = await changePlan(planId);
52
+ if (result.checkoutUrl && typeof window !== "undefined") {
53
+ window.location.href = result.checkoutUrl;
54
+ }
55
+ }
56
+
57
+ /** The operation named by the Stripe cancel link the page was opened from. */
58
+ function cancelledOperationId(): string | null {
59
+ const { query } = route;
60
+ const operationId = query[CHECKOUT_OPERATION_PARAM];
61
+ if (query[CHECKOUT_CANCELLED_PARAM] !== CHECKOUT_CANCELLED_VALUE) {
62
+ return null;
63
+ }
64
+ return typeof operationId === "string" && operationId ? operationId : null;
65
+ }
66
+
67
+ /**
68
+ * Stripe's cancel link lands back on the billing page naming the checkout
69
+ * the owner walked out of; releasing it here lets them choose again at
70
+ * once. The marker is dropped either way, so a reload does not replay it.
71
+ */
72
+ async function consumeCancelledCheckout(): Promise<CancelCheckoutResult> {
73
+ const operationId = cancelledOperationId();
74
+ if (!operationId) return { released: false };
75
+ const {
76
+ [CHECKOUT_CANCELLED_PARAM]: _cancelled,
77
+ [CHECKOUT_OPERATION_PARAM]: _operation,
78
+ ...query
79
+ } = route.query;
80
+ try {
81
+ return await cancelCheckout(operationId);
82
+ } finally {
83
+ await router.replace({ query });
84
+ }
85
+ }
86
+
87
+ return { prompt, offerFor, resume, startOver, consumeCancelledCheckout };
88
+ }
@@ -293,6 +293,7 @@ export function useSaasRegistration(options: UseSaasRegistrationOptions = {}) {
293
293
  publishableKey,
294
294
  clientSecret: setup.clientSecret,
295
295
  containerId: paymentElementId,
296
+ billingEmail: () => form.email,
296
297
  });
297
298
  }
298
299
 
@@ -1,14 +1,55 @@
1
- import { onUnmounted } from "vue";
1
+ import { type MaybeRefOrGetter, onUnmounted, toValue } from "vue";
2
2
 
3
3
  interface UseStripePaymentElementOptions {
4
4
  publishableKey: string;
5
5
  clientSecret: string;
6
6
  containerId: string;
7
+ /**
8
+ * The payer's email, sent with the card: the Payment Element does not ask
9
+ * for it, since every caller already knows who is paying. Read at confirm
10
+ * time, so a form field may be passed as a getter.
11
+ */
12
+ billingEmail: MaybeRefOrGetter<string>;
13
+ }
14
+
15
+ interface ConfirmError {
16
+ message: string;
7
17
  }
8
18
 
9
19
  interface ConfirmResult {
10
20
  paymentMethodId?: string;
11
- error?: { message: string };
21
+ error?: ConfirmError;
22
+ }
23
+
24
+ interface SetupIntentSnapshot {
25
+ payment_method?: unknown;
26
+ }
27
+
28
+ interface StripeErrorSnapshot {
29
+ message?: string;
30
+ }
31
+
32
+ interface SetupIntentResult {
33
+ setupIntent?: SetupIntentSnapshot;
34
+ error?: StripeErrorSnapshot;
35
+ }
36
+
37
+ interface BillingDetails {
38
+ email: string;
39
+ }
40
+
41
+ interface PaymentMethodData {
42
+ billing_details: BillingDetails;
43
+ }
44
+
45
+ interface SetupConfirmParams {
46
+ payment_method_data: PaymentMethodData;
47
+ }
48
+
49
+ interface SetupConfirmation {
50
+ elements: unknown;
51
+ redirect: "if_required";
52
+ confirmParams: SetupConfirmParams;
12
53
  }
13
54
 
14
55
  interface StripePaymentElementHandle {
@@ -19,6 +60,43 @@ interface StripePaymentElementHandle {
19
60
  // rejects `paymentMethodTypes` next to a `clientSecret`, since it only applies
20
61
  // to an Elements instance created in deferred-intent `mode`.
21
62
  const ALLOWED_CARD_BRANDS = ["visa", "mastercard"];
63
+ const UNKNOWN_STRIPE_ERROR = "Stripe could not confirm the card";
64
+
65
+ /**
66
+ * The `confirmSetup` parameters. The element hides the email field, and
67
+ * Stripe then refuses any confirmation that does not carry the email itself.
68
+ */
69
+ export function buildSetupConfirmation(
70
+ elements: unknown,
71
+ email: string,
72
+ ): SetupConfirmation {
73
+ return {
74
+ elements,
75
+ redirect: "if_required",
76
+ confirmParams: {
77
+ payment_method_data: { billing_details: { email } },
78
+ },
79
+ };
80
+ }
81
+
82
+ /** Maps a `confirmSetup` outcome to the confirmed card, or Stripe's reason. */
83
+ export function toConfirmResult(result: SetupIntentResult): ConfirmResult {
84
+ if (result.error) {
85
+ return { error: { message: result.error.message ?? UNKNOWN_STRIPE_ERROR } };
86
+ }
87
+ const paymentMethodId = result.setupIntent?.payment_method;
88
+ if (typeof paymentMethodId !== "string") {
89
+ return { error: { message: "No payment method returned" } };
90
+ }
91
+ return { paymentMethodId };
92
+ }
93
+
94
+ // Stripe.js throws, rather than returns, integration errors: without this
95
+ // the caller only sees its own generic failure and the cause is lost.
96
+ function toThrownConfirmResult(error: unknown): ConfirmResult {
97
+ const message = error instanceof Error ? error.message : "";
98
+ return { error: { message: message || UNKNOWN_STRIPE_ERROR } };
99
+ }
22
100
 
23
101
  export function useStripePaymentElement(
24
102
  options: UseStripePaymentElementOptions,
@@ -49,18 +127,17 @@ export function useStripePaymentElement(
49
127
  if (!stripeInstance || !elementsInstance) {
50
128
  return { error: { message: "Stripe not initialized" } };
51
129
  }
52
- const result = await stripeInstance.confirmSetup({
53
- elements: elementsInstance,
54
- redirect: "if_required",
55
- });
56
- if (result.error) {
57
- return { error: { message: result.error.message } };
58
- }
59
- const paymentMethodId = result.setupIntent?.payment_method;
60
- if (typeof paymentMethodId !== "string") {
61
- return { error: { message: "No payment method returned" } };
130
+ try {
131
+ const result: SetupIntentResult = await stripeInstance.confirmSetup(
132
+ buildSetupConfirmation(
133
+ elementsInstance,
134
+ toValue(options.billingEmail),
135
+ ),
136
+ );
137
+ return toConfirmResult(result);
138
+ } catch (error) {
139
+ return toThrownConfirmResult(error);
62
140
  }
63
- return { paymentMethodId };
64
141
  }
65
142
 
66
143
  onUnmounted(() => {
@@ -2,6 +2,10 @@ import type { PlanInterval } from "./usePlanIntervalLabel";
2
2
 
3
3
  const TENANT_PLAN_ENDPOINT = "/api/saas/tenant/plan";
4
4
  const TENANT_PLAN_STATE_KEY = "saas-tenant-plan";
5
+ const TENANT_CHECKOUT_ENDPOINT = `${TENANT_PLAN_ENDPOINT}/checkout`;
6
+
7
+ /** Query parameter naming the checkout a Stripe cancel link belongs to. */
8
+ export const CHECKOUT_OPERATION_PARAM = "checkoutOperation";
5
9
 
6
10
  export interface TenantPlanFeature {
7
11
  featureId: string;
@@ -68,6 +72,24 @@ export interface ChangePlanResult {
68
72
  checkoutUrl: string | null;
69
73
  }
70
74
 
75
+ /** The Stripe Checkout a workspace is waiting on. */
76
+ export interface PendingCheckout {
77
+ targetPlanId: string | null;
78
+ /** Where the owner resumes paying; null once nothing is left to pay. */
79
+ checkoutUrl: string | null;
80
+ expiresAt: string | null;
81
+ /** Paid, and waiting for Stripe to confirm it. */
82
+ isPaid: boolean;
83
+ }
84
+
85
+ export interface PendingCheckoutResult {
86
+ pending: PendingCheckout | null;
87
+ }
88
+
89
+ export interface CancelCheckoutResult {
90
+ released: boolean;
91
+ }
92
+
71
93
  /** The payload resolves inheritance for every public plan and carries the
72
94
  * features catalogue, so the plan card and the free-access banner share it. */
73
95
  export function useTenantPlan() {
@@ -91,5 +113,23 @@ export function useTenantPlan() {
91
113
  });
92
114
  }
93
115
 
94
- return { ...shared, changePlan, cancelPendingChange };
116
+ function loadPendingCheckout(): Promise<PendingCheckoutResult> {
117
+ return $authFetch<PendingCheckoutResult>(TENANT_CHECKOUT_ENDPOINT);
118
+ }
119
+
120
+ /** Without an operation id, gives up on whatever checkout is pending. */
121
+ function cancelCheckout(operationId?: string): Promise<CancelCheckoutResult> {
122
+ return $authFetch<CancelCheckoutResult>(TENANT_CHECKOUT_ENDPOINT, {
123
+ method: "DELETE",
124
+ query: operationId ? { [CHECKOUT_OPERATION_PARAM]: operationId } : {},
125
+ });
126
+ }
127
+
128
+ return {
129
+ ...shared,
130
+ changePlan,
131
+ cancelPendingChange,
132
+ loadPendingCheckout,
133
+ cancelCheckout,
134
+ };
95
135
  }
@@ -130,6 +130,7 @@ async function initStripeElement(): Promise<void> {
130
130
  publishableKey,
131
131
  clientSecret: setup.clientSecret,
132
132
  containerId: PAYMENT_ELEMENT_ID,
133
+ billingEmail: () => pendingRegistration.value?.email ?? "",
133
134
  });
134
135
  }
135
136
 
@@ -45,6 +45,7 @@
45
45
  "unpaid_invoice_blocks_downgrade": "An invoice is unpaid. Settle it before changing to a cheaper plan.",
46
46
  "no_free_plan": "No free plan is available for sign-up right now.",
47
47
  "checkout_in_progress": "A payment for a plan change is already open. Complete it, or wait for it to expire, before choosing another plan.",
48
+ "checkout_already_paid": "This payment has already been made and is being confirmed. Your plan will update in a moment.",
48
49
  "change_in_progress": "A plan change is already being processed. Try again in a few minutes."
49
50
  },
50
51
  "workspace": {
@@ -1081,6 +1082,17 @@
1081
1082
  "change_applied": "Plan changed.",
1082
1083
  "change_scheduled": "Downgrade scheduled for the end of the current cycle.",
1083
1084
  "change_error": "Failed to change plan",
1085
+ "checkout_pending": {
1086
+ "title": "A payment is already open",
1087
+ "description": "You opened the secure Stripe payment page without completing it. Resume that payment, or cancel it and start over.",
1088
+ "description_paid": "Your payment has been received and is being confirmed. Your plan will update in a moment.",
1089
+ "description_opening": "A payment page is still being opened for this workspace. Try again in a few minutes.",
1090
+ "resume": "Resume payment",
1091
+ "restart": "Cancel and start over",
1092
+ "close": "Close",
1093
+ "cancelled": "Payment cancelled. Nothing was charged and your plan is unchanged.",
1094
+ "restart_error": "The pending payment could not be cancelled. Try again in a moment."
1095
+ },
1084
1096
  "interval": {
1085
1097
  "month": "month",
1086
1098
  "year": "year"
@@ -45,6 +45,7 @@
45
45
  "unpaid_invoice_blocks_downgrade": "Une facture est impayée. Réglez-la avant de passer à un plan moins cher.",
46
46
  "no_free_plan": "Aucun plan gratuit n'est disponible pour l'inscription pour le moment.",
47
47
  "checkout_in_progress": "Un paiement de changement de plan est déjà ouvert. Terminez-le, ou attendez son expiration, avant de choisir un autre plan.",
48
+ "checkout_already_paid": "Ce paiement a déjà été effectué et est en cours de confirmation. Votre plan sera mis à jour dans un instant.",
48
49
  "change_in_progress": "Un changement de plan est déjà en cours. Réessayez dans quelques minutes."
49
50
  },
50
51
  "workspace": {
@@ -1081,6 +1082,17 @@
1081
1082
  "change_applied": "Plan modifié.",
1082
1083
  "change_scheduled": "Downgrade programmé pour la fin du cycle en cours.",
1083
1084
  "change_error": "Échec du changement de plan",
1085
+ "checkout_pending": {
1086
+ "title": "Un paiement est déjà en cours",
1087
+ "description": "Vous avez ouvert la page de paiement sécurisée de Stripe sans la terminer. Reprenez ce paiement, ou annulez-le pour recommencer.",
1088
+ "description_paid": "Votre paiement a été reçu et est en cours de confirmation. Votre plan sera mis à jour dans un instant.",
1089
+ "description_opening": "Une page de paiement est encore en cours d'ouverture pour cet espace de travail. Réessayez dans quelques minutes.",
1090
+ "resume": "Reprendre le paiement",
1091
+ "restart": "Annuler et recommencer",
1092
+ "close": "Fermer",
1093
+ "cancelled": "Paiement annulé. Rien n'a été débité et votre plan est inchangé.",
1094
+ "restart_error": "Le paiement en cours n'a pas pu être annulé. Réessayez dans un instant."
1095
+ },
1084
1096
  "interval": {
1085
1097
  "month": "mois",
1086
1098
  "year": "an"
@@ -5,6 +5,9 @@
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
7
7
  "packageManager": "pnpm@10.6.5",
8
+ "engines": {
9
+ "@antelopejs/dms-frontend": ">=0.3.1 <0.4.0"
10
+ },
8
11
  "scripts": {
9
12
  "format": "prettier --write .",
10
13
  "lint": "eslint .",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antelopejs/dms-saas",
3
- "version": "0.3.9",
3
+ "version": "0.3.10",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",