@mohasinac/appkit 4.53.2 → 4.54.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 (350) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/server/features/auth/capabilities.js +7 -5
  3. package/dist/_internal/server/features/checkout/actions.d.ts +22 -6
  4. package/dist/_internal/server/features/checkout/actions.js +96 -51
  5. package/dist/_internal/server/features/checkout/index.d.ts +1 -1
  6. package/dist/_internal/server/features/checkout/index.js +1 -1
  7. package/dist/_internal/server/features/checkout/supplier-identity.js +28 -6
  8. package/dist/_internal/server/features/orders/adapters.js +1 -3
  9. package/dist/_internal/server/features/products/listing-tab-counts.js +81 -25
  10. package/dist/_internal/server/features/search/index-build/sources.js +43 -2
  11. package/dist/_internal/server/features/site-settings/adapters.js +1 -1
  12. package/dist/_internal/server/features/stores/adapters.d.ts +1 -1
  13. package/dist/_internal/server/features/stores/adapters.js +0 -1
  14. package/dist/_internal/server/jobs/core/analyticsAlertEvaluate.js +2 -5
  15. package/dist/_internal/server/jobs/core/jobRunners.js +0 -10
  16. package/dist/_internal/server/jobs/core/onOrderCreate.js +10 -104
  17. package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +0 -2
  18. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +0 -1
  19. package/dist/_internal/server/jobs/core/onScamReportCreate.js +0 -1
  20. package/dist/_internal/server/jobs/core/onScamReportRejected.js +0 -1
  21. package/dist/_internal/server/jobs/core/onScamReportVerified.js +0 -1
  22. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +0 -1
  23. package/dist/_internal/server/jobs/core/pendingOrderTimeout.js +0 -1
  24. package/dist/_internal/server/notifications/channel-health.d.ts +7 -3
  25. package/dist/_internal/server/notifications/channel-health.js +2 -2
  26. package/dist/_internal/server/notifications/send-guard.d.ts +1 -1
  27. package/dist/_internal/server/notifications/send-guard.js +2 -4
  28. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  29. package/dist/_internal/shared/actions/action-registry.js +128 -28
  30. package/dist/_internal/shared/checkout/order-math.d.ts +1 -1
  31. package/dist/_internal/shared/checkout/order-math.js +1 -1
  32. package/dist/_internal/shared/features/categories/bundle-copy.d.ts +1 -1
  33. package/dist/_internal/shared/features/checkout/config.d.ts +0 -2
  34. package/dist/_internal/shared/features/checkout/config.js +0 -2
  35. package/dist/_internal/shared/features/messaging/config.d.ts +7 -5
  36. package/dist/_internal/shared/features/messaging/config.js +1 -4
  37. package/dist/_internal/shared/features/site-settings/fees.d.ts +0 -2
  38. package/dist/_internal/shared/features/site-settings/fees.js +0 -2
  39. package/dist/_internal/shared/features/site-settings/supplier-of-record.d.ts +56 -0
  40. package/dist/_internal/shared/features/site-settings/supplier-of-record.js +57 -0
  41. package/dist/_internal/shared/fees/calculator.d.ts +0 -8
  42. package/dist/_internal/shared/fees/calculator.js +0 -7
  43. package/dist/_internal/shared/listing-types/tiers.d.ts +94 -0
  44. package/dist/_internal/shared/listing-types/tiers.js +150 -0
  45. package/dist/cli/index.js +0 -2
  46. package/dist/client.d.ts +25 -4
  47. package/dist/client.js +36 -5
  48. package/dist/constants/api-endpoints.d.ts +21 -15
  49. package/dist/constants/api-endpoints.js +7 -8
  50. package/dist/constants/field-names.d.ts +1 -0
  51. package/dist/constants/field-names.js +1 -0
  52. package/dist/constants/notification-types.d.ts +1 -1
  53. package/dist/constants/notification-types.js +1 -1
  54. package/dist/core/integration-keys.d.ts +5 -5
  55. package/dist/core/integration-keys.js +21 -10
  56. package/dist/features/about/components/FeesView.js +0 -6
  57. package/dist/features/about/components/GuidesHubView.js +15 -2
  58. package/dist/features/account/components/NotificationPreferencesPanel.js +3 -4
  59. package/dist/features/account/components/UserOrdersView.js +26 -7
  60. package/dist/features/account/types/index.d.ts +0 -2
  61. package/dist/features/addresses/utils/postal-autofill.d.ts +39 -0
  62. package/dist/features/addresses/utils/postal-autofill.js +54 -0
  63. package/dist/features/admin/actions/notification-actions.d.ts +2 -8
  64. package/dist/features/admin/actions/notification-actions.js +9 -104
  65. package/dist/features/admin/components/AdminGuideHubView.js +1 -8
  66. package/dist/features/admin/components/AdminOrderEditorView.d.ts +1 -1
  67. package/dist/features/admin/components/AdminOrdersView.js +0 -2
  68. package/dist/features/admin/components/AdminSectionsView.js +3 -2
  69. package/dist/features/admin/components/AdminSiteSettingsView.js +22 -68
  70. package/dist/features/admin/components/AdminStoreEditorView.js +72 -34
  71. package/dist/features/admin/components/OwnerQuickActions.d.ts +29 -0
  72. package/dist/features/admin/components/OwnerQuickActions.js +142 -0
  73. package/dist/features/admin/components/sections/adminSectionsTypes.js +13 -4
  74. package/dist/features/admin/components/sections/icon-options.d.ts +21 -0
  75. package/dist/features/admin/components/sections/icon-options.js +23 -0
  76. package/dist/features/admin/components/sections/sectionTemplates.js +4 -1
  77. package/dist/features/admin/constants/site-settings-tabs.d.ts +7 -12
  78. package/dist/features/admin/constants/site-settings-tabs.js +6 -12
  79. package/dist/features/admin/repository/site-settings.repository.js +1 -1
  80. package/dist/features/admin/schemas/admin-editor-forms.d.ts +1 -1
  81. package/dist/features/admin/schemas/admin-editor-forms.js +4 -1
  82. package/dist/features/admin/schemas/admin-user-form.d.ts +0 -61
  83. package/dist/features/admin/schemas/admin-user-form.js +3 -44
  84. package/dist/features/admin/schemas/firestore.d.ts +28 -54
  85. package/dist/features/admin/schemas/firestore.js +40 -18
  86. package/dist/features/auctions/components/AuctionDetailPageView.js +4 -3
  87. package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +11 -1
  88. package/dist/features/auctions/components/MarketplaceAuctionCard.js +9 -2
  89. package/dist/features/auth/checkout-value-otp.d.ts +1 -1
  90. package/dist/features/auth/checkout-value-otp.js +1 -1
  91. package/dist/features/auth/permissions/constants.d.ts +29 -2
  92. package/dist/features/auth/permissions/constants.js +67 -1
  93. package/dist/features/blog/components/BlogFeaturedCard.d.ts +11 -1
  94. package/dist/features/blog/components/BlogFeaturedCard.js +9 -2
  95. package/dist/features/cart/components/CartDrawer.js +3 -2
  96. package/dist/features/cart/components/CartGroupLineRow.js +2 -1
  97. package/dist/features/cart/components/CartPriceBreakdown.d.ts +0 -2
  98. package/dist/features/cart/components/CartPriceBreakdown.js +1 -1
  99. package/dist/features/cart/components/StoreAddonsPicker.d.ts +2 -5
  100. package/dist/features/cart/components/StoreAddonsPicker.js +4 -5
  101. package/dist/features/cart/hooks/useAddToCart.js +10 -5
  102. package/dist/features/cart/repository/cart.repository.js +1 -2
  103. package/dist/features/cart/schemas/firestore.d.ts +1 -2
  104. package/dist/features/cart/utils/pending-ops.d.ts +11 -1
  105. package/dist/features/cart/utils/pending-ops.js +14 -2
  106. package/dist/features/categories/components/BrandDetailPageView.js +2 -1
  107. package/dist/features/categories/components/BundleDetailView.js +2 -1
  108. package/dist/features/categories/components/CategoryDetailPageView.js +2 -1
  109. package/dist/features/categories/components/CategoryGrid.d.ts +11 -1
  110. package/dist/features/categories/components/CategoryGrid.js +9 -2
  111. package/dist/features/checkout/actions/checkout-value-otp-actions.d.ts +10 -5
  112. package/dist/features/checkout/actions/checkout-value-otp-actions.js +2 -88
  113. package/dist/features/classified/components/ClassifiedDetailPageView.js +2 -1
  114. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +2 -1
  115. package/dist/features/events/components/EventCard.d.ts +11 -1
  116. package/dist/features/events/components/EventCard.js +9 -2
  117. package/dist/features/grouped/components/GroupedListingDetailView.js +3 -1
  118. package/dist/features/homepage/components/CTABannerSection.d.ts +3 -1
  119. package/dist/features/homepage/components/CTABannerSection.js +6 -3
  120. package/dist/features/homepage/components/HeroCarousel.js +8 -6
  121. package/dist/features/homepage/components/MarketplaceHomepageView.js +33 -7
  122. package/dist/features/homepage/components/SectionCarousel.js +13 -5
  123. package/dist/features/homepage/components/SecurityHighlightsSection.d.ts +8 -3
  124. package/dist/features/homepage/components/SecurityHighlightsSection.js +2 -2
  125. package/dist/features/homepage/components/StatsCounterSection.d.ts +9 -4
  126. package/dist/features/homepage/components/StatsCounterSection.js +2 -2
  127. package/dist/features/homepage/components/TestimonialsCarousel.js +1 -1
  128. package/dist/features/homepage/components/TrustFeaturesSection.d.ts +18 -4
  129. package/dist/features/homepage/components/TrustFeaturesSection.js +5 -5
  130. package/dist/features/homepage/components/WelcomeSection.d.ts +13 -2
  131. package/dist/features/homepage/components/WelcomeSection.js +3 -3
  132. package/dist/features/homepage/components/WhatsAppCommunitySection.d.ts +28 -0
  133. package/dist/features/homepage/components/WhatsAppCommunitySection.js +42 -6
  134. package/dist/features/homepage/components/WhatsAppGlyph.d.ts +20 -0
  135. package/dist/features/homepage/components/WhatsAppGlyph.js +20 -0
  136. package/dist/features/homepage/constants/hero-carousel-styles.d.ts +8 -6
  137. package/dist/features/homepage/constants/hero-carousel-styles.js +8 -6
  138. package/dist/features/homepage/constants/section-copy.d.ts +12 -10
  139. package/dist/features/homepage/constants/section-copy.js +28 -6
  140. package/dist/features/homepage/constants/stat-icons.d.ts +12 -0
  141. package/dist/features/homepage/constants/stat-icons.js +17 -0
  142. package/dist/features/homepage/constants/trust-icon-aliases.d.ts +8 -0
  143. package/dist/features/homepage/constants/trust-icon-aliases.js +75 -0
  144. package/dist/features/homepage/lib/section-defaults.d.ts +16 -1
  145. package/dist/features/homepage/lib/section-defaults.js +24 -4
  146. package/dist/features/homepage/lib/section-renderer.js +48 -8
  147. package/dist/features/homepage/schemas/firestore.d.ts +18 -1
  148. package/dist/features/layout/AppLayoutShell.js +2 -1
  149. package/dist/features/layout/BottomActions.d.ts +1 -0
  150. package/dist/features/layout/BottomActions.js +330 -0
  151. package/dist/features/layout/BottomChrome.d.ts +45 -0
  152. package/dist/features/layout/BottomChrome.js +5 -17
  153. package/dist/features/layout/SideActionDock.js +36 -13
  154. package/dist/features/layout/index.d.ts +2 -7
  155. package/dist/features/layout/index.js +7 -7
  156. package/dist/features/layout/useIsDesktop.d.ts +36 -0
  157. package/dist/features/layout/useIsDesktop.js +48 -0
  158. package/dist/features/live/components/LiveItemDetailPageView.js +2 -1
  159. package/dist/features/orders/actions/refund-actions.js +0 -1
  160. package/dist/features/orders/components/OrderAddonBadges.d.ts +1 -3
  161. package/dist/features/orders/components/OrderAddonBadges.js +3 -4
  162. package/dist/features/orders/components/OrderPaymentSummary.js +15 -2
  163. package/dist/features/orders/components/YourPurchaseStrip.d.ts +24 -0
  164. package/dist/features/orders/components/YourPurchaseStrip.js +77 -0
  165. package/dist/features/orders/components/index.d.ts +2 -1
  166. package/dist/features/orders/components/index.js +1 -1
  167. package/dist/features/orders/repository/orders.repository.d.ts +0 -8
  168. package/dist/features/orders/repository/orders.repository.js +0 -2
  169. package/dist/features/orders/schemas/firestore.d.ts +17 -9
  170. package/dist/features/orders/types/index.d.ts +2 -5
  171. package/dist/features/orders/utils/order-announcement-message.d.ts +18 -0
  172. package/dist/features/orders/utils/order-announcement-message.js +16 -0
  173. package/dist/features/orders/utils/payment-proof-message.d.ts +20 -0
  174. package/dist/features/orders/utils/payment-proof-message.js +17 -0
  175. package/dist/features/parts/components/PartDetailPageView.js +96 -1
  176. package/dist/features/parts/schemas/firestore.d.ts +247 -0
  177. package/dist/features/parts/schemas/firestore.js +6 -6
  178. package/dist/features/pre-orders/components/MarketplacePreorderCard.d.ts +11 -1
  179. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +10 -3
  180. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +4 -3
  181. package/dist/features/products/api/[id]/route.js +8 -1
  182. package/dist/features/products/api/route.js +16 -4
  183. package/dist/features/products/components/AvailabilityScopeHint.js +1 -1
  184. package/dist/features/products/components/InteractiveProductCard.d.ts +7 -1
  185. package/dist/features/products/components/InteractiveProductCard.js +16 -4
  186. package/dist/features/products/components/MarketplaceBundleCard.d.ts +11 -1
  187. package/dist/features/products/components/MarketplaceBundleCard.js +9 -2
  188. package/dist/features/products/components/MarketplacePrizeDrawCard.d.ts +11 -1
  189. package/dist/features/products/components/MarketplacePrizeDrawCard.js +9 -2
  190. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -1
  191. package/dist/features/products/components/ProductDetailPageView.js +27 -2
  192. package/dist/features/products/components/ProductGrid.d.ts +14 -1
  193. package/dist/features/products/components/ProductGrid.js +22 -5
  194. package/dist/features/products/components/ProductsIndexListing.js +2 -2
  195. package/dist/features/reviews/api/[id]/route.js +83 -23
  196. package/dist/features/reviews/components/PurchaseReviewAffordance.d.ts +6 -0
  197. package/dist/features/reviews/components/PurchaseReviewAffordance.js +42 -0
  198. package/dist/features/reviews/components/ReviewFormDrawer.d.ts +34 -0
  199. package/dist/features/reviews/components/ReviewFormDrawer.js +127 -0
  200. package/dist/features/reviews/components/index.d.ts +4 -0
  201. package/dist/features/reviews/components/index.js +2 -0
  202. package/dist/features/scams/schemas/index.d.ts +10 -10
  203. package/dist/features/search/action-index/settings-entries.js +0 -9
  204. package/dist/features/seller/actions/seller-actions.d.ts +1 -1
  205. package/dist/features/seller/actions/seller-actions.js +49 -3
  206. package/dist/features/seller/components/SellerPayoutSettingsView.js +30 -2
  207. package/dist/features/seller/components/SellerProductShell.d.ts +17 -1
  208. package/dist/features/seller/hooks/useStoreListingEntitlements.d.ts +8 -0
  209. package/dist/features/seller/hooks/useStoreListingEntitlements.js +70 -0
  210. package/dist/features/store-extensions/repository/store-extensions.repositories.d.ts +1 -6
  211. package/dist/features/store-extensions/repository/store-extensions.repositories.js +1 -10
  212. package/dist/features/store-extensions/schemas/firestore.d.ts +1 -17
  213. package/dist/features/store-extensions/schemas/firestore.js +0 -10
  214. package/dist/features/stores/components/InteractiveStoreCard.d.ts +11 -1
  215. package/dist/features/stores/components/InteractiveStoreCard.js +9 -2
  216. package/dist/features/stores/components/StoreCapabilitiesGuideView.js +0 -1
  217. package/dist/features/stores/components/StoreGuideHubView.js +2 -8
  218. package/dist/features/stores/components/StoreSettingsGuideView.js +2 -6
  219. package/dist/features/stores/components/index.d.ts +0 -2
  220. package/dist/features/stores/components/index.js +0 -1
  221. package/dist/features/stores/repository/store.repository.d.ts +1 -26
  222. package/dist/features/stores/repository/store.repository.js +5 -60
  223. package/dist/features/stores/schemas/firestore.d.ts +6 -25
  224. package/dist/features/stores/schemas/firestore.js +6 -3
  225. package/dist/features/stores/schemas/index.d.ts +1 -87
  226. package/dist/features/stores/schemas/index.js +10 -15
  227. package/dist/features/tester/seed-data/authored/admin__site-system.js +0 -48
  228. package/dist/features/tester/seed-data/authored/buying__buying-checkout.js +0 -40
  229. package/dist/features/tester/seed-data/authored/selling__quick-add-minimum-details.js +0 -16
  230. package/dist/features/tester/seed-data/authored/selling__seller-guide.js +1 -1
  231. package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.js +0 -79
  232. package/dist/features/tester/seed-data/authored/selling__seller-orders.js +1 -1
  233. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +415 -69
  234. package/dist/index.d.ts +20 -32
  235. package/dist/index.js +34 -43
  236. package/dist/next/routing/route-map.d.ts +2 -8
  237. package/dist/next/routing/route-map.js +21 -4
  238. package/dist/providers/db-firebase/base.repository.d.ts +1 -1
  239. package/dist/providers/db-firebase/base.repository.js +1 -1
  240. package/dist/providers/payment-razorpay/index.d.ts +125 -0
  241. package/dist/providers/payment-razorpay/index.js +232 -0
  242. package/dist/providers/payment-razorpay/signature.d.ts +53 -0
  243. package/dist/providers/payment-razorpay/signature.js +71 -0
  244. package/dist/providers/shipping-shiprocket/index.d.ts +98 -0
  245. package/dist/providers/shipping-shiprocket/index.js +356 -0
  246. package/dist/providers.d.ts +3 -0
  247. package/dist/providers.js +3 -0
  248. package/dist/react/hooks/useCanSeePrices.d.ts +0 -27
  249. package/dist/react/hooks/useCanSeePrices.js +25 -0
  250. package/dist/repositories/index.d.ts +1 -1
  251. package/dist/repositories/index.js +1 -1
  252. package/dist/schemas/registry.d.ts +10 -115
  253. package/dist/schemas/registry.js +1 -2
  254. package/dist/security/pii-encrypt.js +1 -1
  255. package/dist/seed/_helpers/category-forest.js +27 -0
  256. package/dist/seed/_helpers/category-parts-glossary-map.js +1816 -88
  257. package/dist/seed/_helpers/category-parts.d.ts +1 -1
  258. package/dist/seed/_helpers/category-parts.js +13399 -3019
  259. package/dist/seed/carousel-slides-seed-data.js +47 -10
  260. package/dist/seed/categories-seed-data.js +48 -6
  261. package/dist/seed/faq-seed-data.js +2 -2
  262. package/dist/seed/homepage-sections-seed-data.js +286 -54
  263. package/dist/seed/index.d.ts +1 -1
  264. package/dist/seed/index.js +1 -1
  265. package/dist/seed/manifest.d.ts +1 -1
  266. package/dist/seed/manifest.js +1 -2
  267. package/dist/seed/model-composition-seed-data.js +6 -8
  268. package/dist/seed/part-glossary/chunk0.d.ts +9 -0
  269. package/dist/seed/part-glossary/chunk0.js +35448 -0
  270. package/dist/seed/part-glossary/chunk1.d.ts +9 -0
  271. package/dist/seed/part-glossary/chunk1.js +40494 -0
  272. package/dist/seed/part-glossary/chunk2.d.ts +9 -0
  273. package/dist/seed/part-glossary/chunk2.js +51242 -0
  274. package/dist/seed/part-glossary/chunk3.d.ts +9 -0
  275. package/dist/seed/part-glossary/chunk3.js +53337 -0
  276. package/dist/seed/part-glossary/chunk4.d.ts +9 -0
  277. package/dist/seed/part-glossary/chunk4.js +51454 -0
  278. package/dist/seed/part-glossary-seed-data.d.ts +1 -1
  279. package/dist/seed/part-glossary-seed-data.js +23 -47483
  280. package/dist/seed/products-catalogue-seed-data.d.ts +5 -5
  281. package/dist/seed/products-catalogue-seed-data.js +63936 -13803
  282. package/dist/seed/site-settings-seed-data.js +34 -35
  283. package/dist/seed/store-extensions-seed-data.d.ts +1 -2
  284. package/dist/seed/store-extensions-seed-data.js +1 -23
  285. package/dist/seed/stores-seed-data.js +0 -1
  286. package/dist/server-entry.d.ts +1 -1
  287. package/dist/server-entry.js +1 -1
  288. package/dist/server.d.ts +8 -10
  289. package/dist/server.js +16 -22
  290. package/dist/styles.css +392 -43
  291. package/dist/tailwind-utilities.css +1 -1
  292. package/dist/tokens/themes/default-dark.js +1 -1
  293. package/dist/tokens/themes/default-light.js +2 -1
  294. package/dist/tokens/tokens.css +6 -2
  295. package/dist/ui/components/Button.d.ts +11 -0
  296. package/dist/ui/components/Button.js +11 -0
  297. package/dist/ui/components/Button.style.css +29 -0
  298. package/dist/ui/components/CarouselNav.d.ts +57 -0
  299. package/dist/ui/components/CarouselNav.js +25 -0
  300. package/dist/ui/components/CarouselNav.style.css +265 -0
  301. package/dist/ui/components/GatedPrice.js +30 -3
  302. package/dist/ui/components/GatedPrice.style.css +43 -40
  303. package/dist/ui/components/HorizontalScroller.d.ts +12 -1
  304. package/dist/ui/components/HorizontalScroller.js +43 -3
  305. package/dist/ui/components/ImageMosaic.d.ts +8 -1
  306. package/dist/ui/components/ImageMosaic.js +3 -2
  307. package/dist/ui/components/ImageMosaic.style.css +22 -0
  308. package/dist/ui/components/Layout.style.css +6 -0
  309. package/dist/ui/components/Semantic.d.ts +3 -2
  310. package/dist/ui/components/Semantic.js +1 -0
  311. package/dist/ui/components/Typography.d.ts +2 -0
  312. package/dist/ui/components/Typography.js +2 -0
  313. package/dist/ui/components/Typography.style.css +19 -0
  314. package/dist/ui/components/index.style.css +1 -0
  315. package/dist/ui/index.d.ts +3 -1
  316. package/dist/ui/index.js +4 -0
  317. package/package.json +3 -2
  318. package/dist/_internal/server/jobs/core/whatsappCatalogImport.d.ts +0 -27
  319. package/dist/_internal/server/jobs/core/whatsappCatalogImport.js +0 -172
  320. package/dist/_internal/server/jobs/core/whatsappNotify.d.ts +0 -35
  321. package/dist/_internal/server/jobs/core/whatsappNotify.js +0 -140
  322. package/dist/features/admin/components/AdminWhatsAppGuideView.d.ts +0 -2
  323. package/dist/features/admin/components/AdminWhatsAppGuideView.js +0 -35
  324. package/dist/features/orders/components/MarketplaceOrderCard.d.ts +0 -36
  325. package/dist/features/orders/components/MarketplaceOrderCard.js +0 -57
  326. package/dist/features/stores/components/StoreWhatsAppGuideView.d.ts +0 -3
  327. package/dist/features/stores/components/StoreWhatsAppGuideView.js +0 -12
  328. package/dist/features/whatsapp-bot/api/send-status/route.d.ts +0 -12
  329. package/dist/features/whatsapp-bot/api/send-status/route.js +0 -38
  330. package/dist/features/whatsapp-bot/api/webhook/route.d.ts +0 -12
  331. package/dist/features/whatsapp-bot/api/webhook/route.js +0 -43
  332. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.d.ts +0 -6
  333. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +0 -270
  334. package/dist/features/whatsapp-bot/components/WhatsAppChatButton.d.ts +0 -9
  335. package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +0 -7
  336. package/dist/features/whatsapp-bot/components/index.d.ts +0 -3
  337. package/dist/features/whatsapp-bot/components/index.js +0 -2
  338. package/dist/features/whatsapp-bot/helpers/payment-proof-message.d.ts +0 -14
  339. package/dist/features/whatsapp-bot/helpers/payment-proof-message.js +0 -17
  340. package/dist/features/whatsapp-bot/helpers/whatsapp.d.ts +0 -52
  341. package/dist/features/whatsapp-bot/helpers/whatsapp.js +0 -283
  342. package/dist/features/whatsapp-bot/index.d.ts +0 -3
  343. package/dist/features/whatsapp-bot/index.js +0 -3
  344. package/dist/features/whatsapp-bot/manifest.d.ts +0 -2
  345. package/dist/features/whatsapp-bot/manifest.js +0 -13
  346. package/dist/features/whatsapp-bot/messages/en.json +0 -7
  347. package/dist/features/whatsapp-bot/server.d.ts +0 -7
  348. package/dist/features/whatsapp-bot/server.js +0 -7
  349. package/dist/features/whatsapp-bot/types/index.d.ts +0 -126
  350. package/dist/features/whatsapp-bot/types/index.js +0 -1
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "stampVersion": 1,
3
- "version": "4.53.2",
4
- "head": "94f4715428f35ab362a11a468072ef933ca8a46d",
3
+ "version": "4.54.1",
4
+ "head": "3fe89608007f66f86562b403eb02772873cdffe2",
5
5
  "branch": "main",
