@rovela-ai/sdk 0.6.1 → 0.7.1

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 (127) hide show
  1. package/dist/admin/api/discounts.d.ts +53 -0
  2. package/dist/admin/api/discounts.d.ts.map +1 -0
  3. package/dist/admin/api/discounts.js +339 -0
  4. package/dist/admin/api/discounts.js.map +1 -0
  5. package/dist/admin/api/index.d.ts +1 -0
  6. package/dist/admin/api/index.d.ts.map +1 -1
  7. package/dist/admin/api/index.js +2 -0
  8. package/dist/admin/api/index.js.map +1 -1
  9. package/dist/admin/api/orders.js +1 -1
  10. package/dist/admin/api/orders.js.map +1 -1
  11. package/dist/admin/api/settings.d.ts.map +1 -1
  12. package/dist/admin/api/settings.js +10 -0
  13. package/dist/admin/api/settings.js.map +1 -1
  14. package/dist/admin/components/CustomerAddressPanel.d.ts.map +1 -1
  15. package/dist/admin/components/CustomerAddressPanel.js +13 -6
  16. package/dist/admin/components/CustomerAddressPanel.js.map +1 -1
  17. package/dist/admin/components/DiscountsManager.d.ts +5 -0
  18. package/dist/admin/components/DiscountsManager.d.ts.map +1 -0
  19. package/dist/admin/components/DiscountsManager.js +363 -0
  20. package/dist/admin/components/DiscountsManager.js.map +1 -0
  21. package/dist/admin/components/ShippingSettings.d.ts.map +1 -1
  22. package/dist/admin/components/ShippingSettings.js +19 -2
  23. package/dist/admin/components/ShippingSettings.js.map +1 -1
  24. package/dist/admin/components/StoreSettings.d.ts.map +1 -1
  25. package/dist/admin/components/StoreSettings.js +8 -1
  26. package/dist/admin/components/StoreSettings.js.map +1 -1
  27. package/dist/admin/components/TaxSettings.d.ts.map +1 -1
  28. package/dist/admin/components/TaxSettings.js +8 -3
  29. package/dist/admin/components/TaxSettings.js.map +1 -1
  30. package/dist/admin/components/index.d.ts +2 -0
  31. package/dist/admin/components/index.d.ts.map +1 -1
  32. package/dist/admin/components/index.js +1 -0
  33. package/dist/admin/components/index.js.map +1 -1
  34. package/dist/admin/hooks/index.d.ts +2 -0
  35. package/dist/admin/hooks/index.d.ts.map +1 -1
  36. package/dist/admin/hooks/index.js +1 -0
  37. package/dist/admin/hooks/index.js.map +1 -1
  38. package/dist/admin/hooks/useAdminDiscounts.d.ts +12 -0
  39. package/dist/admin/hooks/useAdminDiscounts.d.ts.map +1 -0
  40. package/dist/admin/hooks/useAdminDiscounts.js +77 -0
  41. package/dist/admin/hooks/useAdminDiscounts.js.map +1 -0
  42. package/dist/admin/index.d.ts +3 -3
  43. package/dist/admin/index.d.ts.map +1 -1
  44. package/dist/admin/index.js +2 -2
  45. package/dist/admin/index.js.map +1 -1
  46. package/dist/admin/types.d.ts +72 -0
  47. package/dist/admin/types.d.ts.map +1 -1
  48. package/dist/auth/components/AddressForm.d.ts.map +1 -1
  49. package/dist/auth/components/AddressForm.js +22 -7
  50. package/dist/auth/components/AddressForm.js.map +1 -1
  51. package/dist/checkout/api/checkout.d.ts.map +1 -1
  52. package/dist/checkout/api/checkout.js +15 -2
  53. package/dist/checkout/api/checkout.js.map +1 -1
  54. package/dist/checkout/api/discount.d.ts +47 -0
  55. package/dist/checkout/api/discount.d.ts.map +1 -0
  56. package/dist/checkout/api/discount.js +77 -0
  57. package/dist/checkout/api/discount.js.map +1 -0
  58. package/dist/checkout/api/index.d.ts +1 -0
  59. package/dist/checkout/api/index.d.ts.map +1 -1
  60. package/dist/checkout/api/index.js +1 -0
  61. package/dist/checkout/api/index.js.map +1 -1
  62. package/dist/checkout/api/manual.d.ts.map +1 -1
  63. package/dist/checkout/api/manual.js +73 -135
  64. package/dist/checkout/api/manual.js.map +1 -1
  65. package/dist/checkout/api/shipping.d.ts.map +1 -1
  66. package/dist/checkout/api/shipping.js +19 -27
  67. package/dist/checkout/api/shipping.js.map +1 -1
  68. package/dist/checkout/components/CheckoutFlow.d.ts.map +1 -1
  69. package/dist/checkout/components/CheckoutFlow.js +89 -9
  70. package/dist/checkout/components/CheckoutFlow.js.map +1 -1
  71. package/dist/checkout/components/OrderSummary.d.ts +1 -1
  72. package/dist/checkout/components/OrderSummary.d.ts.map +1 -1
  73. package/dist/checkout/components/OrderSummary.js +3 -3
  74. package/dist/checkout/components/OrderSummary.js.map +1 -1
  75. package/dist/checkout/components/ShippingForm.d.ts.map +1 -1
  76. package/dist/checkout/components/ShippingForm.js +42 -13
  77. package/dist/checkout/components/ShippingForm.js.map +1 -1
  78. package/dist/checkout/constants.d.ts +38 -0
  79. package/dist/checkout/constants.d.ts.map +1 -1
  80. package/dist/checkout/constants.js +39 -0
  81. package/dist/checkout/constants.js.map +1 -1
  82. package/dist/checkout/hooks/useCheckout.d.ts.map +1 -1
  83. package/dist/checkout/hooks/useCheckout.js +2 -0
  84. package/dist/checkout/hooks/useCheckout.js.map +1 -1
  85. package/dist/checkout/server/checkout-customer.d.ts +30 -0
  86. package/dist/checkout/server/checkout-customer.d.ts.map +1 -0
  87. package/dist/checkout/server/checkout-customer.js +47 -0
  88. package/dist/checkout/server/checkout-customer.js.map +1 -0
  89. package/dist/checkout/server/create-checkout-session.d.ts.map +1 -1
  90. package/dist/checkout/server/create-checkout-session.js +149 -9
  91. package/dist/checkout/server/create-checkout-session.js.map +1 -1
  92. package/dist/checkout/server/discounts.d.ts +75 -0
  93. package/dist/checkout/server/discounts.d.ts.map +1 -0
  94. package/dist/checkout/server/discounts.js +294 -0
  95. package/dist/checkout/server/discounts.js.map +1 -0
  96. package/dist/checkout/server/handle-webhook.js +34 -8
  97. package/dist/checkout/server/handle-webhook.js.map +1 -1
  98. package/dist/checkout/server/index.d.ts +4 -0
  99. package/dist/checkout/server/index.d.ts.map +1 -1
  100. package/dist/checkout/server/index.js +4 -0
  101. package/dist/checkout/server/index.js.map +1 -1
  102. package/dist/checkout/server/order-service.d.ts.map +1 -1
  103. package/dist/checkout/server/order-service.js +60 -10
  104. package/dist/checkout/server/order-service.js.map +1 -1
  105. package/dist/checkout/server/pricing.d.ts +164 -0
  106. package/dist/checkout/server/pricing.d.ts.map +1 -0
  107. package/dist/checkout/server/pricing.js +309 -0
  108. package/dist/checkout/server/pricing.js.map +1 -0
  109. package/dist/checkout/types.d.ts +8 -0
  110. package/dist/checkout/types.d.ts.map +1 -1
  111. package/dist/core/StoreSettingsProvider.d.ts +4 -0
  112. package/dist/core/StoreSettingsProvider.d.ts.map +1 -1
  113. package/dist/core/StoreSettingsProvider.js +6 -0
  114. package/dist/core/StoreSettingsProvider.js.map +1 -1
  115. package/dist/core/api/settings.d.ts +1 -0
  116. package/dist/core/api/settings.d.ts.map +1 -1
  117. package/dist/core/api/settings.js +2 -0
  118. package/dist/core/api/settings.js.map +1 -1
  119. package/dist/core/db/queries.d.ts +267 -19
  120. package/dist/core/db/queries.d.ts.map +1 -1
  121. package/dist/core/db/queries.js +297 -0
  122. package/dist/core/db/queries.js.map +1 -1
  123. package/dist/core/db/schema.d.ts +618 -0
  124. package/dist/core/db/schema.d.ts.map +1 -1
  125. package/dist/core/db/schema.js +78 -0
  126. package/dist/core/db/schema.js.map +1 -1
  127. package/package.json +5 -1
