@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.
- package/dist/.build-stamp.json +3 -3
- package/dist/_internal/client/theme/ThemeProvider.js +15 -1
- package/dist/_internal/server/features/auth/capabilities.js +7 -5
- package/dist/_internal/server/features/categories/price-guidance-resolve.d.ts +66 -0
- package/dist/_internal/server/features/categories/price-guidance-resolve.js +138 -0
- package/dist/_internal/server/features/checkout/actions.d.ts +22 -6
- package/dist/_internal/server/features/checkout/actions.js +96 -51
- package/dist/_internal/server/features/checkout/index.d.ts +1 -1
- package/dist/_internal/server/features/checkout/index.js +1 -1
- package/dist/_internal/server/features/checkout/supplier-identity.js +28 -6
- package/dist/_internal/server/features/orders/adapters.js +1 -3
- package/dist/_internal/server/features/price-index/market.d.ts +57 -0
- package/dist/_internal/server/features/price-index/market.js +120 -0
- package/dist/_internal/server/features/products/list-public.d.ts +12 -0
- package/dist/_internal/server/features/products/list-public.js +10 -1
- package/dist/_internal/server/features/products/listing-tab-counts.d.ts +25 -1
- package/dist/_internal/server/features/products/listing-tab-counts.js +184 -10
- package/dist/_internal/server/features/search/index-build/sources.js +43 -2
- package/dist/_internal/server/features/site-settings/adapters.js +1 -1
- package/dist/_internal/server/features/stores/adapters.d.ts +1 -1
- package/dist/_internal/server/features/stores/adapters.js +0 -1
- package/dist/_internal/server/features/stores/tabs.d.ts +7 -2
- package/dist/_internal/server/features/stores/tabs.js +5 -3
- package/dist/_internal/server/jobs/core/analyticsAlertEvaluate.js +2 -5
- package/dist/_internal/server/jobs/core/jobRunners.js +0 -10
- package/dist/_internal/server/jobs/core/onOrderCreate.js +10 -104
- package/dist/_internal/server/jobs/core/onOrderStatusChange.d.ts +0 -2
- package/dist/_internal/server/jobs/core/onOrderStatusChange.js +0 -1
- package/dist/_internal/server/jobs/core/onScamReportCreate.js +0 -1
- package/dist/_internal/server/jobs/core/onScamReportRejected.js +0 -1
- package/dist/_internal/server/jobs/core/onScamReportVerified.js +0 -1
- package/dist/_internal/server/jobs/core/paymentWindowTimeout.js +0 -1
- package/dist/_internal/server/jobs/core/pendingOrderTimeout.js +0 -1
- package/dist/_internal/server/notifications/channel-health.d.ts +7 -3
- package/dist/_internal/server/notifications/channel-health.js +2 -2
- package/dist/_internal/server/notifications/send-guard.d.ts +1 -1
- package/dist/_internal/server/notifications/send-guard.js +2 -4
- package/dist/_internal/shared/actions/action-registry.d.ts +1 -1
- package/dist/_internal/shared/actions/action-registry.js +128 -28
- package/dist/_internal/shared/checkout/order-math.d.ts +1 -1
- package/dist/_internal/shared/checkout/order-math.js +1 -1
- package/dist/_internal/shared/features/categories/bundle-copy.d.ts +1 -1
- package/dist/_internal/shared/features/checkout/config.d.ts +0 -2
- package/dist/_internal/shared/features/checkout/config.js +0 -2
- package/dist/_internal/shared/features/messaging/config.d.ts +7 -5
- package/dist/_internal/shared/features/messaging/config.js +1 -4
- package/dist/_internal/shared/features/site-settings/fees.d.ts +0 -2
- package/dist/_internal/shared/features/site-settings/fees.js +0 -2
- package/dist/_internal/shared/features/site-settings/supplier-of-record.d.ts +56 -0
- package/dist/_internal/shared/features/site-settings/supplier-of-record.js +57 -0
- package/dist/_internal/shared/fees/calculator.d.ts +0 -8
- package/dist/_internal/shared/fees/calculator.js +0 -7
- package/dist/_internal/shared/listing-types/tiers.d.ts +94 -0
- package/dist/_internal/shared/listing-types/tiers.js +150 -0
- package/dist/_internal/shared/search/match.js +28 -2
- package/dist/cli/index.js +0 -2
- package/dist/client.d.ts +25 -4
- package/dist/client.js +36 -5
- package/dist/constants/api-endpoints.d.ts +28 -15
- package/dist/constants/api-endpoints.js +14 -8
- package/dist/constants/field-names.d.ts +1 -0
- package/dist/constants/field-names.js +1 -0
- package/dist/constants/notification-types.d.ts +1 -1
- package/dist/constants/notification-types.js +1 -1
- package/dist/core/integration-keys.d.ts +5 -5
- package/dist/core/integration-keys.js +21 -10
- package/dist/features/about/components/FeesView.js +0 -6
- package/dist/features/about/components/GuidesHubView.js +15 -2
- package/dist/features/account/components/NotificationPreferencesPanel.js +3 -4
- package/dist/features/account/components/UserOrdersView.js +26 -7
- package/dist/features/account/types/index.d.ts +0 -2
- package/dist/features/addresses/utils/postal-autofill.d.ts +39 -0
- package/dist/features/addresses/utils/postal-autofill.js +54 -0
- package/dist/features/admin/actions/notification-actions.d.ts +2 -8
- package/dist/features/admin/actions/notification-actions.js +9 -104
- package/dist/features/admin/components/AdminGuideHubView.js +1 -8
- package/dist/features/admin/components/AdminOrderEditorView.d.ts +1 -1
- package/dist/features/admin/components/AdminOrdersView.js +0 -2
- package/dist/features/admin/components/AdminSectionsView.js +3 -2
- package/dist/features/admin/components/AdminSiteSettingsView.js +22 -68
- package/dist/features/admin/components/AdminStoreEditorView.js +72 -34
- package/dist/features/admin/components/OwnerQuickActions.d.ts +29 -0
- package/dist/features/admin/components/OwnerQuickActions.js +142 -0
- package/dist/features/admin/components/sections/adminSectionsTypes.js +13 -4
- package/dist/features/admin/components/sections/icon-options.d.ts +21 -0
- package/dist/features/admin/components/sections/icon-options.js +23 -0
- package/dist/features/admin/components/sections/sectionTemplates.js +4 -1
- package/dist/features/admin/constants/site-settings-tabs.d.ts +7 -12
- package/dist/features/admin/constants/site-settings-tabs.js +6 -12
- package/dist/features/admin/repository/site-settings.repository.js +1 -1
- package/dist/features/admin/schemas/admin-editor-forms.d.ts +1 -1
- package/dist/features/admin/schemas/admin-editor-forms.js +4 -1
- package/dist/features/admin/schemas/admin-user-form.d.ts +0 -61
- package/dist/features/admin/schemas/admin-user-form.js +3 -44
- package/dist/features/admin/schemas/firestore.d.ts +28 -54
- package/dist/features/admin/schemas/firestore.js +40 -18
- package/dist/features/auctions/components/AuctionDetailPageView.js +12 -10
- package/dist/features/auctions/components/MarketplaceAuctionCard.d.ts +11 -1
- package/dist/features/auctions/components/MarketplaceAuctionCard.js +9 -2
- package/dist/features/auth/checkout-value-otp.d.ts +1 -1
- package/dist/features/auth/checkout-value-otp.js +1 -1
- package/dist/features/auth/permissions/constants.d.ts +29 -2
- package/dist/features/auth/permissions/constants.js +67 -1
- package/dist/features/blog/components/BlogFeaturedCard.d.ts +11 -1
- package/dist/features/blog/components/BlogFeaturedCard.js +9 -2
- package/dist/features/cart/components/CartDrawer.js +3 -2
- package/dist/features/cart/components/CartGroupLineRow.js +2 -1
- package/dist/features/cart/components/CartPriceBreakdown.d.ts +0 -2
- package/dist/features/cart/components/CartPriceBreakdown.js +1 -1
- package/dist/features/cart/components/StoreAddonsPicker.d.ts +2 -5
- package/dist/features/cart/components/StoreAddonsPicker.js +4 -5
- package/dist/features/cart/hooks/useAddToCart.js +10 -5
- package/dist/features/cart/repository/cart.repository.js +1 -2
- package/dist/features/cart/schemas/firestore.d.ts +1 -2
- package/dist/features/cart/utils/pending-ops.d.ts +11 -1
- package/dist/features/cart/utils/pending-ops.js +14 -2
- package/dist/features/categories/api/[id]/price-guidance/route.js +1 -24
- package/dist/features/categories/components/BrandDetailPageView.js +15 -6
- package/dist/features/categories/components/BrandDetailTabs.d.ts +7 -1
- package/dist/features/categories/components/BrandDetailTabs.js +18 -3
- package/dist/features/categories/components/BundleCollage.js +3 -2
- package/dist/features/categories/components/BundleDetailView.js +2 -1
- package/dist/features/categories/components/BundleItemsPicker.js +3 -4
- package/dist/features/categories/components/CategoryDetailPageView.js +19 -8
- package/dist/features/categories/components/CategoryDetailTabs.d.ts +7 -1
- package/dist/features/categories/components/CategoryDetailTabs.js +29 -7
- package/dist/features/categories/components/CategoryGrid.d.ts +11 -1
- package/dist/features/categories/components/CategoryGrid.js +9 -2
- package/dist/features/checkout/actions/checkout-value-otp-actions.d.ts +10 -5
- package/dist/features/checkout/actions/checkout-value-otp-actions.js +2 -88
- package/dist/features/classified/components/ClassifiedDetailPageView.js +12 -2
- package/dist/features/digital-codes/components/DigitalCodeDetailPageView.js +12 -2
- package/dist/features/events/components/EventCard.d.ts +11 -1
- package/dist/features/events/components/EventCard.js +9 -2
- package/dist/features/grouped/components/GroupedListingDetailView.js +3 -1
- package/dist/features/homepage/components/CTABannerSection.d.ts +3 -1
- package/dist/features/homepage/components/CTABannerSection.js +6 -3
- package/dist/features/homepage/components/HeroCarousel.js +8 -6
- package/dist/features/homepage/components/MarketplaceHomepageView.js +33 -7
- package/dist/features/homepage/components/SectionCarousel.js +13 -5
- package/dist/features/homepage/components/SecurityHighlightsSection.d.ts +8 -3
- package/dist/features/homepage/components/SecurityHighlightsSection.js +2 -2
- package/dist/features/homepage/components/StatsCounterSection.d.ts +9 -4
- package/dist/features/homepage/components/StatsCounterSection.js +2 -2
- package/dist/features/homepage/components/TestimonialsCarousel.js +1 -1
- package/dist/features/homepage/components/TrustFeaturesSection.d.ts +18 -4
- package/dist/features/homepage/components/TrustFeaturesSection.js +5 -5
- package/dist/features/homepage/components/WelcomeSection.d.ts +13 -2
- package/dist/features/homepage/components/WelcomeSection.js +3 -3
- package/dist/features/homepage/components/WhatsAppCommunitySection.d.ts +28 -0
- package/dist/features/homepage/components/WhatsAppCommunitySection.js +42 -6
- package/dist/features/homepage/components/WhatsAppGlyph.d.ts +20 -0
- package/dist/features/homepage/components/WhatsAppGlyph.js +20 -0
- package/dist/features/homepage/constants/hero-carousel-styles.d.ts +8 -6
- package/dist/features/homepage/constants/hero-carousel-styles.js +8 -6
- package/dist/features/homepage/constants/section-copy.d.ts +12 -10
- package/dist/features/homepage/constants/section-copy.js +28 -6
- package/dist/features/homepage/constants/stat-icons.d.ts +12 -0
- package/dist/features/homepage/constants/stat-icons.js +17 -0
- package/dist/features/homepage/constants/trust-icon-aliases.d.ts +8 -0
- package/dist/features/homepage/constants/trust-icon-aliases.js +75 -0
- package/dist/features/homepage/lib/section-defaults.d.ts +16 -1
- package/dist/features/homepage/lib/section-defaults.js +24 -4
- package/dist/features/homepage/lib/section-renderer.js +48 -8
- package/dist/features/homepage/schemas/firestore.d.ts +18 -1
- package/dist/features/layout/AppLayoutShell.js +2 -1
- package/dist/features/layout/BottomActions.d.ts +1 -0
- package/dist/features/layout/BottomActions.js +330 -0
- package/dist/features/layout/BottomChrome.d.ts +45 -0
- package/dist/features/layout/BottomChrome.js +5 -17
- package/dist/features/layout/SideActionDock.js +36 -13
- package/dist/features/layout/index.d.ts +2 -7
- package/dist/features/layout/index.js +7 -7
- package/dist/features/layout/useIsDesktop.d.ts +36 -0
- package/dist/features/layout/useIsDesktop.js +48 -0
- package/dist/features/live/components/LiveItemDetailPageView.js +12 -2
- package/dist/features/orders/actions/refund-actions.js +0 -1
- package/dist/features/orders/components/OrderAddonBadges.d.ts +1 -3
- package/dist/features/orders/components/OrderAddonBadges.js +3 -4
- package/dist/features/orders/components/OrderPaymentSummary.js +15 -2
- package/dist/features/orders/components/YourPurchaseStrip.d.ts +24 -0
- package/dist/features/orders/components/YourPurchaseStrip.js +77 -0
- package/dist/features/orders/components/index.d.ts +2 -1
- package/dist/features/orders/components/index.js +1 -1
- package/dist/features/orders/repository/orders.repository.d.ts +0 -8
- package/dist/features/orders/repository/orders.repository.js +0 -2
- package/dist/features/orders/schemas/firestore.d.ts +17 -9
- package/dist/features/orders/types/index.d.ts +2 -5
- package/dist/features/orders/utils/order-announcement-message.d.ts +18 -0
- package/dist/features/orders/utils/order-announcement-message.js +16 -0
- package/dist/features/orders/utils/payment-proof-message.d.ts +20 -0
- package/dist/features/orders/utils/payment-proof-message.js +17 -0
- package/dist/features/parts/components/PartDetailPageView.js +96 -1
- package/dist/features/parts/schemas/firestore.d.ts +247 -0
- package/dist/features/parts/schemas/firestore.js +6 -6
- package/dist/features/pre-orders/components/MarketplacePreorderCard.d.ts +11 -1
- package/dist/features/pre-orders/components/MarketplacePreorderCard.js +10 -3
- package/dist/features/pre-orders/components/PreOrderDetailPageView.js +12 -10
- package/dist/features/price-index/components/PriceIndexToolView.d.ts +21 -0
- package/dist/features/price-index/components/PriceIndexToolView.js +230 -27
- package/dist/features/price-index/lookup-target.d.ts +48 -0
- package/dist/features/price-index/lookup-target.js +107 -0
- package/dist/features/products/api/[id]/route.js +8 -1
- package/dist/features/products/api/route.js +16 -4
- package/dist/features/products/components/AvailabilityScopeHint.d.ts +22 -0
- package/dist/features/products/components/AvailabilityScopeHint.js +27 -0
- package/dist/features/products/components/CompareOverlay.d.ts +2 -1
- package/dist/features/products/components/CompareOverlay.js +2 -1
- package/dist/features/products/components/GroupSettingsPanel.js +2 -1
- package/dist/features/products/components/InteractiveProductCard.d.ts +7 -1
- package/dist/features/products/components/InteractiveProductCard.js +16 -4
- package/dist/features/products/components/MarketplaceBundleCard.d.ts +11 -1
- package/dist/features/products/components/MarketplaceBundleCard.js +9 -2
- package/dist/features/products/components/MarketplacePrizeDrawCard.d.ts +11 -1
- package/dist/features/products/components/MarketplacePrizeDrawCard.js +9 -2
- package/dist/features/products/components/PrizeDrawDetailPageView.js +2 -1
- package/dist/features/products/components/ProductDetailPageView.js +34 -4
- package/dist/features/products/components/ProductGrid.d.ts +14 -1
- package/dist/features/products/components/ProductGrid.js +22 -5
- package/dist/features/products/components/ProductsIndexListing.js +2 -2
- package/dist/features/products/components/SublistingCarouselSection.js +2 -1
- package/dist/features/products/repository/products.repository.d.ts +1 -0
- package/dist/features/products/repository/products.repository.js +5 -1
- package/dist/features/products/utils/group-member-image.d.ts +9 -2
- package/dist/features/products/utils/group-member-image.js +2 -1
- package/dist/features/reviews/api/[id]/route.js +83 -23
- package/dist/features/reviews/components/PurchaseReviewAffordance.d.ts +6 -0
- package/dist/features/reviews/components/PurchaseReviewAffordance.js +42 -0
- package/dist/features/reviews/components/ReviewFormDrawer.d.ts +34 -0
- package/dist/features/reviews/components/ReviewFormDrawer.js +127 -0
- package/dist/features/reviews/components/index.d.ts +4 -0
- package/dist/features/reviews/components/index.js +2 -0
- package/dist/features/scams/schemas/index.d.ts +10 -10
- package/dist/features/search/action-index/settings-entries.js +0 -9
- package/dist/features/seller/actions/seller-actions.d.ts +1 -1
- package/dist/features/seller/actions/seller-actions.js +49 -3
- package/dist/features/seller/components/SellerPayoutSettingsView.js +30 -2
- package/dist/features/seller/components/SellerProductShell.d.ts +17 -1
- package/dist/features/seller/components/SellerProductsView.js +3 -2
- package/dist/features/seller/hooks/useStoreListingEntitlements.d.ts +8 -0
- package/dist/features/seller/hooks/useStoreListingEntitlements.js +70 -0
- package/dist/features/store-extensions/repository/store-extensions.repositories.d.ts +1 -6
- package/dist/features/store-extensions/repository/store-extensions.repositories.js +1 -10
- package/dist/features/store-extensions/schemas/firestore.d.ts +1 -17
- package/dist/features/store-extensions/schemas/firestore.js +0 -10
- package/dist/features/stores/components/InteractiveStoreCard.d.ts +11 -1
- package/dist/features/stores/components/InteractiveStoreCard.js +9 -2
- package/dist/features/stores/components/StoreAuctionsListing.js +2 -1
- package/dist/features/stores/components/StoreCapabilitiesGuideView.js +0 -1
- package/dist/features/stores/components/StoreGuideHubView.js +2 -8
- package/dist/features/stores/components/StoreSettingsGuideView.js +2 -6
- package/dist/features/stores/components/index.d.ts +0 -2
- package/dist/features/stores/components/index.js +0 -1
- package/dist/features/stores/repository/store.repository.d.ts +1 -26
- package/dist/features/stores/repository/store.repository.js +5 -60
- package/dist/features/stores/schemas/firestore.d.ts +6 -25
- package/dist/features/stores/schemas/firestore.js +6 -3
- package/dist/features/stores/schemas/index.d.ts +1 -87
- package/dist/features/stores/schemas/index.js +10 -15
- package/dist/features/tester/seed-data/authored/admin__site-system.js +0 -48
- package/dist/features/tester/seed-data/authored/buying__buying-checkout.js +0 -40
- package/dist/features/tester/seed-data/authored/content-discovery__authenticity-checker.js +114 -2
- package/dist/features/tester/seed-data/authored/selling__quick-add-minimum-details.js +0 -16
- package/dist/features/tester/seed-data/authored/selling__seller-guide.js +1 -1
- package/dist/features/tester/seed-data/authored/selling__seller-marketing-extras.js +0 -79
- package/dist/features/tester/seed-data/authored/selling__seller-orders.js +1 -1
- package/dist/features/tester/seed-data/tester-checklist-seed-data.js +427 -69
- package/dist/index.d.ts +20 -32
- package/dist/index.js +34 -43
- package/dist/next/routing/route-map.d.ts +2 -8
- package/dist/next/routing/route-map.js +21 -4
- package/dist/providers/db-firebase/base.repository.d.ts +1 -1
- package/dist/providers/db-firebase/base.repository.js +1 -1
- package/dist/providers/payment-razorpay/index.d.ts +125 -0
- package/dist/providers/payment-razorpay/index.js +232 -0
- package/dist/providers/payment-razorpay/signature.d.ts +53 -0
- package/dist/providers/payment-razorpay/signature.js +71 -0
- package/dist/providers/shipping-shiprocket/index.d.ts +98 -0
- package/dist/providers/shipping-shiprocket/index.js +356 -0
- package/dist/providers.d.ts +3 -0
- package/dist/providers.js +3 -0
- package/dist/react/hooks/useCanSeePrices.d.ts +0 -27
- package/dist/react/hooks/useCanSeePrices.js +25 -0
- package/dist/repositories/index.d.ts +1 -1
- package/dist/repositories/index.js +1 -1
- package/dist/schemas/registry.d.ts +10 -115
- package/dist/schemas/registry.js +1 -2
- package/dist/security/pii-encrypt.js +1 -1
- package/dist/seed/_helpers/category-forest.js +27 -0
- package/dist/seed/_helpers/category-parts-glossary-map.js +1816 -86
- package/dist/seed/_helpers/category-parts.d.ts +1 -1
- package/dist/seed/_helpers/category-parts.js +13412 -3020
- package/dist/seed/carousel-slides-seed-data.js +47 -10
- package/dist/seed/categories-seed-data.js +48 -6
- package/dist/seed/faq-seed-data.js +2 -2
- package/dist/seed/homepage-sections-seed-data.js +286 -54
- package/dist/seed/index.d.ts +1 -1
- package/dist/seed/index.js +1 -1
- package/dist/seed/manifest.d.ts +1 -1
- package/dist/seed/manifest.js +1 -2
- package/dist/seed/model-composition-seed-data.js +6 -8
- package/dist/seed/part-glossary/chunk0.d.ts +9 -0
- package/dist/seed/part-glossary/chunk0.js +35448 -0
- package/dist/seed/part-glossary/chunk1.d.ts +9 -0
- package/dist/seed/part-glossary/chunk1.js +40494 -0
- package/dist/seed/part-glossary/chunk2.d.ts +9 -0
- package/dist/seed/part-glossary/chunk2.js +51242 -0
- package/dist/seed/part-glossary/chunk3.d.ts +9 -0
- package/dist/seed/part-glossary/chunk3.js +53337 -0
- package/dist/seed/part-glossary/chunk4.d.ts +9 -0
- package/dist/seed/part-glossary/chunk4.js +51454 -0
- package/dist/seed/part-glossary-seed-data.d.ts +1 -1
- package/dist/seed/part-glossary-seed-data.js +23 -47483
- package/dist/seed/products-beyblade-x-seed-data.js +36 -1
- package/dist/seed/site-settings-seed-data.js +34 -35
- package/dist/seed/store-extensions-seed-data.d.ts +1 -2
- package/dist/seed/store-extensions-seed-data.js +1 -23
- package/dist/seed/stores-seed-data.js +0 -1
- package/dist/server-entry.d.ts +1 -1
- package/dist/server-entry.js +1 -1
- package/dist/server.d.ts +10 -10
- package/dist/server.js +24 -22
- package/dist/styles.css +392 -43
- package/dist/tailwind-utilities.css +1 -1
- package/dist/tokens/themes/default-dark.js +1 -1
- package/dist/tokens/themes/default-light.js +2 -1
- package/dist/tokens/tokens.css +6 -2
- package/dist/ui/components/Button.d.ts +11 -0
- package/dist/ui/components/Button.js +11 -0
- package/dist/ui/components/Button.style.css +29 -0
- package/dist/ui/components/CarouselNav.d.ts +57 -0
- package/dist/ui/components/CarouselNav.js +25 -0
- package/dist/ui/components/CarouselNav.style.css +265 -0
- package/dist/ui/components/GatedPrice.js +30 -3
- package/dist/ui/components/GatedPrice.style.css +43 -40
- package/dist/ui/components/HorizontalScroller.d.ts +12 -1
- package/dist/ui/components/HorizontalScroller.js +43 -3
- package/dist/ui/components/ImageMosaic.d.ts +8 -1
- package/dist/ui/components/ImageMosaic.js +3 -2
- package/dist/ui/components/ImageMosaic.style.css +22 -0
- package/dist/ui/components/Layout.style.css +6 -0
- package/dist/ui/components/Semantic.d.ts +3 -2
- package/dist/ui/components/Semantic.js +1 -0
- package/dist/ui/components/Typography.d.ts +2 -0
- package/dist/ui/components/Typography.js +2 -0
- package/dist/ui/components/Typography.style.css +19 -0
- package/dist/ui/components/index.style.css +1 -0
- package/dist/ui/index.d.ts +3 -1
- package/dist/ui/index.js +4 -0
- package/package.json +3 -2
- package/scripts/seed-cli.mjs +133 -27
- package/dist/_internal/server/jobs/core/whatsappCatalogImport.d.ts +0 -27
- package/dist/_internal/server/jobs/core/whatsappCatalogImport.js +0 -172
- package/dist/_internal/server/jobs/core/whatsappNotify.d.ts +0 -35
- package/dist/_internal/server/jobs/core/whatsappNotify.js +0 -140
- package/dist/features/admin/components/AdminWhatsAppGuideView.d.ts +0 -2
- package/dist/features/admin/components/AdminWhatsAppGuideView.js +0 -35
- package/dist/features/orders/components/MarketplaceOrderCard.d.ts +0 -36
- package/dist/features/orders/components/MarketplaceOrderCard.js +0 -57
- package/dist/features/stores/components/StoreWhatsAppGuideView.d.ts +0 -3
- package/dist/features/stores/components/StoreWhatsAppGuideView.js +0 -12
- package/dist/features/whatsapp-bot/api/send-status/route.d.ts +0 -12
- package/dist/features/whatsapp-bot/api/send-status/route.js +0 -38
- package/dist/features/whatsapp-bot/api/webhook/route.d.ts +0 -12
- package/dist/features/whatsapp-bot/api/webhook/route.js +0 -43
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.d.ts +0 -6
- package/dist/features/whatsapp-bot/components/SellerWhatsAppSettingsView.js +0 -270
- package/dist/features/whatsapp-bot/components/WhatsAppChatButton.d.ts +0 -9
- package/dist/features/whatsapp-bot/components/WhatsAppChatButton.js +0 -7
- package/dist/features/whatsapp-bot/components/index.d.ts +0 -3
- package/dist/features/whatsapp-bot/components/index.js +0 -2
- package/dist/features/whatsapp-bot/helpers/payment-proof-message.d.ts +0 -14
- package/dist/features/whatsapp-bot/helpers/payment-proof-message.js +0 -17
- package/dist/features/whatsapp-bot/helpers/whatsapp.d.ts +0 -52
- package/dist/features/whatsapp-bot/helpers/whatsapp.js +0 -283
- package/dist/features/whatsapp-bot/index.d.ts +0 -3
- package/dist/features/whatsapp-bot/index.js +0 -3
- package/dist/features/whatsapp-bot/manifest.d.ts +0 -2
- package/dist/features/whatsapp-bot/manifest.js +0 -13
- package/dist/features/whatsapp-bot/messages/en.json +0 -7
- package/dist/features/whatsapp-bot/server.d.ts +0 -7
- package/dist/features/whatsapp-bot/server.js +0 -7
- package/dist/features/whatsapp-bot/types/index.d.ts +0 -126
- package/dist/features/whatsapp-bot/types/index.js +0 -1
|
@@ -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,
|
|
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
|
|
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 {
|
|
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 +
|
|
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 /
|
|
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 `
|
|
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("
|
|
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("
|
|
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("
|
|
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 `
|
|
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 +
|
|
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
|
-
|
|
1602
|
-
|
|
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:
|
|
1619
|
+
verifiedBy: `${gatewayName}-order-status`,
|
|
1610
1620
|
verificationMethod: "order-status",
|
|
1611
1621
|
gatewayRef: {
|
|
1612
1622
|
merchantOrderId,
|
|
1613
|
-
|
|
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
|
|
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("
|
|
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
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
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", "
|
|
1732
|
-
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
|
|
1741
|
-
//
|
|
1742
|
-
|
|
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:
|
|
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(
|
|
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:
|
|
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:
|
|
1982
|
-
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(`
|
|
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,
|
|
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,
|
|
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.
|
|
65
|
-
*
|
|
66
|
-
*
|
|
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
|
|
91
|
+
const platform = getPlatformSupplier();
|
|
92
|
+
const platformGstin = trimmed(platform.gstin);
|
|
71
93
|
if (platformGstin) {
|
|
72
94
|
return {
|
|
73
95
|
gstin: platformGstin,
|
|
74
|
-
legalName: trimmed(
|
|
75
|
-
address: trimmed(
|
|
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
|
-
//
|
|
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,
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { PRICE_GUIDANCE_TAX_BASIS } from "../../../shared/features/categories/price-guidance";
|
|
2
|
+
export interface PriceIndexMarketRow {
|
|
3
|
+
categoryId: string;
|
|
4
|
+
/**
|
|
5
|
+
* The typical ASK, not a transaction.
|
|
6
|
+
*
|
|
7
|
+
* 🛑 `median` is the only required figure, and the three optional ones are
|
|
8
|
+
* optional because the crawl genuinely did not measure them everywhere — Hot
|
|
9
|
+
* Wheels has a median over n=7,418 and a RANGE, never quartiles, and the
|
|
10
|
+
* Beyblade-top table carries no per-leaf `n` at all. An absent field must
|
|
11
|
+
* render as absent; filling one in to make the shape look complete is the
|
|
12
|
+
* single thing `price-bands.md` warns about most.
|
|
13
|
+
*/
|
|
14
|
+
median: number;
|
|
15
|
+
p25?: number;
|
|
16
|
+
p75?: number;
|
|
17
|
+
sampleSize?: number;
|
|
18
|
+
asOf?: string;
|
|
19
|
+
/**
|
|
20
|
+
* The share of competitor listings at this level that are SOLD OUT (0.85,
|
|
21
|
+
* measured across the five largest catalogues).
|
|
22
|
+
*
|
|
23
|
+
* Carried because it is what stops the band being read as a clearing price:
|
|
24
|
+
* most asks at this level did not convert. The renderer must say so.
|
|
25
|
+
*/
|
|
26
|
+
soldOutShare?: number;
|
|
27
|
+
/** Which crawl, and any caveat — pooling, a disagreeing source, a small n. */
|
|
28
|
+
source?: string;
|
|
29
|
+
/**
|
|
30
|
+
* `true` when the band came from an ANCESTOR rather than this leaf.
|
|
31
|
+
*
|
|
32
|
+
* 🛑 Load-bearing, not decoration. `MARKET_BANDS` is keyed on era and part
|
|
33
|
+
* leaves, never on the ~216 named-model leaves, so a model lookup resolves
|
|
34
|
+
* its generation's band — "typical for Burst DB" is a true statement and
|
|
35
|
+
* "typical for Rage Longinus" is not. The renderer names the source leaf so
|
|
36
|
+
* the reader can tell which they are being told.
|
|
37
|
+
*/
|
|
38
|
+
inherited: boolean;
|
|
39
|
+
/** The ancestor the band actually came from, when `inherited`. */
|
|
40
|
+
viaCategoryId?: string;
|
|
41
|
+
viaName?: string;
|
|
42
|
+
/** The basis every figure above is on. Always inclusive; stated, not assumed. */
|
|
43
|
+
taxBasis: typeof PRICE_GUIDANCE_TAX_BASIS;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Market bands for the leaves the client already resolved.
|
|
47
|
+
*
|
|
48
|
+
* Bounded by `PRICE_INDEX_SEARCH_LIMIT` — the same cap the public half uses, so
|
|
49
|
+
* a crafted request cannot demand an unbounded read, and the two halves of one
|
|
50
|
+
* lookup can never disagree about how many rows a lookup covers.
|
|
51
|
+
*
|
|
52
|
+
* A leaf with no band at any level is ABSENT from the result rather than
|
|
53
|
+
* present with a null band. "We have no market evidence for this" and "this id
|
|
54
|
+
* does not exist" are different answers and the caller renders them
|
|
55
|
+
* differently; collapsing them is how a missing band becomes a confident ₹0.
|
|
56
|
+
*/
|
|
57
|
+
export declare function getPriceIndexMarketForIds(rawIds: readonly string[]): Promise<PriceIndexMarketRow[]>;
|