6
6
  "dirty": false,
7
- "builtAt": "2026-10-19T22:24:09.397Z"
7
+ "builtAt": "2026-10-20T06:16:45.850Z"
8
8
  }
@@ -5,7 +5,7 @@
5
5
  * Call this server-side only — never trust client-provided capability arrays.
6
6
  */
7
7
  import { storeRepository } from "../../../../repositories/index.js";
8
- import { DEFAULT_STORE_CAPABILITIES, } from "../../../../features/auth/permissions/constants.js";
8
+ import { DEFAULT_STORE_CAPABILITIES, resolveStoreCapabilities, } from "../../../../features/auth/permissions/constants.js";
9
9
  /**
10
10
  * Return the resolved capability set for a store.
11
11
  * Falls back to DEFAULT_STORE_CAPABILITIES when the store has no capabilities field.
@@ -16,10 +16,12 @@ export async function getStoreCapabilities(storeId) {
16
16
  const store = await storeRepository.findById(storeId);
17
17
  if (!store)
18
18
  return [...DEFAULT_STORE_CAPABILITIES];
19
- const raw = store.capabilities;
20
- if (Array.isArray(raw) && raw.length > 0)
21
- return raw;
22
- return [...DEFAULT_STORE_CAPABILITIES];
19
+ /*
20
+ * The merge itself lives in `resolveStoreCapabilities` so a caller holding
21
+ * the store document already can run the same rule without a second read.
22
+ * This function is now just "fetch, then resolve".
23
+ */
24
+ return resolveStoreCapabilities(store.capabilities);
23
25
  }