@@ -0,0 +1,294 @@
1
+ /**
2
+ * @rovela/sdk/checkout/server/discounts
3
+ *
4
+ * The native discount EVALUATOR — step 2 of the pricing core.
5
+ *
6
+ * Given the server-priced cart lines and the (trusted) customer context, it
7
+ * decides which discounts apply and how much they take off. It runs
8
+ * identically for every payment path (Stripe, manual methods, future
9
+ * providers) because it operates BEFORE any processor is involved.
10
+ *
11
+ * Model (see schema.ts `discounts`):
12
+ * - `automatic` discounts are always candidates; a `code` discount is a
13
+ * candidate only when the shopper entered its code.
14
+ * - Each discount belongs to a CLASS — product / order / shipping — and
15
+ * carries per-class `combinesWith` flags. A set of discounts can coexist
16
+ * only when every PAIR allows the other's class (Shopify's model, without
17
+ * Shopify's caps).
18
+ * - Resolution is deterministic: the entered code is honored first (the
19
+ * shopper asked for it), then automatic discounts are added greedily in
20
+ * descending amount order while pairwise-compatible. One shipping-class
21
+ * discount at most (a shipping rate can't be discounted twice).
22
+ * - The cumulative product+order discount is clamped to the subtotal.
23
+ *
24
+ * Validation per candidate: enabled → schedule → eligibility (all /
25
+ * logged_in / groups) → scoped minimums (min subtotal / quantity count only
26
+ * the items in scope, like Shopify) → usage limit → once-per-customer.
27
+ * Automatic discounts failing a check are silently skipped; a failing CODE
28
+ * reports a friendly `codeError` for the checkout UI.
29
+ */
30
+ import { findDiscountByCode, findActiveAutomaticDiscounts, countDiscountRedemptionsForCustomer, } from '../../core/db/queries';
31
+ // =============================================================================
32
+ // Helpers
33
+ // =============================================================================
34
+ export function discountClassOf(d) {
35
+ if (d.type === 'free_shipping')
36
+ return 'shipping';
37
+ if (d.type === 'buy_x_get_y')
38
+ return 'product';
39
+ return d.appliesTo === 'order' ? 'order' : 'product';
40
+ }
41
+ function pairCanCombine(a, b) {
42
+ const flagsA = (a.combinesWith ?? {});
43
+ const flagsB = (b.combinesWith ?? {});
44
+ return !!flagsA[discountClassOf(b)] && !!flagsB[discountClassOf(a)];
45
+ }
46
+ /** Lines matched by a products/categories scope. 'order'/'any' matches all. */
47
+ function matchingLines(lines, appliesTo, targetIds, categoryByProductId) {
48
+ if (appliesTo === 'order' || appliesTo === 'any')
49
+ return lines;
50
+ const targets = new Set(targetIds);
51
+ if (targets.size === 0)
52
+ return [];
53
+ if (appliesTo === 'products') {
54
+ return lines.filter((l) => l.productId && targets.has(l.productId));
55
+ }
56
+ // categories
57
+ return lines.filter((l) => {
58
+ const cat = l.productId ? categoryByProductId[l.productId] : null;
59
+ return !!cat && targets.has(cat);
60
+ });
61
+ }
62
+ function sumCents(lines) {
63
+ return lines.reduce((sum, l) => sum + l.price * l.quantity, 0);
64
+ }
65
+ function sumQuantity(lines) {
66
+ return lines.reduce((sum, l) => sum + l.quantity, 0);
67
+ }
68
+ function decimalToNumber(v) {
69
+ if (v == null)
70
+ return 0;
71
+ const n = Number.parseFloat(v);
72
+ return Number.isFinite(n) ? n : 0;
73
+ }
74
+ async function validateCandidate(d, ctx) {
75
+ const now = ctx.now ?? new Date();
76
+ if (!d.enabled)
77
+ return 'INVALID_CODE';
78
+ if (d.startsAt && now < d.startsAt)
79
+ return 'EXPIRED';
80
+ if (d.endsAt && now > d.endsAt)
81
+ return 'EXPIRED';
82
+ // Eligibility
83
+ if (d.eligibility === 'logged_in' && !ctx.customerId)
84
+ return 'NOT_ELIGIBLE';
85
+ if (d.eligibility === 'groups') {
86
+ const groups = (d.groupIds ?? []);
87
+ if (!ctx.customerGroupId || !groups.includes(ctx.customerGroupId)) {
88
+ return 'NOT_ELIGIBLE';
89
+ }
90
+ }
91
+ // Scoped minimums — only in-scope items count (Shopify semantics).
92
+ const catMap = ctx.categoryByProductId ?? {};
93
+ const scopeLines = d.type === 'buy_x_get_y'
94
+ ? ctx.lines // BXGY qualification handled by its own config below
95
+ : matchingLines(ctx.lines, d.appliesTo, (d.targetIds ?? []), catMap);
96
+ const minSubtotal = decimalToNumber(d.minSubtotal);
97
+ if (minSubtotal > 0 && sumCents(scopeLines) < Math.round(minSubtotal * 100)) {
98
+ return 'MINIMUM_NOT_MET';
99
+ }
100
+ if (d.minQuantity && sumQuantity(scopeLines) < d.minQuantity) {
101
+ return 'MINIMUM_NOT_MET';
102
+ }
103
+ // Usage limits
104
+ if (d.usageLimit != null && d.usedCount >= d.usageLimit) {
105
+ return 'USAGE_LIMIT_REACHED';
106
+ }
107
+ if (d.oncePerCustomer && (ctx.customerId || ctx.customerEmail)) {
108
+ const used = await countDiscountRedemptionsForCustomer(d.id, {
109
+ customerId: ctx.customerId,
110
+ email: ctx.customerEmail,
111
+ });
112
+ if (used > 0)
113
+ return 'ALREADY_USED';
114
+ }
115
+ return null;
116
+ }
117
+ // =============================================================================
118
+ // Amount computation
119
+ // =============================================================================
120
+ function computeBxgyAmount(d, ctx) {
121
+ const cfg = d.bxgy;
122
+ if (!cfg || cfg.buyQuantity < 1 || cfg.getQuantity < 1)
123
+ return 0;
124
+ const catMap = ctx.categoryByProductId ?? {};
125
+ const buyLines = matchingLines(ctx.lines, cfg.buyAppliesTo, cfg.buyTargetIds ?? [], catMap);
126
+ const getLines = matchingLines(ctx.lines, cfg.getAppliesTo, cfg.getTargetIds ?? [], catMap);
127
+ if (buyLines.length === 0 || getLines.length === 0)
128
+ return 0;
129
+ // Expand get-candidates into single units, cheapest first (the discount
130
+ // always lands on the cheapest qualifying units — Shopify's behavior).
131
+ const getUnits = [];
132
+ for (const l of getLines) {
133
+ for (let i = 0; i < l.quantity; i++)
134
+ getUnits.push(l.price);
135
+ }
136
+ getUnits.sort((a, b) => a - b);
137
+ const buyUnits = sumQuantity(buyLines);
138
+ let applications = Math.floor(buyUnits / cfg.buyQuantity);
139
+ if (cfg.maxUsesPerOrder && cfg.maxUsesPerOrder > 0) {
140
+ applications = Math.min(applications, cfg.maxUsesPerOrder);
141
+ }
142
+ if (applications < 1)
143
+ return 0;
144
+ const unitsToDiscount = Math.min(applications * cfg.getQuantity, getUnits.length);
145
+ const pct = cfg.getType === 'free' ? 100 : Math.min(100, Math.max(0, cfg.getValue));
146
+ let amount = 0;
147
+ for (let i = 0; i < unitsToDiscount; i++) {
148
+ amount += Math.round(getUnits[i] * (pct / 100));
149
+ }
150
+ return amount;
151
+ }
152
+ /** Standalone value of a discount against the cart, in cents. */
153
+ function computeAmountCents(d, ctx) {
154
+ const catMap = ctx.categoryByProductId ?? {};
155
+ const value = decimalToNumber(d.value);
156
+ switch (d.type) {
157
+ case 'free_shipping':
158
+ return 0; // applied on the shipping axis, not the subtotal
159
+ case 'buy_x_get_y':
160
+ return computeBxgyAmount(d, ctx);
161
+ case 'percentage': {
162
+ const pct = Math.min(100, Math.max(0, value));
163
+ const base = d.appliesTo === 'order'
164
+ ? ctx.subtotalCents
165
+ : sumCents(matchingLines(ctx.lines, d.appliesTo, (d.targetIds ?? []), catMap));
166
+ return Math.round(base * (pct / 100));
167
+ }
168
+ case 'fixed_amount': {
169
+ const cents = Math.max(0, Math.round(value * 100));
170
+ const base = d.appliesTo === 'order'
171
+ ? ctx.subtotalCents
172
+ : sumCents(matchingLines(ctx.lines, d.appliesTo, (d.targetIds ?? []), catMap));
173
+ // A scoped fixed amount requires at least one matching item.
174
+ if (d.appliesTo !== 'order' && base <= 0)
175
+ return 0;
176
+ return Math.min(cents, base);
177
+ }
178
+ default:
179
+ return 0;
180
+ }
181
+ }
182
+ // =============================================================================
183
+ // Friendly code-error copy
184
+ // =============================================================================
185
+ const CODE_ERROR_MESSAGES = {
186
+ INVALID_CODE: "This code isn't valid.",
187
+ EXPIRED: 'This code has expired.',
188
+ NOT_ELIGIBLE: "This code isn't available on your account.",
189
+ MINIMUM_NOT_MET: "Your order doesn't meet the minimum for this code.",
190
+ USAGE_LIMIT_REACHED: 'This code has reached its usage limit.',
191
+ ALREADY_USED: "You've already used this code.",
192
+ NOT_APPLICABLE: "This code doesn't apply to the items in your cart.",
193
+ };
194
+ function codeError(reason) {
195
+ return { reason, message: CODE_ERROR_MESSAGES[reason] };
196
+ }
197
+ // =============================================================================
198
+ // Evaluation
199
+ // =============================================================================
200
+ export async function evaluateDiscounts(ctx) {
201
+ const result = {
202
+ discountCents: 0,
203
+ freeShipping: false,
204
+ applied: [],
205
+ };
206
+ if (!ctx.lines || ctx.lines.length === 0 || ctx.subtotalCents <= 0) {
207
+ return result;
208
+ }
209
+ // ── Candidates ────────────────────────────────────────────────────────────
210
+ let codeDiscount = null;
211
+ if (ctx.code && ctx.code.trim()) {
212
+ codeDiscount = await findDiscountByCode(ctx.code);
213
+ if (!codeDiscount) {
214
+ result.codeError = codeError('INVALID_CODE');
215
+ }
216
+ }
217
+ let automatics = [];
218
+ try {
219
+ automatics = await findActiveAutomaticDiscounts();
220
+ }
221
+ catch (err) {
222
+ // Discounts must never break checkout — degrade to "no automatics".
223
+ console.error('[Discounts] automatic-discounts lookup failed:', err);
224
+ }
225
+ let codeCandidate = null;
226
+ if (codeDiscount) {
227
+ const rejection = await validateCandidate(codeDiscount, ctx);
228
+ if (rejection) {
229
+ result.codeError = codeError(rejection);
230
+ }
231
+ else {
232
+ const amountCents = computeAmountCents(codeDiscount, ctx);
233
+ const cls = discountClassOf(codeDiscount);
234
+ if (cls !== 'shipping' && amountCents <= 0) {
235
+ result.codeError = codeError('NOT_APPLICABLE');
236
+ }
237
+ else {
238
+ codeCandidate = { discount: codeDiscount, amountCents, discountClass: cls };
239
+ }
240
+ }
241
+ }
242
+ const automaticCandidates = [];
243
+ for (const d of automatics) {
244
+ const rejection = await validateCandidate(d, ctx);
245
+ if (rejection)
246
+ continue;
247
+ const amountCents = computeAmountCents(d, ctx);
248
+ const cls = discountClassOf(d);
249
+ if (cls !== 'shipping' && amountCents <= 0)
250
+ continue;
251
+ automaticCandidates.push({ discount: d, amountCents, discountClass: cls });
252
+ }
253
+ // Highest value first (free-shipping candidates carry 0 and sort last —
254
+ // they compete on their own axis anyway).
255
+ automaticCandidates.sort((a, b) => b.amountCents - a.amountCents);
256
+ // ── Deterministic greedy resolution ──────────────────────────────────────
257
+ // The entered code is honored first; automatics join when every pair in
258
+ // the growing set allows the combination. At most one shipping discount.
259
+ const selected = [];
260
+ const canJoin = (candidate) => {
261
+ if (candidate.discountClass === 'shipping' &&
262
+ selected.some((s) => s.discountClass === 'shipping')) {
263
+ return false;
264
+ }
265
+ return selected.every((s) => pairCanCombine(s.discount, candidate.discount));
266
+ };
267
+ if (codeCandidate)
268
+ selected.push(codeCandidate);
269
+ for (const candidate of automaticCandidates) {
270
+ if (canJoin(candidate))
271
+ selected.push(candidate);
272
+ }
273
+ // ── Totals (clamped to the subtotal) ─────────────────────────────────────
274
+ let remaining = ctx.subtotalCents;
275
+ for (const s of selected) {
276
+ const clamped = s.discountClass === 'shipping' ? 0 : Math.min(s.amountCents, remaining);
277
+ remaining -= clamped;
278
+ result.applied.push({
279
+ id: s.discount.id,
280
+ title: s.discount.title,
281
+ code: s.discount.code,
282
+ method: s.discount.method ?? 'code',
283
+ type: s.discount.type,
284
+ discountClass: s.discountClass,
285
+ amountCents: clamped,
286
+ freeShipping: s.discount.type === 'free_shipping',
287
+ });
288
+ if (s.discount.type === 'free_shipping')
289
+ result.freeShipping = true;
290
+ }
291
+ result.discountCents = ctx.subtotalCents - remaining;
292
+ return result;
293
+ }
294
+ //# sourceMappingURL=discounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discounts.js","sourceRoot":"","sources":["../../../src/checkout/server/discounts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EACL,kBAAkB,EAClB,4BAA4B,EAC5B,mCAAmC,GACpC,MAAM,uBAAuB,CAAA;AA6D9B,gFAAgF;AAChF,UAAU;AACV,gFAAgF;AAEhF,MAAM,UAAU,eAAe,CAAC,CAAuC;IACrE,IAAI,CAAC,CAAC,IAAI,KAAK,eAAe;QAAE,OAAO,UAAU,CAAA;IACjD,IAAI,CAAC,CAAC,IAAI,KAAK,aAAa;QAAE,OAAO,SAAS,CAAA;IAC9C,OAAO,CAAC,CAAC,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAA;AACtD,CAAC;AAED,SAAS,cAAc,CAAC,CAAW,EAAE,CAAW;IAC9C,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,CAAwC,CAAA;IAC5E,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,CAAwC,CAAA;IAC5E,OAAO,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAA;AACrE,CAAC;AAED,+EAA+E;AAC/E,SAAS,aAAa,CACpB,KAAyB,EACzB,SAAiB,EACjB,SAAmB,EACnB,mBAAkD;IAElD,IAAI,SAAS,KAAK,OAAO,IAAI,SAAS,KAAK,KAAK;QAAE,OAAO,KAAK,CAAA;IAC9D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAA;IAClC,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IACjC,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;IACrE,CAAC;IACD,aAAa;IACb,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACxB,MAAM,GAAG,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACjE,OAAO,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAClC,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,KAAyB;IACzC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;AAChE,CAAC;AAED,SAAS,WAAW,CAAC,KAAyB;IAC5C,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;AACtD,CAAC;AAED,SAAS,eAAe,CAAC,CAA4B;IACnD,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,CAAC,CAAA;IACvB,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;IAC9B,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACnC,CAAC;AAQD,KAAK,UAAU,iBAAiB,CAC9B,CAAW,EACX,GAA8B;IAE9B,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAA;IAEjC,IAAI,CAAC,CAAC,CAAC,OAAO;QAAE,OAAO,cAAc,CAAA;IACrC,IAAI,CAAC,CAAC,QAAQ,IAAI,GAAG,GAAG,CAAC,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAA;IACpD,IAAI,CAAC,CAAC,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,MAAM;QAAE,OAAO,SAAS,CAAA;IAEhD,cAAc;IACd,IAAI,CAAC,CAAC,WAAW,KAAK,WAAW,IAAI,CAAC,GAAG,CAAC,UAAU;QAAE,OAAO,cAAc,CAAA;IAC3E,IAAI,CAAC,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAa,CAAA;QAC7C,IAAI,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,CAAC;YAClE,OAAO,cAAc,CAAA;QACvB,CAAC;IACH,CAAC;IAED,mEAAmE;IACnE,MAAM,MAAM,GAAG,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAA;IAC5C,MAAM,UAAU,GACd,CAAC,CAAC,IAAI,KAAK,aAAa;QACtB,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,qDAAqD;QACjE,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAa,EAAE,MAAM,CAAC,CAAA;IACpF,MAAM,WAAW,GAAG,eAAe,CAAC,CAAC,CAAC,WAAW,CAAC,CAAA;IAClD,IAAI,WAAW,GAAG,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,EAAE,CAAC;QAC5E,OAAO,iBAAiB,CAAA;IAC1B,CAAC;IACD,IAAI,CAAC,CAAC,WAAW,IAAI,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7D,OAAO,iBAAiB,CAAA;IAC1B,CAAC;IAED,eAAe;IACf,IAAI,CAAC,CAAC,UAAU,IAAI,IAAI,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;QACxD,OAAO,qBAAqB,CAAA;IAC9B,CAAC;IACD,IAAI,CAAC,CAAC,eAAe,IAAI,CAAC,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;QAC/D,MAAM,IAAI,GAAG,MAAM,mCAAmC,CAAC,CAAC,CAAC,EAAE,EAAE;YAC3D,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,KAAK,EAAE,GAAG,CAAC,aAAa;SACzB,CAAC,CAAA;QACF,IAAI,IAAI,GAAG,CAAC;YAAE,OAAO,cAAc,CAAA;IACrC,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,gFAAgF;AAChF,qBAAqB;AACrB,gFAAgF;AAEhF,SAAS,iBAAiB,CACxB,CAAW,EACX,GAA8B;IAE9B,MAAM,GAAG,GAAG,CAAC,CAAC,IAAyB,CAAA;IACvC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,WAAW,GAAG,CAAC,IAAI,GAAG,CAAC,WAAW,GAAG,CAAC;QAAE,OAAO,CAAC,CAAA;IAChE,MAAM,MAAM,GAAG,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAA;IAE5C,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,EAAE,EAAE,MAAM,CAAC,CAAA;IAC3F,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,EAAE,EAAE,MAAM,CAAC,CAAA;IAC3F,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAA;IAE5D,wEAAwE;IACxE,uEAAuE;IACvE,MAAM,QAAQ,GAAa,EAAE,CAAA;IAC7B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE;YAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;IAC7D,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IAE9B,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAA;IACtC,IAAI,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC,WAAW,CAAC,CAAA;IACzD,IAAI,GAAG,CAAC,eAAe,IAAI,GAAG,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;QACnD,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,eAAe,CAAC,CAAA;IAC5D,CAAC;IACD,IAAI,YAAY,GAAG,CAAC;QAAE,OAAO,CAAC,CAAA;IAE9B,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;IACjF,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;IACnF,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAA;IACjD,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,iEAAiE;AACjE,SAAS,kBAAkB,CAAC,CAAW,EAAE,GAA8B;IACrE,MAAM,MAAM,GAAG,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAA;IAC5C,MAAM,KAAK,GAAG,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;IAEtC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,eAAe;YAClB,OAAO,CAAC,CAAA,CAAC,iDAAiD;QAC5D,KAAK,aAAa;YAChB,OAAO,iBAAiB,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAClC,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAA;YAC7C,MAAM,IAAI,GACR,CAAC,CAAC,SAAS,KAAK,OAAO;gBACrB,CAAC,CAAC,GAAG,CAAC,aAAa;gBACnB,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAa,EAAE,MAAM,CAAC,CAAC,CAAA;YAC9F,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAA;QACvC,CAAC;QACD,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAA;YAClD,MAAM,IAAI,GACR,CAAC,CAAC,SAAS,KAAK,OAAO;gBACrB,CAAC,CAAC,GAAG,CAAC,aAAa;gBACnB,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAa,EAAE,MAAM,CAAC,CAAC,CAAA;YAC9F,6DAA6D;YAC7D,IAAI,CAAC,CAAC,SAAS,KAAK,OAAO,IAAI,IAAI,IAAI,CAAC;gBAAE,OAAO,CAAC,CAAA;YAClD,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAC9B,CAAC;QACD;YACE,OAAO,CAAC,CAAA;IACZ,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,2BAA2B;AAC3B,gFAAgF;AAEhF,MAAM,mBAAmB,GAAiC;IACxD,YAAY,EAAE,wBAAwB;IACtC,OAAO,EAAE,wBAAwB;IACjC,YAAY,EAAE,4CAA4C;IAC1D,eAAe,EAAE,oDAAoD;IACrE,mBAAmB,EAAE,wCAAwC;IAC7D,YAAY,EAAE,gCAAgC;IAC9C,cAAc,EAAE,oDAAoD;CACrE,CAAA;AAED,SAAS,SAAS,CAAC,MAAoB;IACrC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAA;AACzD,CAAC;AAED,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAA8B;IAE9B,MAAM,MAAM,GAAuB;QACjC,aAAa,EAAE,CAAC;QAChB,YAAY,EAAE,KAAK;QACnB,OAAO,EAAE,EAAE;KACZ,CAAA;IACD,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,GAAG,CAAC,aAAa,IAAI,CAAC,EAAE,CAAC;QACnE,OAAO,MAAM,CAAA;IACf,CAAC;IAED,6EAA6E;IAC7E,IAAI,YAAY,GAAoB,IAAI,CAAA;IACxC,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QAChC,YAAY,GAAG,MAAM,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACjD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,cAAc,CAAC,CAAA;QAC9C,CAAC;IACH,CAAC;IAED,IAAI,UAAU,GAAe,EAAE,CAAA;IAC/B,IAAI,CAAC;QACH,UAAU,GAAG,MAAM,4BAA4B,EAAE,CAAA;IACnD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,oEAAoE;QACpE,OAAO,CAAC,KAAK,CAAC,gDAAgD,EAAE,GAAG,CAAC,CAAA;IACtE,CAAC;IASD,IAAI,aAAa,GAA2B,IAAI,CAAA;IAChD,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,YAAY,EAAE,GAAG,CAAC,CAAA;QAC5D,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;QACzC,CAAC;aAAM,CAAC;YACN,MAAM,WAAW,GAAG,kBAAkB,CAAC,YAAY,EAAE,GAAG,CAAC,CAAA;YACzD,MAAM,GAAG,GAAG,eAAe,CAAC,YAAY,CAAC,CAAA;YACzC,IAAI,GAAG,KAAK,UAAU,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;gBAC3C,MAAM,CAAC,SAAS,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAAA;YAChD,CAAC;iBAAM,CAAC;gBACN,aAAa,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,EAAE,CAAA;YAC7E,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,mBAAmB,GAAsB,EAAE,CAAA;IACjD,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QACjD,IAAI,SAAS;YAAE,SAAQ;QACvB,MAAM,WAAW,GAAG,kBAAkB,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAC9C,MAAM,GAAG,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;QAC9B,IAAI,GAAG,KAAK,UAAU,IAAI,WAAW,IAAI,CAAC;YAAE,SAAQ;QACpD,mBAAmB,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC,CAAA;IAC5E,CAAC;IACD,wEAAwE;IACxE,0CAA0C;IAC1C,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC,CAAA;IAEjE,4EAA4E;IAC5E,wEAAwE;IACxE,yEAAyE;IACzE,MAAM,QAAQ,GAAsB,EAAE,CAAA;IACtC,MAAM,OAAO,GAAG,CAAC,SAA0B,EAAW,EAAE;QACtD,IACE,SAAS,CAAC,aAAa,KAAK,UAAU;YACtC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,UAAU,CAAC,EACpD,CAAC;YACD,OAAO,KAAK,CAAA;QACd,CAAC;QACD,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC9E,CAAC,CAAA;IAED,IAAI,aAAa;QAAE,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;IAC/C,KAAK,MAAM,SAAS,IAAI,mBAAmB,EAAE,CAAC;QAC5C,IAAI,OAAO,CAAC,SAAS,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;IAClD,CAAC;IAED,4EAA4E;IAC5E,IAAI,SAAS,GAAG,GAAG,CAAC,aAAa,CAAA;IACjC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,OAAO,GACX,CAAC,CAAC,aAAa,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;QACzE,SAAS,IAAI,OAAO,CAAA;QACpB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;YAClB,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE;YACjB,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK;YACvB,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI;YACrB,MAAM,EAAG,CAAC,CAAC,QAAQ,CAAC,MAA+B,IAAI,MAAM;YAC7D,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI;YACrB,aAAa,EAAE,CAAC,CAAC,aAAa;YAC9B,WAAW,EAAE,OAAO;YACpB,YAAY,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,KAAK,eAAe;SAClD,CAAC,CAAA;QACF,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,KAAK,eAAe;YAAE,MAAM,CAAC,YAAY,GAAG,IAAI,CAAA;IACrE,CAAC;IACD,MAAM,CAAC,aAAa,GAAG,GAAG,CAAC,aAAa,GAAG,SAAS,CAAA;IAEpD,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { getStripe, getAllWebhookSecrets, getConnectedAccountId } from '../stripe/client';
8
8
  import { createOrderFromCheckout, extractOrderParamsFromSession, handleRefund, attachReceiptToOrder, } from './order-service';
