@mohasinac/appkit 4.62.0 → 4.62.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 (204) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/server/features/checkout/actions.d.ts +80 -0
  3. package/dist/_internal/server/features/checkout/actions.js +542 -26
  4. package/dist/_internal/server/features/invoicing/allocate.d.ts +63 -0
  5. package/dist/_internal/server/features/invoicing/allocate.js +162 -0
  6. package/dist/_internal/server/features/invoicing/credit-note.d.ts +57 -0
  7. package/dist/_internal/server/features/invoicing/credit-note.js +126 -0
  8. package/dist/_internal/server/features/invoicing/gstr1.d.ts +74 -0
  9. package/dist/_internal/server/features/invoicing/gstr1.js +251 -0
  10. package/dist/_internal/server/features/invoicing/issue.d.ts +96 -0
  11. package/dist/_internal/server/features/invoicing/issue.js +202 -0
  12. package/dist/_internal/server/features/orders/actions.d.ts +8 -1
  13. package/dist/_internal/server/features/orders/actions.js +81 -8
  14. package/dist/_internal/server/features/orders/adapters.js +33 -0
  15. package/dist/_internal/server/features/orders/cancellation-refund.d.ts +15 -9
  16. package/dist/_internal/server/features/orders/cancellation-refund.js +15 -9
  17. package/dist/_internal/server/features/points/award.js +46 -4
  18. package/dist/_internal/server/features/refunds/actions.js +26 -0
  19. package/dist/_internal/server/features/shipping/courier-block.d.ts +69 -0
  20. package/dist/_internal/server/features/shipping/courier-block.js +239 -0
  21. package/dist/_internal/server/features/site-settings/adapters.d.ts +1 -1
  22. package/dist/_internal/server/features/site-settings/adapters.js +15 -0
  23. package/dist/_internal/server/features/stores/adapters.d.ts +2 -2
  24. package/dist/_internal/server/features/stores/adapters.js +51 -0
  25. package/dist/_internal/server/functions/scheduled.js +38 -1
  26. package/dist/_internal/server/jobs/core/autoPayoutEligibility.js +9 -2
  27. package/dist/_internal/server/jobs/core/dailyStatusDigest.d.ts +4 -0
  28. package/dist/_internal/server/jobs/core/dailyStatusDigest.js +19 -2
  29. package/dist/_internal/server/jobs/core/index.d.ts +2 -1
  30. package/dist/_internal/server/jobs/core/index.js +2 -1
  31. package/dist/_internal/server/jobs/core/onJobCreated.d.ts +30 -7
  32. package/dist/_internal/server/jobs/core/onJobCreated.js +78 -45
  33. package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +7 -0
  34. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +62 -0
  35. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +33 -0
  36. package/dist/_internal/server/jobs/core/runJobOnce.d.ts +48 -0
  37. package/dist/_internal/server/jobs/core/runJobOnce.js +195 -0
  38. package/dist/_internal/server/jobs/core/weeklyPayoutEligibility.js +10 -2
  39. package/dist/_internal/server/jobs/handlers/onOrderStatusChange.js +17 -0
  40. package/dist/_internal/server/notifications/channel-health.d.ts +26 -3
  41. package/dist/_internal/shared/actions/action-registry.js +28 -0
  42. package/dist/_internal/shared/checkout/coupon-discount.d.ts +43 -1
  43. package/dist/_internal/shared/checkout/coupon-discount.js +26 -1
  44. package/dist/_internal/shared/checkout/order-math.d.ts +145 -0
  45. package/dist/_internal/shared/checkout/order-math.js +173 -0
  46. package/dist/_internal/shared/checkout/refundable-base.d.ts +25 -0
  47. package/dist/_internal/shared/checkout/refundable-base.js +13 -1
  48. package/dist/_internal/shared/checkout/split.d.ts +87 -0
  49. package/dist/_internal/shared/checkout/split.js +100 -0
  50. package/dist/_internal/shared/content/disclaimers.d.ts +88 -0
  51. package/dist/_internal/shared/content/disclaimers.js +217 -0
  52. package/dist/_internal/shared/content/published-values.d.ts +88 -0
  53. package/dist/_internal/shared/content/published-values.js +198 -0
  54. package/dist/_internal/shared/features/admin/integrations.d.ts +109 -0
  55. package/dist/_internal/shared/features/admin/integrations.js +253 -0
  56. package/dist/_internal/shared/features/orders/dispute-reasons.d.ts +113 -0
  57. package/dist/_internal/shared/features/orders/dispute-reasons.js +181 -0
  58. package/dist/_internal/shared/features/orders/refund-copy.d.ts +1 -1
  59. package/dist/_internal/shared/features/orders/refund-copy.js +18 -1
  60. package/dist/_internal/shared/features/points/accepts.d.ts +36 -0
  61. package/dist/_internal/shared/features/points/accepts.js +43 -0
  62. package/dist/_internal/shared/features/shipping/shared-purchase.d.ts +91 -0
  63. package/dist/_internal/shared/features/shipping/shared-purchase.js +108 -0
  64. package/dist/_internal/shared/features/site-settings/types.d.ts +11 -0
  65. package/dist/_internal/shared/fees/calculator.d.ts +33 -1
  66. package/dist/_internal/shared/fees/calculator.js +32 -2
  67. package/dist/client.d.ts +11 -0
  68. package/dist/client.js +30 -0
  69. package/dist/constants/api-endpoints.d.ts +42 -0
  70. package/dist/constants/api-endpoints.js +14 -0
  71. package/dist/constants/field-names.d.ts +1 -0
  72. package/dist/constants/field-names.js +5 -0
  73. package/dist/contracts/index.d.ts +1 -1
  74. package/dist/contracts/shipping.d.ts +45 -0
  75. package/dist/contracts/shipping.js +15 -0
  76. package/dist/features/about/components/AboutView.js +1 -1
  77. package/dist/features/account/components/BuyerAuctionsGuideView.js +4 -1
  78. package/dist/features/account/components/UserOrdersView.js +19 -33
  79. package/dist/features/admin/components/AdminCouponEditorView.js +17 -0
  80. package/dist/features/admin/components/AdminInvoicingView.d.ts +2 -0
  81. package/dist/features/admin/components/AdminInvoicingView.js +65 -0
  82. package/dist/features/admin/components/AdminOrderEditorView.d.ts +18 -1
  83. package/dist/features/admin/components/AdminOrderEditorView.js +11 -2
  84. package/dist/features/admin/components/AdminOrdersGuideView.js +23 -2
  85. package/dist/features/admin/components/AdminOrdersView.js +67 -5
  86. package/dist/features/admin/components/OwnerQuickActions.js +24 -2
  87. package/dist/features/admin/constants/filter-tabs.d.ts +6 -0
  88. package/dist/features/admin/constants/filter-tabs.js +6 -0
  89. package/dist/features/admin/constants/site-settings-tabs.d.ts +1 -1
  90. package/dist/features/admin/hooks/useAdminListingData.js +16 -0
  91. package/dist/features/admin/schemas/admin-user-form.d.ts +2 -2
  92. package/dist/features/admin/schemas/firestore.d.ts +30 -0
  93. package/dist/features/admin/schemas/firestore.js +5 -0
  94. package/dist/features/audit-log/schemas/firestore.d.ts +30 -0
  95. package/dist/features/audit-log/schemas/firestore.js +15 -0
  96. package/dist/features/auth/permissions/constants.js +13 -0
  97. package/dist/features/cart/components/CartPriceBreakdown.d.ts +13 -0
  98. package/dist/features/cart/components/CartPriceBreakdown.js +6 -2
  99. package/dist/features/cart/components/PointsTenderPicker.d.ts +61 -0
  100. package/dist/features/cart/components/PointsTenderPicker.js +15 -0
  101. package/dist/features/cart/components/StoreAddonsPicker.js +2 -1
  102. package/dist/features/cart/components/index.d.ts +2 -0
  103. package/dist/features/cart/components/index.js +1 -0
  104. package/dist/features/cart/repository/cart.repository.d.ts +19 -0
  105. package/dist/features/cart/repository/cart.repository.js +27 -0
  106. package/dist/features/cart/schemas/firestore.d.ts +92 -0
  107. package/dist/features/contact/email.d.ts +27 -10
  108. package/dist/features/contact/email.js +20 -3
  109. package/dist/features/dispute-reasons/repository/dispute-reasons.repository.d.ts +38 -0
  110. package/dist/features/dispute-reasons/repository/dispute-reasons.repository.js +80 -0
  111. package/dist/features/dispute-reasons/schemas/firestore.d.ts +64 -0
  112. package/dist/features/dispute-reasons/schemas/firestore.js +40 -0
  113. package/dist/features/faq/components/FAQAccordion.d.ts +13 -1
  114. package/dist/features/faq/components/FAQAccordion.js +29 -4
  115. package/dist/features/invoicing/schemas/firestore.d.ts +112 -0
  116. package/dist/features/invoicing/schemas/firestore.js +45 -0
  117. package/dist/features/invoicing/utils/financial-year.d.ts +43 -0
  118. package/dist/features/invoicing/utils/financial-year.js +53 -0
  119. package/dist/features/jobs/actions/enqueue-job.js +18 -1
  120. package/dist/features/jobs/repository/jobs.repository.d.ts +62 -1
  121. package/dist/features/jobs/repository/jobs.repository.js +84 -1
  122. package/dist/features/jobs/schemas/firestore.d.ts +80 -0
  123. package/dist/features/jobs/schemas/firestore.js +37 -0
  124. package/dist/features/lottery/schemas/zod.d.ts +6 -6
  125. package/dist/features/media/MediaImage.js +22 -1
  126. package/dist/features/media/upload/ImageUpload.js +1 -1
  127. package/dist/features/obligations/constants/policies.js +24 -1
  128. package/dist/features/orders/components/OrderPaymentSummary.js +10 -1
  129. package/dist/features/orders/components/OrderProvenanceCard.d.ts +8 -0
  130. package/dist/features/orders/components/OrderProvenanceCard.js +185 -0
  131. package/dist/features/orders/components/RaiseDisputeForm.d.ts +14 -0
  132. package/dist/features/orders/components/RaiseDisputeForm.js +111 -0
  133. package/dist/features/orders/components/RefundRequestView.js +19 -1
  134. package/dist/features/orders/components/index.d.ts +4 -0
  135. package/dist/features/orders/components/index.js +2 -0
  136. package/dist/features/orders/constants/order-lane-tabs.d.ts +69 -0
  137. package/dist/features/orders/constants/order-lane-tabs.js +88 -0
  138. package/dist/features/orders/repository/orders.repository.d.ts +57 -0
  139. package/dist/features/orders/repository/orders.repository.js +145 -0
  140. package/dist/features/orders/schemas/firestore.d.ts +196 -1
  141. package/dist/features/orders/schemas/index.d.ts +54 -6
  142. package/dist/features/orders/schemas/index.js +12 -0
  143. package/dist/features/orders/types/index.d.ts +26 -0
  144. package/dist/features/orders/utils/courier-block.d.ts +25 -0
  145. package/dist/features/orders/utils/courier-block.js +23 -0
  146. package/dist/features/payment-cases/schemas/firestore.d.ts +26 -1
  147. package/dist/features/payment-cases/schemas/firestore.js +1 -0
  148. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -2
  149. package/dist/features/products/components/ProductDetailPageView.d.ts +17 -1
  150. package/dist/features/products/components/ProductDetailPageView.js +2 -2
  151. package/dist/features/products/schemas/product-features.validators.d.ts +10 -10
  152. package/dist/features/promotions/actions/coupon-stacking.d.ts +30 -3
  153. package/dist/features/promotions/actions/coupon-stacking.js +21 -2
  154. package/dist/features/promotions/components/CouponCard.js +13 -0
  155. package/dist/features/promotions/constants/coupon-help.d.ts +2 -2
  156. package/dist/features/promotions/constants/coupon-help.js +9 -1
  157. package/dist/features/promotions/schemas/firestore.d.ts +24 -0
  158. package/dist/features/promotions/schemas/firestore.js +4 -0
  159. package/dist/features/promotions/types/index.d.ts +19 -1
  160. package/dist/features/scams/components/ScamProfileView.js +2 -2
  161. package/dist/features/scams/components/ScamRegistryView.js +2 -2
  162. package/dist/features/search/action-index/tab-entries.js +1 -1
  163. package/dist/features/seller/actions/seller-actions.js +33 -3
  164. package/dist/features/seller/components/SellerOrdersView.js +129 -27
  165. package/dist/features/seller/hooks/useSellerListingData.js +25 -0
  166. package/dist/features/shipments/schemas/validation.d.ts +4 -4
  167. package/dist/features/shipping-boxes/repository/shipping-boxes.repository.d.ts +43 -0
  168. package/dist/features/shipping-boxes/repository/shipping-boxes.repository.js +90 -0
  169. package/dist/features/shipping-boxes/schemas/firestore.d.ts +82 -0
  170. package/dist/features/shipping-boxes/schemas/firestore.js +53 -0
  171. package/dist/features/store-extensions/schemas/report-create-form.d.ts +2 -2
  172. package/dist/features/store-extensions/schemas/shipping-config-form.d.ts +2 -2
  173. package/dist/features/stores/components/StoreOrdersGuideView.js +6 -1
  174. package/dist/features/stores/schemas/firestore.d.ts +71 -0
  175. package/dist/features/stores/types/index.d.ts +19 -0
  176. package/dist/features/support/schemas/index.d.ts +6 -6
  177. package/dist/features/wishlist/hooks/useWishlistWithGuest.d.ts +1 -1
  178. package/dist/index.d.ts +6 -1
  179. package/dist/index.js +14 -1
  180. package/dist/next/routing/route-map.d.ts +20 -0
  181. package/dist/next/routing/route-map.js +10 -0
  182. package/dist/providers/shipping-shiprocket/index.d.ts +27 -1
  183. package/dist/providers/shipping-shiprocket/index.js +84 -1
  184. package/dist/schemas/registry.d.ts +47 -18
  185. package/dist/schemas/sieve.d.ts +2 -2
  186. package/dist/server-entry.d.ts +2 -2
  187. package/dist/server-entry.js +8 -1
  188. package/dist/server.d.ts +10 -1
  189. package/dist/server.js +39 -1
  190. package/dist/styles.css +64 -80
  191. package/dist/tailwind-utilities.css +1 -1
  192. package/dist/tokens/themes/default-dark.js +1 -0
  193. package/dist/tokens/themes/default-light.js +1 -0
  194. package/dist/tokens/themes/required.d.ts +1 -1
  195. package/dist/tokens/themes/required.js +1 -0
  196. package/dist/tokens/tokens.css +15 -0
  197. package/dist/ui/components/Disclaimer.d.ts +19 -0
  198. package/dist/ui/components/Disclaimer.js +74 -0
  199. package/dist/ui/components/tabs-overflow.js +64 -11
  200. package/dist/ui/index.d.ts +2 -0
  201. package/dist/ui/index.js +6 -0
  202. package/dist/ui/rich-text/RichText.style.css +48 -79
  203. package/package.json +1 -1
  204. package/scripts/seed-cli.mjs +1831 -1822
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Dispute KINDS and the gate each one must pass.
3
+ *
4
+ * ## Why the kind is closed and the reason list is not
5
+ *
6
+ * The owner's two rules are policy:
7
+ *
8
+ * > An item dispute can only be raised after the order was received. A
9
+ * > "not reached" dispute is allowed once the ETD is more than 3 days past.
10
+ *
11
+ * A gate cannot branch on a user-created string. `return-reasons.ts` already
12
+ * makes this argument in its own header — *"'No returns, unless the buyer
13
+ * didn't get what they paid for' is not a policy that can be enforced against
14
+ * a free-text box: it needs a machine-readable statement of what went
15
+ * wrong"* — and it applies with more force here, because these two gates are
16
+ * MUTUALLY EXCLUSIVE.
17
+ *
18
+ * So there are two levels:
19
+ *
20
+ * 1. **`DisputeKind` — closed, here, two values.** It picks the gate.
21
+ * 2. **`disputeReasons` — a staff-creatable Firestore collection.** Every row
22
+ * carries a `kind`, so a new reason inherits an existing gate and cannot
23
+ * invent one. That list is for triage and analytics, never for policy.
24
+ *
25
+ * ## What this replaces
26
+ *
27
+ * `raiseOrderDisputeAction` took `reason: string` and checked only that it was
28
+ * non-empty. So today a buyer can file "it never arrived" on an order that was
29
+ * delivered last week, and "it arrived damaged" on one still in transit — both
30
+ * nonsense, both accepted, and both raising a `severity: "error"` fraud-category
31
+ * admin alert. The gate is the point of this file.
32
+ */
33
+ export const DISPUTE_KIND = ["item", "not_reached"];
34
+ /**
35
+ * 🛑 `Record<DisputeKind, string>`, so a third kind is a COMPILE error here
36
+ * rather than a dispute that renders `undefined` and passes no gate.
37
+ */
38
+ export const DISPUTE_KIND_LABEL = {
39
+ item: "There's a problem with what I received",
40
+ not_reached: "My order hasn't arrived",
41
+ };
42
+ export function isDisputeKind(value) {
43
+ return typeof value === "string" && DISPUTE_KIND.includes(value);
44
+ }
45
+ /**
46
+ * How long after dispatch a parcel is ASSUMED to have been deliverable, when
47
+ * the courier gave us no estimate.
48
+ *
49
+ * 🛑 This exists so the `not_reached` gate is reachable AT ALL. There is no
50
+ * courier ETD on an order today: nothing platform-books (`createShipment` has
51
+ * zero callers), and a self-shipping seller types a tracking number with no
52
+ * estimate attached. Gate solely on a stored ETD and no buyer could ever file
53
+ * a non-delivery dispute — a gate nobody can pass is the same as no feature.
54
+ *
55
+ * Published through `PublishedValueKey` so the policy page and this gate
56
+ * cannot disagree (Phase 9).
57
+ */
58
+ export const DISPUTE_TRANSIT_WINDOW_DAYS = 7;
59
+ /**
60
+ * The owner's "more than 3 days" grace, measured from the ETD.
61
+ *
62
+ * Separate from the transit window on purpose: one is "when should it have
63
+ * arrived", the other is "how long after that before we believe it is lost".
64
+ * Folding them into a single 10 would make neither number explicable on a
65
+ * policy page.
66
+ */
67
+ export const DISPUTE_NOT_REACHED_GRACE_DAYS = 3;
68
+ const DAY_MS = 24 * 60 * 60 * 1000;
69
+ function asDate(v) {
70
+ if (!v)
71
+ return null;
72
+ const d = v instanceof Date ? v : new Date(v);
73
+ return Number.isFinite(d.getTime()) ? d : null;
74
+ }
75
+ function fmt(d) {
76
+ return d.toLocaleDateString("en-IN", { day: "numeric", month: "short", year: "numeric" });
77
+ }
78
+ /**
79
+ * The effective ETD, and WHY we think so.
80
+ *
81
+ * Exported because the buyer-facing form needs to show the date they can file
82
+ * from — telling someone "not yet" without saying when is a dead end.
83
+ */
84
+ export function resolveDisputeEtd(order, transitWindowDays = DISPUTE_TRANSIT_WINDOW_DAYS) {
85
+ const courier = asDate(order.estimatedDeliveryDate);
86
+ if (courier)
87
+ return { etd: courier, source: "courier" };
88
+ const shipped = asDate(order.shippingDate);
89
+ if (shipped) {
90
+ return { etd: new Date(shipped.getTime() + transitWindowDays * DAY_MS), source: "assumed" };
91
+ }
92
+ return null;
93
+ }
94
+ /** The date from which a `not_reached` dispute becomes filable. */
95
+ export function disputeNotReachedFilableFrom(order, graceDays = DISPUTE_NOT_REACHED_GRACE_DAYS) {
96
+ const resolved = resolveDisputeEtd(order);
97
+ if (!resolved)
98
+ return null;
99
+ return new Date(resolved.etd.getTime() + graceDays * DAY_MS);
100
+ }
101
+ /**
102
+ * 🛑 `Record<DisputeKind, …>`. A third kind cannot be added without deciding
103
+ * what gates it — which is the whole reason the kind is closed.
104
+ */
105
+ export const DISPUTE_GATE = {
106
+ /**
107
+ * You cannot judge an item you have not seen.
108
+ *
109
+ * `completedAt` counts as well as `deliveryDate`: a buyer who pressed "Mark
110
+ * complete" has told us they received it, and refusing them because no
111
+ * courier scan landed would be refusing the more reliable signal of the two.
112
+ */
113
+ item: (order) => {
114
+ if (asDate(order.deliveryDate) || asDate(order.completedAt))
115
+ return { allowed: true };
116
+ return {
117
+ allowed: false,
118
+ message: "You can report a problem with an item once it arrives. If it hasn't arrived, raise a delivery issue instead.",
119
+ };
120
+ },
121
+ /**
122
+ * Only valid BEFORE receipt, and only once the parcel is genuinely late.
123
+ *
124
+ * Three refusals, each pointing somewhere:
125
+ * - delivered → the wrong kind; offer the item route or a return.
126
+ * - never dispatched → not a courier problem at all. That is the
127
+ * `seller-dispatch` obligation's job, and it is already running.
128
+ * - too early → say the date, not just "not yet".
129
+ */
130
+ not_reached: (order, now = new Date()) => {
131
+ const delivered = asDate(order.deliveryDate);
132
+ if (delivered) {
133
+ return {
134
+ allowed: false,
135
+ message: `This order was marked delivered on ${fmt(delivered)}. If something is wrong with what arrived, report a problem with the item instead.`,
136
+ };
137
+ }
138
+ if (!asDate(order.shippingDate) && !asDate(order.estimatedDeliveryDate)) {
139
+ return {
140
+ allowed: false,
141
+ message: "This order hasn't been dispatched yet, so there's nothing in transit to chase. We already track late dispatch and will act on it without you needing to do anything.",
142
+ };
143
+ }
144
+ const filableFrom = disputeNotReachedFilableFrom(order);
145
+ if (!filableFrom) {
146
+ // Unreachable given the check above; kept rather than asserted, because
147
+ // a thrown non-null assertion here would be a 500 on a buyer action.
148
+ return {
149
+ allowed: false,
150
+ message: "We can't work out an expected delivery date for this order yet. Contact support.",
151
+ };
152
+ }
153
+ if (now.getTime() < filableFrom.getTime()) {
154
+ return {
155
+ allowed: false,
156
+ message: `It's still within the expected delivery window. If it hasn't arrived by ${fmt(filableFrom)}, you can raise a delivery issue then.`,
157
+ };
158
+ }
159
+ return { allowed: true };
160
+ },
161
+ };
162
+ /**
163
+ * Convenience wrapper so callers do not index the record by hand.
164
+ *
165
+ * 🛑 Takes the NARROW `DisputeGateOrder`, and an `OrderDocument` satisfies it
166
+ * structurally — so no adapter is needed and none should be added.
167
+ *
168
+ * A first draft had a `toDisputeGateOrder(order: OrderDocument)` helper, which
169
+ * meant this module imported the order schema while the order schema imports
170
+ * `DisputeKind` from here. That cycle is type-only and therefore erased, so it
171
+ * would have compiled and run — but it is also entirely avoidable, and a
172
+ * module that defines a policy should not depend on the document the policy is
173
+ * applied to. `return-reasons.ts` beside it has no imports at all for the same
174
+ * reason.
175
+ *
176
+ * Nothing leaks by passing the whole order in: what crosses back out is a
177
+ * `DisputeGateResult`, never the document (Root Cause #70).
178
+ */
179
+ export function checkDisputeGate(kind, order, now) {
180
+ return DISPUTE_GATE[kind](order, now);
181
+ }
@@ -35,7 +35,7 @@ export declare const REFUND_COPY: {
35
35
  readonly reasonSelectPlaceholder: "Choose a reason";
36
36
  readonly reasonNoteLabel: "Anything else we should know? (optional)";
37
37
  readonly alreadyRefundedMessage: "A refund has already been processed on this order. No further disputes or refund requests can be filed.";
38
- readonly acknowledgments: readonly ["I understand this refund request, once approved, permanently removes my ability to file any dispute or RMA claim on this order.", "I confirm the item has not been used, worn, or damaged by me, and I am returning it in original condition (if a return is required).", "I understand the refund amount may take 5–7 business days to reflect and that platform fees may be non-recoverable."];
38
+ readonly acknowledgments: readonly ["I understand this refund request, once approved, permanently removes my ability to file any dispute or RMA claim on this order.", "I confirm the item has not been used, worn, or damaged by me, and I am returning it in original condition (if a return is required).", "I understand the refund amount may take {{refundBusinessDaysMin}}–{{refundBusinessDaysMax}} business days to reflect and that platform fees may be non-recoverable."];
39
39
  };