24
26
  /**
25
27
  * Check whether a store has a specific capability.
@@ -113,7 +113,6 @@ export interface CheckoutPricingPreviewStore {
113
113
  subtotal: number;
114
114
  shippingFee: number;
115
115
  codHandlingFee: number;
116
- whatsappNotifyFee: number;
117
116
  giftWrapFee: number;
118
117
  shipmentProtectionFee: number;
119
118
  saleProtectionFee: number;
@@ -145,7 +144,6 @@ export interface CheckoutPricingPreview {
145
144
  subtotal: number;
146
145
  shippingFee: number;
147
146
  codHandlingFee: number;
148
- whatsappNotifyFee: number;
149
147
  giftWrapFee: number;
150
148
  shipmentProtectionFee: number;
151
149
  saleProtectionFee: number;
@@ -168,7 +166,7 @@ export interface CheckoutPricingPreview {
168
166
  /**
169
167
  * Read-only "what will I actually be charged" preview for the checkout
170
168
  * Order Summary. Reuses the exact same building blocks
171
- * createCheckoutOrderAction / verifyAndPlacePhonePeOrderAction use when an
169
+ * createCheckoutOrderAction / verifyAndPlaceGatewayOrderAction use when an
172
170
  * order is actually placed — resolveShippingCost, the compute*Fee helpers,
173
171
  * computeGroupCouponDiscount, and the GST calc — so the number shown to the
174
172
  * buyer can never diverge from what gets charged/recorded. Never decrements
@@ -184,9 +182,27 @@ export declare function attachPaymentAction(input: {
184
182
  paymentId: string;
185
183
  paidAmount: number;
186
184
  }): Promise<void>;
187
- export interface VerifyAndPlacePhonePeOrderInput {
188
- /** PhonePe's merchantOrderId — our own id, generated in PhonePeProvider.createOrder(). */
185
+ export interface VerifyAndPlaceGatewayOrderInput {
186
+ /**
187
+ * The gateway order id every lookup for this payment is keyed on, and what
188
+ * gets stored as `order.paymentId`: PhonePe's own `merchantOrderId`
189
+ * (generated in `PhonePeProvider.createOrder()`), or Razorpay's `order_…`.
190
+ */
189
191
  merchantOrderId: string;
192
+ /**
193
+ * Razorpay's client callback, when the buyer-present path has it. Omit on
194
+ * the webhook path and for PhonePe, which has no such callback.
195
+ *
196
+ * Verified IN ADDITION to the server-side order fetch, never instead of it
197
+ * — see the block comment above. A present-but-invalid signature is a hard
198
+ * failure: it means the browser's callback was forged or tampered with,
199
+ * even if the order did turn out to be paid.
200
+ */
201
+ razorpaySignature?: {
202
+ razorpay_order_id: string;
203
+ razorpay_payment_id: string;
204
+ razorpay_signature: string;
205
+ };
190
206
  /**
191
207
  * Buyer identity. Omit on the webhook path — no session exists there, so
192
208
  * it's resolved from `uid` packed into PhonePe's `metaInfo` at
@@ -205,4 +221,4 @@ export interface VerifyAndPlacePhonePeOrderInput {
205
221
  */
206
222
  outOfStockPolicy?: OutOfStockPolicy;
207
223
  }
