@alphasquad/saleor-template-advance 0.1.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/.env.example +57 -0
- package/APPLE_PAY_QUICK_START.md +165 -0
- package/APPLE_PAY_SETUP.md +331 -0
- package/README.md +46 -0
- package/SEO_AUDIT_CHECKLIST_STATUS.md +244 -0
- package/SEO_AUDIT_REPORT.md +66 -0
- package/eslint.config.mjs +16 -0
- package/next-env.d.ts +5 -0
- package/next.config.ts +109 -0
- package/package.json +47 -0
- package/postcss.config.mjs +5 -0
- package/public/.well-known/apple-developer-merchantid-domain-association +1 -0
- package/public/Logo.png +0 -0
- package/public/brand-video.mp4 +0 -0
- package/public/favicon.ico +0 -0
- package/public/file.svg +1 -0
- package/public/footer/facebook.tsx +34 -0
- package/public/footer/instagram.tsx +27 -0
- package/public/footer/mail.tsx +5 -0
- package/public/footer/x.tsx +35 -0
- package/public/globe.svg +1 -0
- package/public/icons/Authorize.net.webp +0 -0
- package/public/icons/amex.gif +0 -0
- package/public/icons/appIcon.png +0 -0
- package/public/icons/discover.gif +0 -0
- package/public/icons/master.gif +0 -0
- package/public/icons/paypal.png +0 -0
- package/public/icons/stripe.png +0 -0
- package/public/icons/visa.gif +0 -0
- package/public/images/BackgroundNoise.png +0 -0
- package/public/images/footer-background.png +0 -0
- package/public/next.svg +1 -0
- package/public/no-image-avail-large.png +0 -0
- package/public/random-car-1.jpeg +0 -0
- package/public/random-car-2.png +0 -0
- package/public/random-car-3.jpg +0 -0
- package/public/random-car-4.jpg +0 -0
- package/public/random-car-5.jpg +0 -0
- package/public/star.svg +3 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
- package/scripts/seo-audit/generate-checklist.mjs +156 -0
- package/src/app/(auth)/account/forgot-password/layout.tsx +16 -0
- package/src/app/(auth)/account/forgot-password/page.tsx +135 -0
- package/src/app/(auth)/account/login/layout.tsx +16 -0
- package/src/app/(auth)/account/login/page.tsx +288 -0
- package/src/app/(auth)/account/otp/layout.tsx +16 -0
- package/src/app/(auth)/account/otp/page.tsx +108 -0
- package/src/app/(auth)/account/register/layout.tsx +16 -0
- package/src/app/(auth)/account/register/page.tsx +431 -0
- package/src/app/(auth)/account/reset-password/layout.tsx +16 -0
- package/src/app/(auth)/account/reset-password/page.tsx +222 -0
- package/src/app/[slug]/page.tsx +43 -0
- package/src/app/about/loading.tsx +17 -0
- package/src/app/about/page.tsx +61 -0
- package/src/app/account/address/layout.tsx +15 -0
- package/src/app/account/address/page.tsx +166 -0
- package/src/app/account/head.tsx +4 -0
- package/src/app/account/layout.tsx +62 -0
- package/src/app/account/orders/[id]/layout.tsx +17 -0
- package/src/app/account/orders/[id]/page.tsx +115 -0
- package/src/app/account/orders/components/orderDetailsModal.tsx +410 -0
- package/src/app/account/orders/layout.tsx +15 -0
- package/src/app/account/orders/page.tsx +146 -0
- package/src/app/account/page.tsx +39 -0
- package/src/app/account/settings/components/editProfileSuccessModal.tsx +28 -0
- package/src/app/account/settings/layout.tsx +15 -0
- package/src/app/account/settings/page.tsx +260 -0
- package/src/app/api/affirm/check-status/route.ts +94 -0
- package/src/app/api/affirm/create-checkout/route.ts +109 -0
- package/src/app/api/affirm/get-config/route.ts +108 -0
- package/src/app/api/affirm/process-payment/route.ts +244 -0
- package/src/app/api/affirm/test-connection/route.ts +45 -0
- package/src/app/api/auth/clear/route.ts +16 -0
- package/src/app/api/auth/clear-cookies/route.ts +42 -0
- package/src/app/api/auth/set/route.ts +47 -0
- package/src/app/api/configuration/route.ts +18 -0
- package/src/app/api/dynamic-page/[slug]/route.ts +24 -0
- package/src/app/api/form-submission/route.ts +237 -0
- package/src/app/api/paypal/capture-order/route.ts +303 -0
- package/src/app/api/paypal/create-order/route.ts +211 -0
- package/src/app/api/paypal/get-config/route.ts +240 -0
- package/src/app/api/search-proxy/route.ts +52 -0
- package/src/app/authorize-net-success/layout.tsx +19 -0
- package/src/app/authorize-net-success/page.tsx +12 -0
- package/src/app/authorize-net-success/summary.tsx +486 -0
- package/src/app/blog/[slug]/blogContentRenderer.tsx +369 -0
- package/src/app/blog/[slug]/layout.tsx +17 -0
- package/src/app/blog/[slug]/page.tsx +151 -0
- package/src/app/blog/constant.tsx +147 -0
- package/src/app/blog/layout.tsx +31 -0
- package/src/app/blog/page.tsx +81 -0
- package/src/app/brand/[id]/BrandPageClient.tsx +188 -0
- package/src/app/brand/[id]/layout.tsx +17 -0
- package/src/app/brand/[id]/page.tsx +176 -0
- package/src/app/brands/components/brandsListingClient.tsx +97 -0
- package/src/app/brands/layout.tsx +31 -0
- package/src/app/brands/page.tsx +40 -0
- package/src/app/cancellation-policy/page.tsx +53 -0
- package/src/app/cart/layout.tsx +19 -0
- package/src/app/cart/page.tsx +752 -0
- package/src/app/category/[slug]/CategoryPageClient.tsx +377 -0
- package/src/app/category/[slug]/layout.tsx +17 -0
- package/src/app/category/[slug]/page.tsx +224 -0
- package/src/app/category/page.tsx +114 -0
- package/src/app/checkout/components/addNewAddressModal.tsx +474 -0
- package/src/app/checkout/layout.tsx +19 -0
- package/src/app/checkout/page.tsx +3312 -0
- package/src/app/components/account/AccountTabs.tsx +40 -0
- package/src/app/components/ads/GoogleAdSense.tsx +74 -0
- package/src/app/components/analytics/AnalyticsScripts.tsx +78 -0
- package/src/app/components/analytics/ConditionalGTMNoscript.tsx +24 -0
- package/src/app/components/analytics/ConditionalGoogleAnalytics.tsx +16 -0
- package/src/app/components/ancillary/AncillaryContent.tsx +7 -0
- package/src/app/components/auth/TokenExpirationHandler.tsx +8 -0
- package/src/app/components/blog/BlogList.tsx +112 -0
- package/src/app/components/checkout/AddressInformationSection.tsx +34 -0
- package/src/app/components/checkout/AddressManagement.tsx +571 -0
- package/src/app/components/checkout/CheckoutHeader.tsx +51 -0
- package/src/app/components/checkout/CheckoutQuestions.tsx +454 -0
- package/src/app/components/checkout/CheckoutTermsModal.tsx +81 -0
- package/src/app/components/checkout/ContactDetailsSection.tsx +52 -0
- package/src/app/components/checkout/DealerShippingSection.tsx +359 -0
- package/src/app/components/checkout/DeliveryMethodSection.tsx +249 -0
- package/src/app/components/checkout/OrderSummary.tsx +386 -0
- package/src/app/components/checkout/TermsContentRenderer.tsx +147 -0
- package/src/app/components/checkout/WillCallSection.tsx +133 -0
- package/src/app/components/checkout/affirmPayment.tsx +383 -0
- package/src/app/components/checkout/checkoutProcessingModal.tsx +96 -0
- package/src/app/components/checkout/googlePayButton.tsx +334 -0
- package/src/app/components/checkout/paymentStep.tsx +180 -0
- package/src/app/components/checkout/paypalPayment.tsx +1083 -0
- package/src/app/components/checkout/saleorNativePayment.tsx +1758 -0
- package/src/app/components/dynamicPage/DynamicPageRenderer.tsx +13 -0
- package/src/app/components/dynamicPage/HtmlWidgetRenderer.tsx +144 -0
- package/src/app/components/filtersCollapsible/index.tsx +365 -0
- package/src/app/components/globalSearch/index.tsx +423 -0
- package/src/app/components/layout/cartDropDown.tsx +628 -0
- package/src/app/components/layout/components/FooterNewsletter.tsx +21 -0
- package/src/app/components/layout/footer.tsx +283 -0
- package/src/app/components/layout/header/accountMenuDropdown.tsx +53 -0
- package/src/app/components/layout/header/components/CartBadge.tsx +18 -0
- package/src/app/components/layout/header/components/LoadingState.tsx +17 -0
- package/src/app/components/layout/header/components/MenuItemDropdown.tsx +124 -0
- package/src/app/components/layout/header/components/MobileNavbar.tsx +123 -0
- package/src/app/components/layout/header/components/NavbarActions.tsx +125 -0
- package/src/app/components/layout/header/components/NavbarBrand.tsx +29 -0
- package/src/app/components/layout/header/components/NavigationLinks.tsx +131 -0
- package/src/app/components/layout/header/hamMenuSlide.tsx +318 -0
- package/src/app/components/layout/header/header.tsx +44 -0
- package/src/app/components/layout/header/hooks/useDropdown.ts +45 -0
- package/src/app/components/layout/header/hooks/useNavbarData.ts +138 -0
- package/src/app/components/layout/header/hooks/useNavbarState.ts +66 -0
- package/src/app/components/layout/header/megaMenuDropdown.tsx +116 -0
- package/src/app/components/layout/header/navBar.tsx +121 -0
- package/src/app/components/layout/header/search.tsx +418 -0
- package/src/app/components/layout/header/styles/navbarStyles.ts +27 -0
- package/src/app/components/layout/header/topBar.tsx +214 -0
- package/src/app/components/layout/joinNewsletterForm/index.tsx +72 -0
- package/src/app/components/layout/mobileAccordian/index.tsx +92 -0
- package/src/app/components/layout/paymentMethods.tsx +75 -0
- package/src/app/components/layout/rootLayout.tsx +23 -0
- package/src/app/components/layout/siteInfo.tsx +103 -0
- package/src/app/components/layout/socialLinks.tsx +65 -0
- package/src/app/components/newsletterSection/emailListSection.tsx +224 -0
- package/src/app/components/newsletterSection/emailSectionServer.tsx +8 -0
- package/src/app/components/providers/ApolloWrapper.tsx +12 -0
- package/src/app/components/providers/AppConfigurationProvider.tsx +108 -0
- package/src/app/components/providers/GoogleAnalyticsProvider.tsx +149 -0
- package/src/app/components/providers/GoogleTagManagerProvider.tsx +31 -0
- package/src/app/components/providers/RecaptchaProvider.tsx +18 -0
- package/src/app/components/providers/ServerAppConfigurationProvider.tsx +133 -0
- package/src/app/components/providers/YMMStatusProvider.tsx +15 -0
- package/src/app/components/reuseableUI/AboutUs.tsx +115 -0
- package/src/app/components/reuseableUI/AddToCartClient.tsx +125 -0
- package/src/app/components/reuseableUI/EditorJsRenderer.tsx +219 -0
- package/src/app/components/reuseableUI/HeroSectionsearchByVehicle.tsx +188 -0
- package/src/app/components/reuseableUI/ImageWithFallback.tsx +41 -0
- package/src/app/components/reuseableUI/Toast.tsx +101 -0
- package/src/app/components/reuseableUI/blogCard.tsx +52 -0
- package/src/app/components/reuseableUI/brandCard.tsx +68 -0
- package/src/app/components/reuseableUI/breadcrumb.tsx +38 -0
- package/src/app/components/reuseableUI/categoryCard.tsx +37 -0
- package/src/app/components/reuseableUI/categorySkeleton.tsx +31 -0
- package/src/app/components/reuseableUI/commonButton.tsx +48 -0
- package/src/app/components/reuseableUI/defaultInputField/index.tsx +84 -0
- package/src/app/components/reuseableUI/emptyState.tsx +29 -0
- package/src/app/components/reuseableUI/errorTag.tsx +15 -0
- package/src/app/components/reuseableUI/heading/index.tsx +20 -0
- package/src/app/components/reuseableUI/input.tsx +117 -0
- package/src/app/components/reuseableUI/listCard.tsx +137 -0
- package/src/app/components/reuseableUI/loadingUI.tsx +12 -0
- package/src/app/components/reuseableUI/modalLayout.tsx +76 -0
- package/src/app/components/reuseableUI/newsletter/newsletterClient.tsx +622 -0
- package/src/app/components/reuseableUI/newsletter/newslettersHomeModal.tsx +68 -0
- package/src/app/components/reuseableUI/offerCard.tsx +42 -0
- package/src/app/components/reuseableUI/passwordRules/passwordRules.tsx +56 -0
- package/src/app/components/reuseableUI/primaryButton/index.tsx +34 -0
- package/src/app/components/reuseableUI/productCard.tsx +118 -0
- package/src/app/components/reuseableUI/productSkeleton.tsx +34 -0
- package/src/app/components/reuseableUI/searchByVehicle.tsx +187 -0
- package/src/app/components/reuseableUI/secondaryButton/index.tsx +34 -0
- package/src/app/components/reuseableUI/section.tsx +20 -0
- package/src/app/components/reuseableUI/select/index.tsx +98 -0
- package/src/app/components/reuseableUI/skeletonLoader.tsx +117 -0
- package/src/app/components/reuseableUI/statusTag.tsx +24 -0
- package/src/app/components/reuseableUI/tags/saleTag.tsx +19 -0
- package/src/app/components/reuseableUI/testimonialCard.tsx +93 -0
- package/src/app/components/richText/EditorRenderer.tsx +318 -0
- package/src/app/components/search/HierarchicalCategoryFilter.tsx +155 -0
- package/src/app/components/search/SearchFilters.tsx +155 -0
- package/src/app/components/search/YMMSearchSidebar.tsx +187 -0
- package/src/app/components/seo/ServerProductCard.tsx +91 -0
- package/src/app/components/seo/ServerProductGrid.tsx +45 -0
- package/src/app/components/shop/CategoryFilter.tsx +184 -0
- package/src/app/components/shop/ItemsPerPageSelect.tsx +69 -0
- package/src/app/components/shop/ItemsPerPageSelectClient.tsx +58 -0
- package/src/app/components/shop/MobileFilters.tsx +103 -0
- package/src/app/components/shop/ProductGridSkeleton.tsx +16 -0
- package/src/app/components/shop/ProductsGrid.tsx +230 -0
- package/src/app/components/shop/SearchFilter.tsx +218 -0
- package/src/app/components/shop/SearchFilterClient.tsx +122 -0
- package/src/app/components/shop/SearchLoadingOverlay.tsx +32 -0
- package/src/app/components/shop/ShopMobileFilters.tsx +205 -0
- package/src/app/components/showroom/VehicleSearchDropdowns.tsx +187 -0
- package/src/app/components/showroom/brandsSwiper.tsx +49 -0
- package/src/app/components/showroom/brandsSwiperClient copy.tsx +93 -0
- package/src/app/components/showroom/brandsSwiperClient.tsx +122 -0
- package/src/app/components/showroom/brandsSwiperServer.tsx +42 -0
- package/src/app/components/showroom/bundleProducts.tsx +120 -0
- package/src/app/components/showroom/categoryGrid.tsx +51 -0
- package/src/app/components/showroom/categoryGridServer.tsx +45 -0
- package/src/app/components/showroom/categorySwiper.tsx +115 -0
- package/src/app/components/showroom/featureStrip.tsx +139 -0
- package/src/app/components/showroom/offersSwiper.tsx +181 -0
- package/src/app/components/showroom/productGrid.tsx +56 -0
- package/src/app/components/showroom/productSwiper.tsx +119 -0
- package/src/app/components/showroom/promotion-slider.tsx +138 -0
- package/src/app/components/showroom/promotion.tsx +207 -0
- package/src/app/components/showroom/promotionsSwiper.tsx +174 -0
- package/src/app/components/showroom/showroomHeroCarousel.tsx +141 -0
- package/src/app/components/showroom/testimonialsGrid.tsx +106 -0
- package/src/app/components/skeletons/ContentSkeleton.tsx +14 -0
- package/src/app/components/sortDropdown/index.tsx +116 -0
- package/src/app/components/tertiaryButton/index.tsx +25 -0
- package/src/app/components/theme/theme-provider.tsx +82 -0
- package/src/app/contact/layout.tsx +32 -0
- package/src/app/contact/page.tsx +591 -0
- package/src/app/content/[slug]/layout.tsx +17 -0
- package/src/app/content/[slug]/page.tsx +159 -0
- package/src/app/content/layout.tsx +31 -0
- package/src/app/content/page.tsx +88 -0
- package/src/app/core-policies/page.tsx +55 -0
- package/src/app/discounts/page.tsx +54 -0
- package/src/app/frequently-asked-questions/page.tsx +57 -0
- package/src/app/globals.css +440 -0
- package/src/app/hooks/useDealerLocations.ts +259 -0
- package/src/app/hooks/useGTMEngagement.ts +71 -0
- package/src/app/hooks/useGoogleAnalytics.ts +145 -0
- package/src/app/layout.tsx +149 -0
- package/src/app/not-found.tsx +31 -0
- package/src/app/order-confirmation/layout.tsx +19 -0
- package/src/app/order-confirmation/page.tsx +12 -0
- package/src/app/order-confirmation/summary.tsx +1775 -0
- package/src/app/page.tsx +194 -0
- package/src/app/privacy-policy/loading.tsx +17 -0
- package/src/app/privacy-policy/page.tsx +56 -0
- package/src/app/product/[id]/ProductDetailClient.tsx +2448 -0
- package/src/app/product/[id]/components/itemInquiryModal.tsx +461 -0
- package/src/app/product/[id]/layout.tsx +116 -0
- package/src/app/product/[id]/page.tsx +200 -0
- package/src/app/product/layout.tsx +15 -0
- package/src/app/products/all/AllProductsClient.tsx +743 -0
- package/src/app/products/all/page.tsx +176 -0
- package/src/app/products/components/shopEmptyState.tsx +29 -0
- package/src/app/request-return/layout.tsx +36 -0
- package/src/app/request-return/page.tsx +597 -0
- package/src/app/robots.txt/route.ts +27 -0
- package/src/app/search/layout.tsx +16 -0
- package/src/app/search/page.tsx +736 -0
- package/src/app/shipping-returns/page.tsx +60 -0
- package/src/app/site-map/layout.tsx +33 -0
- package/src/app/site-map/page.tsx +113 -0
- package/src/app/sitemap-index.xml/route.ts +20 -0
- package/src/app/sitemap.ts +10 -0
- package/src/app/terms-and-conditions/loading.tsx +17 -0
- package/src/app/terms-and-conditions/page.tsx +56 -0
- package/src/app/utils/appConfiguration.ts +327 -0
- package/src/app/utils/branding.ts +52 -0
- package/src/app/utils/configurationService.ts +202 -0
- package/src/app/utils/constant.tsx +242 -0
- package/src/app/utils/editorJsUtils.tsx +249 -0
- package/src/app/utils/functions.ts +146 -0
- package/src/app/utils/googleAnalytics.ts +168 -0
- package/src/app/utils/googleTagManager.ts +475 -0
- package/src/app/utils/ipDetection.ts +270 -0
- package/src/app/utils/serverConfigurationService.ts +209 -0
- package/src/app/utils/svgs/GridIcon.tsx +45 -0
- package/src/app/utils/svgs/account/myAccount/listDotIcon.tsx +3 -0
- package/src/app/utils/svgs/account/myAccount/tickIcon.tsx +10 -0
- package/src/app/utils/svgs/account/orderHistory/InfoIcon.tsx +49 -0
- package/src/app/utils/svgs/arrowDownIcon.tsx +17 -0
- package/src/app/utils/svgs/arrowIcon.tsx +25 -0
- package/src/app/utils/svgs/arrowUpIcon.tsx +16 -0
- package/src/app/utils/svgs/brandsSearchIcon.tsx +25 -0
- package/src/app/utils/svgs/cart/cartIcon.tsx +31 -0
- package/src/app/utils/svgs/cart/plusIcon.tsx +13 -0
- package/src/app/utils/svgs/cart/subtractIcon.tsx +13 -0
- package/src/app/utils/svgs/cart/successTickIcon.tsx +14 -0
- package/src/app/utils/svgs/chevronDownIcon.tsx +21 -0
- package/src/app/utils/svgs/closeEyeIcon.tsx +47 -0
- package/src/app/utils/svgs/crossIcon.tsx +25 -0
- package/src/app/utils/svgs/eyeIcon.tsx +29 -0
- package/src/app/utils/svgs/featureTag.tsx +20 -0
- package/src/app/utils/svgs/filterIcon.tsx +3 -0
- package/src/app/utils/svgs/globleIcon.tsx +41 -0
- package/src/app/utils/svgs/infoIcon.tsx +34 -0
- package/src/app/utils/svgs/listIcon.tsx +50 -0
- package/src/app/utils/svgs/logOutIcon.tsx +35 -0
- package/src/app/utils/svgs/menuIcon.tsx +8 -0
- package/src/app/utils/svgs/minusIcon.tsx +18 -0
- package/src/app/utils/svgs/newsletterIcon.tsx +19 -0
- package/src/app/utils/svgs/noDataFoundIcon-.tsx +26 -0
- package/src/app/utils/svgs/noProductFoundIcon.tsx +43 -0
- package/src/app/utils/svgs/passwordIcons/errorIcon.tsx +31 -0
- package/src/app/utils/svgs/passwordIcons/successIcon.tsx +24 -0
- package/src/app/utils/svgs/paymentProcessingIcons/hourglassIcon.tsx +43 -0
- package/src/app/utils/svgs/paymentProcessingIcons/modalCrossIcon.tsx +23 -0
- package/src/app/utils/svgs/paymentProcessingIcons/paymentFailedIcon.tsx +47 -0
- package/src/app/utils/svgs/pencilIcon.tsx +11 -0
- package/src/app/utils/svgs/plusIcon.tsx +25 -0
- package/src/app/utils/svgs/productInquiryIcon.tsx +40 -0
- package/src/app/utils/svgs/searchIcon.tsx +31 -0
- package/src/app/utils/svgs/shoppingCart.tsx +32 -0
- package/src/app/utils/svgs/spinnerIcon.tsx +22 -0
- package/src/app/utils/svgs/spinnerLoadingIcon.tsx +26 -0
- package/src/app/utils/svgs/successTickIcon.tsx +40 -0
- package/src/app/utils/svgs/swiperArrowIconLeft.tsx +18 -0
- package/src/app/utils/svgs/swiperArrowIconRight.tsx +18 -0
- package/src/app/utils/svgs/userProfileIcon.tsx +31 -0
- package/src/app/utils/svgs/warningCircleIcon.tsx +15 -0
- package/src/app/warranty/constant.tsx +63 -0
- package/src/app/warranty/loading.tsx +17 -0
- package/src/app/warranty/page.tsx +56 -0
- package/src/graphql/client.ts +288 -0
- package/src/graphql/mutations/accountAddressCreate.ts +56 -0
- package/src/graphql/mutations/accountAddressDelete.ts +23 -0
- package/src/graphql/mutations/accountAddressUpdate.ts +55 -0
- package/src/graphql/mutations/accountSetDefaultAddress.ts +32 -0
- package/src/graphql/mutations/accountUpdate.ts +34 -0
- package/src/graphql/mutations/changePassword.ts +25 -0
- package/src/graphql/mutations/checkout.ts +117 -0
- package/src/graphql/mutations/checkoutAddVoucher.ts +63 -0
- package/src/graphql/mutations/checkoutComplete.ts +79 -0
- package/src/graphql/mutations/checkoutCreate.ts +131 -0
- package/src/graphql/mutations/checkoutCustomerAttach.ts +50 -0
- package/src/graphql/mutations/checkoutEmailUpdate.ts +15 -0
- package/src/graphql/mutations/checkoutLineMetadataUpdate.ts +52 -0
- package/src/graphql/mutations/checkoutPaymentCreate.ts +82 -0
- package/src/graphql/mutations/paymentGatewayInitialize.ts +58 -0
- package/src/graphql/mutations/registerAccount.ts +65 -0
- package/src/graphql/mutations/requestPasswordReset.ts +32 -0
- package/src/graphql/mutations/setPassword.ts +49 -0
- package/src/graphql/mutations/signIn.ts +50 -0
- package/src/graphql/mutations/tokenRefresh.ts +19 -0
- package/src/graphql/mutations/updateCheckoutMetadata.ts +49 -0
- package/src/graphql/mutations/updateProfile.ts +18 -0
- package/src/graphql/mutations/willCallDeliveryMethod.ts +81 -0
- package/src/graphql/queries/checkout.ts +168 -0
- package/src/graphql/queries/findProductByOldSlug.ts +58 -0
- package/src/graphql/queries/getAboutPage.ts +24 -0
- package/src/graphql/queries/getAboutPageId.ts +9 -0
- package/src/graphql/queries/getAboutUs.ts +38 -0
- package/src/graphql/queries/getAddressInformation.ts +38 -0
- package/src/graphql/queries/getAllCategories.ts +41 -0
- package/src/graphql/queries/getAllCategoriesTree.ts +67 -0
- package/src/graphql/queries/getAllCategoriesWithProducts.ts +29 -0
- package/src/graphql/queries/getAllCollectionsWithProducts.ts +16 -0
- package/src/graphql/queries/getBlogs.ts +222 -0
- package/src/graphql/queries/getBrands.ts +17 -0
- package/src/graphql/queries/getBundles.ts +43 -0
- package/src/graphql/queries/getCategories.ts +20 -0
- package/src/graphql/queries/getChannels.ts +77 -0
- package/src/graphql/queries/getCheckoutQuestions.ts +115 -0
- package/src/graphql/queries/getCheckoutTermsAndConditions.ts +37 -0
- package/src/graphql/queries/getContactPage.ts +117 -0
- package/src/graphql/queries/getContentPage.ts +191 -0
- package/src/graphql/queries/getDiscountOffers.ts +18 -0
- package/src/graphql/queries/getDynamicPageBySlug.ts +251 -0
- package/src/graphql/queries/getFeaturedProducts.ts +48 -0
- package/src/graphql/queries/getHeroMetadata.ts +23 -0
- package/src/graphql/queries/getMenuBySlug.ts +84 -0
- package/src/graphql/queries/getMyProfile.ts +23 -0
- package/src/graphql/queries/getNewsletter.ts +122 -0
- package/src/graphql/queries/getNewsletterPage.ts +111 -0
- package/src/graphql/queries/getPageBySlug.ts +52 -0
- package/src/graphql/queries/getPageTypeId.ts +27 -0
- package/src/graphql/queries/getPaymentMethods.ts +61 -0
- package/src/graphql/queries/getProducts.ts +78 -0
- package/src/graphql/queries/getPromotions.ts +24 -0
- package/src/graphql/queries/getRequestReturnPage.ts +121 -0
- package/src/graphql/queries/getSiteInfo.ts +54 -0
- package/src/graphql/queries/getSocialLinks.ts +52 -0
- package/src/graphql/queries/getTestimonials.ts +25 -0
- package/src/graphql/queries/getUserWithCheckout.ts +27 -0
- package/src/graphql/queries/getVehicleMakes.ts +21 -0
- package/src/graphql/queries/getVehicleModels.ts +21 -0
- package/src/graphql/queries/getVehicleYears.ts +21 -0
- package/src/graphql/queries/meAddresses.ts +56 -0
- package/src/graphql/queries/myOrders.ts +37 -0
- package/src/graphql/queries/orderDetail.ts +231 -0
- package/src/graphql/queries/productDetailsById.ts +197 -0
- package/src/graphql/queries/productInquiry.ts +115 -0
- package/src/graphql/queries/productsByCategoriesAndCollections.ts +39 -0
- package/src/graphql/queries/willCallCollectionPoints.ts +55 -0
- package/src/graphql/server-client.ts +54 -0
- package/src/graphql/types/categories.ts +9 -0
- package/src/graphql/types/checkout.ts +168 -0
- package/src/graphql/types/offer.ts +12 -0
- package/src/graphql/types/product.ts +44 -0
- package/src/hooks/scrollPageTop.ts +9 -0
- package/src/hooks/serverNavbarData.ts +79 -0
- package/src/hooks/useCartSync.ts +24 -0
- package/src/hooks/useRecaptcha.ts +33 -0
- package/src/hooks/useTokenExpiration.ts +81 -0
- package/src/hooks/useVehicleData.ts +346 -0
- package/src/lib/api/kount.ts +165 -0
- package/src/lib/api/shop.ts +1445 -0
- package/src/lib/saleor/getSaleorApiUrl.ts +25 -0
- package/src/lib/schema.ts +303 -0
- package/src/lib/seo/extractTextFromEditorJs.ts +58 -0
- package/src/lib/seo/site.ts +10 -0
- package/src/lib/urls/normalizeInternalUrl.ts +53 -0
- package/src/middleware.ts +134 -0
- package/src/sitemaps/README.md +105 -0
- package/src/sitemaps/dynamic-pages-sitemap.ts +247 -0
- package/src/sitemaps/sitemap-index.ts +21 -0
- package/src/sitemaps/static-pages-sitemap.ts +36 -0
- package/src/store/useGlobalStore.tsx +1656 -0
- package/src/types/global.d.ts +148 -0
- package/tsconfig.json +27 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
2
|
+
|
|
3
|
+
const TRANSACTION_PROCESS = `
|
|
4
|
+
mutation TransactionProcess(
|
|
5
|
+
$id: ID!
|
|
6
|
+
$data: JSON
|
|
7
|
+
) {
|
|
8
|
+
transactionProcess(
|
|
9
|
+
id: $id
|
|
10
|
+
data: $data
|
|
11
|
+
) {
|
|
12
|
+
transaction {
|
|
13
|
+
id
|
|
14
|
+
actions
|
|
15
|
+
chargedAmount {
|
|
16
|
+
amount
|
|
17
|
+
currency
|
|
18
|
+
}
|
|
19
|
+
checkout {
|
|
20
|
+
id
|
|
21
|
+
}
|
|
22
|
+
order {
|
|
23
|
+
id
|
|
24
|
+
number
|
|
25
|
+
total {
|
|
26
|
+
gross {
|
|
27
|
+
amount
|
|
28
|
+
currency
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
transactionEvent {
|
|
34
|
+
pspReference
|
|
35
|
+
message
|
|
36
|
+
type
|
|
37
|
+
}
|
|
38
|
+
data
|
|
39
|
+
errors {
|
|
40
|
+
field
|
|
41
|
+
message
|
|
42
|
+
code
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
`;
|
|
47
|
+
|
|
48
|
+
const CHECKOUT_COMPLETE = `
|
|
49
|
+
mutation CheckoutComplete($checkoutId: ID!) {
|
|
50
|
+
checkoutComplete(checkoutId: $checkoutId) {
|
|
51
|
+
order {
|
|
52
|
+
id
|
|
53
|
+
number
|
|
54
|
+
total {
|
|
55
|
+
gross {
|
|
56
|
+
amount
|
|
57
|
+
currency
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
errors {
|
|
62
|
+
field
|
|
63
|
+
message
|
|
64
|
+
code
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
`;
|
|
69
|
+
|
|
70
|
+
export async function POST(request: NextRequest) {
|
|
71
|
+
try {
|
|
72
|
+
const body = await request.json();
|
|
73
|
+
const { checkoutId, orderId, transactionId } = body;
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
if (!checkoutId || !orderId) {
|
|
77
|
+
return NextResponse.json(
|
|
78
|
+
{ error: "Missing required fields: checkoutId, orderId" },
|
|
79
|
+
{ status: 400 }
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// If no transactionId provided, we'll try to use checkoutId
|
|
84
|
+
const txnId = transactionId || checkoutId;
|
|
85
|
+
|
|
86
|
+
// Get Saleor API URL
|
|
87
|
+
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
|
|
88
|
+
if (!apiUrl) {
|
|
89
|
+
throw new Error("NEXT_PUBLIC_API_URL is not configured");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Get auth token from request cookies
|
|
93
|
+
const token = request.cookies.get("token")?.value;
|
|
94
|
+
|
|
95
|
+
const headers: Record<string, string> = {
|
|
96
|
+
"Content-Type": "application/json",
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
if (token) {
|
|
100
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Step 1: Process the transaction with PayPal order ID
|
|
104
|
+
const processResponse = await fetch(apiUrl, {
|
|
105
|
+
method: "POST",
|
|
106
|
+
headers,
|
|
107
|
+
body: JSON.stringify({
|
|
108
|
+
query: TRANSACTION_PROCESS,
|
|
109
|
+
variables: {
|
|
110
|
+
id: txnId,
|
|
111
|
+
data: {
|
|
112
|
+
paypalOrderId: orderId,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
}),
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
if (!processResponse.ok) {
|
|
119
|
+
const errorText = await processResponse.text();
|
|
120
|
+
console.error("❌ Response body:", errorText);
|
|
121
|
+
throw new Error(`Transaction process request failed: ${processResponse.status}`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const processResult = await processResponse.json();
|
|
125
|
+
|
|
126
|
+
const processData = processResult.data;
|
|
127
|
+
const processErrors = processResult.errors;
|
|
128
|
+
|
|
129
|
+
if (processErrors || processData?.transactionProcess?.errors?.length > 0) {
|
|
130
|
+
const errorMessage =
|
|
131
|
+
processData?.transactionProcess?.errors?.[0]?.message ||
|
|
132
|
+
processErrors?.[0]?.message ||
|
|
133
|
+
"Failed to process transaction";
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
return NextResponse.json({ error: errorMessage }, { status: 400 });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const transactionEvent = processData?.transactionProcess?.transactionEvent;
|
|
140
|
+
const eventType = transactionEvent?.type;
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
// Check if payment was successful
|
|
144
|
+
if (eventType && !eventType.includes("SUCCESS")) {
|
|
145
|
+
if (eventType.includes("FAILURE")) {
|
|
146
|
+
return NextResponse.json(
|
|
147
|
+
{ error: `Payment failed: ${transactionEvent?.message || "Unknown error"}` },
|
|
148
|
+
{ status: 400 }
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Check if order was created by transactionProcess
|
|
154
|
+
const transaction = processData?.transactionProcess?.transaction;
|
|
155
|
+
let order = transaction?.order;
|
|
156
|
+
|
|
157
|
+
// If no order exists yet, try to complete the checkout manually
|
|
158
|
+
if (!order) {
|
|
159
|
+
// Avoid noisy logs in templates/production.
|
|
160
|
+
|
|
161
|
+
// Try to complete the checkout manually
|
|
162
|
+
const completeResponse = await fetch(apiUrl, {
|
|
163
|
+
method: "POST",
|
|
164
|
+
headers,
|
|
165
|
+
body: JSON.stringify({
|
|
166
|
+
query: CHECKOUT_COMPLETE,
|
|
167
|
+
variables: {
|
|
168
|
+
checkoutId: checkoutId,
|
|
169
|
+
},
|
|
170
|
+
}),
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
if (!completeResponse.ok) {
|
|
174
|
+
console.error("❌ checkoutComplete request failed:", completeResponse.status);
|
|
175
|
+
|
|
176
|
+
// Return processing status - the webhook might complete it
|
|
177
|
+
return NextResponse.json(
|
|
178
|
+
{
|
|
179
|
+
error: "Payment is being processed. Please wait a moment and check your order status.",
|
|
180
|
+
checkoutId,
|
|
181
|
+
transactionId: transaction?.id,
|
|
182
|
+
status: "processing",
|
|
183
|
+
message: "The payment has been authorized with PayPal. Your order is being created.",
|
|
184
|
+
},
|
|
185
|
+
{ status: 202 } // 202 Accepted - processing
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const completeResult = await completeResponse.json();
|
|
190
|
+
const completeData = completeResult.data;
|
|
191
|
+
const completeErrors = completeResult.errors || completeData?.checkoutComplete?.errors;
|
|
192
|
+
|
|
193
|
+
if (completeErrors && completeErrors.length > 0) {
|
|
194
|
+
console.error("❌ checkoutComplete errors:", completeErrors);
|
|
195
|
+
|
|
196
|
+
// Check if it's a duplicate key error (order already created)
|
|
197
|
+
const isDuplicateError = completeErrors.some((err: { message?: string; extensions?: { exception?: { code?: string } } }) =>
|
|
198
|
+
err.message?.includes('duplicate key') ||
|
|
199
|
+
err.message?.includes('already exists') ||
|
|
200
|
+
err.extensions?.exception?.code === 'IntegrityError'
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
if (isDuplicateError) {
|
|
204
|
+
// Avoid noisy logs in templates/production.
|
|
205
|
+
|
|
206
|
+
// Re-fetch transaction to get the order that was created
|
|
207
|
+
const recheckResponse = await fetch(apiUrl, {
|
|
208
|
+
method: "POST",
|
|
209
|
+
headers,
|
|
210
|
+
body: JSON.stringify({
|
|
211
|
+
query: TRANSACTION_PROCESS,
|
|
212
|
+
variables: {
|
|
213
|
+
id: txnId,
|
|
214
|
+
data: {
|
|
215
|
+
paypalOrderId: orderId,
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
}),
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
if (recheckResponse.ok) {
|
|
222
|
+
const recheckResult = await recheckResponse.json();
|
|
223
|
+
const recheckOrder = recheckResult.data?.transactionProcess?.transaction?.order;
|
|
224
|
+
|
|
225
|
+
if (recheckOrder) {
|
|
226
|
+
order = recheckOrder;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// If still no order after recheck, return processing status
|
|
231
|
+
if (!order) {
|
|
232
|
+
return NextResponse.json(
|
|
233
|
+
{
|
|
234
|
+
error: "Payment is being processed. Please wait a moment and check your order status.",
|
|
235
|
+
checkoutId,
|
|
236
|
+
transactionId: transaction?.id,
|
|
237
|
+
status: "processing",
|
|
238
|
+
message: "The payment has been authorized with PayPal. Your order is being created.",
|
|
239
|
+
},
|
|
240
|
+
{ status: 202 } // 202 Accepted - processing
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
} else {
|
|
244
|
+
// Other errors - return processing status
|
|
245
|
+
return NextResponse.json(
|
|
246
|
+
{
|
|
247
|
+
error: "Payment is being processed. Please wait a moment and check your order status.",
|
|
248
|
+
checkoutId,
|
|
249
|
+
transactionId: transaction?.id,
|
|
250
|
+
status: "processing",
|
|
251
|
+
message: "The payment has been authorized with PayPal. Your order is being created.",
|
|
252
|
+
details: completeErrors,
|
|
253
|
+
},
|
|
254
|
+
{ status: 202 } // 202 Accepted - processing
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (!order) {
|
|
260
|
+
order = completeData?.checkoutComplete?.order;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (!order) {
|
|
264
|
+
console.warn("⚠️ checkoutComplete did not create order - may still be processing");
|
|
265
|
+
|
|
266
|
+
// Return processing status
|
|
267
|
+
return NextResponse.json(
|
|
268
|
+
{
|
|
269
|
+
error: "Payment is being processed. Please wait a moment and check your order status.",
|
|
270
|
+
checkoutId,
|
|
271
|
+
transactionId: transaction?.id,
|
|
272
|
+
status: "processing",
|
|
273
|
+
message: "The payment has been authorized with PayPal. Your order is being created.",
|
|
274
|
+
},
|
|
275
|
+
{ status: 202 } // 202 Accepted - processing
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Avoid noisy logs in templates/production.
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Avoid noisy logs in templates/production.
|
|
283
|
+
|
|
284
|
+
return NextResponse.json({
|
|
285
|
+
success: true,
|
|
286
|
+
order: {
|
|
287
|
+
id: order.id,
|
|
288
|
+
number: order.number,
|
|
289
|
+
total: order.total.gross.amount,
|
|
290
|
+
currency: order.total.gross.currency,
|
|
291
|
+
},
|
|
292
|
+
});
|
|
293
|
+
} catch (error) {
|
|
294
|
+
console.error("❌ Error in capture-order API:", error);
|
|
295
|
+
|
|
296
|
+
return NextResponse.json(
|
|
297
|
+
{
|
|
298
|
+
error: error instanceof Error ? error.message : "Internal server error",
|
|
299
|
+
},
|
|
300
|
+
{ status: 500 }
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
2
|
+
|
|
3
|
+
const TRANSACTION_INITIALIZE = `
|
|
4
|
+
mutation TransactionInitialize(
|
|
5
|
+
$id: ID!
|
|
6
|
+
$amount: PositiveDecimal!
|
|
7
|
+
$paymentGateway: PaymentGatewayToInitialize!
|
|
8
|
+
$idempotencyKey: String
|
|
9
|
+
) {
|
|
10
|
+
transactionInitialize(
|
|
11
|
+
id: $id
|
|
12
|
+
amount: $amount
|
|
13
|
+
paymentGateway: $paymentGateway
|
|
14
|
+
idempotencyKey: $idempotencyKey
|
|
15
|
+
) {
|
|
16
|
+
transaction {
|
|
17
|
+
id
|
|
18
|
+
actions
|
|
19
|
+
}
|
|
20
|
+
transactionEvent {
|
|
21
|
+
pspReference
|
|
22
|
+
amount {
|
|
23
|
+
amount
|
|
24
|
+
currency
|
|
25
|
+
}
|
|
26
|
+
type
|
|
27
|
+
}
|
|
28
|
+
data
|
|
29
|
+
errors {
|
|
30
|
+
field
|
|
31
|
+
message
|
|
32
|
+
code
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
`;
|
|
37
|
+
|
|
38
|
+
export async function POST(request: NextRequest) {
|
|
39
|
+
try {
|
|
40
|
+
const body = await request.json();
|
|
41
|
+
const { checkoutId, amount, currency = "USD" } = body;
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
if (!checkoutId || !amount) {
|
|
45
|
+
return NextResponse.json(
|
|
46
|
+
{ error: "Missing required fields: checkoutId, amount" },
|
|
47
|
+
{ status: 400 }
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Get Saleor API URL
|
|
52
|
+
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
|
|
53
|
+
if (!apiUrl) {
|
|
54
|
+
throw new Error("NEXT_PUBLIC_API_URL is not configured");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
// Get auth token from request cookies
|
|
59
|
+
const token = request.cookies.get("token")?.value;
|
|
60
|
+
|
|
61
|
+
const headers: Record<string, string> = {
|
|
62
|
+
"Content-Type": "application/json",
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Add auth token if available (needed for checkout access)
|
|
66
|
+
if (token) {
|
|
67
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Generate idempotency key for safe retries
|
|
71
|
+
const idempotencyKey = `paypal-${checkoutId}-${Date.now()}`;
|
|
72
|
+
|
|
73
|
+
// Get the storefront URL for return/cancel URLs
|
|
74
|
+
const storefrontUrl =
|
|
75
|
+
process.env.NEXT_PUBLIC_STOREFRONT_URL ||
|
|
76
|
+
request.headers.get("origin") ||
|
|
77
|
+
"http://localhost:3000";
|
|
78
|
+
|
|
79
|
+
const requestBody = {
|
|
80
|
+
query: TRANSACTION_INITIALIZE,
|
|
81
|
+
variables: {
|
|
82
|
+
id: checkoutId,
|
|
83
|
+
amount: amount.toString(),
|
|
84
|
+
// action: "CHARGE", // REMOVED: This field requires HANDLE_PAYMENTS permission
|
|
85
|
+
paymentGateway: {
|
|
86
|
+
id: "saleor.app.payment.paypal",
|
|
87
|
+
data: {
|
|
88
|
+
// Pass return and cancel URLs to PayPal app
|
|
89
|
+
returnUrl: `${storefrontUrl}/checkout?checkoutId=${checkoutId}&payment=success`,
|
|
90
|
+
cancelUrl: `${storefrontUrl}/checkout?checkoutId=${checkoutId}&payment=cancelled`,
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
idempotencyKey,
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
// Call Saleor's transaction initialize mutation
|
|
99
|
+
const response = await fetch(apiUrl, {
|
|
100
|
+
method: "POST",
|
|
101
|
+
headers,
|
|
102
|
+
body: JSON.stringify(requestBody),
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Always try to parse the response body to see GraphQL errors
|
|
106
|
+
const result = await response.json();
|
|
107
|
+
|
|
108
|
+
if (!response.ok) {
|
|
109
|
+
console.error(
|
|
110
|
+
"❌ GraphQL request failed:",
|
|
111
|
+
response.status,
|
|
112
|
+
response.statusText
|
|
113
|
+
);
|
|
114
|
+
console.error("❌ Response body:", result);
|
|
115
|
+
|
|
116
|
+
// Try to extract more specific error from GraphQL response
|
|
117
|
+
const errorDetail =
|
|
118
|
+
result.errors?.[0]?.message || result.error || response.statusText;
|
|
119
|
+
throw new Error(
|
|
120
|
+
`GraphQL request failed: ${response.status} - ${errorDetail}`
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const data = result.data;
|
|
125
|
+
const graphqlErrors = result.errors;
|
|
126
|
+
|
|
127
|
+
if (graphqlErrors || data?.transactionInitialize?.errors?.length > 0) {
|
|
128
|
+
const errorMessage =
|
|
129
|
+
data?.transactionInitialize?.errors?.[0]?.message ||
|
|
130
|
+
graphqlErrors?.[0]?.message ||
|
|
131
|
+
"Failed to initialize transaction";
|
|
132
|
+
|
|
133
|
+
console.error("❌ Transaction initialize error:", errorMessage);
|
|
134
|
+
|
|
135
|
+
return NextResponse.json({ error: errorMessage }, { status: 400 });
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Extract PayPal order ID from response
|
|
139
|
+
// Saleor's PayPal app returns the order ID in the `data` field
|
|
140
|
+
const responseData = data?.transactionInitialize?.data;
|
|
141
|
+
const transactionId = data?.transactionInitialize?.transaction?.id;
|
|
142
|
+
const transactionEvent = data?.transactionInitialize?.transactionEvent;
|
|
143
|
+
const errors = data?.transactionInitialize?.errors;
|
|
144
|
+
|
|
145
|
+
// Avoid noisy logs (and accidental sensitive output) in templates/production.
|
|
146
|
+
|
|
147
|
+
// Check if the transaction failed
|
|
148
|
+
if (
|
|
149
|
+
transactionEvent?.type === "CHARGE_FAILURE" ||
|
|
150
|
+
transactionEvent?.type === "AUTHORIZATION_FAILURE"
|
|
151
|
+
) {
|
|
152
|
+
console.error("❌ PayPal transaction failed:", {
|
|
153
|
+
eventType: transactionEvent.type,
|
|
154
|
+
responseData,
|
|
155
|
+
errors,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
return NextResponse.json(
|
|
159
|
+
{
|
|
160
|
+
error: "Transaction failed",
|
|
161
|
+
eventType: transactionEvent.type,
|
|
162
|
+
transactionId,
|
|
163
|
+
responseData,
|
|
164
|
+
errors,
|
|
165
|
+
},
|
|
166
|
+
{ status: 400 }
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// The PayPal order ID is in responseData.paypal_order_id
|
|
171
|
+
const orderId =
|
|
172
|
+
responseData?.paypal_order_id ||
|
|
173
|
+
responseData?.paypalOrderId ||
|
|
174
|
+
responseData?.orderId ||
|
|
175
|
+
transactionEvent?.pspReference;
|
|
176
|
+
|
|
177
|
+
if (!orderId) {
|
|
178
|
+
console.error("❌ No PayPal order ID in response:", {
|
|
179
|
+
responseData,
|
|
180
|
+
transactionEvent,
|
|
181
|
+
});
|
|
182
|
+
return NextResponse.json(
|
|
183
|
+
{
|
|
184
|
+
error: "No PayPal order ID in response",
|
|
185
|
+
responseData,
|
|
186
|
+
transactionEvent,
|
|
187
|
+
},
|
|
188
|
+
{ status: 500 }
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Avoid noisy logs in templates/production.
|
|
193
|
+
|
|
194
|
+
return NextResponse.json({
|
|
195
|
+
orderId,
|
|
196
|
+
transactionId,
|
|
197
|
+
checkoutId,
|
|
198
|
+
amount,
|
|
199
|
+
currency,
|
|
200
|
+
});
|
|
201
|
+
} catch (error) {
|
|
202
|
+
console.error("❌ Error in create-order API:", error);
|
|
203
|
+
|
|
204
|
+
return NextResponse.json(
|
|
205
|
+
{
|
|
206
|
+
error: error instanceof Error ? error.message : "Internal server error",
|
|
207
|
+
},
|
|
208
|
+
{ status: 500 }
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
}
|