40
40
  readonly siblingPayments: {
41
41
  readonly heading: (count: number) => string;
@@ -38,7 +38,24 @@ export const REFUND_COPY = {
38
38
  acknowledgments: [
39
39
  "I understand this refund request, once approved, permanently removes my ability to file any dispute or RMA claim on this order.",
40
40
  "I confirm the item has not been used, worn, or damaged by me, and I am returning it in original condition (if a return is required).",
41
- "I understand the refund amount may take 5–7 business days to reflect and that platform fees may be non-recoverable.",
41
+ /*
42
+ * 🛑 Phase 9 — TOKENS, resolved by `resolvePublishedCopy` at render.
43
+ *
44
+ * This literal was one of the three contradicting owners of the refund
45
+ * timeline: "5–7 business days" here, "5–7 business days via Razorpay"
46
+ * on the policy page (naming a gateway that was not even the one in
47
+ * use), and "3–5 business days" in the FAQ. Three statements of one
48
+ * fact, no reconciliation, and the FAQ one admin-editable so it could
49
+ * drift further after deployment.
50
+ *
51
+ * The caller renders this through `resolvePublishedCopy`, so the number
52
+ * now has exactly one definition. Note this string is an
53
+ * ACKNOWLEDGEMENT the buyer ticks — a token left unresolved here would
54
+ * appear in something they are agreeing to, which is the strongest
55
+ * possible argument for the unknown-token rule leaving `{{…}}` visible
56
+ * rather than blanking it.
57
+ */
58
+ "I understand the refund amount may take {{refundBusinessDaysMin}}–{{refundBusinessDaysMax}} business days to reflect and that platform fees may be non-recoverable.",
42
59
  ],
43
60
  },
44
61
  siblingPayments: {
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Does this store accept buyer points as part-payment?
3
+ *
4
+ * ## Why this is a function and not a bare field read
5
+ *
6
+ * Decision 3 has two halves: *"the main store always accepts, others opt in"*.
7
+ * The opt-in half is `StoreDocument.acceptsPoints`; the always half is the
8
+ * platform's own storefront, which cannot decline to fund its own programme.
9
+ *
10
+ * 🛑 The platform store is resolved in CODE rather than seeded `true`, because a
11
+ * seeded flag can be switched off by an edit, a reseed, or an admin clicking the
12
+ * wrong toggle — and the one store that must never stop accepting is the one the
13
+ * whole programme is advertised on. `UserPointsView` tells buyers points are
14
+ * spendable; if the only store could opt out, that promise would be a lie that
15
+ * nothing detected.
16
+ *
17
+ * ## 🛑 Absent means NOT accepted
18
+ *
19
+ * Matching `supportsSaleProtection`'s rule on the same document, and for the
20
+ * same reason: the accepting store ABSORBS the redemption against its payout,
21
+ * so defaulting absent to `true` would enrol every existing seller in funding
22
+ * discounts they never agreed to. A tri-state would be worse still — a buyer
23
+ * cannot tell a seller who declined from one who has not been asked.
24
+ */
25
+ /**
26
+ * The platform's own storefront.
27
+ *
28
+ * Hard-coded deliberately: this is an identity, not a setting. It is the same
29
+ * id `realListingsOnly` and the seed's `REAL_STORE_IDS` already treat as the
30
+ * platform's own.
31
+ */
32
+ export declare const PLATFORM_STORE_ID = "store-letitrip-official";
33
+ export declare function storeAcceptsPoints(store: {
34
+ id?: string;
35
+ acceptsPoints?: boolean;
36
+ } | null | undefined, storeId?: string): boolean;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Does this store accept buyer points as part-payment?
3
+ *
4
+ * ## Why this is a function and not a bare field read
5
+ *
6
+ * Decision 3 has two halves: *"the main store always accepts, others opt in"*.
7
+ * The opt-in half is `StoreDocument.acceptsPoints`; the always half is the
8
+ * platform's own storefront, which cannot decline to fund its own programme.
9
+ *
10
+ * 🛑 The platform store is resolved in CODE rather than seeded `true`, because a
11
+ * seeded flag can be switched off by an edit, a reseed, or an admin clicking the
12
+ * wrong toggle — and the one store that must never stop accepting is the one the
13
+ * whole programme is advertised on. `UserPointsView` tells buyers points are
14
+ * spendable; if the only store could opt out, that promise would be a lie that
15
+ * nothing detected.
16
+ *
17
+ * ## 🛑 Absent means NOT accepted
18
+ *
19
+ * Matching `supportsSaleProtection`'s rule on the same document, and for the
20
+ * same reason: the accepting store ABSORBS the redemption against its payout,
21
+ * so defaulting absent to `true` would enrol every existing seller in funding
22
+ * discounts they never agreed to. A tri-state would be worse still — a buyer
23
+ * cannot tell a seller who declined from one who has not been asked.
24
+ */
25
+ /**
26
+ * The platform's own storefront.
27
+ *
28
+ * Hard-coded deliberately: this is an identity, not a setting. It is the same
29
+ * id `realListingsOnly` and the seed's `REAL_STORE_IDS` already treat as the
30
+ * platform's own.
31
+ */
32
+ export const PLATFORM_STORE_ID = "store-letitrip-official";
33
+ export function storeAcceptsPoints(store, storeId) {
34
+ /*
35
+ * The id is taken from either source so a caller holding only an id (the
36
+ * order-group loop) and one holding the document (an admin surface) get the
37
+ * same answer. Mismatched sources would be two rules again.
38
+ */
39
+ const id = store?.id ?? storeId;
40
+ if (id === PLATFORM_STORE_ID)
41
+ return true;
42
+ return store?.acceptsPoints === true;
43
+ }
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Shared purchase, S5a — one payer, N destinations.
3
+ *
4
+ * ## What this is, and what it deliberately is not
5
+ *
6
+ * The coordinator buys everything and assigns a destination per item, so one
7
+ * paid order becomes N parcels. That is **~20% of the shared-purchase work for
8
+ * most of its value** (the plan's own assessment), because it needs none of
9
+ * the hard parts: no multi-party payment, no coordinator deposit, no approval
10
+ * cascade, no per-buyer invoicing, no per-buyer GST, and no stock-reservation
11
+ * primitive.
12
+ *
13
+ * 🛑 It is NOT S5b. There is exactly ONE payer and ONE place of supply, which
14
+ * is what keeps the tax, the invoice and the refund path unchanged. The moment
15
+ * a second person pays, every one of those becomes per-buyer and the design is
16
+ * a different design.
17
+ *
18
+ * ## 🛑 Why the fees are SNAPSHOTTED, and the precedent that proves it
19
+ *
20
+ * A coordinator commits to a quoted total. If the handling fee or the
21
+ * per-destination shipping is re-read at settle, a seller can raise it after
22
+ * the quote and the coordinator absorbs the difference.
23
+ *
24
+ * The codebase already has this exact hole and this exact fix: the refund path
25
+ * reads `finalSale` from the ORDER snapshot rather than the live product,
26
+ * because — in its own words — "re-reading the live product would let a seller
27
+ * flip the switch afterwards". D61 generalises it: *any agreement with a gap
28
+ * between "terms agreed" and "money taken" must snapshot its terms at
29
+ * agreement.*
30
+ *
31
+ * So `quoteSharedPurchase` takes the rates as ARGUMENTS and the caller
32
+ * snapshots the result onto the order. There is no settings read in here.
33
+ */
34
+ /** The two rates, read from the store document at quote time. */
35
+ export interface SharedPurchaseRates {
36
+ allowSharedPurchase?: boolean;
37
+ sharedPurchaseHandlingFee?: number;
38
+ sharedPurchaseExtraShippingPerDestination?: number;
39
+ }
40
+ export interface SharedPurchaseQuoteInput {
41
+ /**
42
+ * Distinct destinations in this order group, INCLUDING the first.
43
+ *
44
+ * 🛑 A count of DISTINCT addresses, not of items. Three items to one address
45
+ * is one parcel and no extra leg; two items to two addresses is two. Passing
46
+ * an item count would charge a coordinator for splitting an order they did
47
+ * not split.
48
+ */
49
+ destinationCount: number;
50
+ /** The store's snapshotted rates. */
51
+ rates: SharedPurchaseRates;
52
+ }
53
+ export interface SharedPurchaseQuote {
54
+ /** True when this is actually a multi-destination order. */
55
+ isShared: boolean;
56
+ /** Flat handling fee, or 0. */
57
+ handlingFee: number;
58
+ /** Extra shipping for destinations beyond the first, or 0. */
59
+ extraShippingFee: number;
60
+ /** `handlingFee + extraShippingFee`, the figure added to the order total. */
61
+ total: number;
62
+ /**
63
+ * Set when the arrangement cannot be priced — the seller allows it but has
64
+ * not configured a rate.
65
+ *
66
+ * 🛑 The caller MUST act on this rather than treating the fee as ₹0. That is
67
+ * D44 exactly: `shippingUnavailable` existed with its own docstring saying
68
+ * "the caller MUST act on this rather than trusting `shippingFee: 0`", had
69
+ * ZERO consumers, and an `estimate`-mode store shipped free on every path as
70
+ * a result. An unpriced arrangement must be refused, not given away.
71
+ */
72
+ unpriced?: "handling" | "extra-shipping";
73
+ }
74
+ /**
75
+ * Price a shared-purchase arrangement for ONE order group.
76
+ *
77
+ * Pure: no settings read, no Firestore, no clock. The rates come in, the
78
+ * figure comes out, and the caller snapshots it.
79
+ */
80
+ export declare function quoteSharedPurchase(input: SharedPurchaseQuoteInput): SharedPurchaseQuote;
81
+ /**
82
+ * Distinct destinations across a set of lines.
83
+ *
84
+ * 🛑 Lines with NO `destinationAddressId` collapse into one bucket — the
85
+ * order's own address — rather than counting as a destination each. Otherwise
86
+ * an ordinary three-item order would look like three destinations and be
87
+ * charged two extra legs.
88
+ */
89
+ export declare function countDestinations(lines: readonly {
90
+ destinationAddressId?: string;
91
+ }[]): number;
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Shared purchase, S5a — one payer, N destinations.
3
+ *
4
+ * ## What this is, and what it deliberately is not
5
+ *
6
+ * The coordinator buys everything and assigns a destination per item, so one
7
+ * paid order becomes N parcels. That is **~20% of the shared-purchase work for
8
+ * most of its value** (the plan's own assessment), because it needs none of
9
+ * the hard parts: no multi-party payment, no coordinator deposit, no approval
10
+ * cascade, no per-buyer invoicing, no per-buyer GST, and no stock-reservation
11
+ * primitive.
12
+ *
13
+ * 🛑 It is NOT S5b. There is exactly ONE payer and ONE place of supply, which
14
+ * is what keeps the tax, the invoice and the refund path unchanged. The moment
15
+ * a second person pays, every one of those becomes per-buyer and the design is
16
+ * a different design.
17
+ *
18
+ * ## 🛑 Why the fees are SNAPSHOTTED, and the precedent that proves it
19
+ *
20
+ * A coordinator commits to a quoted total. If the handling fee or the
21
+ * per-destination shipping is re-read at settle, a seller can raise it after
22
+ * the quote and the coordinator absorbs the difference.
23
+ *
24
+ * The codebase already has this exact hole and this exact fix: the refund path
25
+ * reads `finalSale` from the ORDER snapshot rather than the live product,
26
+ * because — in its own words — "re-reading the live product would let a seller
27
+ * flip the switch afterwards". D61 generalises it: *any agreement with a gap
28
+ * between "terms agreed" and "money taken" must snapshot its terms at
29
+ * agreement.*
30
+ *
31
+ * So `quoteSharedPurchase` takes the rates as ARGUMENTS and the caller
32
+ * snapshots the result onto the order. There is no settings read in here.
33
+ */
34
+ import { roundRupees } from "../../../../utils/number.formatter.js";
35
+ /**
36
+ * Price a shared-purchase arrangement for ONE order group.
37
+ *
38
+ * Pure: no settings read, no Firestore, no clock. The rates come in, the
39
+ * figure comes out, and the caller snapshots it.
40
+ */
41
+ export function quoteSharedPurchase(input) {
42
+ const none = {
43
+ isShared: false,
44
+ handlingFee: 0,
45
+ extraShippingFee: 0,
46
+ total: 0,
47
+ };
48
+ /*
49
+ * One destination is an ordinary order. Checked BEFORE the allow flag, so a
50
+ * seller who has not opted in is unaffected by this code path entirely —
51
+ * rather than being refused an order they were always able to take.
52
+ */
53
+ const destinations = Math.max(1, Math.floor(input.destinationCount));
54
+ if (destinations <= 1)
55
+ return none;
56
+ if (input.rates.allowSharedPurchase !== true) {
57
+ /*
58
+ * 🛑 Returns `isShared: false` rather than throwing, and the CALLER
59
+ * refuses. This function prices; it does not authorise. A thrown error
60
+ * here would be caught by a preview path and rendered as a broken page,
61
+ * where the correct behaviour is to tell the buyer this seller does not
62
+ * split orders.
63
+ */
64
+ return none;
65
+ }
66
+ const handling = input.rates.sharedPurchaseHandlingFee;
67
+ const perExtra = input.rates.sharedPurchaseExtraShippingPerDestination;
68
+ /*
69
+ * 🛑 `undefined` is UNPRICED, not zero — see the `unpriced` field. A seller
70
+ * who opted in without setting a rate has not agreed to do it for free, and
71
+ * charging ₹0 would hand them the extra labour at their own cost silently.
72
+ */
73
+ if (typeof handling !== "number" || !Number.isFinite(handling)) {
74
+ return { ...none, isShared: true, unpriced: "handling" };
75
+ }
76
+ if (typeof perExtra !== "number" || !Number.isFinite(perExtra)) {
77
+ return { ...none, isShared: true, unpriced: "extra-shipping" };
78
+ }
79
+ const handlingFee = roundRupees(Math.max(0, handling));
80
+ // BEYOND THE FIRST: the first destination's shipping is what the order would
81
+ // have paid anyway, so only the marginal legs are charged here.
82
+ const extraShippingFee = roundRupees(Math.max(0, perExtra) * (destinations - 1));
83
+ return {
84
+ isShared: true,
85
+ handlingFee,
86
+ extraShippingFee,
87
+ total: roundRupees(handlingFee + extraShippingFee),
88
+ };
89
+ }
90
+ /**
91
+ * Distinct destinations across a set of lines.
92
+ *
93
+ * 🛑 Lines with NO `destinationAddressId` collapse into one bucket — the
94
+ * order's own address — rather than counting as a destination each. Otherwise
95
+ * an ordinary three-item order would look like three destinations and be
96
+ * charged two extra legs.
97
+ */
98
+ export function countDestinations(lines) {
99
+ const ids = new Set();
100
+ let usesOrderAddress = false;
101
+ for (const line of lines) {
102
+ if (line.destinationAddressId)
103
+ ids.add(line.destinationAddressId);
104
+ else
105
+ usesOrderAddress = true;
106
+ }
107
+ return ids.size + (usesOrderAddress ? 1 : 0);
108
+ }
@@ -42,6 +42,17 @@ export interface PublicSiteSettings {
42
42
  chat?: {
43
43
  enabled: boolean;
44
44
  };
45
+ /**
46
+ * Is the support desk reachable — read by `UserLayoutClient`, a client
47
+ * component. Narrowed to the one boolean rather than passed by reference,
48
+ * so a field added to the document's `support` group later is not published
49
+ * by accident; `PUBLIC_SITE_SETTINGS_FIELDS` carries the same caveat beside
50
+ * its entry. Optional here because the group is absent on a settings
51
+ * document written before it existed.
52
+ */
53
+ support?: {
54
+ enabled: boolean;
55
+ };
45
56
  /**
46
57
  * The browser-side search index kill switch. **ON by default** — the
47
58
  * projection emits `indexEnabled: doc.search?.indexEnabled !== false`, so
@@ -79,6 +79,17 @@ export interface PayoutDeduction {
79
79
  * plus ₹80 postage" is a sentence; one net figure is not.
80
80
  */
81
81
  shippingReimbursement: number;
82
+ /**
83
+ * Rupee value of buyer points this order was settled with, deducted from
84
+ * `netAmount` (D46/D47, decisions 3 and 17 — the accepting store funds the
85
+ * redemption).
86
+ *
87
+ * Returned as its own figure rather than folded into `totalDeduction` for the
88
+ * same reason `shippingReimbursement` is: *"'₹900 less ₹30 commission plus
89
+ * ₹80 postage' is a sentence; one net figure is not."* A seller looking at a
90
+ * short payout needs to see which of the four terms shortened it.
91
+ */
92
+ pointsFunded: number;
82
93
  }
83
94
  /**
84
95
  * What a seller is actually paid.
@@ -101,8 +112,29 @@ export interface PayoutDeduction {
101
112
  *
102
113
  * Defaulted to 0, so the three call sites that do not yet pass it keep their
103
114
  * current behaviour exactly rather than silently gaining a term.
115
+ *
116
+ * ## 🛑 `pointsFunded` is the mirror of that, and it is a DEDUCTION
117
+ *
118
+ * Decisions 3 and 17: the programme is seller-funded at both ends — the
119
+ * accepting store absorbs the redemption, the originating store bears the
120
+ * earn — and the platform funds neither. So points spent on an order reduce
121
+ * that order's payout by the rupee value spent.
122
+ *
123
+ * It sits in the SAME position as postage and for the inverse reason: outside
124
+ * the commission and gateway bases. The seller agreed to fund a discount, not
125
+ * to pay us a commission on the discount they funded, and a gateway percentage
126
+ * on money no gateway touched is not a card fee at all.
127
+ *
128
+ * 🛑 So `grossAmount` is untouched and the fee figures are IDENTICAL whether
129
+ * points were used or not. That is what keeps the commission the seller is
130
+ * charged a function of the sale rather than of how the buyer chose to settle
131
+ * it — and it is why this cannot be implemented by passing a smaller
132
+ * `grossAmount`, which is the obvious shortcut and silently reduces our own
133
+ * commission by 2% of every redemption.
134
+ *
135
+ * Also defaulted to 0, for the same reason.
104
136
  */
105
- export declare function computePayoutDeduction(grossAmount: number, commissions: FeeCommissionRates, shippingReimbursement?: number): PayoutDeduction;
137
+ export declare function computePayoutDeduction(grossAmount: number, commissions: FeeCommissionRates, shippingReimbursement?: number, pointsFunded?: number): PayoutDeduction;
106
138
  export interface CodHandlingFeeRates {
107
139
  /**
108
140
  * Rupee CEILING on the COD handling fee. Optional so a `siteSettings`
@@ -114,8 +114,29 @@ export function allocateCheckoutFees(groupSubtotals, fees) {
114
114
  *
115
115
  * Defaulted to 0, so the three call sites that do not yet pass it keep their
116
116
  * current behaviour exactly rather than silently gaining a term.
117
+ *
118
+ * ## 🛑 `pointsFunded` is the mirror of that, and it is a DEDUCTION
119
+ *
120
+ * Decisions 3 and 17: the programme is seller-funded at both ends — the
121
+ * accepting store absorbs the redemption, the originating store bears the
122
+ * earn — and the platform funds neither. So points spent on an order reduce
123
+ * that order's payout by the rupee value spent.
124
+ *
125
+ * It sits in the SAME position as postage and for the inverse reason: outside
126
+ * the commission and gateway bases. The seller agreed to fund a discount, not
127
+ * to pay us a commission on the discount they funded, and a gateway percentage
128
+ * on money no gateway touched is not a card fee at all.
129
+ *
130
+ * 🛑 So `grossAmount` is untouched and the fee figures are IDENTICAL whether
131
+ * points were used or not. That is what keeps the commission the seller is
132
+ * charged a function of the sale rather than of how the buyer chose to settle
133
+ * it — and it is why this cannot be implemented by passing a smaller
134
+ * `grossAmount`, which is the obvious shortcut and silently reduces our own
135
+ * commission by 2% of every redemption.
136
+ *
137
+ * Also defaulted to 0, for the same reason.
117
138
  */
118
- export function computePayoutDeduction(grossAmount, commissions, shippingReimbursement = 0) {
139
+ export function computePayoutDeduction(grossAmount, commissions, shippingReimbursement = 0, pointsFunded = 0) {
119
140
  const platformFee = roundRupees(grossAmount * (commissions.platformFeePercent / 100));
120
141
  const gatewayFee = roundRupees(grossAmount * ((commissions.gatewayFeePercent ?? 0) / 100));
121
142
  const gstOnFee = roundRupees(platformFee * (commissions.gstPercent / 100));
@@ -123,7 +144,15 @@ export function computePayoutDeduction(grossAmount, commissions, shippingReimbur
123
144
  const postage = Number.isFinite(shippingReimbursement)
124
145
  ? Math.max(0, shippingReimbursement)
125
146
  : 0;
126
- const netAmount = Math.max(0, roundRupees(grossAmount - totalDeduction + postage));
147
+ const points = Number.isFinite(pointsFunded) ? Math.max(0, pointsFunded) : 0;
148
+ /*
149
+ * Clamped at zero, as it already was. A redemption cannot exceed 50% of the
150
+ * order total, so it cannot plausibly exceed the net — but a floor here means
151
+ * no caller can ever hand a seller a negative payout, which would be written
152
+ * to a `PayoutDocument.amount` that every downstream sum then treats as a
153
+ * credit against the platform.
154
+ */
155
+ const netAmount = Math.max(0, roundRupees(grossAmount - totalDeduction + postage - points));
127
156
  return {
128
157
  platformFee,
129
158
  gatewayFee,
@@ -131,6 +160,7 @@ export function computePayoutDeduction(grossAmount, commissions, shippingReimbur
131
160
  totalDeduction,
132
161
  netAmount,
133
162
  shippingReimbursement: roundRupees(postage),
163
+ pointsFunded: roundRupees(points),
134
164
  };
135
165
  }
136
166
  /** Buyer-facing COD handling ceiling, in decimal rupees. */
package/dist/client.d.ts CHANGED
@@ -283,6 +283,8 @@ export { useLogout, useLogin, useGoogleLogin, useLinkGoogleAccount, useRegister,
283
283
  export type { LoginCredentials, RegisterData, ForgotPasswordData, ResetPasswordData, VerifyEmailData, ChangeEmailData } from "./features/auth/index";
284
284
  export { CartView, CartItemRow, CartGroupLineRow, CartSummary, CartPriceBreakdown, CartDrawer, CheckoutView, CheckoutSuccessView, CheckoutAddressStep, useGuestCart, useCartCount, useAddToCart, useCart, useGuestCartMerge, useCartQuery } from "./features/cart/index";
285
285
  export { StoreAddonsPicker, hasAnyStoreAddon } from "./features/cart/index";
286
+ export { PointsTenderPicker } from "./features/cart/index";
287
+ export type { PointsTenderPickerProps } from "./features/cart/index";
286
288
  export { clientLineTotal } from "./features/cart/utils/line-total";
287
289
  export type { PricedCartLine } from "./features/cart/utils/line-total";
288
290
  export type { CartPriceBreakdownData, CartPriceBreakdownStore, StoreAddonsValue, StoreAddonsRates } from "./features/cart/index";
@@ -389,6 +391,11 @@ export type { UserAccountHubViewProps, UserAccountHubViewLabels, UserOrdersViewP
389
391
  export { useOrders, useOrder, OrdersList } from "./features/orders/index";
390
392
  export { OrderStatusTimeline } from "./features/orders/components/OrderStatusTimeline";
391
393
  export type { OrderStatusTimelineProps } from "./features/orders/components/OrderStatusTimeline";
394
+ export { OrderProvenanceCard } from "./features/orders/components/OrderProvenanceCard";
395
+ export type { OrderProvenanceCardProps } from "./features/orders/components/OrderProvenanceCard";
396
+ export { RaiseDisputeForm } from "./features/orders/components/RaiseDisputeForm";
397
+ export type { RaiseDisputeFormProps } from "./features/orders/components/RaiseDisputeForm";
398
+ export type { OrderSourceContext } from "./features/orders/schemas/firestore";
392
399
  export { PROTECTION_CLAIM_REASON_LABEL } from "./features/protection-claims/schemas/firestore";
393
400
  export type { ProtectionClaimReason } from "./features/protection-claims/schemas/firestore";
394
401
  export { OrderCompletionPanel } from "./features/orders/components/OrderCompletionPanel";
@@ -586,6 +593,10 @@ export type { SellerSupportViewProps } from "./features/seller/components/Seller
586
593
  export { REFUND_COPY } from "./_internal/shared/features/orders/refund-copy";
587
594
  export { RETURN_REASON, FINAL_SALE_EXEMPT_REASONS, RETURN_REASON_LABEL, RETURN_REASON_GROUP_LABEL, isFinalSaleExempt, isReturnReason, selectableReturnReasons, } from "./_internal/shared/features/orders/return-reasons";
588
595
  export type { ReturnReason } from "./_internal/shared/features/orders/return-reasons";
596
+ export { DISPUTE_KIND, DISPUTE_KIND_LABEL, DISPUTE_GATE, DISPUTE_TRANSIT_WINDOW_DAYS, DISPUTE_NOT_REACHED_GRACE_DAYS, isDisputeKind, checkDisputeGate, resolveDisputeEtd, disputeNotReachedFilableFrom, } from "./_internal/shared/features/orders/dispute-reasons";
597
+ export type { DisputeKind, DisputeGateOrder, DisputeGateResult, } from "./_internal/shared/features/orders/dispute-reasons";
598
+ export { INTEGRATIONS, INTEGRATION_ORDER, readIntegrationStates, integrationPatch, allIntegrationsPatch, } from "./_internal/shared/features/admin/integrations";
599
+ export type { IntegrationId, IntegrationDescriptor, IntegrationState, } from "./_internal/shared/features/admin/integrations";
589
600
  export { RefundRequestView } from "./features/orders/components/RefundRequestView";
590
601
  export type { RefundRequestViewProps, RefundRequestSubmission, } from "./features/orders/components/RefundRequestView";
591
602
  export { ORDER_RETURN_WINDOW_DAYS, ORDER_RETURN_WINDOW_MS, ORDER_CANCELLABLE_STATUSES, } from "./_internal/shared/features/orders/config";