208
- export declare function verifyAndPlacePhonePeOrderAction(input: VerifyAndPlacePhonePeOrderInput): Promise<CheckoutOrderResult>;
224
+ export declare function verifyAndPlaceGatewayOrderAction(input: VerifyAndPlaceGatewayOrderInput): Promise<CheckoutOrderResult>;
@@ -23,7 +23,7 @@ import { computeProtectionFees } from "../../../shared/features/shipping/protect
23
23
  import { resolveCouponCategorySlugs } from "../../../../features/promotions/actions/coupon-actions.js";
24
24
  import { assertCheckoutLane, assertLockedLinesStillValid, finalizeLockedLines, } from "./locked-lines.js";
25
25
  import { activeLane, defaultCheckoutItems, laneOf, } from "../../../shared/checkout/lanes.js";
26
- import { computeCodHandlingFee, computeWhatsAppNotifyFee, computeGiftWrapFee, computeShipmentProtectionFee, computeSaleProtectionFee, computeCheckoutFees, allocateCheckoutFees, } from "../../../shared/fees/calculator.js";
26
+ import { computeCodHandlingFee, computeGiftWrapFee, computeShipmentProtectionFee, computeSaleProtectionFee, computeCheckoutFees, allocateCheckoutFees, } from "../../../shared/fees/calculator.js";
27
27
  import { getAdminDb, getAdminRealtimeDb, RTDB_PATHS, } from "../../../../providers/db-firebase/index.js";
28
28
  import { PRODUCT_COLLECTION, PRODUCT_CODES_SUBCOLLECTION } from "../../../../features/products/schemas/firestore.js";
29
29
  import { CART_COLLECTION } from "../../../../features/cart/schemas/index.js";
@@ -33,6 +33,13 @@ import { expandCartLineToOrderRows } from "./expand-order-items.js";
33
33
  import { OrderStatusValues, PaymentStatusValues, PaymentMethodValues, OutOfStockPolicyValues, } from "../../../../features/orders/schemas/index.js";
34
34
  import { getDefaultCurrency } from "../../../../core/index.js";
35
35
  import { getProviders } from "../../../../contracts/index.js";
36
+ /*
37
+ * The SDK-free signature module, NOT the provider's `index.ts`. Importing the
38
+ * index would pull a static `import Razorpay from "razorpay"` into this
39
+ * action's import graph for one HMAC comparison — see that file's header.
40
+ */
41
+ import { verifyPaymentSignature as verifyRazorpayPaymentSignature } from "../../../../providers/payment-razorpay/signature.js";
42
+ import { resolveKeys } from "../../../../core/integration-keys.js";
36
43
  import { paiseToRupees } from "../../../../core/money.js";
37
44
  import { CHECKOUT_DEFAULT_COMMISSIONS, CHECKOUT_DEFAULT_EMI_SETTINGS } from "../../../shared/features/checkout/config.js";
38
45
  import { checkEmiEligibility, computeEmiSchedule } from "../../../shared/features/emi/schedule.js";
