'use client'; import { Middleware } from '@reduxjs/toolkit'; import { setAddressList, setAttributeBasedShippingOptions, setBankAccounts, setCanGuestPurchase, setCardType, setCreditPaymentOptions, setDataSourceShippingOptions, setDeliveryOptions, setErrors, setHasGiftBox, setInstallmentOptions, setLoyaltyBalance, setLoyaltyBalances, setPaymentChoices, setPaymentOptions, setRetailStores, setShippingOptions, setHepsipayAvailability, setWalletPaymentData, setPayOnDeliveryOtpModalActive, setUnavailablePaymentOptions } from '../../redux/reducers/checkout'; import { RootState, TypedDispatch } from 'redux/store'; import { checkoutApi } from '../../data/client/checkout'; import { CheckoutContext, PreOrder } from '../../types'; import { getCookie } from '../../utils'; import settings from 'settings'; import { LocaleUrlStrategy } from '../../localization'; import { showMobile3dIframe } from '../../utils/mobile-3d-iframe'; import { showRedirectionIframe } from '../../utils/redirection-iframe'; interface CheckoutResult { payload: { errors?: Record; pre_order?: PreOrder; context_list?: CheckoutContext[]; redirect_url?: string; }; } interface MiddlewareParams { getState: () => RootState; dispatch: TypedDispatch; } export const errorMiddleware: Middleware = ({ dispatch }: MiddlewareParams) => { return (next) => (action) => { const result = next(action) as CheckoutResult; const errors = result?.payload?.errors; if ( !!errors && ((typeof errors === 'object' && Object.keys(errors).length > 0) || (Array.isArray(errors) && errors.length > 0)) ) { dispatch(setErrors(errors)); } return result; }; }; export const redirectUrlMiddleware: Middleware = () => { return (next) => (action) => { const result = next(action) as CheckoutResult; const redirectUrl = result?.payload?.redirect_url; if (redirectUrl) { const currentLocale = getCookie('pz-locale'); let url = redirectUrl; if (currentLocale && !redirectUrl.includes('/orders/redirection')) { const { defaultLocaleValue, localeUrlStrategy } = settings.localization; url = currentLocale === defaultLocaleValue && localeUrlStrategy !== LocaleUrlStrategy.ShowAllLocales ? redirectUrl : `/${currentLocale}${redirectUrl}`; } window.location.href = url; } return result; }; }; export const contextListMiddleware: Middleware = ({ dispatch, getState }: MiddlewareParams) => { return (next) => (action) => { const { isMobileApp, userPhoneNumber } = getState().root; const result = next(action) as CheckoutResult; const preOrder = result?.payload?.pre_order; if (result?.payload?.context_list) { result.payload.context_list.forEach((context) => { const redirectUrl = context.page_context.redirect_url; const isIframe = context.page_context.is_iframe ?? false; if (redirectUrl) { const currentLocale = getCookie('pz-locale'); let url = redirectUrl; if (currentLocale && !redirectUrl.includes('/orders/redirection')) { const { defaultLocaleValue, localeUrlStrategy } = settings.localization; url = currentLocale === defaultLocaleValue && localeUrlStrategy !== LocaleUrlStrategy.ShowAllLocales ? redirectUrl : `/${currentLocale}${redirectUrl}`; } const urlObj = new URL(url, window.location.origin); const isMobileDevice = isMobileApp || /iPad|iPhone|iPod|Android/i.test(navigator.userAgent); const isIframePaymentOptionIncluded = settings.checkout?.iframeIncludedPaymentOptions?.includes( result.payload?.pre_order?.payment_option?.slug ); urlObj.searchParams.set('t', new Date().getTime().toString()); if (isMobileDevice && isIframePaymentOptionIncluded) { showMobile3dIframe(urlObj.toString()); } else if (isIframe) { showRedirectionIframe(urlObj.toString()); } else { window.location.href = urlObj.toString(); } return; } if (context.page_context.has_gift_box) { dispatch(setHasGiftBox(context.page_context.has_gift_box)); } if (typeof context.page_context.can_guest_purchase === 'boolean') { dispatch( setCanGuestPurchase(context.page_context.can_guest_purchase) ); } if (context.page_context.delivery_options) { dispatch(setDeliveryOptions(context.page_context.delivery_options)); } if (context.page_context.addresses) { dispatch(setAddressList(context.page_context.addresses)); } if (context.page_context.shipping_options) { dispatch(setShippingOptions(context.page_context.shipping_options)); } if (context.page_context.data_sources) { dispatch( setDataSourceShippingOptions(context.page_context.data_sources) ); } if (context.page_context.attribute_based_shipping_options) { dispatch( setAttributeBasedShippingOptions( context.page_context.attribute_based_shipping_options ) ); } if (context.page_context.payment_options) { dispatch(setPaymentOptions(context.page_context.payment_options)); } if (context.page_context.unavailable_options) { dispatch( setUnavailablePaymentOptions( context.page_context.unavailable_options ) ); } if (context.page_context.credit_payment_options) { dispatch( setCreditPaymentOptions(context.page_context.credit_payment_options) ); } if (context.page_context.payment_choices) { dispatch(setPaymentChoices(context.page_context.payment_choices)); } if (context.page_context.bank_accounts) { dispatch(setBankAccounts(context.page_context.bank_accounts)); } if ( !result.payload.context_list.find( (ctx) => ctx.page_name === 'DeliveryOptionSelectionPage' ) ) { if (context.page_context.card_type) { dispatch(setCardType(context.page_context.card_type)); } if ( context.page_context.installments && preOrder?.payment_option?.payment_type !== 'masterpass_rest' ) { dispatch(setInstallmentOptions(context.page_context.installments)); } } if (context.page_context.balance) { dispatch(setLoyaltyBalance(context.page_context.balance)); } if (context.page_context.balances) { dispatch(setLoyaltyBalances(context.page_context.balances)); } if (context.page_context.accounts) { dispatch(setLoyaltyBalances(context.page_context.accounts)); } if (context.page_context.retail_stores) { dispatch(setRetailStores(context.page_context.retail_stores)); } if (context.page_name === 'SendSmsPage' && !preOrder?.phone_number) { dispatch( checkoutApi.endpoints.sendSms.initiate({ phone_number: userPhoneNumber ?? preOrder?.user_phone_number }) ); } if (context.page_name === 'VerifySmsPage') { dispatch(setPayOnDeliveryOtpModalActive(true)); } }); } return result; }; }; export const hepsiPayMiddleware: Middleware = ({ getState, dispatch }: MiddlewareParams) => { return (next) => (action) => { const result = next(action) as CheckoutResult; const { payload } = result; const preOrder = payload?.pre_order; const contextList = payload?.context_list; const isHepsiPayMethod = preOrder?.wallet_method === 'hepsipay'; const { paymentOptions } = getState().checkout; const { endpoints: apiEndpoints } = checkoutApi; if (contextList) { const walletSelectionPage = contextList.find( (ctx) => ctx.page_name === 'WalletSelectionPage' ); if ( isHepsiPayMethod && preOrder.payment_option?.payment_type === 'wallet' ) { if (walletSelectionPage) { dispatch( apiEndpoints.setWalletSelectionPage.initiate({ payment_option: paymentOptions.find( (opt) => opt.slug === 'hepsipay' )?.pk }) ); if ( walletSelectionPage && walletSelectionPage.page_context.paymentMethod === 'hepsipay' && walletSelectionPage.page_context.paymentData.data.Success === true ) { dispatch( setHepsipayAvailability( walletSelectionPage.page_context.paymentData.data.Success ) ); } } if (contextList.find((ctx) => ctx.page_name === 'WalletPaymentPage')) { dispatch(apiEndpoints.setWalletPaymentPage.initiate({})); } } } return result; }; }; export const walletPaymentMiddleware: Middleware = ({ getState, dispatch }: MiddlewareParams) => { return (next) => (action) => { const result = next(action) as CheckoutResult; const { payload } = result; const preOrder = payload?.pre_order; const contextList = payload?.context_list; if (contextList) { if (preOrder?.payment_option?.payment_type === 'wallet') { const walletSelectionPageContext = contextList.find( (ctx) => ctx.page_name === 'WalletSelectionPage' ); if (walletSelectionPageContext) { dispatch( setWalletPaymentData( walletSelectionPageContext.page_context.paymentData ) ); } } } return result; }; };