@mohasinac/appkit 4.53.1 → 4.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. package/dist/.build-stamp.json +3 -3
  2. package/dist/_internal/client/theme/ThemeProvider.js +15 -1
  3. package/dist/_internal/server/features/auth/capabilities.js +7 -5
  4. package/dist/_internal/server/features/categories/price-guidance-resolve.d.ts +66 -0
  5. package/dist/_internal/server/features/categories/price-guidance-resolve.js +138 -0
  6. package/dist/_internal/server/features/checkout/actions.d.ts +22 -6
  7. package/dist/_internal/server/features/checkout/actions.js +96 -51
  8. package/dist/_internal/server/features/checkout/index.d.ts +1 -1
  9. package/dist/_internal/server/features/checkout/index.js +1 -1
  10. package/dist/_internal/server/features/checkout/supplier-identity.js +28 -6
  11. package/dist/_internal/server/features/orders/adapters.js +1 -3
  12. package/dist/_internal/server/features/price-index/market.d.ts +57 -0
  13. package/dist/_internal/server/features/price-index/market.js +120 -0
  14. package/dist/_internal/server/features/products/list-public.d.ts +12 -0
  15. package/dist/_internal/server/features/products/list-public.js +10 -1
  16. package/dist/_internal/server/features/products/listing-tab-counts.d.ts +25 -1
  17. package/dist/_internal/server/features/products/listing-tab-counts.js +184 -10
  18. package/dist/_internal/server/features/search/index-build/sources.js +43 -2
  19. package/dist/_internal/server/features/site-settings/adapters.js +1 -1
  20. package/dist/_internal/server/features/stores/adapters.d.ts +1 -1
  21. package/dist/_internal/server/features/stores/adapters.js +0 -1
  22. package/dist/_internal/server/features/stores/tabs.d.ts +7 -2
  23. package/dist/_internal/server/features/stores/tabs.js +5 -3
  24. package/dist/_internal/server/jobs/core/analyticsAlertEvaluate.js +2 -5
  25. package/dist/_internal/server/jobs/core/jobRunners.js +0 -10
  26. package/dist/_internal/server/jobs/core/onOrderCreate.js +10 -104
  27. package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +0 -2
  28. package/dist/_internal/server/jobs/core/onOrderStatusChange.js +0 -1
  29. package/dist/_internal/server/jobs/core/onScamReportCreate.js +0 -1
  30. package/dist/_internal/server/jobs/core/onScamReportRejected.js +0 -1
  31. package/dist/_internal/server/jobs/core/onScamReportVerified.js +0 -1
  32. package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +0 -1
  33. package/dist/_internal/server/jobs/core/pendingOrderTimeout.js +0 -1
  34. package/dist/_internal/server/notifications/channel-health.d.ts +7 -3
  35. package/dist/_internal/server/notifications/channel-health.js +2 -2
  36. package/dist/_internal/server/notifications/send-guard.d.ts +1 -1
  37. package/dist/_internal/server/notifications/send-guard.js +2 -4
  38. package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
  39. package/dist/_internal/shared/actions/action-registry.js +128 -28
  40. package/dist/_internal/shared/checkout/order-math.d.ts +1 -1
  41. package/dist/_internal/shared/checkout/order-math.js +1 -1
  42. package/dist/_internal/shared/features/categories/bundle-copy.d.ts +1 -1
  43. package/dist/_internal/shared/features/checkout/config.d.ts +0 -2
  44. package/dist/_internal/shared/features/checkout/config.js +0 -2
  45. package/dist/_internal/shared/features/messaging/config.d.ts +7 -5
  46. package/dist/_internal/shared/features/messaging/config.js +1 -4
  47. package/dist/_internal/shared/features/site-settings/fees.d.ts +0 -2
  48. package/dist/_internal/shared/features/site-settings/fees.js +0 -2
  49. package/dist/_internal/shared/features/site-settings/supplier-of-record.d.ts +56 -0
  50. package/dist/_internal/shared/features/site-settings/supplier-of-record.js +57 -0
  51. package/dist/_internal/shared/fees/calculator.d.ts +0 -8
  52. package/dist/_internal/shared/fees/calculator.js +0 -7
  53. package/dist/_internal/shared/listing-types/tiers.d.ts +94 -0
  54. package/dist/_internal/shared/listing-types/tiers.js +150 -0
  55. package/dist/_internal/shared/search/match.js +28 -2
  56. package/dist/cli/index.js +0 -2
  57. package/dist/client.d.ts +25 -4
  58. package/dist/client.js +36 -5
  59. package/dist/constants/api-endpoints.d.ts +28 -15
  60. package/dist/constants/api-endpoints.js +14 -8
  61. package/dist/constants/field-names.d.ts +1 -0
  62. package/dist/constants/field-names.js +1 -0
  63. package/dist/constants/notification-types.d.ts +1 -1
  64. package/dist/constants/notification-types.js +1 -1
  65. package/dist/core/integration-keys.d.ts +5 -5
  66. package/dist/core/integration-keys.js +21 -10
  67. package/dist/features/about/components/FeesView.js +0 -6
  68. package/dist/features/about/components/GuidesHubView.js +15 -2
  69. package/dist/features/account/components/NotificationPreferencesPanel.js +3 -4
  70. package/dist/features/account/components/UserOrdersView.js +26 -7
  71. package/dist/features/account/types/index.d.ts +0 -2
  72. package/dist/features/addresses/utils/postal-autofill.d.ts +39 -0
  73. package/dist/features/addresses/utils/postal-autofill.js +54 -0
  74. package/dist/features/admin/actions/notification-actions.d.ts +2 -8
  75. package/dist/features/admin/actions/notification-actions.js +9 -104
  76. package/dist/features/admin/components/AdminGuideHubView.js +1 -8
  77. package/dist/features/admin/components/AdminOrderEditorView.d.ts +1 -1
  78. package/dist/features/admin/components/AdminOrdersView.js +0 -2
  79. package/dist/features/admin/components/AdminSectionsView.js +3 -2
  80. package/dist/features/admin/components/AdminSiteSettingsView.js +22 -68
  81. package/dist/features/admin/components/AdminStoreEditorView.js +72 -34
  82. package/dist/features/admin/components/OwnerQuickActions.d.ts +29 -0
  83. package/dist/features/admin/components/OwnerQuickActions.js +142 -0
  84. package/dist/features/admin/components/sections/adminSectionsTypes.js +13 -4
  85. package/dist/features/admin/components/sections/icon-options.d.ts +21 -0
  86. package/dist/features/admin/components/sections/icon-options.js +23 -0
  87. package/dist/features/admin/components/sections/sectionTemplates.js +4 -1
  88. package/dist/features/admin/constants/site-settings-tabs.d.ts +7 -12
  89. package/dist/features/admin/constants/site-settings-tabs.js +6 -12
  90. package/dist/features/admin/repository/site-settings.repository.js +1 -1
  91. package/dist/features/admin/schemas/admin-editor-forms.d.ts +1 -1
  92. package/dist/features/admin/schemas/admin-editor-forms.js +4 -1
  93. package/dist/features/admin/schemas/admin-user-form.d.ts +0 -61
  94. package/dist/features/admin/schemas/admin-user-form.js +3 -44
  95. package/dist/features/admin/schemas/firestore.d.ts +28 -54
  96. package/dist/features/admin/schemas/firestore.js +40 -18
  97. package/dist/features/auctions/components/AuctionDetailPageView.js +12 -10
  98. package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +11 -1
  99. package/dist/features/auctions/components/MarketplaceAuctionCard.js +9 -2
  100. package/dist/features/auth/checkout-value-otp.d.ts +1 -1
  101. package/dist/features/auth/checkout-value-otp.js +1 -1
  102. package/dist/features/auth/permissions/constants.d.ts +29 -2
  103. package/dist/features/auth/permissions/constants.js +67 -1
  104. package/dist/features/blog/components/BlogFeaturedCard.d.ts +11 -1
  105. package/dist/features/blog/components/BlogFeaturedCard.js +9 -2
  106. package/dist/features/cart/components/CartDrawer.js +3 -2
  107. package/dist/features/cart/components/CartGroupLineRow.js +2 -1
  108. package/dist/features/cart/components/CartPriceBreakdown.d.ts +0 -2
  109. package/dist/features/cart/components/CartPriceBreakdown.js +1 -1
  110. package/dist/features/cart/components/StoreAddonsPicker.d.ts +2 -5
  111. package/dist/features/cart/components/StoreAddonsPicker.js +4 -5
  112. package/dist/features/cart/hooks/useAddToCart.js +10 -5
  113. package/dist/features/cart/repository/cart.repository.js +1 -2
  114. package/dist/features/cart/schemas/firestore.d.ts +1 -2
  115. package/dist/features/cart/utils/pending-ops.d.ts +11 -1
  116. package/dist/features/cart/utils/pending-ops.js +14 -2
  117. package/dist/features/categories/api/[id]/price-guidance/route.js +1 -24
  118. package/dist/features/categories/components/BrandDetailPageView.js +15 -6
  119. package/dist/features/categories/components/BrandDetailTabs.d.ts +7 -1
  120. package/dist/features/categories/components/BrandDetailTabs.js +18 -3
  121. package/dist/features/categories/components/BundleCollage.js +3 -2
  122. package/dist/features/categories/components/BundleDetailView.js +2 -1
  123. package/dist/features/categories/components/BundleItemsPicker.js +3 -4
  124. package/dist/features/categories/components/CategoryDetailPageView.js +19 -8
  125. package/dist/features/categories/components/CategoryDetailTabs.d.ts +7 -1
  126. package/dist/features/categories/components/CategoryDetailTabs.js +29 -7
  127. package/dist/features/categories/components/CategoryGrid.d.ts +11 -1
  128. package/dist/features/categories/components/CategoryGrid.js +9 -2
  129. package/dist/features/checkout/actions/checkout-value-otp-actions.d.ts +10 -5
  130. package/dist/features/checkout/actions/checkout-value-otp-actions.js +2 -88
  131. package/dist/features/classified/components/ClassifiedDetailPageView.js +12 -2
  132. package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +12 -2
  133. package/dist/features/events/components/EventCard.d.ts +11 -1
  134. package/dist/features/events/components/EventCard.js +9 -2
  135. package/dist/features/grouped/components/GroupedListingDetailView.js +3 -1
  136. package/dist/features/homepage/components/CTABannerSection.d.ts +3 -1
  137. package/dist/features/homepage/components/CTABannerSection.js +6 -3
  138. package/dist/features/homepage/components/HeroCarousel.js +8 -6
  139. package/dist/features/homepage/components/MarketplaceHomepageView.js +33 -7
  140. package/dist/features/homepage/components/SectionCarousel.js +13 -5
  141. package/dist/features/homepage/components/SecurityHighlightsSection.d.ts +8 -3
  142. package/dist/features/homepage/components/SecurityHighlightsSection.js +2 -2
  143. package/dist/features/homepage/components/StatsCounterSection.d.ts +9 -4
  144. package/dist/features/homepage/components/StatsCounterSection.js +2 -2
  145. package/dist/features/homepage/components/TestimonialsCarousel.js +1 -1
  146. package/dist/features/homepage/components/TrustFeaturesSection.d.ts +18 -4
  147. package/dist/features/homepage/components/TrustFeaturesSection.js +5 -5
  148. package/dist/features/homepage/components/WelcomeSection.d.ts +13 -2
  149. package/dist/features/homepage/components/WelcomeSection.js +3 -3
  150. package/dist/features/homepage/components/WhatsAppCommunitySection.d.ts +28 -0
  151. package/dist/features/homepage/components/WhatsAppCommunitySection.js +42 -6
  152. package/dist/features/homepage/components/WhatsAppGlyph.d.ts +20 -0
  153. package/dist/features/homepage/components/WhatsAppGlyph.js +20 -0
  154. package/dist/features/homepage/constants/hero-carousel-styles.d.ts +8 -6
  155. package/dist/features/homepage/constants/hero-carousel-styles.js +8 -6
  156. package/dist/features/homepage/constants/section-copy.d.ts +12 -10
  157. package/dist/features/homepage/constants/section-copy.js +28 -6
  158. package/dist/features/homepage/constants/stat-icons.d.ts +12 -0
  159. package/dist/features/homepage/constants/stat-icons.js +17 -0
  160. package/dist/features/homepage/constants/trust-icon-aliases.d.ts +8 -0
  161. package/dist/features/homepage/constants/trust-icon-aliases.js +75 -0
  162. package/dist/features/homepage/lib/section-defaults.d.ts +16 -1
  163. package/dist/features/homepage/lib/section-defaults.js +24 -4
  164. package/dist/features/homepage/lib/section-renderer.js +48 -8
  165. package/dist/features/homepage/schemas/firestore.d.ts +18 -1
  166. package/dist/features/layout/AppLayoutShell.js +2 -1
  167. package/dist/features/layout/BottomActions.d.ts +1 -0
  168. package/dist/features/layout/BottomActions.js +330 -0
  169. package/dist/features/layout/BottomChrome.d.ts +45 -0
  170. package/dist/features/layout/BottomChrome.js +5 -17
  171. package/dist/features/layout/SideActionDock.js +36 -13
  172. package/dist/features/layout/index.d.ts +2 -7
  173. package/dist/features/layout/index.js +7 -7
  174. package/dist/features/layout/useIsDesktop.d.ts +36 -0
  175. package/dist/features/layout/useIsDesktop.js +48 -0
  176. package/dist/features/live/components/LiveItemDetailPageView.js +12 -2
  177. package/dist/features/orders/actions/refund-actions.js +0 -1
  178. package/dist/features/orders/components/OrderAddonBadges.d.ts +1 -3
  179. package/dist/features/orders/components/OrderAddonBadges.js +3 -4
  180. package/dist/features/orders/components/OrderPaymentSummary.js +15 -2
  181. package/dist/features/orders/components/YourPurchaseStrip.d.ts +24 -0
  182. package/dist/features/orders/components/YourPurchaseStrip.js +77 -0
  183. package/dist/features/orders/components/index.d.ts +2 -1
  184. package/dist/features/orders/components/index.js +1 -1
  185. package/dist/features/orders/repository/orders.repository.d.ts +0 -8
  186. package/dist/features/orders/repository/orders.repository.js +0 -2
  187. package/dist/features/orders/schemas/firestore.d.ts +17 -9
  188. package/dist/features/orders/types/index.d.ts +2 -5
  189. package/dist/features/orders/utils/order-announcement-message.d.ts +18 -0
  190. package/dist/features/orders/utils/order-announcement-message.js +16 -0
  191. package/dist/features/orders/utils/payment-proof-message.d.ts +20 -0
  192. package/dist/features/orders/utils/payment-proof-message.js +17 -0
  193. package/dist/features/parts/components/PartDetailPageView.js +96 -1
  194. package/dist/features/parts/schemas/firestore.d.ts +247 -0
  195. package/dist/features/parts/schemas/firestore.js +6 -6
  196. package/dist/features/pre-orders/components/MarketplacePreorderCard.d.ts +11 -1
  197. package/dist/features/pre-orders/components/MarketplacePreorderCard.js +10 -3
  198. package/dist/features/pre-orders/components/PreOrderDetailPageView.js +12 -10
  199. package/dist/features/price-index/components/PriceIndexToolView.d.ts +21 -0
  200. package/dist/features/price-index/components/PriceIndexToolView.js +230 -27
  201. package/dist/features/price-index/lookup-target.d.ts +48 -0
  202. package/dist/features/price-index/lookup-target.js +107 -0
  203. package/dist/features/products/api/[id]/route.js +8 -1
  204. package/dist/features/products/api/route.js +16 -4
  205. package/dist/features/products/components/AvailabilityScopeHint.d.ts +22 -0
  206. package/dist/features/products/components/AvailabilityScopeHint.js +27 -0
  207. package/dist/features/products/components/CompareOverlay.d.ts +2 -1
  208. package/dist/features/products/components/CompareOverlay.js +2 -1
  209. package/dist/features/products/components/GroupSettingsPanel.js +2 -1
  210. package/dist/features/products/components/InteractiveProductCard.d.ts +7 -1
  211. package/dist/features/products/components/InteractiveProductCard.js +16 -4
  212. package/dist/features/products/components/MarketplaceBundleCard.d.ts +11 -1
  213. package/dist/features/products/components/MarketplaceBundleCard.js +9 -2
  214. package/dist/features/products/components/MarketplacePrizeDrawCard.d.ts +11 -1
  215. package/dist/features/products/components/MarketplacePrizeDrawCard.js +9 -2
  216. package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -1
  217. package/dist/features/products/components/ProductDetailPageView.js +34 -4
  218. package/dist/features/products/components/ProductGrid.d.ts +14 -1
  219. package/dist/features/products/components/ProductGrid.js +22 -5
  220. package/dist/features/products/components/ProductsIndexListing.js +2 -2
  221. package/dist/features/products/components/SublistingCarouselSection.js +2 -1
  222. package/dist/features/products/repository/products.repository.d.ts +1 -0
  223. package/dist/features/products/repository/products.repository.js +5 -1
  224. package/dist/features/products/utils/group-member-image.d.ts +9 -2
  225. package/dist/features/products/utils/group-member-image.js +2 -1
  226. package/dist/features/reviews/api/[id]/route.js +83 -23
  227. package/dist/features/reviews/components/PurchaseReviewAffordance.d.ts +6 -0
  228. package/dist/features/reviews/components/PurchaseReviewAffordance.js +42 -0
  229. package/dist/features/reviews/components/ReviewFormDrawer.d.ts +34 -0
  230. package/dist/features/reviews/components/ReviewFormDrawer.js +127 -0
  231. package/dist/features/reviews/components/index.d.ts +4 -0
  232. package/dist/features/reviews/components/index.js +2 -0
  233. package/dist/features/scams/schemas/index.d.ts +10 -10
  234. package/dist/features/search/action-index/settings-entries.js +0 -9
  235. package/dist/features/seller/actions/seller-actions.d.ts +1 -1
  236. package/dist/features/seller/actions/seller-actions.js +49 -3
  237. package/dist/features/seller/components/SellerPayoutSettingsView.js +30 -2
  238. package/dist/features/seller/components/SellerProductShell.d.ts +17 -1
  239. package/dist/features/seller/components/SellerProductsView.js +3 -2
  240. package/dist/features/seller/hooks/useStoreListingEntitlements.d.ts +8 -0
  241. package/dist/features/seller/hooks/useStoreListingEntitlements.js +70 -0
  242. package/dist/features/store-extensions/repository/store-extensions.repositories.d.ts +1 -6
  243. package/dist/features/store-extensions/repository/store-extensions.repositories.js +1 -10
  244. package/dist/features/store-extensions/schemas/firestore.d.ts +1 -17
  245. package/dist/features/store-extensions/schemas/firestore.js +0 -10
  246. package/dist/features/stores/components/InteractiveStoreCard.d.ts +11 -1
  247. package/dist/features/stores/components/InteractiveStoreCard.js +9 -2
  248. package/dist/features/stores/components/StoreAuctionsListing.js +2 -1
  249. package/dist/features/stores/components/StoreCapabilitiesGuideView.js +0 -1
  250. package/dist/features/stores/components/StoreGuideHubView.js +2 -8
  251. package/dist/features/stores/components/StoreSettingsGuideView.js +2 -6
  252. package/dist/features/stores/components/index.d.ts +0 -2
  253. package/dist/features/stores/components/index.js +0 -1
  254. package/dist/features/stores/repository/store.repository.d.ts +1 -26
  255. package/dist/features/stores/repository/store.repository.js +5 -60
  256. package/dist/features/stores/schemas/firestore.d.ts +6 -25
  257. package/dist/features/stores/schemas/firestore.js +6 -3
  258. package/dist/features/stores/schemas/index.d.ts +1 -87
  259. package/dist/features/stores/schemas/index.js +10 -15
  260. package/dist/features/tester/seed-data/authored/admin__site-system.js +0 -48
  261. package/dist/features/tester/seed-data/authored/buying__buying-checkout.js +0 -40
  262. package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +114 -2
  263. package/dist/features/tester/seed-data/authored/selling__quick-add-minimum-details.js +0 -16
  264. package/dist/features/tester/seed-data/authored/selling__seller-guide.js +1 -1
  265. package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.js +0 -79
  266. package/dist/features/tester/seed-data/authored/selling__seller-orders.js +1 -1
  267. package/dist/features/tester/seed-data/tester-checklist-seed-data.js +427 -69
  268. package/dist/index.d.ts +20 -32
  269. package/dist/index.js +34 -43
  270. package/dist/next/routing/route-map.d.ts +2 -8
  271. package/dist/next/routing/route-map.js +21 -4
  272. package/dist/providers/db-firebase/base.repository.d.ts +1 -1
  273. package/dist/providers/db-firebase/base.repository.js +1 -1
  274. package/dist/providers/payment-razorpay/index.d.ts +125 -0
  275. package/dist/providers/payment-razorpay/index.js +232 -0
  276. package/dist/providers/payment-razorpay/signature.d.ts +53 -0
  277. package/dist/providers/payment-razorpay/signature.js +71 -0
  278. package/dist/providers/shipping-shiprocket/index.d.ts +98 -0
  279. package/dist/providers/shipping-shiprocket/index.js +356 -0
  280. package/dist/providers.d.ts +3 -0
  281. package/dist/providers.js +3 -0
  282. package/dist/react/hooks/useCanSeePrices.d.ts +0 -27
  283. package/dist/react/hooks/useCanSeePrices.js +25 -0
  284. package/dist/repositories/index.d.ts +1 -1
  285. package/dist/repositories/index.js +1 -1
  286. package/dist/schemas/registry.d.ts +10 -115
  287. package/dist/schemas/registry.js +1 -2
  288. package/dist/security/pii-encrypt.js +1 -1
  289. package/dist/seed/_helpers/category-forest.js +27 -0
  290. package/dist/seed/_helpers/category-parts-glossary-map.js +1816 -86
  291. package/dist/seed/_helpers/category-parts.d.ts +1 -1
  292. package/dist/seed/_helpers/category-parts.js +13412 -3020
  293. package/dist/seed/carousel-slides-seed-data.js +47 -10
  294. package/dist/seed/categories-seed-data.js +48 -6
  295. package/dist/seed/faq-seed-data.js +2 -2
  296. package/dist/seed/homepage-sections-seed-data.js +286 -54
  297. package/dist/seed/index.d.ts +1 -1
  298. package/dist/seed/index.js +1 -1
  299. package/dist/seed/manifest.d.ts +1 -1
  300. package/dist/seed/manifest.js +1 -2
  301. package/dist/seed/model-composition-seed-data.js +6 -8
  302. package/dist/seed/part-glossary/chunk0.d.ts +9 -0
  303. package/dist/seed/part-glossary/chunk0.js +35448 -0
  304. package/dist/seed/part-glossary/chunk1.d.ts +9 -0
  305. package/dist/seed/part-glossary/chunk1.js +40494 -0
  306. package/dist/seed/part-glossary/chunk2.d.ts +9 -0
  307. package/dist/seed/part-glossary/chunk2.js +51242 -0
  308. package/dist/seed/part-glossary/chunk3.d.ts +9 -0
  309. package/dist/seed/part-glossary/chunk3.js +53337 -0
  310. package/dist/seed/part-glossary/chunk4.d.ts +9 -0
  311. package/dist/seed/part-glossary/chunk4.js +51454 -0
  312. package/dist/seed/part-glossary-seed-data.d.ts +1 -1
  313. package/dist/seed/part-glossary-seed-data.js +23 -47483
  314. package/dist/seed/products-beyblade-x-seed-data.js +36 -1
  315. package/dist/seed/site-settings-seed-data.js +34 -35
  316. package/dist/seed/store-extensions-seed-data.d.ts +1 -2
  317. package/dist/seed/store-extensions-seed-data.js +1 -23
  318. package/dist/seed/stores-seed-data.js +0 -1
  319. package/dist/server-entry.d.ts +1 -1
  320. package/dist/server-entry.js +1 -1
  321. package/dist/server.d.ts +10 -10
  322. package/dist/server.js +24 -22
  323. package/dist/styles.css +392 -43
  324. package/dist/tailwind-utilities.css +1 -1
  325. package/dist/tokens/themes/default-dark.js +1 -1
  326. package/dist/tokens/themes/default-light.js +2 -1
  327. package/dist/tokens/tokens.css +6 -2
  328. package/dist/ui/components/Button.d.ts +11 -0
  329. package/dist/ui/components/Button.js +11 -0
  330. package/dist/ui/components/Button.style.css +29 -0
  331. package/dist/ui/components/CarouselNav.d.ts +57 -0
  332. package/dist/ui/components/CarouselNav.js +25 -0
  333. package/dist/ui/components/CarouselNav.style.css +265 -0
  334. package/dist/ui/components/GatedPrice.js +30 -3
  335. package/dist/ui/components/GatedPrice.style.css +43 -40
  336. package/dist/ui/components/HorizontalScroller.d.ts +12 -1
  337. package/dist/ui/components/HorizontalScroller.js +43 -3
  338. package/dist/ui/components/ImageMosaic.d.ts +8 -1
  339. package/dist/ui/components/ImageMosaic.js +3 -2
  340. package/dist/ui/components/ImageMosaic.style.css +22 -0
  341. package/dist/ui/components/Layout.style.css +6 -0
  342. package/dist/ui/components/Semantic.d.ts +3 -2
  343. package/dist/ui/components/Semantic.js +1 -0
  344. package/dist/ui/components/Typography.d.ts +2 -0
  345. package/dist/ui/components/Typography.js +2 -0
  346. package/dist/ui/components/Typography.style.css +19 -0
  347. package/dist/ui/components/index.style.css +1 -0
  348. package/dist/ui/index.d.ts +3 -1
  349. package/dist/ui/index.js +4 -0
  350. package/package.json +3 -2
  351. package/scripts/seed-cli.mjs +133 -27
  352. package/dist/_internal/server/jobs/core/whatsappCatalogImport.d.ts +0 -27
  353. package/dist/_internal/server/jobs/core/whatsappCatalogImport.js +0 -172
  354. package/dist/_internal/server/jobs/core/whatsappNotify.d.ts +0 -35
  355. package/dist/_internal/server/jobs/core/whatsappNotify.js +0 -140
  356. package/dist/features/admin/components/AdminWhatsAppGuideView.d.ts +0 -2
  357. package/dist/features/admin/components/AdminWhatsAppGuideView.js +0 -35
  358. package/dist/features/orders/components/MarketplaceOrderCard.d.ts +0 -36
  359. package/dist/features/orders/components/MarketplaceOrderCard.js +0 -57
  360. package/dist/features/stores/components/StoreWhatsAppGuideView.d.ts +0 -3
  361. package/dist/features/stores/components/StoreWhatsAppGuideView.js +0 -12
  362. package/dist/features/whatsapp-bot/api/send-status/route.d.ts +0 -12
  363. package/dist/features/whatsapp-bot/api/send-status/route.js +0 -38
  364. package/dist/features/whatsapp-bot/api/webhook/route.d.ts +0 -12
  365. package/dist/features/whatsapp-bot/api/webhook/route.js +0 -43
  366. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.d.ts +0 -6
  367. package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +0 -270
  368. package/dist/features/whatsapp-bot/components/WhatsAppChatButton.d.ts +0 -9
  369. package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +0 -7
  370. package/dist/features/whatsapp-bot/components/index.d.ts +0 -3
  371. package/dist/features/whatsapp-bot/components/index.js +0 -2
  372. package/dist/features/whatsapp-bot/helpers/payment-proof-message.d.ts +0 -14
  373. package/dist/features/whatsapp-bot/helpers/payment-proof-message.js +0 -17
  374. package/dist/features/whatsapp-bot/helpers/whatsapp.d.ts +0 -52
  375. package/dist/features/whatsapp-bot/helpers/whatsapp.js +0 -283
  376. package/dist/features/whatsapp-bot/index.d.ts +0 -3
  377. package/dist/features/whatsapp-bot/index.js +0 -3
  378. package/dist/features/whatsapp-bot/manifest.d.ts +0 -2
  379. package/dist/features/whatsapp-bot/manifest.js +0 -13
  380. package/dist/features/whatsapp-bot/messages/en.json +0 -7
  381. package/dist/features/whatsapp-bot/server.d.ts +0 -7
  382. package/dist/features/whatsapp-bot/server.js +0 -7
  383. package/dist/features/whatsapp-bot/types/index.d.ts +0 -126
  384. package/dist/features/whatsapp-bot/types/index.js +0 -1