@@ -137,7 +144,7 @@ function assertLiveJurisdiction(cartItemsArg, productByIdArg, buyerState) {
137
144
  * either party. We emit the buyer + seller rows here at the create boundary.
138
145
  */
139
146
  function emitOrderPlacedNotifications(args) {
140
- const { orderId, buyerUid, buyerName, storeOwnerId, productLabel, paid, whatsappNotifyAddon } = args;
147
+ const { orderId, buyerUid, buyerName, storeOwnerId, productLabel, paid } = args;
141
148
  const buyerNotif = sendNotification({
142
149
  userId: buyerUid,
143
150
  type: "order_placed",
@@ -147,7 +154,6 @@ function emitOrderPlacedNotifications(args) {
147
154
  relatedId: orderId,
148
155
  relatedType: "order",
149
156
  actionUrl: `/user/orders/view/${orderId}`,
150
- orderWhatsappAddonPaid: whatsappNotifyAddon,
151
157
  }).catch((err) => serverLogger.warn("Failed to send buyer order_placed notification", {
152
158
  err: err instanceof Error ? err.message : String(err),
153
159
  orderId,
@@ -486,7 +492,7 @@ async function createOrderForGroup(group, orderType, ctx) {
486
492
  const firstItem = group[0].item;
487
493
  const firstProduct = group[0].product;
488
494
  // Add-ons are this store's choice, not the cart's — see OrderGroupContext.
489
- const { whatsappNotifyAddon = false, giftWrapAddon = false, giftWrapMessage, shipmentProtectionAddon = false, saleProtectionAddon = false, } = storeAddons?.[firstItem.storeId] ?? {};
495
+ const { giftWrapAddon = false, giftWrapMessage, shipmentProtectionAddon = false, saleProtectionAddon = false, } = storeAddons?.[firstItem.storeId] ?? {};
490
496
  const { platformFee = 0, gstOnFee: platformFeeGst = 0 } = platformFeeByStore.get(firstItem.storeId) ?? {};
491
497
  const groupTotal = group.reduce((sum, { item, product }) => sum + lineTotalFor(item, product), 0);
492
498
  // S-SBUNI-RULES 2026-05-13 — order-item decoration via rule registry.
@@ -569,7 +575,6 @@ async function createOrderForGroup(group, orderType, ctx) {
569
575
  // Handling fee charged to the buyer for choosing COD, on top of the order
570
576
  // total — not deducted from the deposit/remaining split above.
571
577
  const codHandlingFee = paymentMethod === "cod" ? computeCodHandlingFee(groupTotal, commissions) : 0;
572
- const whatsappNotifyFee = computeWhatsAppNotifyFee(whatsappNotifyAddon, commissions);
573
578
  const giftWrapFee = computeGiftWrapFee(giftWrapAddon, commissions);
574
579
  /*
575
580
  * ── C5e: all three protection tiers, enforced SERVER-SIDE ────────────────
@@ -622,7 +627,7 @@ async function createOrderForGroup(group, orderType, ctx) {
622
627
  * OUR service fee to the seller, charged to the buyer on top of the fee —
623
628
  * not tax on the goods.
624
629
  */
625
- Math.max(0, groupTotal - couponDiscount) + shippingFee + codHandlingFee + whatsappNotifyFee + giftWrapFee + shipmentProtectionFee + saleProtectionFee + platformFee + platformFeeGst + (emiSchedule?.surchargeAmount ?? 0);
630
+ Math.max(0, groupTotal - couponDiscount) + shippingFee + codHandlingFee + giftWrapFee + shipmentProtectionFee + saleProtectionFee + platformFee + platformFeeGst + (emiSchedule?.surchargeAmount ?? 0);
626
631
  const imageUrls = [
627
632
  ...new Set(group
628
633
  .map(({ product }) => product.mainImage)
@@ -691,8 +696,6 @@ async function createOrderForGroup(group, orderType, ctx) {
691
696
  // This group's pro-rata share of the checkout's single capped commission —
692
697
  // the shares across a multi-store checkout sum to exactly what was charged.
693
698
  platformFee: !adminBypass && platformFee > 0 ? platformFee : undefined,
694
- whatsappNotifyAddon: !adminBypass && whatsappNotifyFee > 0 ? true : undefined,
695
- whatsappNotifyFee: !adminBypass && whatsappNotifyFee > 0 ? whatsappNotifyFee : undefined,
696
699
  giftWrapAddon: !adminBypass && giftWrapFee > 0 ? true : undefined,
697
700
  giftWrapFee: !adminBypass && giftWrapFee > 0 ? giftWrapFee : undefined,
698
701
  giftWrapMessage: !adminBypass && giftWrapFee > 0 ? giftWrapMessage?.slice(0, 500) : undefined,
@@ -800,7 +803,6 @@ async function createOrderForGroup(group, orderType, ctx) {
800
803
  storeOwnerId,
801
804
  productLabel: orderItems.length > 1 ? `${orderItems.length} items` : firstItem.productTitle,
802
805
  paid: adminBypass,
803
- whatsappNotifyAddon: !adminBypass && whatsappNotifyFee > 0,
804
806
  });
805
807
  return groupTotal;
806
808
  }
@@ -1132,7 +1134,6 @@ const EMPTY_PRICING_PREVIEW = {
1132
1134
  subtotal: 0,
1133
1135
  shippingFee: 0,
1134
1136
  codHandlingFee: 0,
1135
- whatsappNotifyFee: 0,
1136
1137
  giftWrapFee: 0,
1137
1138
  shipmentProtectionFee: 0,
1138
1139
  saleProtectionFee: 0,
@@ -1146,7 +1147,7 @@ const EMPTY_PRICING_PREVIEW = {
1146
1147
  /**
1147
1148
  * Read-only "what will I actually be charged" preview for the checkout
1148
1149
  * Order Summary. Reuses the exact same building blocks
1149
- * createCheckoutOrderAction / verifyAndPlacePhonePeOrderAction use when an
1150
+ * createCheckoutOrderAction / verifyAndPlaceGatewayOrderAction use when an
1150
1151
  * order is actually placed — resolveShippingCost, the compute*Fee helpers,
1151
1152
  * computeGroupCouponDiscount, and the GST calc — so the number shown to the
1152
1153
  * buyer can never diverge from what gets charged/recorded. Never decrements
@@ -1214,7 +1215,6 @@ export async function previewCheckoutPricing(input) {
1214
1215
  // ever charged for literal "cod" (pay the courier), never upi_manual or
1215
1216
  // cash (both pre-paid via UPI/bank transfer before dispatch).
1216
1217
  const groupCodHandlingFee = paymentMethod === "cod" ? computeCodHandlingFee(groupTotal, commissions) : 0;
1217
- const groupWhatsappFee = computeWhatsAppNotifyFee(addons.whatsappNotifyAddon ?? false, commissions);
1218
1218
  const groupGiftWrapFee = computeGiftWrapFee(addons.giftWrapAddon ?? false, commissions);
1219
1219
  /*
1220
1220
  * C5e — the same three tiers `createOrderForGroup` enforces, so the figure
@@ -1267,7 +1267,6 @@ export async function previewCheckoutPricing(input) {
1267
1267
  subtotal: groupTotal,
1268
1268
  shippingFee: groupShippingFee,
1269
1269
  codHandlingFee: groupCodHandlingFee,
1270
- whatsappNotifyFee: groupWhatsappFee,
1271
1270
  giftWrapFee: groupGiftWrapFee,
1272
1271
  shipmentProtectionFee: groupShipmentProtectionFee,
1273
1272
  saleProtectionFee: groupSaleProtectionFee,
@@ -1285,7 +1284,6 @@ export async function previewCheckoutPricing(input) {
1285
1284
  total: Math.max(0, groupTotal - groupCouponDiscount) +
1286
1285
  groupShippingFee +
1287
1286
  groupCodHandlingFee +
1288
- groupWhatsappFee +
1289
1287
  groupGiftWrapFee +
1290
1288
  groupShipmentProtectionFee +
1291
1289
  groupSaleProtectionFee,
@@ -1297,7 +1295,6 @@ export async function previewCheckoutPricing(input) {
1297
1295
  const sum = (pick) => stores.reduce((acc, s) => acc + pick(s), 0);
1298
1296
  const shippingFee = sum((s) => s.shippingFee);
1299
1297
  const codHandlingFee = sum((s) => s.codHandlingFee);
1300
- const whatsappNotifyFeeTotal = sum((s) => s.whatsappNotifyFee);
1301
1298
  const giftWrapFeeTotal = sum((s) => s.giftWrapFee);
1302
1299
  const shipmentProtectionFeeTotal = sum((s) => s.shipmentProtectionFee);
1303
1300
  const saleProtectionFeeTotal = sum((s) => s.saleProtectionFee);
@@ -1309,7 +1306,6 @@ export async function previewCheckoutPricing(input) {
1309
1306
  const total = Math.max(0, cartSubtotal - couponDiscount) +
1310
1307
  shippingFee +
1311
1308
  codHandlingFee +
1312
- whatsappNotifyFeeTotal +
1313
1309
  giftWrapFeeTotal +
1314
1310
  shipmentProtectionFeeTotal +
1315
1311
  saleProtectionFeeTotal +
@@ -1320,7 +1316,6 @@ export async function previewCheckoutPricing(input) {
1320
1316
  subtotal: cartSubtotal,
1321
1317
  shippingFee,
1322
1318
  codHandlingFee,
1323
- whatsappNotifyFee: whatsappNotifyFeeTotal,
1324
1319
  giftWrapFee: giftWrapFeeTotal,
1325
1320
  shipmentProtectionFee: shipmentProtectionFeeTotal,
1326
1321
  saleProtectionFee: saleProtectionFeeTotal,
@@ -1367,7 +1362,7 @@ export async function attachPaymentAction(input) {
1367
1362
  * Auto-refund the value of items dropped from a PhonePe checkout under the
1368
1363
  * "skip_items" out-of-stock policy. PhonePe captures payment for the FULL
1369
1364
  * cart before the stock check runs, so anything not placed as an order must
1370
- * be given back. Extracted from `verifyAndPlacePhonePeOrderAction` — same
1365
+ * be given back. Extracted from `verifyAndPlaceGatewayOrderAction` — same
1371
1366
  * behavior, kept as a named step so the parent function stays readable.
1372
1367
  *
1373
1368
  * Awaited by the caller (this moves money, never fire-and-forget). On
@@ -1418,7 +1413,7 @@ async function refundDroppedItemsForPhonePeCheckout(input) {
1418
1413
  }
1419
1414
  catch (refundErr) {
1420
1415
  void normalizeError(refundErr);
1421
- serverLogger.warn("verifyAndPlacePhonePeOrderAction: automatic partial refund for dropped items failed — flagging for manual follow-up", {
1416
+ serverLogger.warn("verifyAndPlaceGatewayOrderAction: automatic partial refund for dropped items failed — flagging for manual follow-up", {
1422
1417
  orderId: primaryOrderId,
1423
1418
  droppedValue,
1424
1419
  err: refundErr instanceof Error ? refundErr.message : String(refundErr),
@@ -1427,7 +1422,7 @@ async function refundDroppedItemsForPhonePeCheckout(input) {
1427
1422
  .update(primaryOrderId, { refundPending: true })
1428
1423
  .catch((updErr) => {
1429
1424
  void normalizeError(updErr);
1430
- serverLogger.error("verifyAndPlacePhonePeOrderAction: failed to flag refundPending after auto-refund failure", { orderId: primaryOrderId, err: updErr instanceof Error ? updErr.message : String(updErr) });
1425
+ serverLogger.error("verifyAndPlaceGatewayOrderAction: failed to flag refundPending after auto-refund failure", { orderId: primaryOrderId, err: updErr instanceof Error ? updErr.message : String(updErr) });
1431
1426
  });
1432
1427
  /*
1433
1428
  * One admin-inbox row, not one notification per admin.
@@ -1455,12 +1450,12 @@ async function refundDroppedItemsForPhonePeCheckout(input) {
1455
1450
  })
1456
1451
  .catch((notifyErr) => {
1457
1452
  void normalizeError(notifyErr);
1458
- serverLogger.error("verifyAndPlacePhonePeOrderAction: failed to write admin notification for failed auto-refund", { orderId: primaryOrderId });
1453
+ serverLogger.error("verifyAndPlaceGatewayOrderAction: failed to write admin notification for failed auto-refund", { orderId: primaryOrderId });
1459
1454
  });
1460
1455
  }
1461
1456
  }
1462
1457
  /**
1463
- * Places one order for one seller-group within `verifyAndPlacePhonePeOrderAction`
1458
+ * Places one order for one seller-group within `verifyAndPlaceGatewayOrderAction`
1464
1459
  * — mirrors `createOrderForGroup`'s role on the COD/cash/EMI path (same
1465
1460
  * per-group fee/coupon/order-doc/notification shape), extracted into its own
1466
1461
  * function purely to keep the parent function under the LARGE_COMPONENT
@@ -1469,6 +1464,14 @@ async function refundDroppedItemsForPhonePeCheckout(input) {
1469
1464
  */
1470
1465
  async function createPhonePeGroupOrder(group, orderType, ctx) {
1471
1466
  const { appliedCoupons, cartSubtotal, storeAddons, platformFeeByStore, siteSettings, uid, userName, userEmail, merchantOrderId, phonepeOrderId, transactionId, shippingAddress, notes, outOfStockPolicy, unavailablePaid, orderIds, emailsToSend, couponUsageAccumulator, productById: phonepeProductById, buyerState, } = ctx;
1467
+ /*
1468
+ * Which online gateway actually took the money, read off the registered
1469
+ * provider rather than passed in — exactly one is registered per process
1470
+ * (`providers.config.ts`), so there is no caller-supplied value that could
1471
+ * disagree with reality. Recorded on the order so a refund months later
1472
+ * knows which API the stored `paymentId` belongs to.
1473
+ */
1474
+ const gatewayName = getProviders().payment?.name ?? "phonepe";
1472
1475
  const firstItem = group[0].item;
1473
1476
  const groupTotal = group.reduce((sum, { item, product }) => sum + lineTotalFor(item, product), 0);
1474
1477
  // Reuses the same store/seller lookup as the COD/UPI path above instead
@@ -1508,7 +1511,6 @@ async function createPhonePeGroupOrder(group, orderType, ctx) {
1508
1511
  // cart-wide fee was passed in and billed against every group.
1509
1512
  const commissionRates = siteSettings?.commissions ?? CHECKOUT_DEFAULT_COMMISSIONS;
1510
1513
  const addons = storeAddons?.[firstItem.storeId] ?? {};
1511
- const whatsappNotifyFee = computeWhatsAppNotifyFee(addons.whatsappNotifyAddon ?? false, commissionRates);
1512
1514
  const giftWrapFee = computeGiftWrapFee(addons.giftWrapAddon ?? false, commissionRates);
1513
1515
  const giftWrapMessage = addons.giftWrapMessage;
1514
1516
  const shipmentProtectionFee = computeShipmentProtectionFee(groupTotal, addons.shipmentProtectionAddon ?? false, commissionRates);
@@ -1544,7 +1546,7 @@ async function createPhonePeGroupOrder(group, orderType, ctx) {
1544
1546
  /* Product GST is not a term — prices are tax-inclusive, so it is already
1545
1547
  * inside `groupTotal`. Matches the COD/UPI path exactly; `platformFeeGst`
1546
1548
  * stays because that is GST on our fee, charged on top. */
1547
- const orderTotal = Math.max(0, groupTotal - couponDiscount) + shippingFee + whatsappNotifyFee + giftWrapFee + shipmentProtectionFee + platformFee + platformFeeGst;
1549
+ const orderTotal = Math.max(0, groupTotal - couponDiscount) + shippingFee + giftWrapFee + shipmentProtectionFee + platformFee + platformFeeGst;
1548
1550
  // S-SBUNI-RULES 2026-05-13 — order-item decoration via rule registry.
1549
1551
  // Same expansion as the COD/UPI path. This was a THIRD hand-rolled copy of
1550
1552
  // the price rule (`isBundle ? item.price : product.price`) that — like the
@@ -1598,19 +1600,29 @@ async function createPhonePeGroupOrder(group, orderType, ctx) {
1598
1600
  status: OrderStatusValues.CONFIRMED,
1599
1601
  paymentStatus: PaymentStatusValues.PAID,
1600
1602
  paymentMethod: PaymentMethodValues.ONLINE,
1601
- // Our own generated id, not PhonePe's — this is what refunds/lookups key
1602
- // on (PhonePe's refund API is `originalMerchantOrderId`-keyed anyway).
1603
+ /*
1604
+ * The id every refund and lookup keys on, whichever gateway is live:
1605
+ * PhonePe's own `merchantOrderId` (its refund API is
1606
+ * `originalMerchantOrderId`-keyed), or Razorpay's `order_…`.
1607
+ *
1608
+ * 🛑 Razorpay's refund API is PAYMENT-keyed, not order-keyed — storing an
1609
+ * order id here works only because `RazorpayProvider.refund()` resolves
1610
+ * the order's captured payment itself. Keep that behaviour if this field
1611
+ * ever changes; the alternative is tracking a second id at ~6 call sites.
1612
+ */
1603
1613
  paymentId: merchantOrderId,
1604
1614
  paymentRecord: {
1605
- method: "phonepe",
1615
+ method: gatewayName === "razorpay" ? "razorpay" : "phonepe",
1606
1616
  transactionId: transactionId ?? merchantOrderId,
1607
1617
  amount: orderTotal,
1608
1618
  paidAt: new Date(),
1609
- verifiedBy: "phonepe-order-status",
1619
+ verifiedBy: `${gatewayName}-order-status`,
1610
1620
  verificationMethod: "order-status",
1611
1621
  gatewayRef: {
1612
1622
  merchantOrderId,
1613
- phonepeOrderId,
1623
+ ...(gatewayName === "razorpay"
1624
+ ? { razorpayOrderId: merchantOrderId, razorpayPaymentId: transactionId }
1625
+ : { phonepeOrderId }),
1614
1626
  transactionId,
1615
1627
  },
1616
1628
  },
@@ -1618,8 +1630,6 @@ async function createPhonePeGroupOrder(group, orderType, ctx) {
1618
1630
  notes,
1619
1631
  platformFee,
1620
1632
  shippingFee: shippingFee > 0 ? shippingFee : undefined,
1621
- whatsappNotifyAddon: whatsappNotifyFee > 0 ? true : undefined,
1622
- whatsappNotifyFee: whatsappNotifyFee > 0 ? whatsappNotifyFee : undefined,
1623
1633
  giftWrapAddon: giftWrapFee > 0 ? true : undefined,
1624
1634
  giftWrapFee: giftWrapFee > 0 ? giftWrapFee : undefined,
1625
1635
  giftWrapMessage: giftWrapFee > 0 ? giftWrapMessage?.slice(0, 500) : undefined,
@@ -1694,19 +1704,44 @@ async function createPhonePeGroupOrder(group, orderType, ctx) {
1694
1704
  storeOwnerId,
1695
1705
  productLabel: orderItems.length > 1 ? `${orderItems.length} items` : firstItem.productTitle,
1696
1706
  paid: true,
1697
- whatsappNotifyAddon: whatsappNotifyFee > 0,
1698
1707
  });
1699
1708
  return orderTotal;
1700
1709
  }
1701
- export async function verifyAndPlacePhonePeOrderAction(input) {
1710
+ export async function verifyAndPlaceGatewayOrderAction(input) {
1702
1711
  const { merchantOrderId } = input;
1712
+ /*
1713
+ * Razorpay's signed client callback, checked BEFORE the claim doc is
1714
+ * created. Order matters: a forged callback that claimed first would make
1715
+ * the real confirmation (webhook or retry) return "in progress" forever,
1716
+ * turning a rejected request into a stuck order. Verify, then claim.
1717
+ *
1718
+ * The key secret is resolved here rather than passed in because the route
1719
+ * has no business holding it. A missing secret cannot verify anything, so
1720
+ * it fails closed — the same direction as `verifyWebhook()`.
1721
+ */
1722
+ if (input.razorpaySignature) {
1723
+ const { razorpayKeySecret } = await resolveKeys();
1724
+ const signatureValid = !!razorpayKeySecret &&
1725
+ verifyRazorpayPaymentSignature(input.razorpaySignature, razorpayKeySecret);
1726
+ if (!signatureValid) {
1727
+ serverLogger.warn(`Razorpay signature rejected: order=${input.razorpaySignature.razorpay_order_id} payment=${input.razorpaySignature.razorpay_payment_id}`);
1728
+ failedCheckoutRepository
1729
+ .logPayment(input.userId ?? "unknown", "signature_mismatch", "Razorpay client signature invalid", {
1730
+ gatewayOrderId: input.razorpaySignature.razorpay_order_id,
1731
+ gatewayPaymentId: input.razorpaySignature.razorpay_payment_id,
1732
+ addressId: input.addressId,
1733
+ })
1734
+ .catch((logErr) => { void normalizeError(logErr); serverLogger.warn(AUDIT_LOG_FAIL_MSG, { error: logErr instanceof Error ? logErr.message : String(logErr) }); });
1735
+ throw new ValidationError(ERROR_MESSAGES.CHECKOUT.PAYMENT_FAILED);
1736
+ }
1737
+ }
1703
1738
  // Idempotency: the buyer's /verify call and the async webhook can both
1704
1739
  // race to confirm+place for the same PhonePe payment (see the module
1705
1740
  // comment above). `.create()` throws on conflict, so whichever caller
1706
1741
  // creates this claim doc first is the sole placer; the loser returns
1707
1742
  // whatever the winner already placed, or a retryable "in progress" error
1708
1743
  // if the winner genuinely hasn't finished yet.
1709
- const claimRef = getAdminDb().collection("phonepeOrderClaims").doc(merchantOrderId);
1744
+ const claimRef = getAdminDb().collection("gatewayOrderClaims").doc(merchantOrderId);
1710
1745
  try {
1711
1746
  await claimRef.create({ claimedAt: new Date() });
1712
1747
  }
@@ -1722,14 +1757,23 @@ export async function verifyAndPlacePhonePeOrderAction(input) {
1722
1757
  }
1723
1758
  throw new ValidationError(ERROR_MESSAGES.CHECKOUT.ORDER_PLACEMENT_IN_PROGRESS);
1724
1759
  }
1725
- // Order Status confirmation — PhonePe never hands the browser a
1726
- // verifiable proof of payment, so this call IS the "signature check".
1727
- const phonepeOrder = await getProviders().payment.getOrder(merchantOrderId);
1728
- if (phonepeOrder.status !== "paid") {
1729
- serverLogger.warn(`PhonePe order not completed: merchantOrderId=${merchantOrderId} state=${phonepeOrder.status}`);
1760
+ /*
1761
+ * THE authoritative check, for either gateway: re-fetch the order from the
1762
+ * gateway and require it to be paid. For PhonePe this is the only possible
1763
+ * proof (the browser never receives a verifiable one); for Razorpay it is
1764
+ * what the client signature above cannot establish on its own.
1765
+ *
1766
+ * 🛑 `RazorpayProvider.getOrder()` must map the gateway's real status for
1767
+ * this to mean anything — the pre-2026 implementation hardcoded "created",
1768
+ * which here would reject every successful Razorpay payment AFTER the buyer
1769
+ * was debited. See that provider's class comment, point 1.
1770
+ */
1771
+ const gatewayOrder = await getProviders().payment.getOrder(merchantOrderId);
1772
+ if (gatewayOrder.status !== "paid") {
1773
+ serverLogger.warn(`Gateway order not paid: merchantOrderId=${merchantOrderId} state=${gatewayOrder.status}`);
1730
1774
  failedCheckoutRepository
1731
- .logPayment(input.userId ?? "unknown", "signature_mismatch", "PhonePe order not COMPLETED", {
1732
- gatewayOrderId: phonepeOrder.gatewayOrderId,
1775
+ .logPayment(input.userId ?? "unknown", "signature_mismatch", "Gateway order not paid", {
1776
+ gatewayOrderId: gatewayOrder.gatewayOrderId,
1733
1777
  gatewayPaymentId: merchantOrderId,
1734
1778
  addressId: input.addressId,
1735
1779
  })
@@ -1737,9 +1781,11 @@ export async function verifyAndPlacePhonePeOrderAction(input) {
1737
1781
  throw new ValidationError(ERROR_MESSAGES.CHECKOUT.PAYMENT_FAILED);
1738
1782
  }
1739
1783
  // The buyer-present /verify call always supplies these; the webhook path
1740
- // (no session) reconstructs them from PhonePe's metaInfo, packed at
1741
- // create-order time — see `PhonePeCheckoutIntent`.
1742
- const intent = phonepeOrder.metadata;
1784
+ // (no session) reconstructs them from the gateway's own passthrough channel
1785
+ // — PhonePe's `metaInfo`, Razorpay's `notes` — both packed at create-order
1786
+ // time and both surfaced as `PaymentOrder.metadata`. See
1787
+ // `PhonePeCheckoutIntent`, which is the shape either one carries.
1788
+ const intent = gatewayOrder.metadata;
1743
1789
  const uid = input.userId ?? intent?.uid;
1744
1790
  if (!uid) {
1745
1791
  throw new ValidationError(ERROR_MESSAGES.CHECKOUT.PAYMENT_FAILED);
@@ -1853,7 +1899,7 @@ export async function verifyAndPlacePhonePeOrderAction(input) {
1853
1899
  .logPayment(uid, reason, exists
1854
1900
  ? `Product ${u.productId} has ${u.availableQty} left, requested ${u.requestedQty}`
1855
1901
  : `Product ${u.productId} not published`, {
1856
- gatewayOrderId: phonepeOrder.gatewayOrderId,
1902
+ gatewayOrderId: gatewayOrder.gatewayOrderId,
1857
1903
  gatewayPaymentId: merchantOrderId,
1858
1904
  addressId,
1859
1905
  })
@@ -1900,7 +1946,6 @@ export async function verifyAndPlacePhonePeOrderAction(input) {
1900
1946
  const addons = cart.storeAddons?.[storeId] ?? {};
1901
1947
  const groupSubtotal = g.items.reduce((gs, { item, product }) => gs + lineTotalFor(item, product), 0);
1902
1948
  return (sum +
1903
- computeWhatsAppNotifyFee(addons.whatsappNotifyAddon ?? false, commissionRates) +
1904
1949
  computeGiftWrapFee(addons.giftWrapAddon ?? false, commissionRates) +
1905
1950
  computeShipmentProtectionFee(groupSubtotal, addons.shipmentProtectionAddon ?? false, commissionRates));
1906
1951
  }, 0);
@@ -1936,12 +1981,12 @@ export async function verifyAndPlacePhonePeOrderAction(input) {
1936
1981
  const expectedPaymentAmountRs = cartSubtotalRs + expectedPlatformFee + expectedGstOnFee + expectedAddonFees + expectedShippingFee;
1937
1982
  // Reuses the order already fetched above to confirm COMPLETED — PhonePe's
1938
1983
  // own amount is in its wire-format smallest unit. // audit-money-units-ok: describes the PhonePe boundary conversion this line performs, not our storage convention
1939
- const paidAmountRs = paiseToRupees(phonepeOrder.amount);
1984
+ const paidAmountRs = paiseToRupees(gatewayOrder.amount);
1940
1985
  if (paidAmountRs < expectedPaymentAmountRs - 1) {
1941
1986
  serverLogger.warn(`Payment amount mismatch for user ${uid}: paid ₹${paidAmountRs}, expected ≥ ₹${expectedPaymentAmountRs}`);
1942
1987
  failedCheckoutRepository
1943
1988
  .logPayment(uid, "amount_mismatch", `Paid ₹${paidAmountRs}, expected ≥ ₹${expectedPaymentAmountRs}`, {
1944
- gatewayOrderId: phonepeOrder.gatewayOrderId,
1989
+ gatewayOrderId: gatewayOrder.gatewayOrderId,
1945
1990
  gatewayPaymentId: merchantOrderId,
1946
1991
  amountRs: paidAmountRs,
1947
1992
  addressId,
@@ -1978,8 +2023,8 @@ export async function verifyAndPlacePhonePeOrderAction(input) {
1978
2023
  userName,
1979
2024
  userEmail,
1980
2025
  merchantOrderId,
1981
- phonepeOrderId: phonepeOrder.gatewayOrderId,
1982
- transactionId: phonepeOrder.transactionId,
2026
+ phonepeOrderId: gatewayOrder.gatewayOrderId,
2027
+ transactionId: gatewayOrder.transactionId,
1983
2028
  shippingAddress,
1984
2029
  // For the CGST/SGST vs IGST split. The TOTAL does not depend on it
1985
2030
  // (see createPhonePeGroupOrder), which is what let the pre-payment
@@ -2033,7 +2078,7 @@ export async function verifyAndPlacePhonePeOrderAction(input) {
2033
2078
  if (emailsToSend.length > 0) {
2034
2079
  Promise.all(emailsToSend.map((e) => sendOrderConfirmationEmail(e))).catch((err) => serverLogger.error("Order confirmation email error:", err));
2035
2080
  }
2036
- serverLogger.info(`verifyAndPlacePhonePeOrderAction: ${orderIds.length} order(s) placed for uid=${uid} — payment ${merchantOrderId}`);
2081
+ serverLogger.info(`verifyAndPlaceGatewayOrderAction: ${orderIds.length} order(s) placed for uid=${uid} — payment ${merchantOrderId}`);
2037
2082
  getAdminRealtimeDb()
2038
2083
  .ref(`${RTDB_PATHS.PAYMENT_EVENTS}/${merchantOrderId}`)
2039
2084
  .update({ status: "success", orderIds, updatedAt: Date.now() })
@@ -1,3 +1,3 @@
1
- export { createCheckoutOrderAction, attachPaymentAction, verifyAndPlacePhonePeOrderAction, previewCheckoutPricing, resolveShippingCost, type CreateCheckoutOrderInput, type VerifyAndPlacePhonePeOrderInput, type CheckoutPricingPreviewInput, type CheckoutPricingPreview, } from "./actions";
1
+ export { createCheckoutOrderAction, attachPaymentAction, verifyAndPlaceGatewayOrderAction, previewCheckoutPricing, resolveShippingCost, type CreateCheckoutOrderInput, type VerifyAndPlaceGatewayOrderInput, type CheckoutPricingPreviewInput, type CheckoutPricingPreview, } from "./actions";
2
2
  export { formatShippingAddress, type CheckoutOrderResult, } from "./data";
3
3
  export { CHECKOUT_DEFAULT_COMMISSIONS, CHECKOUT_PAYMENT_METHODS, type CheckoutPaymentMethod, } from "../../../shared/features/checkout/config";
@@ -1,3 +1,3 @@
1
- export { createCheckoutOrderAction, attachPaymentAction, verifyAndPlacePhonePeOrderAction, previewCheckoutPricing, resolveShippingCost, } from "./actions.js";
1
+ export { createCheckoutOrderAction, attachPaymentAction, verifyAndPlaceGatewayOrderAction, previewCheckoutPricing, resolveShippingCost, } from "./actions.js";
2
2
  export { formatShippingAddress, } from "./data.js";
3
3
  export { CHECKOUT_DEFAULT_COMMISSIONS, CHECKOUT_PAYMENT_METHODS, } from "../../../shared/features/checkout/config.js";
@@ -29,6 +29,7 @@
29
29
  * registration as it stood at the moment of supply" — an admin correcting a
30
30
  * typo in the GSTIN must not silently reissue every invoice ever produced.
31
31
  */
32
+ import { getPlatformSupplier } from "../../../shared/features/site-settings/supplier-of-record.js";
32
33
  const trimmed = (v) => {
33
34
  const s = (v ?? "").trim();
34
35
  return s.length > 0 ? s : undefined;
@@ -61,18 +62,39 @@ export function resolveSupplierIdentity(store, settings) {
61
62
  };
62
63
  }
63
64
  /*
64
- * Platform branch. Gated on `gst.enabled`, matching what the checkout
65
- * already did before sellers could have a GSTIN at all — disabling GST must
66
- * continue to produce plain invoices rather than tax invoices.
65
+ * Platform branch. Still gated on `gst.enabled` — disabling GST must
66
+ * continue to produce plain invoices rather than tax invoices, and
67
+ * `source: "none"` must stay reachable.
68
+ *
69
+ * 🛑 But the IDENTITY now comes from `appkit.config.js → business`, not from
70
+ * `siteSettings.gst.*`.
71
+ *
72
+ * That block documents itself as "THE one owner of the business's statutory
73
+ * identity", and records that before it existed the legal name, address,
74
+ * GSTIN and support channels lived in five places that already disagreed —
75
+ * four different support addresses published, the registered address saying
76
+ * Solapur while the warehouse said Hyderabad. Reading the GSTIN from site
77
+ * settings here made this invoice path a SIXTH owner, and the one that
78
+ * decides what a tax invoice says.
79
+ *
80
+ * `siteSettings.gst.enabled` stays the switch because whether to charge GST
81
+ * at all is an operational decision an admin makes. WHO the supplier is, is
82
+ * not: it is a fact about the registered entity, it is legally required to be
83
+ * published, and it belongs in a committed, code-reviewed file.
84
+ *
85
+ * The snapshot contract is unchanged — the caller writes the result onto the
86
+ * order at creation and never recomputes it, so correcting a typo in the
87
+ * business block does not reissue historical invoices.
67
88
  */
68
89
  const gst = settings?.gst;
69
90
  if (gst?.enabled) {
70
- const platformGstin = trimmed(gst.gstin);
91
+ const platform = getPlatformSupplier();
92
+ const platformGstin = trimmed(platform.gstin);
71
93
  if (platformGstin) {
72
94
  return {
73
95
  gstin: platformGstin,
74
- legalName: trimmed(gst.legalName),
75
- address: trimmed(gst.address),
96
+ legalName: trimmed(platform.legalName),
97
+ address: trimmed(platform.address),
76
98
  source: "platform",
77
99
  };
78
100
  }
@@ -167,11 +167,9 @@ export function orderDocumentToOrder(doc) {
167
167
  couponDiscount: doc.couponDiscount,
168
168
  appliedDiscounts: doc.appliedDiscounts,
169
169
  // Add-ons are operational, not decorative: the status-change notifier reads
170
- // whatsappNotifyAddon, and the packer needs giftWrapMessage in hand. An
170
+ // the packer needs giftWrapMessage in hand. An
171
171
  // adapter that drops them makes every downstream surface render its
172
172
  // "not applicable" fallback instead (Root Cause #57).
173
- whatsappNotifyAddon: doc.whatsappNotifyAddon,
174
- whatsappNotifyFee: doc.whatsappNotifyFee,
175
173
  giftWrapAddon: doc.giftWrapAddon,
176
174
  giftWrapFee: doc.giftWrapFee,
177
175
  giftWrapMessage: doc.giftWrapMessage,