@rovela-ai/sdk 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +325 -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 +106 -155
  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 +23 -1
  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 +249 -1
  120. package/dist/core/db/queries.d.ts.map +1 -1
  121. package/dist/core/db/queries.js +301 -1
  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,47 @@
1
+ /**
2
+ * @rovela/sdk/checkout/api/discount
3
+ *
4
+ * POST /api/checkout/discount — validate a redemption code against the
5
+ * current cart BEFORE placing the order (the checkout "Apply" button).
6
+ *
7
+ * The evaluation runs the SAME pricing-core pipeline (server re-price +
8
+ * native discounts engine) as order creation, so what the shopper sees here
9
+ * is exactly what the order will apply. Identity is session-resolved —
10
+ * group-gated / logged-in-only codes evaluate against the REAL customer.
11
+ *
12
+ * Usage:
13
+ * ```typescript
14
+ * // app/api/checkout/discount/route.ts
15
+ * export { POST } from '@rovela-ai/sdk/checkout/api/discount'
16
+ * ```
17
+ */
18
+ import { NextRequest, NextResponse } from 'next/server';
19
+ import type { CheckoutApiError } from '../types';
20
+ interface DiscountPreviewResponse {
21
+ success: true;
22
+ /** Validity of the ENTERED code (true when no code was sent). */
23
+ valid: boolean;
24
+ /** The normalized applied code, when one applies. */
25
+ code: string | null;
26
+ /** The entered code's display title (when valid). */
27
+ title: string | null;
28
+ /** Friendly rejection copy for the entered code (when invalid). */
29
+ error: string | null;
30
+ /** Machine-readable rejection reason — localized storefronts map their own copy. */
31
+ errorReason: 'INVALID_CODE' | 'EXPIRED' | 'NOT_ELIGIBLE' | 'MINIMUM_NOT_MET' | 'USAGE_LIMIT_REACHED' | 'ALREADY_USED' | 'NOT_APPLICABLE' | null;
32
+ /** TOTAL net discount off the goods (code + automatics), in cents. */
33
+ totalDiscountCents: number;
34
+ /** True when any applied discount zeroes the shipping cost. */
35
+ freeShipping: boolean;
36
+ /** Every applied discount, for review-step display. */
37
+ applied: Array<{
38
+ title: string;
39
+ code: string | null;
40
+ method: 'code' | 'automatic';
41
+ amountCents: number;
42
+ freeShipping: boolean;
43
+ }>;
44
+ }
45
+ export declare function POST(request: NextRequest): Promise<NextResponse<DiscountPreviewResponse | CheckoutApiError>>;
46
+ export {};
47
+ //# sourceMappingURL=discount.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discount.d.ts","sourceRoot":"","sources":["../../../src/checkout/api/discount.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAIvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAchD,UAAU,uBAAuB;IAC/B,OAAO,EAAE,IAAI,CAAA;IACb,iEAAiE;IACjE,KAAK,EAAE,OAAO,CAAA;IACd,qDAAqD;IACrD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,qDAAqD;IACrD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,mEAAmE;IACnE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,oFAAoF;IACpF,WAAW,EACP,cAAc,GACd,SAAS,GACT,cAAc,GACd,iBAAiB,GACjB,qBAAqB,GACrB,cAAc,GACd,gBAAgB,GAChB,IAAI,CAAA;IACR,sEAAsE;IACtE,kBAAkB,EAAE,MAAM,CAAA;IAC1B,+DAA+D;IAC/D,YAAY,EAAE,OAAO,CAAA;IACrB,uDAAuD;IACvD,OAAO,EAAE,KAAK,CAAC;QACb,KAAK,EAAE,MAAM,CAAA;QACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;QACnB,MAAM,EAAE,MAAM,GAAG,WAAW,CAAA;QAC5B,WAAW,EAAE,MAAM,CAAA;QACnB,YAAY,EAAE,OAAO,CAAA;KACtB,CAAC,CAAA;CACH;AAED,wBAAsB,IAAI,CACxB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,CAAC,uBAAuB,GAAG,gBAAgB,CAAC,CAAC,CA+DnE"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @rovela/sdk/checkout/api/discount
3
+ *
4
+ * POST /api/checkout/discount — validate a redemption code against the
5
+ * current cart BEFORE placing the order (the checkout "Apply" button).
6
+ *
7
+ * The evaluation runs the SAME pricing-core pipeline (server re-price +
8
+ * native discounts engine) as order creation, so what the shopper sees here
9
+ * is exactly what the order will apply. Identity is session-resolved —
10
+ * group-gated / logged-in-only codes evaluate against the REAL customer.
11
+ *
12
+ * Usage:
13
+ * ```typescript
14
+ * // app/api/checkout/discount/route.ts
15
+ * export { POST } from '@rovela-ai/sdk/checkout/api/discount'
16
+ * ```
17
+ */
18
+ import { NextResponse } from 'next/server';
19
+ import { repriceItems, PricingError } from '../server/pricing';
20
+ import { evaluateDiscounts } from '../server/discounts';
21
+ import { resolveCheckoutCustomer } from '../server/checkout-customer';
22
+ export async function POST(request) {
23
+ try {
24
+ const body = (await request.json());
25
+ const code = typeof body.code === 'string' ? body.code.trim() : '';
26
+ // Server re-price ('floor' — mirrors the Stripe path so previews work for
27
+ // configurator carts too).
28
+ let repriced;
29
+ try {
30
+ repriced = await repriceItems(body.items ?? [], 'floor');
31
+ }
32
+ catch (err) {
33
+ if (err instanceof PricingError) {
34
+ return NextResponse.json({ error: err.message, code: err.code }, { status: err.status });
35
+ }
36
+ throw err;
37
+ }
38
+ const trustedCustomer = await resolveCheckoutCustomer();
39
+ const evaluation = await evaluateDiscounts({
40
+ lines: repriced.lines,
41
+ subtotalCents: repriced.subtotalCents,
42
+ categoryByProductId: repriced.categoryByProductId,
43
+ code: code || null,
44
+ customerId: trustedCustomer?.id ?? null,
45
+ customerGroupId: trustedCustomer?.groupId ?? null,
46
+ customerEmail: body.customerEmail || trustedCustomer?.email || null,
47
+ });
48
+ const appliedCode = evaluation.applied.find((a) => a.method === 'code') ?? null;
49
+ const codeInvalid = !!code && (!!evaluation.codeError || !appliedCode);
50
+ return NextResponse.json({
51
+ success: true,
52
+ valid: !codeInvalid,
53
+ code: appliedCode?.code ?? null,
54
+ title: appliedCode?.title ?? null,
55
+ error: codeInvalid
56
+ ? evaluation.codeError?.message ?? "This code isn't valid."
57
+ : null,
58
+ errorReason: codeInvalid
59
+ ? evaluation.codeError?.reason ?? 'INVALID_CODE'
60
+ : null,
61
+ totalDiscountCents: evaluation.discountCents,
62
+ freeShipping: evaluation.freeShipping,
63
+ applied: evaluation.applied.map((a) => ({
64
+ title: a.title,
65
+ code: a.code,
66
+ method: a.method,
67
+ amountCents: a.amountCents,
68
+ freeShipping: a.freeShipping,
69
+ })),
70
+ });
71
+ }
72
+ catch (error) {
73
+ console.error('[Discount Preview API] error:', error);
74
+ return NextResponse.json({ error: 'Failed to validate the code. Please try again.', code: 'CHECKOUT_ERROR' }, { status: 500 });
75
+ }
76
+ }
77
+ //# sourceMappingURL=discount.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discount.js","sourceRoot":"","sources":["../../../src/checkout/api/discount.ts"],"names":[],"mappings":"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"}
@@ -10,5 +10,6 @@ export { POST as ShippingPOST } from './shipping';
10
10
  export { GET as CountriesGET } from './countries';