9
- import { findSettings } from '../../core/db/queries';
9
+ import { findSettings, recordDiscountRedemption } from '../../core/db/queries';
10
10
  import { sendOrderConfirmation, formatPrice, formatDate, formatOrderNumber, } from '../../emails';
11
11
  // =============================================================================
12
12
  // Main Webhook Handler
@@ -150,6 +150,28 @@ async function handleCheckoutSessionCompleted(session) {
150
150
  // Create the order
151
151
  const { orderId, isNew } = await createOrderFromCheckout(orderParams);
152
152
  console.log('[Webhook] Order', isNew ? 'created' : 'already exists', orderId);
153
+ // Record native-discount redemptions (usage limits + audit). The session
154
+ // builder stamped the applied snapshot in metadata. Best-effort — a
155
+ // redemption failure must never fail the webhook/order.
156
+ if (isNew && session.metadata?.rovelaDiscounts) {
157
+ try {
158
+ const applied = JSON.parse(session.metadata.rovelaDiscounts);
159
+ for (const d of applied) {
160
+ if (!d?.id)
161
+ continue;
162
+ await recordDiscountRedemption({
163
+ discountId: d.id,
164
+ orderId,
165
+ customerId: orderParams.customerId ?? null,
166
+ email: orderParams.email || null,
167
+ amountCents: typeof d.a === 'number' ? d.a : 0,
168
+ });
169
+ }
170
+ }
171
+ catch (err) {
172
+ console.error('[Webhook] discount redemption recording failed:', err);
173
+ }
174
+ }
153
175
  // Attach receipt URL to order (non-blocking, errors are logged)
154
176
  let receiptUrl = null;
155
177
  if (isNew && orderParams.stripePaymentIntentId) {
@@ -264,11 +286,15 @@ async function sendOrderConfirmationEmail(orderId, params, session, receiptUrl,
264
286
  const customerName = session.customer_details?.name ||
265
287
  params.email.split('@')[0] ||
266
288
  'Customer';
267
- // Convert order items to email format
289
+ // Convert order items to email format.
290
+ // formatPrice's integer input is AMBIGUOUS (its cents-vs-dollars heuristic
291
+ // breaks at <= 100 cents — a 1.00 amount renders as 100.00). Always hand
292
+ // it an unambiguous decimal STRING.
293
+ const emailAmount = (cents) => (cents / 100).toFixed(2);
268
294
  const items = params.items.map((item) => ({
269
295
  name: item.name,
270
296
  quantity: item.quantity,
271
- price: formatPrice(item.price, currency), // Convert cents to formatted price
297
+ price: formatPrice(emailAmount(item.price), currency),
272
298
  imageUrl: item.image, // Note: CheckoutLineItem uses 'image' not 'imageUrl'
273
299
  }));
274
300
  // Convert shipping address to email format
@@ -296,14 +322,14 @@ async function sendOrderConfirmationEmail(orderId, params, session, receiptUrl,
296
322
  orderDate: formatDate(new Date()),
297
323
  paymentStatus: 'Paid',
298
324
  items,
299
- subtotal: formatPrice(params.subtotal, currency),
325
+ subtotal: formatPrice(emailAmount(params.subtotal), currency),
300
326
  discount: params.discountAmount && params.discountAmount > 0
301
- ? `-${formatPrice(params.discountAmount, currency)}`
327
+ ? `-${formatPrice(emailAmount(params.discountAmount), currency)}`
302
328
  : undefined,
303
329
  discountCode: params.discountCode,
304
- shippingCost: params.shipping > 0 ? formatPrice(params.shipping, currency) : 'Free',
305
- tax: formatPrice(params.tax, currency),
306
- total: formatPrice(params.total, currency),
330
+ shippingCost: params.shipping > 0 ? formatPrice(emailAmount(params.shipping), currency) : 'Free',
331
+ tax: formatPrice(emailAmount(params.tax), currency),
332
+ total: formatPrice(emailAmount(params.total), currency),
307
333
  shippingAddress,
308
334
  orderTrackingUrl,
309
335
  receiptUrl: receiptUrl || undefined,
@@ -1 +1 @@
1
- {"version":3,"file":"handle-webhook.js","sourceRoot":"","sources":["../../../src/checkout/server/handle-webhook.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handle-webhook.js","sourceRoot":"","sources":["../../../src/checkout/server/handle-webhook.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,10 @@ export { createCheckoutSession, getCheckoutSession, deserializeItemsFromMetadata
7
7
  export type { CreateCheckoutSessionOptions } from './create-checkout-session';
8
8
  export { handleStripeWebhook } from './handle-webhook';
9
9
  export { createOrderFromCheckout, extractOrderParamsFromSession, handleRefund, } from './order-service';
10
+ export { buildQuote, repriceItems, resolveShippingSelection, resolveTax, PricingError, } from './pricing';
11
+ export type { Quote, QuoteInput, QuoteItemInput, RepricedItems, ShippingResolution, TaxResolution, } from './pricing';
12
+ export { resolveCheckoutCustomer } from './checkout-customer';
13
+ export type { TrustedCheckoutCustomer } from './checkout-customer';
10
14
  export { createCouponWithCode, createBulkPromotionCodes, } from './coupons';
11
15
  export type { CreateCouponWithCodeOptions, CreateCouponResult, CreateBulkPromotionCodesOptions, CreateBulkResult, } from './coupons';
12
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/checkout/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,4BAA4B,GAC7B,MAAM,2BAA2B,CAAA;AAElC,YAAY,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAA;AAE7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAEtD,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,YAAY,GACb,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACL,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,WAAW,CAAA;AAElB,YAAY,EACV,2BAA2B,EAC3B,kBAAkB,EAClB,+BAA+B,EAC/B,gBAAgB,GACjB,MAAM,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/checkout/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,4BAA4B,GAC7B,MAAM,2BAA2B,CAAA;AAElC,YAAY,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAA;AAE7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAEtD,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,YAAY,GACb,MAAM,iBAAiB,CAAA;AAIxB,OAAO,EACL,UAAU,EACV,YAAY,EACZ,wBAAwB,EACxB,UAAU,EACV,YAAY,GACb,MAAM,WAAW,CAAA;AAElB,YAAY,EACV,KAAK,EACL,UAAU,EACV,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,aAAa,GACd,MAAM,WAAW,CAAA;AAElB,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAC7D,YAAY,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAElE,OAAO,EACL,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,WAAW,CAAA;AAElB,YAAY,EACV,2BAA2B,EAC3B,kBAAkB,EAClB,+BAA+B,EAC/B,gBAAgB,GACjB,MAAM,WAAW,CAAA"}
@@ -6,5 +6,9 @@
6
6
  export { createCheckoutSession, getCheckoutSession, deserializeItemsFromMetadata, } from './create-checkout-session';
7
7
  export { handleStripeWebhook } from './handle-webhook';
8
8
  export { createOrderFromCheckout, extractOrderParamsFromSession, handleRefund, } from './order-service';
9
+ // Pricing core — the processor-agnostic pipeline that computes an order's
10
+ // final price. Payment processors only collect what this computes.
11
+ export { buildQuote, repriceItems, resolveShippingSelection, resolveTax, PricingError, } from './pricing';
12
+ export { resolveCheckoutCustomer } from './checkout-customer';
9
13
  export { createCouponWithCode, createBulkPromotionCodes, } from './coupons';
10
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checkout/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,4BAA4B,GAC7B,MAAM,2BAA2B,CAAA;AAIlC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAEtD,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,YAAY,GACb,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACL,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,WAAW,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checkout/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,4BAA4B,GAC7B,MAAM,2BAA2B,CAAA;AAIlC,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAEtD,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,YAAY,GACb,MAAM,iBAAiB,CAAA;AAExB,0EAA0E;AAC1E,mEAAmE;AACnE,OAAO,EACL,UAAU,EACV,YAAY,EACZ,wBAAwB,EACxB,UAAU,EACV,YAAY,GACb,MAAM,WAAW,CAAA;AAWlB,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAG7D,OAAO,EACL,oBAAoB,EACpB,wBAAwB,GACzB,MAAM,WAAW,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"order-service.d.ts","sourceRoot":"","sources":["../../../src/checkout/server/order-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;AAchC,OAAO,KAAK,EAAE,iBAAiB,EAAoB,MAAM,UAAU,CAAA;AAOnE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,CA+J9C;AAMD;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,EAChC,SAAS,CAAC,EAAE,MAAM,CAAC,QAAQ,EAAE,GAC5B,iBAAiB,CA6InB;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,YAAY,CAChC,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAuCpF;AAMD;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+CxB"}
1
+ {"version":3,"file":"order-service.d.ts","sourceRoot":"","sources":["../../../src/checkout/server/order-service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAA;AAchC,OAAO,KAAK,EAAE,iBAAiB,EAAoB,MAAM,UAAU,CAAA;AAOnE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,CAgK9C;AAMD;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,OAAO,EAChC,SAAS,CAAC,EAAE,MAAM,CAAC,QAAQ,EAAE,GAC5B,iBAAiB,CA8MnB;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,YAAY,CAChC,eAAe,EAAE,MAAM,EACvB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,OAAO,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAuCpF;AAMD;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA+CxB"}
@@ -88,6 +88,7 @@ export async function createOrderFromCheckout(params) {
88
88
  discountAmount: params.discountAmount ? centsToDecimal(params.discountAmount) : '0',
89
89
  stripePromotionCodeId: params.stripePromotionCodeId,
90
90
  total: centsToDecimal(params.total),
91
+ currency: params.currency ? params.currency.toUpperCase().slice(0, 3) : undefined,
91
92
  shippingAddress: params.shippingAddress,
92
93
  billingAddress: params.billingAddress,
93
94
  stripePaymentIntentId: params.stripePaymentIntentId,
@@ -244,11 +245,16 @@ export function extractOrderParamsFromSession(session, lineItems) {
244
245
  ? parseStripeAddress(session.customer_details.address, session.customer_details.name || undefined)
245
246
  : undefined;
246
247
  }
247
- // Extract discount/promotion code info from Stripe session
248
- // Stripe stores discount in total_details.amount_discount and discounts[] array
249
- const discountAmount = session.total_details?.amount_discount || 0;
248
+ // Extract discount info. NATIVE discounts (our engine) stamp their code +
249
+ // NET amount in metadata — preferred. Legacy Stripe-hosted promo codes fall
250
+ // back to total_details.amount_discount / discounts[].
251
+ const nativeDiscountCode = typeof session.metadata?.rovelaDiscountCode === 'string' &&
252
+ session.metadata.rovelaDiscountCode
253
+ ? session.metadata.rovelaDiscountCode
254
+ : undefined;
255
+ const stripeDiscountAmount = session.total_details?.amount_discount || 0;
250
256
  const firstDiscount = session.discounts?.[0];
251
- const discountCode = firstDiscount
257
+ const legacyDiscountCode = firstDiscount
252
258
  ? (typeof firstDiscount === 'object' && 'coupon' in firstDiscount
253
259
  ? firstDiscount.coupon?.name
254
260
  : undefined)
@@ -260,8 +266,44 @@ export function extractOrderParamsFromSession(session, lineItems) {
260
266
  : undefined)
261
267
  : undefined)
262
268
  : undefined;
263
- // Extract tax and shipping from metadata first (stored during checkout creation)
264
- // Fallback to total_details for backwards compatibility
269
+ const discountCode = nativeDiscountCode ?? legacyDiscountCode;
270
+ // ==========================================================================
271
+ // Authoritative totals (pricing core) — `rovelaTotals` is OUR server-side
272
+ // computation stamped at session creation. When present it is the source
273
+ // of truth for the recorded order; Stripe's amounts are a cross-check.
274
+ // Sessions from the standard flow (shipping chosen on the hosted page) or
275
+ // from older SDK versions don't carry it and use the legacy fallbacks.
276
+ // ==========================================================================
277
+ let quoteTotals = null;
278
+ if (session.metadata?.rovelaTotals) {
279
+ try {
280
+ const parsed = JSON.parse(session.metadata.rovelaTotals);
281
+ if (parsed && typeof parsed === 'object')
282
+ quoteTotals = parsed;
283
+ }
284
+ catch {
285
+ console.warn('[Order] Unparseable rovelaTotals metadata — using Stripe amounts');
286
+ }
287
+ }
288
+ // Discount provenance: NATIVE (our engine, stamped in rovelaTotals — the
289
+ // recorded amount is the NET goods discount) vs LEGACY Stripe-hosted promo
290
+ // (allow_promotion_codes; only the Stripe amounts know about it).
291
+ const isNativeDiscount = !!session.metadata?.rovelaDiscounts;
292
+ const legacyStripeDiscount = !isNativeDiscount && stripeDiscountAmount > 0;
293
+ const discountAmount = isNativeDiscount
294
+ ? quoteTotals?.discount ?? 0
295
+ : stripeDiscountAmount;
296
+ if (quoteTotals &&
297
+ !legacyStripeDiscount &&
298
+ !isNativeDiscount &&
299
+ typeof quoteTotals.total === 'number' &&
300
+ typeof session.amount_total === 'number' &&
301
+ quoteTotals.total !== session.amount_total) {
302
+ // Should never happen — the session's line items were built from the same
303
+ // quote. Loud log so a drift is investigated, then OUR number is recorded.
304
+ console.error('[Order] QUOTE/STRIPE TOTAL MISMATCH:', 'quote =', quoteTotals.total, 'stripe =', session.amount_total, 'session =', session.id);
305
+ }
306
+ // Legacy metadata fallbacks (pre-rovelaTotals sessions)
265
307
  const taxFromMetadata = session.metadata?.taxAmount
266
308
  ? parseInt(session.metadata.taxAmount, 10)
267
309
  : null;
@@ -282,13 +324,21 @@ export function extractOrderParamsFromSession(session, lineItems) {
282
324
  sessionId: session.id,
283
325
  email: session.customer_details?.email || session.customer_email || '',
284
326
  items,
285
- subtotal: session.amount_subtotal || 0,
286
- tax: taxFromMetadata ?? (session.total_details?.amount_tax || 0),
287
- shipping: shippingFromMetadata ?? (session.total_details?.amount_shipping || 0),
327
+ // Our quote wins; Stripe amounts are the legacy fallback. NOTE: Stripe's
328
+ // amount_subtotal INCLUDES the synthetic Tax/Shipping line items our
329
+ // sessions carry, so the quote subtotal is also the more correct number.
330
+ subtotal: quoteTotals?.subtotal ?? (session.amount_subtotal || 0),
331
+ tax: quoteTotals?.tax ?? taxFromMetadata ?? (session.total_details?.amount_tax || 0),
332
+ shipping: quoteTotals?.shipping ??
333
+ shippingFromMetadata ??
334
+ (session.total_details?.amount_shipping || 0),
288
335
  discountCode,
289
336
  discountAmount,
290
337
  stripePromotionCodeId,
291
- total: session.amount_total || 0,
338
+ total: legacyStripeDiscount
339
+ ? session.amount_total || 0 // legacy hosted promo — charged amount wins
340
+ : quoteTotals?.total ?? (session.amount_total || 0),
341
+ currency: session.currency ? session.currency.toUpperCase() : undefined,
292
342
  shippingAddress,
293
343
  billingAddress,
294
344
  stripePaymentIntentId: typeof session.payment_intent === 'string'