@@ -0,0 +1,125 @@
1
+ /**
2
+ * @mohasinac/payment-razorpay — Razorpay IPaymentProvider implementation
3
+ *
4
+ * Implements the `IPaymentProvider` contract using the official `razorpay`
5
+ * package. Accepts credentials via constructor — no Firestore or DB
6
+ * dependency (same shape as `payment-manual` and `payment-phonepe`).
7
+ *
8
+ * 🛑 This is a RESTORE, not the original file. The pre-2026-10 provider was
9
+ * deleted in "replace Razorpay with PhonePe Standard Checkout v2" and this
10
+ * one is deliberately NOT a revert of it. Three things changed, each because
11
+ * the old shape could not work against the current money path:
12
+ *
13
+ * 1. **`getOrder()` maps the real status.** The old implementation
14
+ * hardcoded `status: "created"` on every fetch. That was survivable
15
+ * when the Razorpay path verified a client-side signature and nothing
16
+ * else, but the current `verifyAndPlaceGatewayOrderAction` treats
17
+ * `getOrder().status === "paid"` as the authoritative proof of payment
18
+ * (PhonePe hands the browser nothing verifiable, so that is the only
19
+ * check it has). A provider that always answers "created" would make
20
+ * every Razorpay checkout fail verification after a successful charge —
21
+ * the buyer is debited and gets no order.
22
+ * 2. **`capturePayment()`/`refund()` are ORDER-keyed, tolerantly.** The
23
+ * rest of this codebase keys gateway lookups on one id — PhonePe's
24
+ * order-keyed `merchantOrderId` — and stores it as `order.paymentId`.
25
+ * Razorpay's refund API is payment-keyed (`pay_…`), so rather than
26
+ * forcing every caller to track a second id, both methods accept EITHER
27
+ * an `order_…` or a `pay_…` id and resolve the order's captured payment
28
+ * themselves. See `resolvePaymentId()`.
29
+ * 3. **The three `@deprecated` standalone helpers are gone.** The old file
30
+ * carried a second, credential-resolving API surface
31
+ * (`createRazorpayOrder`, `fetchRazorpayOrder`, `createRazorpayRefund`,
32
+ * …) that bypassed the provider registry entirely. Its own JSDoc said
33
+ * to use `getProviders().payment` instead, and every live caller now
34
+ * does. Restoring a bypass layer nothing needs would be reviving the
35
+ * exact duplication Root Cause #75 is about.
36
+ *
37
+ * Unlike PhonePe, Razorpay uses a client-side modal: `createOrder()` returns
38
+ * no `checkoutUrl`, and the browser opens Razorpay's `checkout.js` with the
39
+ * returned order id plus the PUBLISHABLE key id. The key id is handed to the
40
+ * client by `/api/payment/create-order`, never by this provider.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * registerProviders({
45
+ * payment: new RazorpayProvider({
46
+ * keyId: process.env.RAZORPAY_KEY_ID!,
47
+ * keySecret: process.env.RAZORPAY_KEY_SECRET!,
48
+ * webhookSecret: process.env.RAZORPAY_WEBHOOK_SECRET,
49
+ * }),
50
+ * });
51
+ * ```
52
+ */
53
+ import type { JsonValue } from "@mohasinac/appkit";
54
+ import { IPaymentProvider } from "../../contracts";
55
+ import type { PaymentOrder, PaymentCapture, Refund } from "../../contracts";
56
+ export { verifyPaymentSignature, verifyWebhookSignature, type RazorpayPaymentResult, } from "./signature";
57
+ export interface RazorpayConfig {
58
+ /** Publishable key (`rzp_test_…` / `rzp_live_…`). Safe to expose to the browser. */
59
+ keyId: string;
60
+ /** Secret key. Server-only — never returned by any route. */
61
+ keySecret: string;
62
+ /** Webhook signing secret from the Razorpay dashboard's Webhooks tab. `verifyWebhook()` returns false without it. */
63
+ webhookSecret?: string;
64
+ }
65
+ export declare class RazorpayProvider extends IPaymentProvider {
66
+ readonly name = "razorpay";
67
+ private readonly razorpay;
68
+ private readonly webhookSecret?;
69
+ constructor(config: RazorpayConfig);
70
+ /**
71
+ * Creates a Razorpay order. `amount` is in PAISE — the smallest currency
72
+ * unit, which is what Razorpay's `amount` field means and what every
73
+ * caller in this codebase already passes (`rupeesToPaise(total)`).
74
+ *
75
+ * The returned `id` is Razorpay's own order id (`order_…`) and is the key
76
+ * every later lookup uses, so `gatewayOrderId` stays unset — the contract
77
+ * reserves that for gateways where the two ids differ. No `checkoutUrl`:
78
+ * Razorpay has no hosted page in this integration, the browser opens its
79
+ * modal instead.
80
+ */
81
+ createOrder(amount: number, currency?: string, metadata?: Record<string, JsonValue>): Promise<PaymentOrder>;
82
+ /**
83
+ * Verifies a Razorpay webhook: HMAC-SHA256 hex over the RAW request body,
84
+ * compared against the `x-razorpay-signature` header.
85
+ *
86
+ * Fails closed when no webhook secret is configured — same shape as
87
+ * PhonePe's missing-credential behaviour. The caller must pass the raw
88
+ * body string, not a re-serialised object: `JSON.stringify(JSON.parse(b))`
89
+ * is not guaranteed to reproduce the bytes that were signed.
90
+ */
91
+ verifyWebhook(payload: string, signature: string): boolean;
92
+ /**
93
+ * Resolves a `pay_…` id for either id shape.
94
+ *
95
+ * Given an `order_…` id, picks that order's captured payment (falling back
96
+ * to an authorized one, which is what a non-auto-capture flow leaves
97
+ * behind). Throws when the order has no such payment, because every caller
98
+ * — capture confirmation and refund alike — is meaningless without one.
99
+ */
100
+ private resolvePaymentId;
101
+ /**
102
+ * Reports the state of the payment behind an order. Accepts our stored
103
+ * order id (`order_…`) or a payment id (`pay_…`) — see the class comment.
104
+ *
105
+ * Named `capturePayment` by the contract, but it does NOT capture: this
106
+ * integration creates orders with Razorpay's default auto-capture, so a
107
+ * successful payment is already captured by the time anything here runs.
108
+ * Issuing a second capture would be an error, not a no-op.
109
+ */
110
+ capturePayment(orderId: string): Promise<PaymentCapture>;
111
+ /**
112
+ * Full or partial refund. `amount` is in paise; omit it to refund the whole
113
+ * payment. `paymentId` may be an `order_…` id — Razorpay refunds are
114
+ * payment-keyed but this codebase stores the order id, so it is resolved
115
+ * here rather than at ~6 call sites (see the class comment).
116
+ */
117
+ refund(paymentId: string, amount?: number): Promise<Refund>;
118
+ /**
119
+ * Fetches an order and reports its REAL status. This is the authoritative
120
+ * "was this paid" check — `verifyAndPlaceGatewayOrderAction` gates order
121
+ * placement on `status === "paid"`, so the mapping here is load-bearing
122
+ * (see point 1 of the class comment).
123
+ */
124
+ getOrder(orderId: string): Promise<PaymentOrder>;
125
+ }
@@ -0,0 +1,232 @@
1
+ /**
2
+ * @mohasinac/payment-razorpay — Razorpay IPaymentProvider implementation
3
+ *
4
+ * Implements the `IPaymentProvider` contract using the official `razorpay`
5
+ * package. Accepts credentials via constructor — no Firestore or DB
6
+ * dependency (same shape as `payment-manual` and `payment-phonepe`).
7
+ *
8
+ * 🛑 This is a RESTORE, not the original file. The pre-2026-10 provider was
9
+ * deleted in "replace Razorpay with PhonePe Standard Checkout v2" and this
10
+ * one is deliberately NOT a revert of it. Three things changed, each because
11
+ * the old shape could not work against the current money path:
12
+ *
13
+ * 1. **`getOrder()` maps the real status.** The old implementation
14
+ * hardcoded `status: "created"` on every fetch. That was survivable
15
+ * when the Razorpay path verified a client-side signature and nothing
16
+ * else, but the current `verifyAndPlaceGatewayOrderAction` treats
17
+ * `getOrder().status === "paid"` as the authoritative proof of payment
18
+ * (PhonePe hands the browser nothing verifiable, so that is the only
19
+ * check it has). A provider that always answers "created" would make
20
+ * every Razorpay checkout fail verification after a successful charge —
21
+ * the buyer is debited and gets no order.
22
+ * 2. **`capturePayment()`/`refund()` are ORDER-keyed, tolerantly.** The
23
+ * rest of this codebase keys gateway lookups on one id — PhonePe's
24
+ * order-keyed `merchantOrderId` — and stores it as `order.paymentId`.
25
+ * Razorpay's refund API is payment-keyed (`pay_…`), so rather than
26
+ * forcing every caller to track a second id, both methods accept EITHER
27
+ * an `order_…` or a `pay_…` id and resolve the order's captured payment
28
+ * themselves. See `resolvePaymentId()`.
29
+ * 3. **The three `@deprecated` standalone helpers are gone.** The old file
30
+ * carried a second, credential-resolving API surface
31
+ * (`createRazorpayOrder`, `fetchRazorpayOrder`, `createRazorpayRefund`,
32
+ * …) that bypassed the provider registry entirely. Its own JSDoc said
33
+ * to use `getProviders().payment` instead, and every live caller now
34
+ * does. Restoring a bypass layer nothing needs would be reviving the
35
+ * exact duplication Root Cause #75 is about.
36
+ *
37
+ * Unlike PhonePe, Razorpay uses a client-side modal: `createOrder()` returns
38
+ * no `checkoutUrl`, and the browser opens Razorpay's `checkout.js` with the
39
+ * returned order id plus the PUBLISHABLE key id. The key id is handed to the
40
+ * client by `/api/payment/create-order`, never by this provider.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * registerProviders({
45
+ * payment: new RazorpayProvider({
46
+ * keyId: process.env.RAZORPAY_KEY_ID!,
47
+ * keySecret: process.env.RAZORPAY_KEY_SECRET!,
48
+ * webhookSecret: process.env.RAZORPAY_WEBHOOK_SECRET,
49
+ * }),
50
+ * });
51
+ * ```
52
+ */
53
+ import Razorpay from "razorpay";
54
+ import { IPaymentProvider } from "../../contracts/index.js";
55
+ import { getDefaultCurrency } from "../../core/baseline-resolver.js";
56
+ import { verifyWebhookSignature } from "./signature.js";
57
+ export { verifyPaymentSignature, verifyWebhookSignature, } from "./signature.js";
58
+ /** Razorpay's own order status vocabulary → the contract's. */
59
+ function mapOrderStatus(status) {
60
+ switch (status) {
61
+ case "paid":
62
+ return "paid";
63
+ case "attempted":
64
+ return "attempted";
65
+ default:
66
+ return "created";
67
+ }
68
+ }
69
+ /**
70
+ * Razorpay `notes` is a flat string map (≤15 keys, 256 chars per value), but
71
+ * `createOrder`'s `metadata` is `Record<string, JsonValue>` and the shared
72
+ * create-order route passes PhonePe-shaped keys (`uid`, `redirectUrl`) through
73
+ * it. Flatten what survives and drop what does not, rather than letting a
74
+ * nested object reach the API and 400 the whole checkout.
75
+ */
76
+ function toNotes(metadata) {
77
+ if (!metadata)
78
+ return undefined;
79
+ const notes = {};
80
+ for (const [key, value] of Object.entries(metadata)) {
81
+ if (value === null || value === undefined)
82
+ continue;
83
+ if (typeof value === "object")
84
+ continue; // arrays/objects have no representation in notes
85
+ if (Object.keys(notes).length >= 15)
86
+ break;
87
+ notes[key] = String(value).slice(0, 256);
88
+ }
89
+ return Object.keys(notes).length > 0 ? notes : undefined;
90
+ }
91
+ // --- IPaymentProvider implementation ------------------------------------------
92
+ export class RazorpayProvider extends IPaymentProvider {
93
+ constructor(config) {
94
+ super();
95
+ this.name = "razorpay";
96
+ if (!config.keyId || !config.keySecret) {
97
+ throw new Error("RazorpayProvider requires keyId and keySecret. Configure them in Admin › Site Settings › Credentials, or set RAZORPAY_KEY_ID / RAZORPAY_KEY_SECRET.");
98
+ }
99
+ this.razorpay = new Razorpay({ key_id: config.keyId, key_secret: config.keySecret });
100
+ this.webhookSecret = config.webhookSecret;
101
+ }
102
+ /**
103
+ * Creates a Razorpay order. `amount` is in PAISE — the smallest currency
104
+ * unit, which is what Razorpay's `amount` field means and what every
105
+ * caller in this codebase already passes (`rupeesToPaise(total)`).
106
+ *
107
+ * The returned `id` is Razorpay's own order id (`order_…`) and is the key
108
+ * every later lookup uses, so `gatewayOrderId` stays unset — the contract
109
+ * reserves that for gateways where the two ids differ. No `checkoutUrl`:
110
+ * Razorpay has no hosted page in this integration, the browser opens its
111
+ * modal instead.
112
+ */
113
+ async createOrder(amount, currency, metadata) {
114
+ const resolvedCurrency = currency ?? getDefaultCurrency();
115
+ const receipt = typeof metadata?.receipt === "string" ? metadata.receipt : undefined;
116
+ const order = await this.razorpay.orders.create({
117
+ amount,
118
+ currency: resolvedCurrency,
119
+ receipt,
120
+ notes: toNotes(metadata),
121
+ });
122
+ return {
123
+ id: String(order.id),
124
+ amount: Number(order.amount),
125
+ currency: String(order.currency),
126
+ status: mapOrderStatus(String(order.status)),
127
+ receipt: order.receipt ?? undefined,
128
+ metadata,
129
+ createdAt: new Date(Number(order.created_at) * 1000).toISOString(),
130
+ };
131
+ }
132
+ /**
133
+ * Verifies a Razorpay webhook: HMAC-SHA256 hex over the RAW request body,
134
+ * compared against the `x-razorpay-signature` header.
135
+ *
136
+ * Fails closed when no webhook secret is configured — same shape as
137
+ * PhonePe's missing-credential behaviour. The caller must pass the raw
138
+ * body string, not a re-serialised object: `JSON.stringify(JSON.parse(b))`
139
+ * is not guaranteed to reproduce the bytes that were signed.
140
+ */
141
+ verifyWebhook(payload, signature) {
142
+ if (!this.webhookSecret)
143
+ return false;
144
+ return verifyWebhookSignature(payload, signature, this.webhookSecret);
145
+ }
146
+ /**
147
+ * Resolves a `pay_…` id for either id shape.
148
+ *
149
+ * Given an `order_…` id, picks that order's captured payment (falling back
150
+ * to an authorized one, which is what a non-auto-capture flow leaves
151
+ * behind). Throws when the order has no such payment, because every caller
152
+ * — capture confirmation and refund alike — is meaningless without one.
153
+ */
154
+ async resolvePaymentId(id) {
155
+ if (!id.startsWith("order_"))
156
+ return id;
157
+ const { items } = await this.razorpay.orders.fetchPayments(id);
158
+ const payment = items.find((p) => p.status === "captured") ?? items.find((p) => p.status === "authorized");
159
+ if (!payment) {
160
+ throw new Error(`Razorpay order ${id} has no captured or authorized payment`);
161
+ }
162
+ return String(payment.id);
163
+ }
164
+ /**
165
+ * Reports the state of the payment behind an order. Accepts our stored
166
+ * order id (`order_…`) or a payment id (`pay_…`) — see the class comment.
167
+ *
168
+ * Named `capturePayment` by the contract, but it does NOT capture: this
169
+ * integration creates orders with Razorpay's default auto-capture, so a
170
+ * successful payment is already captured by the time anything here runs.
171
+ * Issuing a second capture would be an error, not a no-op.
172
+ */
173
+ async capturePayment(orderId) {
174
+ const paymentId = await this.resolvePaymentId(orderId);
175
+ const payment = await this.razorpay.payments.fetch(paymentId);
176
+ return {
177
+ id: String(payment.id),
178
+ orderId: String(payment.order_id ?? orderId),
179
+ amount: Number(payment.amount),
180
+ currency: String(payment.currency),
181
+ status: payment.status === "captured" ? "captured" : "failed",
182
+ capturedAt: new Date().toISOString(),
183
+ transactionId: String(payment.id),
184
+ };
185
+ }
186
+ /**
187
+ * Full or partial refund. `amount` is in paise; omit it to refund the whole
188
+ * payment. `paymentId` may be an `order_…` id — Razorpay refunds are
189
+ * payment-keyed but this codebase stores the order id, so it is resolved
190
+ * here rather than at ~6 call sites (see the class comment).
191
+ */
192
+ async refund(paymentId, amount) {
193
+ const resolvedPaymentId = await this.resolvePaymentId(paymentId);
194
+ const result = await this.razorpay.payments.refund(resolvedPaymentId, amount === undefined ? {} : { amount });
195
+ return {
196
+ id: String(result.id),
197
+ paymentId: resolvedPaymentId,
198
+ amount: Number(result.amount),
199
+ currency: String(result.currency),
200
+ status: result.status === "processed"
201
+ ? "processed"
202
+ : result.status === "failed"
203
+ ? "failed"
204
+ : "pending",
205
+ createdAt: new Date(Number(result.created_at) * 1000).toISOString(),
206
+ };
207
+ }
208
+ /**
209
+ * Fetches an order and reports its REAL status. This is the authoritative
210
+ * "was this paid" check — `verifyAndPlaceGatewayOrderAction` gates order
211
+ * placement on `status === "paid"`, so the mapping here is load-bearing
212
+ * (see point 1 of the class comment).
213
+ */
214
+ async getOrder(orderId) {
215
+ const order = await this.razorpay.orders.fetch(orderId);
216
+ return {
217
+ id: String(order.id),
218
+ amount: Number(order.amount),
219
+ currency: String(order.currency),
220
+ status: mapOrderStatus(String(order.status)),
221
+ receipt: order.receipt ?? undefined,
222
+ createdAt: new Date(Number(order.created_at) * 1000).toISOString(),
223
+ /*
224
+ * `notes` round-trips whatever `createOrder` put there, which is how the
225
+ * WEBHOOK path (no buyer session) recovers the checkout intent — the
226
+ * same job PhonePe's `metaInfo` does. Without this the webhook could
227
+ * confirm a payment and then have no uid to place the order for.
228
+ */
229
+ metadata: order.notes,
230
+ };
231
+ }
232
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Razorpay signature verification — pure `node:crypto`, NO SDK import.
3
+ *
4
+ * 🛑 This is a separate module from `./index.ts` on purpose, and the split is
5
+ * load-bearing rather than tidiness. `_internal/server/features/checkout/
6
+ * actions.ts` needs `verifyPaymentSignature` on the buyer-present verify path,
7
+ * and importing it from the provider's `index.ts` would pull a static
8
+ * `import Razorpay from "razorpay"` into the checkout action's import graph —
9
+ * the whole SDK, its transitive deps and its own `node:` requires — for one
10
+ * HMAC comparison. Root Cause #24 is the same shape one layer down: a static
11
+ * top-level import is resolved before anything is tree-shaken, so "the symbol
12
+ * I use is cheap" does not make the module it lives in cheap.
13
+ *
14
+ * Keep this file free of SDK imports. `./index.ts` re-exports from here so
15
+ * the provider still has one public surface.
16
+ */
17
+ /** The three fields Razorpay's `checkout.js` hands back on a successful payment. */
18
+ export interface RazorpayPaymentResult {
19
+ razorpay_order_id: string;
20
+ razorpay_payment_id: string;
21
+ razorpay_signature: string;
22
+ }
23
+ /**
24
+ * Compares two hex digests without leaking position through an early exit.
25
+ *
26
+ * `timingSafeEqual` throws on unequal buffer lengths, and a non-hex input
27
+ * silently produces a short buffer — both are "not equal", so both are
28
+ * caught rather than propagated. Returning false on malformed input is the
29
+ * fail-closed direction.
30
+ */
31
+ export declare function hexEqual(expected: string, received: string): boolean;
32
+ /**
33
+ * Verifies the signature Razorpay's modal returns to the browser:
34
+ * HMAC-SHA256 over `{order_id}|{payment_id}`, keyed with the SECRET.
35
+ *
36
+ * 🛑 This proves the browser's callback was not forged or tampered with. It is
37
+ * NOT on its own proof that money moved — the digest is computable the moment
38
+ * an order id and a payment id exist, and both are visible to the client.
39
+ * `verifyAndPlaceGatewayOrderAction` therefore checks this AND re-fetches the
40
+ * order from Razorpay; this is the cheap guard, the fetch is the authority.
41
+ * Each alone has a failure mode: signature-only trusts a client-reported
42
+ * outcome, fetch-only accepts a replayed order id from another session.
43
+ */
44
+ export declare function verifyPaymentSignature(params: RazorpayPaymentResult, keySecret: string): boolean;
45
+ /**
46
+ * Verifies a Razorpay webhook: HMAC-SHA256 hex over the RAW request body,
47
+ * compared against the `x-razorpay-signature` header.
48
+ *
49
+ * 🛑 The caller must pass the raw body STRING, not a re-serialised object.
50
+ * `JSON.stringify(JSON.parse(body))` is not guaranteed to reproduce the bytes
51
+ * that were signed — key order and whitespace both survive into the digest.
52
+ */
53
+ export declare function verifyWebhookSignature(rawBody: string, signature: string, webhookSecret: string): boolean;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Razorpay signature verification — pure `node:crypto`, NO SDK import.
3
+ *
4
+ * 🛑 This is a separate module from `./index.ts` on purpose, and the split is
5
+ * load-bearing rather than tidiness. `_internal/server/features/checkout/
6
+ * actions.ts` needs `verifyPaymentSignature` on the buyer-present verify path,
7
+ * and importing it from the provider's `index.ts` would pull a static
8
+ * `import Razorpay from "razorpay"` into the checkout action's import graph —
9
+ * the whole SDK, its transitive deps and its own `node:` requires — for one
10
+ * HMAC comparison. Root Cause #24 is the same shape one layer down: a static
11
+ * top-level import is resolved before anything is tree-shaken, so "the symbol
12
+ * I use is cheap" does not make the module it lives in cheap.
13
+ *
14
+ * Keep this file free of SDK imports. `./index.ts` re-exports from here so
15
+ * the provider still has one public surface.
16
+ */
17
+ import { createHmac, timingSafeEqual } from "crypto";
18
+ import { normalizeError } from "../../errors/normalize.js";
19
+ /**
20
+ * Compares two hex digests without leaking position through an early exit.
21
+ *
22
+ * `timingSafeEqual` throws on unequal buffer lengths, and a non-hex input
23
+ * silently produces a short buffer — both are "not equal", so both are
24
+ * caught rather than propagated. Returning false on malformed input is the
25
+ * fail-closed direction.
26
+ */
27
+ export function hexEqual(expected, received) {
28
+ if (expected.length !== received.length)
29
+ return false;
30
+ try {
31
+ return timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(received, "hex"));
32
+ }
33
+ catch (err) {
34
+ void normalizeError(err);
35
+ return false;
36
+ }
37
+ }
38
+ /**
39
+ * Verifies the signature Razorpay's modal returns to the browser:
40
+ * HMAC-SHA256 over `{order_id}|{payment_id}`, keyed with the SECRET.
41
+ *
42
+ * 🛑 This proves the browser's callback was not forged or tampered with. It is
43
+ * NOT on its own proof that money moved — the digest is computable the moment
44
+ * an order id and a payment id exist, and both are visible to the client.
45
+ * `verifyAndPlaceGatewayOrderAction` therefore checks this AND re-fetches the
46
+ * order from Razorpay; this is the cheap guard, the fetch is the authority.
47
+ * Each alone has a failure mode: signature-only trusts a client-reported
48
+ * outcome, fetch-only accepts a replayed order id from another session.
49
+ */
50
+ export function verifyPaymentSignature(params, keySecret) {
51
+ if (!keySecret)
52
+ return false;
53
+ const expected = createHmac("sha256", keySecret)
54
+ .update(`${params.razorpay_order_id}|${params.razorpay_payment_id}`)
55
+ .digest("hex");
56
+ return hexEqual(expected, params.razorpay_signature);
57
+ }
58
+ /**
59
+ * Verifies a Razorpay webhook: HMAC-SHA256 hex over the RAW request body,
60
+ * compared against the `x-razorpay-signature` header.
61
+ *
62
+ * 🛑 The caller must pass the raw body STRING, not a re-serialised object.
63
+ * `JSON.stringify(JSON.parse(body))` is not guaranteed to reproduce the bytes
64
+ * that were signed — key order and whitespace both survive into the digest.
65
+ */
66
+ export function verifyWebhookSignature(rawBody, signature, webhookSecret) {
67
+ if (!webhookSecret)
68
+ return false;
69
+ const expected = createHmac("sha256", webhookSecret).update(rawBody).digest("hex");
70
+ return hexEqual(expected, signature);
71
+ }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * @mohasinac/shipping-shiprocket — IShippingProvider over Shiprocket's v1 API.
3
+ *
4
+ * ── Read this before trusting it ──────────────────────────────────────────
5
+ *
6
+ * ── What is verified, and what is not ────────────────────────────────────
7
+ *
8
+ * ✅ VERIFIED against the live API (2026-10-20, real API-user credentials):
9
+ * `POST /v1/external/auth/login` returns HTTP 200 with
10
+ * `{ company_id, created_at, email, first_name, id, last_name, token }`.
11
+ * The `token` field is present and non-empty, which is the only field
12
+ * `loginResponse` requires — the rest are ignored, as Zod ignores unknown
13
+ * keys by default.
14
+ *
15
+ * 🛑 NOT VERIFIED: every other endpoint. Order creation, AWB assignment,
16
+ * tracking, serviceability and label generation all MUTATE or bill against
17
+ * a real carrier account, so none was called. Their field names below are
18
+ * claims taken from the published docs, not facts read off a payload.
19
+ *
20
+ * That asymmetry is the reason every response is parsed through Zod rather
21
+ * than cast: an unverified contract that is wrong surfaces as a named error at
22
+ * the boundary, instead of as an `undefined` AWB written to an order and shown
23
+ * to a buyer as a tracking number that tracks nothing.
24
+ *
25
+ * ── Auth: why a dedicated API user, and why the token is cached ───────────
26
+ *
27
+ * Shiprocket's core v1 API has no long-lived key/secret. You POST credentials
28
+ * to `/v1/external/auth/login` and receive a bearer token valid for roughly
29
+ * ten days, then log in again.
30
+ *
31
+ * 🛑 Those credentials should be a DEDICATED API USER (Shiprocket dashboard →
32
+ * Settings → API → Configure), not the dashboard login. Using the dashboard
33
+ * account means the token dies whenever someone changes that password — a
34
+ * shipping integration that breaks on an unrelated admin action — and it hands
35
+ * full account scope to this process. The env var is named
36
+ * `SHIPROCKET_LOGIN_USER_EMAIL` rather than `LOGIN_ID` because the login payload
37
+ * field is `email`; a var called "login id" invites someone to put a username
38
+ * in it and get a 400 they cannot explain.
39
+ *
40
+ * 🛑 The token is cached in module state with its expiry. Logging in per
41
+ * request would mean two round trips for every shipment and would hit
42
+ * Shiprocket's auth rate limit under any real volume. A 401 mid-flight clears
43
+ * the cache and retries ONCE — exactly once, because a credential that is
44
+ * genuinely wrong must fail fast rather than loop.
45
+ *
46
+ * ── What is deliberately NOT here ────────────────────────────────────────
47
+ *
48
+ * Inbound webhooks. Shiprocket pushes status updates to a URL configured in
49
+ * its dashboard and authenticates them with an `x-api-key` header whose value
50
+ * you set there — a THIRD secret, and an inbound route rather than a provider
51
+ * method. `trackShipment` below polls instead, which is correct for a provider
52
+ * contract and wasteful as a status mechanism; the webhook is the better
53
+ * answer and belongs in its own route with its own verification.
54
+ *
55
+ * @tag domain:shipping
56
+ * @tag layer:providers
57
+ * @tag access:server-only
58
+ */
59
+ import { IShippingProvider } from "../../contracts";
60
+ import type { CreateShipmentInput, Shipment, TrackingInfo, ServiceabilityResult } from "../../contracts";
61
+ export interface ShiprocketConfig {
62
+ /** The API user's email. See the header on why this is not a "login id". */
63
+ email: string;
64
+ password: string;
65
+ /** Shiprocket pickup-location nickname, as registered in their dashboard. */
66
+ pickupLocation?: string;
67
+ }
68
+ export declare class ShiprocketShippingProvider extends IShippingProvider {
69
+ private readonly config;
70
+ readonly name = "shiprocket";
71
+ private token;
72
+ private tokenExpiresAt;
73
+ constructor(config: ShiprocketConfig);
74
+ /**
75
+ * A bearer token, logging in only when the cached one is absent or stale.
76
+ *
77
+ * The 60-second safety margin matters: a token that expires mid-request
78
+ * produces a 401 the caller has to interpret, and shaving a minute off a
79
+ * ten-day lifetime costs nothing.
80
+ */
81
+ private getToken;
82
+ /**
83
+ * One authenticated call, with a single re-auth on 401.
84
+ *
85
+ * 🛑 Exactly one retry. A token that expired early is worth one more attempt;
86
+ * a credential that is wrong must fail rather than loop, because a retry loop
87
+ * against an auth endpoint is how an integration gets rate-limited and then
88
+ * looks like an outage.
89
+ */
90
+ private call;
91
+ /** Their order payload wants the address flattened across many keys. */
92
+ private addressFields;
93
+ createShipment(data: CreateShipmentInput): Promise<Shipment>;
94
+ trackShipment(trackingId: string): Promise<TrackingInfo>;
95
+ cancelShipment(shipmentId: string): Promise<void>;
96
+ checkServiceability(pincode: string, weight: number): Promise<ServiceabilityResult>;
97
+ generateLabel(shipmentId: string): Promise<ArrayBuffer>;
98
+ }