11
11
  export { GET as PaymentMethodsGET } from './payment-methods';
12
12
  export { POST as ManualCheckoutPOST } from './manual';
13
+ export { POST as DiscountPreviewPOST } from './discount';
13
14
  export type { PaymentStatusResponse } from './payment-status';
14
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/checkout/api/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,GAAG,IAAI,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAC1D,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,GAAG,IAAI,YAAY,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,GAAG,IAAI,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EAAE,IAAI,IAAI,kBAAkB,EAAE,MAAM,UAAU,CAAA;AACrD,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/checkout/api/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,GAAG,IAAI,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAC1D,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,GAAG,IAAI,YAAY,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,GAAG,IAAI,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EAAE,IAAI,IAAI,kBAAkB,EAAE,MAAM,UAAU,CAAA;AACrD,OAAO,EAAE,IAAI,IAAI,mBAAmB,EAAE,MAAM,YAAY,CAAA;AACxD,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA"}
@@ -10,4 +10,5 @@ export { POST as ShippingPOST } from './shipping';
10
10
  export { GET as CountriesGET } from './countries';
11
11
  export { GET as PaymentMethodsGET } from './payment-methods';
12
12
  export { POST as ManualCheckoutPOST } from './manual';
13
+ export { POST as DiscountPreviewPOST } from './discount';
13
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checkout/api/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,GAAG,IAAI,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAC1D,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,GAAG,IAAI,YAAY,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,GAAG,IAAI,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EAAE,IAAI,IAAI,kBAAkB,EAAE,MAAM,UAAU,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checkout/api/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AACjC,OAAO,EAAE,IAAI,IAAI,WAAW,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,GAAG,IAAI,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAC1D,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,GAAG,IAAI,YAAY,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,GAAG,IAAI,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EAAE,IAAI,IAAI,kBAAkB,EAAE,MAAM,UAAU,CAAA;AACrD,OAAO,EAAE,IAAI,IAAI,mBAAmB,EAAE,MAAM,YAAY,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"manual.d.ts","sourceRoot":"","sources":["../../../src/checkout/api/manual.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAmBvD,OAAO,KAAK,EAAE,gBAAgB,EAAoC,MAAM,UAAU,CAAA;AAyBlF,UAAU,sBAAsB;IAC9B,OAAO,EAAE,IAAI,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAA;IACjB,+CAA+C;IAC/C,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAA;CAClE;AAoBD,wBAAsB,IAAI,CACxB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,CAAC,sBAAsB,GAAG,gBAAgB,CAAC,CAAC,CAgQlE"}
1
+ {"version":3,"file":"manual.d.ts","sourceRoot":"","sources":["../../../src/checkout/api/manual.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAkBvD,OAAO,KAAK,EAAE,gBAAgB,EAAoC,MAAM,UAAU,CAAA;AA2BlF,UAAU,sBAAsB;IAC9B,OAAO,EAAE,IAAI,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAA;IACjB,+CAA+C;IAC/C,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAA;CAClE;AAUD,wBAAsB,IAAI,CACxB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,CAAC,sBAAsB,GAAG,gBAAgB,CAAC,CAAC,CAiNlE"}
@@ -19,23 +19,15 @@
19
19
  */
20
20
  import { randomUUID } from 'crypto';
21
21
  import { NextResponse } from 'next/server';
22
- import { findSettings, findPaymentMethodById, findProductById, findVariantById, findShippingOptionsForCountry, findTaxRateForAddress, } from '../../core/db/queries';
22
+ import { findSettings, findPaymentMethodById, recordDiscountRedemption, } from '../../core/db/queries';
23
+ import { buildQuote, PricingError } from '../server/pricing';
24
+ import { resolveCheckoutCustomer } from '../server/checkout-customer';
23
25
  import { createOrderFromCheckout } from '../server/order-service';
24
26
  import { sendOrderConfirmation, formatPrice, formatDate, formatOrderNumber, } from '../../emails';
25
27
  import { recordEvent } from '../../analytics/server';
26
- const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
27
28
  function bad(error, status = 400) {
28
29
  return NextResponse.json({ error, code: 'INVALID_REQUEST' }, { status });
29
30
  }
30
- /** Dollars (decimal string from the DB) → integer cents. */
31
- function dollarsToCents(decimal) {
32
- if (decimal == null)
33
- return null;
34
- const n = Number.parseFloat(decimal);
35
- if (!Number.isFinite(n))
36
- return null;
37
- return Math.round(n * 100);
38
- }
39
31
  // =============================================================================
40
32
  // Handler
41
33
  // =============================================================================
@@ -44,8 +36,12 @@ export async function POST(request) {
44
36
  const body = (await request.json());
45
37
  // ── Gates ────────────────────────────────────────────────────────────────
46
38
  const settings = await findSettings();
39
+ // Trusted identity: resolved from the SESSION COOKIE, never from the
40
+ // client body (body.customerId is spoofable on a money path — an order
41
+ // could be attached to another customer's account history).
42
+ const trustedCustomer = await resolveCheckoutCustomer();
47
43
  const allowGuestCheckout = settings?.guestCheckout ?? true;
48
- if (!allowGuestCheckout && !body.customerId) {
44
+ if (!allowGuestCheckout && !trustedCustomer) {
49
45
  return NextResponse.json({
50
46
  error: 'Guest checkout is disabled. Please sign in to continue.',
51
47
  code: 'GUEST_CHECKOUT_DISABLED',
@@ -63,118 +59,33 @@ export async function POST(request) {
63
59
  if (!method || !method.enabled || method.kind !== 'manual') {
64
60
  return bad('This payment method is not available', 400);
65
61
  }
66
- // ── Items: re-price EVERYTHING from the database ─────────────────────────
67
- if (!body.items || !Array.isArray(body.items) || body.items.length === 0) {
68
- return NextResponse.json({ error: 'No items provided', code: 'EMPTY_CART' }, { status: 400 });
62
+ // ── The Quote: items (discounts) shipping → tax → total ─────────────
63
+ // The pricing core recomputes EVERYTHING server-side ('strict': client
64
+ // prices are used for nothing). See checkout/server/pricing.ts.
65
+ let quote;
66
+ try {
67
+ quote = await buildQuote({
68
+ items: body.items,
69
+ shippingAddress: body.shippingAddress,
70
+ selectedShipping: body.selectedShipping,
71
+ pricingMode: 'strict',
72
+ discountCode: body.discountCode ?? null,
73
+ customerId: trustedCustomer?.id ?? null,
74
+ customerGroupId: trustedCustomer?.groupId ?? null,
75
+ customerEmail: email,
76
+ }, { settings });
69
77
  }
70
- const repricedItems = [];
71
- let subtotalCents = 0;
72
- for (const item of body.items) {
73
- const quantity = Number(item.quantity);
74
- if (!Number.isInteger(quantity) || quantity < 1 || quantity > 999) {
75
- return bad('Invalid item quantity');
76
- }
77
- if (!item.productId || !UUID_RE.test(item.productId)) {
78
- // Manual orders are strict: every line must map to a real catalog
79
- // product (no client-invented lines on an unsupervised money path).
80
- return bad('Invalid item: unknown product');
78
+ catch (err) {
79
+ if (err instanceof PricingError) {
80
+ return NextResponse.json({ error: err.message, code: err.code }, { status: err.status });
81
81
  }
82
- const product = await findProductById(item.productId);
83
- if (!product || product.status !== 'active') {
84
- return bad('Invalid item: product unavailable');
85
- }
86
- let unitCents = dollarsToCents(product.price);
87
- let name = product.name;
88
- let variantId;
89
- if (item.variantId) {
90
- if (!UUID_RE.test(item.variantId))
91
- return bad('Invalid item variant');
92
- const variant = await findVariantById(item.variantId);
93
- if (!variant || variant.productId !== product.id) {
94
- return bad('Invalid item variant');
95
- }
96
- const variantCents = dollarsToCents(variant.price);
97
- if (variantCents != null)
98
- unitCents = variantCents;
99
- name = `${product.name} - ${variant.name}`;
100
- variantId = variant.id;
101
- }
102
- if (unitCents == null || unitCents <= 0) {
103
- return bad('Invalid item: product has no price');
104
- }
105
- subtotalCents += unitCents * quantity;
106
- repricedItems.push({
107
- productId: product.id,
108
- variantId,
109
- name,
110
- price: unitCents,
111
- quantity,
112
- image: product.images?.[0],
113
- });
82
+ throw err;
114
83
  }
115
- // ── Shipping: validate the selection server-side ─────────────────────────
116
- const shippingEnabled = settings?.shippingEnabled ?? true;
117
- let shippingCents = 0;
118
- let shippingMethodName;
119
- let carrier;
120
- let shippoRateId;
121
- if (shippingEnabled) {
122
- if (!body.shippingAddress)
123
- return bad('Shipping address is required');
124
- const a = body.shippingAddress;
125
- if (!a.firstName || !a.lastName || !a.line1 || !a.city || !a.postalCode || !a.country) {
126
- return bad('Complete shipping address is required');
127
- }
128
- if (!body.selectedShipping?.id)
129
- return bad('A shipping method is required');
130
- const sel = body.selectedShipping;
131
- if (sel.source === 'shippo') {
132
- // Shippo rates are ephemeral quotes served by our own /api/checkout/
133
- // shipping moments earlier — they can't be deterministically re-derived.
134
- // Accept with sanity bounds (the rate id is stored for reconciliation).
135
- const price = Number(sel.price);
136
- if (!Number.isFinite(price) || price < 0 || price > 1_000_000) {
137
- return bad('Invalid shipping selection');
138
- }
139
- shippingCents = Math.round(price);
140
- shippingMethodName = [sel.carrierName, sel.name].filter(Boolean).join(' - ') || sel.name;
141
- carrier = sel.carrierCode || sel.carrierId || undefined;
142
- shippoRateId = sel.id;
143
- }
144
- else {
145
- // Manual zone rates ARE deterministic — recompute and use the SERVER's
146
- // price for the selected option id. Unknown id = tampered/stale → 400.
147
- const grouped = await findShippingOptionsForCountry(a.country, subtotalCents / 100);
148
- const flat = grouped.flatMap((g) => g.options);
149
- const match = flat.find((o) => o.id === sel.id);
150
- if (!match)
151
- return bad('Selected shipping method is no longer available');
152
- shippingCents = Math.round(Number(match.price) || 0);
153
- shippingMethodName =
154
- [match.carrierName, match.name].filter(Boolean).join(' - ') || match.name;
155
- carrier = match.carrierCode || match.carrierId || undefined;
156
- }
157
- }
158
- // ── Tax: recompute server-side ───────────────────────────────────────────
159
- const taxIncludedInPrices = settings?.taxIncludedInPrices ?? true;
160
- let taxCents = 0;
161
- if (body.shippingAddress?.country) {
162
- const taxMatch = await findTaxRateForAddress(body.shippingAddress.country, body.shippingAddress.state || undefined);
163
- const rate = taxMatch?.taxRate ?? 0;
164
- if (rate > 0) {
165
- const taxableCents = subtotalCents + shippingCents;
166
- if (taxIncludedInPrices) {
167
- const divisor = 1 + rate / 100;
168
- taxCents = Math.round(taxableCents - taxableCents / divisor);
169
- }
170
- else {
171
- taxCents = Math.round(taxableCents * (rate / 100));
172
- }
173
- }
174
- }
175
- const totalCents = taxIncludedInPrices
176
- ? subtotalCents + shippingCents
177
- : subtotalCents + shippingCents + taxCents;
84
+ const repricedItems = quote.lines;
85
+ const subtotalCents = quote.subtotalCents;
86
+ const shippingCents = quote.shippingCents;
87
+ const taxCents = quote.taxCents;
88
+ const totalCents = quote.totalCents;
178
89
  // ── Idempotency reference ────────────────────────────────────────────────
179
90
  // Stored in the shared payment-reference column so double-submits dedupe
180
91
  // through the existing findOrderByPaymentIntent lookup.
@@ -190,21 +101,47 @@ export async function POST(request) {
190
101
  tax: taxCents,
191
102
  shipping: shippingCents,
192
103
  total: totalCents,
104
+ currency: quote.currency,
105
+ discountCode: quote.discountCode ?? undefined,
106
+ discountAmount: quote.discountCents > 0 ? quote.discountCents : undefined,
193
107
  shippingAddress: body.shippingAddress,
194
108
  billingAddress: body.billingAddress,
195
109
  stripePaymentIntentId: reference,
196
- customerId: body.customerId,
197
- shippingMethod: shippingMethodName,
198
- carrier,
199
- shippoRateId,
110
+ customerId: trustedCustomer?.id,
111
+ shippingMethod: quote.shippingMethodName,
112
+ carrier: quote.carrier,
113
+ shippoRateId: quote.shippoRateId,
200
114
  status: 'pending',
201
115
  paymentProvider: 'manual',
202
116
  paymentMethodId: method.id,
203
117
  paymentMethodLabel: method.name,
204
118
  });
205
- // ── Post-order side effects (fire-and-forget; never block the response) ──
119
+ // ── Discount redemptions (usage limits + audit) ──────────────────────────
120
+ // Recorded once per NEW order. Best-effort: a redemption write failure
121
+ // must never fail the already-created order.
122
+ if (isNew && quote.appliedDiscounts.length > 0) {
123
+ for (const applied of quote.appliedDiscounts) {
124
+ try {
125
+ await recordDiscountRedemption({
126
+ discountId: applied.id,
127
+ orderId,
128
+ customerId: trustedCustomer?.id ?? null,
129
+ email,
130
+ amountCents: applied.amountCents,
131
+ });
132
+ }
133
+ catch (err) {
134
+ console.error('[Manual Checkout] redemption record failed:', err);
135
+ }
136
+ }
137
+ }
138
+ // ── Post-order side effects ──────────────────────────────────────────────
139
+ // AWAITED (not fire-and-forget): on serverless hosts the function freezes
140
+ // as soon as the response returns, killing un-awaited promises — the email
141
+ // would silently never send. Each is guarded so a failure can never fail
142
+ // the already-created order.
206
143
  if (isNew) {
207
- const currency = settings?.storeCurrency || 'USD';
144
+ const currency = quote.currency;
208
145
  const storeUrl = process.env.NEXT_PUBLIC_APP_URL || '';
209
146
  const emailItems = repricedItems.map((i) => ({
210
147
  name: i.name,
@@ -222,39 +159,53 @@ export async function POST(request) {
222
159
  postalCode: addr.postalCode,
223
160
  country: addr.country,
224
161
  };
225
- void sendOrderConfirmation({
226
- to: email,
227
- customerName: addr.firstName || email.split('@')[0] || 'Customer',
228
- orderNumber: formatOrderNumber(orderId),
229
- orderDate: formatDate(new Date()),
230
- paymentStatus: `Pending — ${method.name}`,
231
- items: emailItems,
232
- subtotal: formatPrice(subtotalCents, currency),
233
- shippingCost: shippingCents > 0 ? formatPrice(shippingCents, currency) : 'Free',
234
- tax: formatPrice(taxCents, currency),
235
- total: formatPrice(totalCents, currency),
236
- shippingAddress: emailAddress,
237
- orderTrackingUrl: `${storeUrl}/account/orders/${orderId}`,
238
- paymentInstructions: method.instructions || undefined,
239
- }).catch((err) => console.error('[Manual Checkout] confirmation email failed:', err));
162
+ try {
163
+ await sendOrderConfirmation({
164
+ to: email,
165
+ customerName: addr.firstName || email.split('@')[0] || 'Customer',
166
+ orderNumber: formatOrderNumber(orderId),
167
+ orderDate: formatDate(new Date()),
168
+ paymentStatus: `Pending — ${method.name}`,
169
+ items: emailItems,
170
+ subtotal: formatPrice(subtotalCents, currency),
171
+ discount: quote.discountCents > 0
172
+ ? `-${formatPrice(quote.discountCents, currency)}`
173
+ : undefined,
174
+ discountCode: quote.discountCode ?? undefined,
175
+ shippingCost: shippingCents > 0 ? formatPrice(shippingCents, currency) : 'Free',
176
+ tax: formatPrice(taxCents, currency),
177
+ total: formatPrice(totalCents, currency),
178
+ shippingAddress: emailAddress,
179
+ orderTrackingUrl: `${storeUrl}/account/orders/${orderId}`,
180
+ paymentInstructions: method.instructions || undefined,
181
+ });
182
+ }
183
+ catch (err) {
184
+ console.error('[Manual Checkout] confirmation email failed:', err);
185
+ }
240
186
  // Server-side purchase analytics — mirrors the Stripe webhook wrapper.
241
187
  // The partial unique index on (order_id) WHERE event='purchase' dedupes.
242
188
  const visitorId = body.metadata?.rovela_visitor_id;
243
189
  const sessionId = body.metadata?.rovela_session_id;
244
190
  if (visitorId && sessionId) {
245
- void recordEvent({
246
- event: {
247
- event: 'purchase',
248
- visitor_id: visitorId,
249
- session_id: sessionId,
250
- order_id: orderId,
251
- value_cents: totalCents,
252
- currency: settings?.storeCurrency || 'USD',
253
- path: '/checkout/success',
254
- },
255
- device: null,
256
- country: null,
257
- });
191
+ try {
192
+ await recordEvent({
193
+ event: {
194
+ event: 'purchase',
195
+ visitor_id: visitorId,
196
+ session_id: sessionId,
197
+ order_id: orderId,
198
+ value_cents: totalCents,
199
+ currency: quote.currency,
200
+ path: '/checkout/success',
201
+ },
202
+ device: null,
203
+ country: null,
204
+ });
205
+ }
206
+ catch (err) {
207
+ console.error('[Manual Checkout] purchase analytics failed:', err);
208
+ }
258
209
  }
259
210
  }
260
211
  return NextResponse.json({
@@ -1 +1 @@
1
- {"version":3,"file":"manual.js","sourceRoot":"","sources":["../../../src/checkout/api/manual.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manual.js","sourceRoot":"","sources":["../../../src/checkout/api/manual.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC,OAAO,EAAe,YAAY,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,EACL,YAAY,EACZ,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAA;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EACL,qBAAqB,EACrB,WAAW,EACX,UAAU,EACV,iBAAiB,GAClB,MAAM,cAAc,CAAA;AAErB,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAsCpD,SAAS,GAAG,CAAC,KAAa,EAAE,MAAM,GAAG,GAAG;IACtC,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,iBAA0B,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;AACnF,CAAC;AAED,gFAAgF;AAChF,UAAU;AACV,gFAAgF;AAEhF,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,OAAoB;IAEpB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAA8B,CAAA;QAEhE,4EAA4E;QAC5E,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAA;QAErC,qEAAqE;QACrE,uEAAuE;QACvE,4DAA4D;QAC5D,MAAM,eAAe,GAAG,MAAM,uBAAuB,EAAE,CAAA;QAEvD,MAAM,kBAAkB,GAAG,QAAQ,EAAE,aAAa,IAAI,IAAI,CAAA;QAC1D,IAAI,CAAC,kBAAkB,IAAI,CAAC,eAAe,EAAE,CAAC;YAC5C,OAAO,YAAY,CAAC,IAAI,CACtB;gBACE,KAAK,EAAE,yDAAyD;gBAChE,IAAI,EAAE,yBAAkC;aACzC,EACD,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAA;QACH,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QACtD,IAAI,CAAC,KAAK,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACxD,OAAO,GAAG,CAAC,2BAA2B,CAAC,CAAA;QACzC,CAAC;QAED,2EAA2E;QAC3E,IAAI,CAAC,IAAI,CAAC,eAAe,IAAI,OAAO,IAAI,CAAC,eAAe,KAAK,QAAQ,EAAE,CAAC;YACtE,OAAO,GAAG,CAAC,6BAA6B,CAAC,CAAA;QAC3C,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;QAChE,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3D,OAAO,GAAG,CAAC,sCAAsC,EAAE,GAAG,CAAC,CAAA;QACzD,CAAC;QAED,2EAA2E;QAC3E,uEAAuE;QACvE,gEAAgE;QAChE,IAAI,KAAK,CAAA;QACT,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,UAAU,CACtB;gBACE,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,eAAe,EAAE,IAAI,CAAC,eAAe;gBACrC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;gBACvC,WAAW,EAAE,QAAQ;gBACrB,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI;gBACvC,UAAU,EAAE,eAAe,EAAE,EAAE,IAAI,IAAI;gBACvC,eAAe,EAAE,eAAe,EAAE,OAAO,IAAI,IAAI;gBACjD,aAAa,EAAE,KAAK;aACrB,EACD,EAAE,QAAQ,EAAE,CACb,CAAA;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,YAAY,EAAE,CAAC;gBAChC,OAAO,YAAY,CAAC,IAAI,CACtB,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,EACtC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CACvB,CAAA;YACH,CAAC;YACD,MAAM,GAAG,CAAA;QACX,CAAC;QAED,MAAM,aAAa,GAAuB,KAAK,CAAC,KAAK,CAAA;QACrD,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAA;QACzC,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAA;QACzC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAA;QAC/B,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAA;QAEnC,4EAA4E;QAC5E,yEAAyE;QACzE,wDAAwD;QACxD,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,CAAA;QACjF,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QAClE,MAAM,SAAS,GAAG,UAAU,OAAO,IAAI,UAAU,EAAE,EAAE,CAAA;QAErD,2EAA2E;QAC3E,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,uBAAuB,CAAC;YACvD,SAAS,EAAE,SAAS;YACpB,KAAK;YACL,KAAK,EAAE,aAAa;YACpB,QAAQ,EAAE,aAAa;YACvB,GAAG,EAAE,QAAQ;YACb,QAAQ,EAAE,aAAa;YACvB,KAAK,EAAE,UAAU;YACjB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,SAAS;YAC7C,cAAc,EAAE,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS;YACzE,eAAe,EAAE,IAAI,CAAC,eAA0B;YAChD,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,qBAAqB,EAAE,SAAS;YAChC,UAAU,EAAE,eAAe,EAAE,EAAE;YAC/B,cAAc,EAAE,KAAK,CAAC,kBAAkB;YACxC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,MAAM,EAAE,SAAS;YACjB,eAAe,EAAE,QAAQ;YACzB,eAAe,EAAE,MAAM,CAAC,EAAE;YAC1B,kBAAkB,EAAE,MAAM,CAAC,IAAI;SAChC,CAAC,CAAA;QAEF,4EAA4E;QAC5E,uEAAuE;QACvE,6CAA6C;QAC7C,IAAI,KAAK,IAAI,KAAK,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/C,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,gBAAgB,EAAE,CAAC;gBAC7C,IAAI,CAAC;oBACH,MAAM,wBAAwB,CAAC;wBAC7B,UAAU,EAAE,OAAO,CAAC,EAAE;wBACtB,OAAO;wBACP,UAAU,EAAE,eAAe,EAAE,EAAE,IAAI,IAAI;wBACvC,KAAK;wBACL,WAAW,EAAE,OAAO,CAAC,WAAW;qBACjC,CAAC,CAAA;gBACJ,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,6CAA6C,EAAE,GAAG,CAAC,CAAA;gBACnE,CAAC;YACH,CAAC;QACH,CAAC;QAED,4EAA4E;QAC5E,0EAA0E;QAC1E,2EAA2E;QAC3E,yEAAyE;QACzE,6BAA6B;QAC7B,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAA;YAC/B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAA;YACtD,MAAM,UAAU,GAAqB,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC7D,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC;gBACrC,QAAQ,EAAE,CAAC,CAAC,KAAK;aAClB,CAAC,CAAC,CAAA;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,eAA0B,CAAA;YAC5C,MAAM,YAAY,GAAiB;gBACjC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE;gBACjD,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,OAAO,EAAE,IAAI,CAAC,OAAO;aACtB,CAAA;YACD,IAAI,CAAC;gBACH,MAAM,qBAAqB,CAAC;oBAC1B,EAAE,EAAE,KAAK;oBACT,YAAY,EAAE,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,UAAU;oBACjE,WAAW,EAAE,iBAAiB,CAAC,OAAO,CAAC;oBACvC,SAAS,EAAE,UAAU,CAAC,IAAI,IAAI,EAAE,CAAC;oBACjC,aAAa,EAAE,aAAa,MAAM,CAAC,IAAI,EAAE;oBACzC,KAAK,EAAE,UAAU;oBACjB,QAAQ,EAAE,WAAW,CAAC,aAAa,EAAE,QAAQ,CAAC;oBAC9C,QAAQ,EACN,KAAK,CAAC,aAAa,GAAG,CAAC;wBACrB,CAAC,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,aAAa,EAAE,QAAQ,CAAC,EAAE;wBAClD,CAAC,CAAC,SAAS;oBACf,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,SAAS;oBAC7C,YAAY,EAAE,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM;oBAC/E,GAAG,EAAE,WAAW,CAAC,QAAQ,EAAE,QAAQ,CAAC;oBACpC,KAAK,EAAE,WAAW,CAAC,UAAU,EAAE,QAAQ,CAAC;oBACxC,eAAe,EAAE,YAAY;oBAC7B,gBAAgB,EAAE,GAAG,QAAQ,mBAAmB,OAAO,EAAE;oBACzD,mBAAmB,EAAE,MAAM,CAAC,YAAY,IAAI,SAAS;iBACtD,CAAC,CAAA;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,8CAA8C,EAAE,GAAG,CAAC,CAAA;YACpE,CAAC;YAED,uEAAuE;YACvE,yEAAyE;YACzE,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAA;YAClD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAA;YAClD,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;gBAC3B,IAAI,CAAC;oBACH,MAAM,WAAW,CAAC;wBAChB,KAAK,EAAE;4BACL,KAAK,EAAE,UAAU;4BACjB,UAAU,EAAE,SAAS;4BACrB,UAAU,EAAE,SAAS;4BACrB,QAAQ,EAAE,OAAO;4BACjB,WAAW,EAAE,UAAU;4BACvB,QAAQ,EAAE,KAAK,CAAC,QAAQ;4BACxB,IAAI,EAAE,mBAAmB;yBAC1B;wBACD,MAAM,EAAE,IAAI;wBACZ,OAAO,EAAE,IAAI;qBACd,CAAC,CAAA;gBACJ,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,8CAA8C,EAAE,GAAG,CAAC,CAAA;gBACpE,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,YAAY,CAAC,IAAI,CAAC;YACvB,OAAO,EAAE,IAAI;YACb,OAAO;YACP,SAAS;YACT,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,IAAI,EAAE;SACxF,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAA;QACpD,OAAO,YAAY,CAAC,IAAI,CACtB,EAAE,KAAK,EAAE,8CAA8C,EAAE,IAAI,EAAE,gBAAyB,EAAE,EAC1F,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAA;IACH,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"shipping.d.ts","sourceRoot":"","sources":["../../../src/checkout/api/shipping.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,KAAK,EACV,2BAA2B,EAG3B,gBAAgB,EACjB,MAAM,UAAU,CAAA;AAqCjB;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,IAAI,CACxB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,CAAC,2BAA2B,GAAG,gBAAgB,CAAC,CAAC,CA+NvE"}
1
+ {"version":3,"file":"shipping.d.ts","sourceRoot":"","sources":["../../../src/checkout/api/shipping.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,KAAK,EACV,2BAA2B,EAG3B,gBAAgB,EACjB,MAAM,UAAU,CAAA;AAsCjB;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,IAAI,CACxB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,YAAY,CAAC,2BAA2B,GAAG,gBAAgB,CAAC,CAAC,CAiNvE"}
@@ -11,7 +11,8 @@
11
11
  * ```
12
12
  */
13
13
  import { NextResponse } from 'next/server';
14
- import { findSettings, findShippingOptionsForCountry, findTaxRateForAddress } from '../../core/db/queries';
14
+ import { findSettings, findShippingOptionsForCountry } from '../../core/db/queries';
15
+ import { resolveTax } from '../server/pricing';
15
16
  import { getShippoRates, groupShippoRatesByCarrier, shippingAddressToShippo, } from '../../shipping/shippo';
16
17
  import { countryRequiresState } from '../constants';
17
18
  // =============================================================================
@@ -168,33 +169,24 @@ export async function POST(request) {
168
169
  // =========================================================================
169
170
  let tax = null;
170
171
  try {
171
- // Look up tax zone for the customer's address
172
- const taxMatch = await findTaxRateForAddress(address.country.toUpperCase(), address.state?.toUpperCase());
173
- if (taxMatch && taxMatch.taxRate > 0) {
174
- const taxIncludedInPrices = settings?.taxIncludedInPrices ?? true;
175
- const taxRate = taxMatch.taxRate; // Percentage (e.g., 8.25 = 8.25%)
176
- // Calculate tax based on mode
177
- // Note: orderAmountCents is the subtotal, tax applies to subtotal only
178
- // (Shipping tax calculation can be added later if needed)
179
- let taxAmountCents;
180
- if (taxIncludedInPrices) {
181
- // Prices already include tax - extract the tax portion
182
- // Formula: taxAmount = subtotal - (subtotal / (1 + taxRate/100))
183
- const taxDivisor = 1 + (taxRate / 100);
184
- const preTaxAmount = orderAmountCents / taxDivisor;
185
- taxAmountCents = Math.round(orderAmountCents - preTaxAmount);
186
- }
187
- else {
188
- // Prices are pre-tax - add tax on top
189
- // Formula: taxAmount = subtotal * (taxRate/100)
190
- taxAmountCents = Math.round(orderAmountCents * (taxRate / 100));
191
- }
172
+ // Canonical tax formula (pricing core). No shipping is selected yet at
173
+ // this pre-checkout stage, so the quoted amount covers the subtotal
174
+ // only — the client (and later the ORDER-time quote) recomputes tax
175
+ // with the chosen shipping included.
176
+ const taxResolution = await resolveTax({
177
+ subtotalCents: orderAmountCents,
178
+ shippingCents: 0,
179
+ country: address.country.toUpperCase(),
180
+ state: address.state?.toUpperCase(),
181
+ taxIncludedInPrices: settings?.taxIncludedInPrices ?? true,
182
+ });
183
+ if (taxResolution.taxRate > 0) {
192
184
  tax = {
193
- zoneId: taxMatch.zoneId,
194
- zoneName: taxMatch.zoneName,
195
- taxRate: taxRate,
196
- amount: taxAmountCents,
197
- includedInPrices: taxIncludedInPrices,
185
+ zoneId: taxResolution.taxZoneId || '',
186
+ zoneName: taxResolution.taxZoneName || '',
187
+ taxRate: taxResolution.taxRate,
188
+ amount: taxResolution.taxCents,
189
+ includedInPrices: taxResolution.taxIncludedInPrices,
198
190
  };
199
191
  }
200
192
  }