Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import PinBottomSheet from 'Components/organism/bottom-sheet/pin-bs';
- import { AuthHandler } from 'handlers/auth-handler';
- import {
- arrayIntersects,
- isMobile,
- moneyDot,
- getWithdrawAmount,
- getTopUpAmount,
- getDefault,
- titleCase,
- isset,
- stringToBoolean,
- exchangeRateConversionHelper,
- } from 'Helpers/common-helper';
- import { ROUTER_NAME, Types } from 'Helpers/navigation-helper';
- import { useRouter } from 'next/router';
- import React, { useEffect, useState, useMemo, useRef } from 'react';
- import { useDispatch, useSelector, shallowEqual } from 'react-redux';
- import navigationObject from 'Redux/reducers/navigation';
- import { CardPaymentRecap, Payments } from 'Components/molecules/card/card-payment-recap';
- import { UserHandler } from 'handlers/user-handler';
- import { WalletHandler } from 'handlers/wallet-handler';
- import { CouponHandler } from 'handlers/coupon-handler';
- import { CoinHandler } from 'handlers/coin-handler';
- import {
- DEFAULT_PAYMENT,
- dompetkuEngagementDialog,
- headerTitleHelper,
- IAllExtraPrice,
- openSandbox,
- paymentConfirmationRoutes,
- paymentMethodDenomFeeHelper,
- paymentMethodFeeHelper,
- paymentWithOvoRoutes,
- PAYMENT_SOURCE,
- IPaidItem,
- IItemsToBePaid,
- checkItemsToBePaidSource,
- } from 'Helpers/payment-helper';
- import { ITransactionData } from 'Helpers/transaction-helper';
- import { TransactionHandler } from 'handlers/transaction-handler';
- import HeaderBack from 'Components/organism/header/header-back';
- import PaymentSkeleton from 'Components/atoms/skeleton/payment-skeleton';
- import Divider from '@itemku/itemku-arcade/components/atoms/marker/divider';
- import CardPaymentMethod from 'Components/molecules/card/card-payment-method';
- import Banner from 'Components/organism/banner/banner';
- import ButtonOutlined from 'Components/molecules/button/button-outlined';
- import UserDetailInput from 'Components/organism/payment/user-detail-input';
- import ButtonText from 'Components/molecules/button/button-text';
- import Dialog from 'Components/organism/dialog';
- import StickyButtonWithText from 'Components/organism/sticky/sticky-button-with-text';
- import CardPremiumOption from 'Components/organism/payment/card-premium-option';
- import { routes } from 'Helpers/route-helper';
- import { TransactionBoundary } from 'Components/templates/transaction-boundary';
- import { analyticsEvent } from 'Helpers/analytics-helper';
- import analyticsObject from 'Redux/reducers/analytics';
- import { IReducers } from 'Redux/reducers';
- import paymentObject from 'Redux/reducers/payment';
- import { useLogin, putLocalStorage, useLocalStorage } from 'Helpers/hook-helper';
- import { withdrawDoneUrlKey } from 'Helpers/withdraw-helper';
- import { ICreateVendorVoucherTransactionPayload } from 'Redux/reducers/transaction-voucher';
- import Head from 'next/head';
- import {
- couponValidationDataKey,
- ICouponValidationData,
- validateEquippedCoupon,
- calculateCouponDiscount,
- paymentMethodCouponValidation,
- couponSessionKey,
- ICouponDetail,
- paymentSourceCouponValidation,
- } from 'Helpers/coupon-helper';
- import statusObject from 'Redux/reducers/status';
- import couponObject from 'Redux/reducers/coupon';
- import { ERR_TYPES, COUPON_ERROR_MESSAGE, getErrorMessage } from 'Helpers/error-helper';
- import CardCoupon from 'Components/molecules/card/card-coupon';
- import CardDompetkuEngagement from 'Components/organism/payment/card-dompetku-engagement';
- import { IModal } from '../dialog';
- import ItemkuWorldCoin from 'Components/organism/payment/itemku-world-coin';
- import coinObject, { IRequestValidCoin } from 'Redux/reducers/coin';
- import loadingComponentObject from 'Redux/reducers/loading-component';
- import { PREMIUM_BUYER_TIER } from 'Helpers/constants';
- import ShoppingRecapSection from 'components-update/templates/payment/sections/shopping-recap-section';
- import CardProductSubscription from 'components-update/organism/payment/card-product-subscription';
- import productDetailObject from 'Redux/reducers/product-detail';
- import { addDays, format } from 'date-fns';
- import persistObject from 'Redux/reducers/persist-state';
- import { hiddenFeatureConfig, HIDDEN_FEATURE_FOR_GLOBAL, REGION_CODE, useLanguage } from 'Helpers/translation-helper';
- import DivHtmlContent from 'Components/atoms/div-html-content';
- import { CurrencyHandler } from 'handlers/currency-handler';
- type DompetkuButton = { label: string; desc: any; onClick: () => void };
- type ItemToPay = { itemInfo: string; serverGroup: string; storeName: string; price: number; totalItem: number };
- type ItemToPayOS = { name: string; nominal: number; qty: number };
- export type UserDetail = {
- isPhoneVerified: boolean;
- isEmailVerified: boolean;
- hasSetupPIN: boolean;
- dompetkuBalance: number;
- totalPayment: number;
- };
- const initialUserData: UserDetail & { id: any; usedCoupon: string[] } = {
- id: 123,
- isEmailVerified: true,
- isPhoneVerified: true,
- hasSetupPIN: true,
- dompetkuBalance: 0,
- totalPayment: 0,
- usedCoupon: [],
- };
- type Input = { name: string; phoneNumber: string };
- interface IProps {
- paymentSource: PAYMENT_SOURCE;
- paymentMethodRoute: ROUTER_NAME;
- }
- const PaymentTemplate = ({ paymentSource, paymentMethodRoute }: IProps) => {
- const router = useRouter();
- const dispatch = useDispatch();
- const { userData } = UserHandler.useUserData();
- const { checkPin, requestResetPinOTP } = AuthHandler.useCheckPin(); // need request reset on handler
- const isMobileDevice = React.useRef(isMobile());
- const [isLoading, setIsLoading] = useState(true);
- const [userDetail, setUserDetail] = useState<UserDetail & { id: any; usedCoupon: string[] }>(initialUserData);
- const [itemToPay, setItemToPay] = useState<ItemToPay[] | ItemToPayOS[]>([]);
- const [extraCharge, setExtraCharge] = useState<Payments>([]);
- const [totalPayment, setTotalPayment] = useState<number>(0);
- const [totalDiscountPrice, setTotalDiscountPrice] = useState<number>(0);
- const [totalExtraCharge, setTotalExtraCharge] = useState<number>(0);
- const [errorBanner, setErrorBanner] = useState(false);
- const [errorVoucherBuyerInfo, setErrorVoucherBuyerInfo] = useState({ name: '', phoneNumber: '' });
- const [dialog, setDialog] = useState({
- dialogProps: {},
- dompetku: false,
- failedTransaction: false,
- loadPayment: false,
- closePayment: false,
- cancelPayment: false,
- });
- const [dompetkuButton, setDompetkuButton] = useState<DompetkuButton>();
- const isAlreadySuccessSendRequest = useRef(false);
- const [latestPaymentErrorBanner, setLatestPaymentErrorBanner] = useState('');
- const [pinBottomSheet, setPinBottomSheet] = useState({
- isOpen: false,
- wrongPin: false,
- errorMessage: undefined as undefined | string,
- pinNumber: undefined as undefined | string,
- isSuccess: false,
- });
- const [convertedTotalPayment, setConvertedTotalPayment] = useState<number>(0);
- const [convertedExtraCharge, setConvertedExtraCharge] = useState<number>(0);
- // Payment using BCA Virtual Account
- const [paymentBCA, setPaymentBCA] = useState<boolean>(false);
- const [unpayBCAPayment, setUnpayBCAPayment] = useState<boolean>(false); // initial value true for testing
- const bcaPaymentMethodId = useSelector(
- (state: IReducers) => state.configReducers.configList.BCA_VA_PAYMENT_METHOD_ID,
- );
- const couponValidationLoading = useSelector(
- (state: IReducers) => state.statusReducers.loadingState[couponObject.names.requestValidateSelectedCoupon],
- shallowEqual,
- );
- const region = useSelector((state: IReducers) => state.regionReducers.regionData.country_code);
- const isGlobal: boolean = region !== REGION_CODE.INDONESIA;
- const { coinLoading } = CoinHandler.useCoin();
- const handleGoToPaymentMethod = () => {
- document.body.scrollIntoView();
- dispatch(navigationObject.actions.routeNavigateReplaceTo({
- routeName: paymentMethodRoute,
- query: isProductSubs === true
- ? {
- ...router.query,
- is_subscription: isSubscription,
- }
- : router.query,
- }));
- };
- const isAnalyticsSent = useSelector((state: IReducers) => state.paymentReducers.isAnalyticsSent);
- // IWorld Coin
- const isUsingCoin = useSelector((state: IReducers) => state.paymentReducers.isUsingCoin);
- const handleToggleUsingCoin = (isUsed: boolean) => {
- dispatch(paymentObject.actions.setIsUsingCoin({
- ...isUsingCoin,
- [itemKey]: isUsed,
- }));
- };
- // Subscription
- const [isSubscription, setSubscription] = useState<boolean>(stringToBoolean(router?.query?.is_subscription as string || '') || false);
- const [pinInteractionValue, setPinInteractionValue] = useState('');
- const handleInputPin = (value: string) => {
- setPinInteractionValue(value);
- const pinCallback = (pinStatus: boolean, msg: any) => {
- if (pinStatus) {
- setPinBottomSheet({
- ...pinBottomSheet,
- isOpen: false,
- wrongPin: false,
- errorMessage: undefined,
- pinNumber: value,
- isSuccess: true,
- });
- } else {
- setPinBottomSheet({ ...pinBottomSheet, wrongPin: true, errorMessage: msg });
- }
- };
- if (value.length >= 6) {
- checkPin(pinCallback, value);
- } else {
- setPinBottomSheet({ ...pinBottomSheet, wrongPin: false });
- }
- };
- // Handle premium option //
- const [itemKey, setItemKey] = useState('');
- const premiumOption = useSelector((state: IReducers) => state.paymentReducers.isPremiumTicked);
- useEffect(() => {
- if (userData?.is_user_member) {
- dispatch(paymentObject.actions.setIsPremiumTicked({
- ...premiumOption,
- [itemKey]: false,
- }));
- }
- }, [userData, itemKey]);
- // End Handle premium option //
- // Items to be Paid & Payment Recap //
- const [noItemToBePaid, setNoItemToBePaid] = useState(false);
- const itemsToBePaidLoading = useSelector((state: IReducers) => state.statusReducers.loadingState[paymentObject.names.requestItemsToBePaid], shallowEqual);
- const itemsToBePaid = useSelector((state: IReducers) => state.paymentReducers.itemsToBePaid, shallowEqual);
- const getItemsToBePaid = () => {
- const cb = (data: any) => {
- if (!data || !data.items.length) {
- dispatch(
- statusObject.actions.errorSetNew({
- errorCode: ERR_TYPES.NO_CHECKOUT_ITEMS,
- errorMessage: getErrorMessage(ERR_TYPES.NO_CHECKOUT_ITEMS),
- }),
- );
- setNoItemToBePaid(true);
- }
- };
- let key = new URL(location.href).searchParams.get('key') || '';
- setItemKey(key);
- dispatch(paymentObject.actions.requestItemsToBePaid(cb, key));
- };
- // itemsToBePaid loading state always true even the data fetched
- const [itemsToBePaidReady, setItemsToBePaidReady] = useState(false);
- useEffect(() => {
- getItemsToBePaid();
- }, []);
- const [currentItemsToBePaid, setCurrentItemsToBePaid] = useState<IItemsToBePaid>();
- useEffect(() => {
- setCurrentItemsToBePaid(itemsToBePaid[itemKey]);
- }, [itemsToBePaid, itemKey]);
- useEffect(() => {
- if (currentItemsToBePaid && !checkItemsToBePaidSource(currentItemsToBePaid, paymentSource)) {
- setNoItemToBePaid(true);
- }
- }, [currentItemsToBePaid, paymentSource]);
- useEffect(() => {
- if (currentItemsToBePaid?.items) {
- setItemsToBePaidReady(true);
- }
- }, [currentItemsToBePaid]);
- useEffect(() => {
- let totalPaymentTemp: number = 0;
- let totalDiscountPriceTemp: number = 0;
- let convertedTotalPaymentTemp: number = 0;
- currentItemsToBePaid?.items.forEach((item: any) => {
- const priceOriginal = item.totalItem * item.price;
- const discountPrice = item.discountPrice ? item.totalItem * +item.discountPrice : 0;
- totalPaymentTemp += priceOriginal - discountPrice;
- totalDiscountPriceTemp += discountPrice;
- convertedTotalPaymentTemp += exchangeRateConversionHelper(foreignExchangeRate, regionData, item.price) * item.totalItem;
- });
- setTotalPayment(totalPaymentTemp);
- setTotalDiscountPrice(totalDiscountPriceTemp);
- setConvertedTotalPayment(convertedTotalPaymentTemp);
- if (
- paymentSource === PAYMENT_SOURCE.OFFICIAL_STORE_TOPUP ||
- paymentSource === PAYMENT_SOURCE.OFFICIAL_STORE_VOUCHER
- ) {
- setItemToPay((currentItemsToBePaid?.items || []) as ItemToPayOS[]);
- } else {
- setItemToPay((currentItemsToBePaid?.items || []) as ItemToPay[]);
- }
- if (currentItemsToBePaid && !isAnalyticsSent) {
- // add event to amplitude
- const productName: string[] = [];
- const productID: number[] = [];
- const gameName: string[] = [];
- currentItemsToBePaid?.items.forEach((item: any) => {
- productName.push(item.itemInfo);
- productID.push(item.productId);
- gameName.push(item.serverGroup);
- });
- const type = titleCase(paymentSource);
- const isQuickbuy =
- paymentSource === PAYMENT_SOURCE.QUICK_BUY
- ? 'YES'
- : paymentSource === PAYMENT_SOURCE.OFFICIAL_STORE_TOPUP ||
- paymentSource === PAYMENT_SOURCE.OFFICIAL_STORE_VOUCHER
- ? 'Official Store'
- : 'NO';
- const sumOfProduct = currentItemsToBePaid.items.length;
- const totalValue = totalPaymentTemp;
- dispatch(
- analyticsObject.actions.logEvent(
- analyticsEvent.addPaymentInfoPage(
- productName,
- productID,
- gameName,
- type,
- isQuickbuy,
- sumOfProduct,
- totalValue,
- ),
- ),
- );
- dispatch(paymentObject.actions.setIsAnalyticsSent(true));
- }
- }, [currentItemsToBePaid]);
- // End Items to be Paid & Payment Recap //
- // Used Payment Method //
- const [usedPaymentMethod, setUsedPaymentMethod] = useState<any>();
- const { latestPayment, getLatestPayment, latestPaymentLoading } = UserHandler.useLatestPayment();
- const { loadWalletDetail, walletDetail, walletDetailLoading } = WalletHandler.useWalletDetail();
- const premiumBuyerPrice = useSelector(
- (state: IReducers) => state.configReducers.configList[PREMIUM_BUYER_TIER.TIER_1],
- shallowEqual,
- ) || 5000;
- const selectedPaymentMethod = useSelector((state: IReducers) => state.paymentReducers.selectedPaymentMethod,);
- const { loadCoupons, coupons, couponLoading } = CouponHandler.useCoupons();
- const [voucherBuyerInfo, setVoucherBuyerInfo] = useState<Input>({
- name: userData.username as string,
- phoneNumber: userData.phone?.substring(2) as string,
- });
- useEffect(() => {
- getLatestPayment({
- web_type: isMobileDevice.current ? 2 : 1,
- });
- }, []);
- useEffect(() => {
- if (latestPayment?.id === 0) {
- Object.assign(latestPayment, DEFAULT_PAYMENT);
- }
- loadWalletDetail();
- }, [latestPayment]);
- useEffect(() => {
- const paymentMethod = selectedPaymentMethod[itemKey] || DEFAULT_PAYMENT;
- let paymentInfoText = paymentMethod?.payment_information_text;
- if (paymentInfoText?.substr(0, 2) === '- ') paymentInfoText = paymentInfoText.substring(2);
- setUsedPaymentMethod({ ...paymentMethod, payment_information_text: paymentInfoText });
- }, [selectedPaymentMethod, latestPayment, itemKey]);
- useEffect(() => {
- setUserDetail({
- ...userDetail,
- id: userData.id,
- isEmailVerified: Boolean(userData.is_email_verified),
- isPhoneVerified: Boolean(userData.phone_verification_id),
- hasSetupPIN: Boolean(userData.has_security_pin),
- dompetkuBalance: walletDetail.order_able,
- });
- // if (paymentSource === PAYMENT_SOURCE.OFFICIAL_STORE_VOUCHER) {
- // setVoucherBuyerInfo({
- // name: userData.username!,
- // phoneNumber: userData.phone!
- // });
- // }
- }, [userData, walletDetail]);
- // End Used Payment Method //
- const invalidPhoneMessage = useLanguage('nomor_telepon_tidak_valid');
- const noPhoneMessage = useLanguage('nomor_telepon_tidak_boleh_kosong');
- const noNameMessage = useLanguage('nama_tidak_boleh_kosong');
- const voucherBuyerInfoValidation = (buyerInfo: Input) => {
- const errorList = {
- name: '',
- phoneNumber: '',
- };
- if (buyerInfo.phoneNumber) {
- const phoneValidation = buyerInfo.phoneNumber.match(/^8\d{8,11}$/);
- if (!phoneValidation) {
- errorList.phoneNumber = invalidPhoneMessage;
- } else {
- errorList.phoneNumber = '';
- }
- } else {
- errorList.phoneNumber = noPhoneMessage;
- }
- if (!buyerInfo.name) {
- errorList.name = noNameMessage;
- }
- setErrorVoucherBuyerInfo(errorList);
- };
- useEffect(() => {
- voucherBuyerInfoValidation(voucherBuyerInfo);
- }, [voucherBuyerInfo]);
- // Payment Skeleton //
- useEffect(() => {
- const loadingState = Boolean(
- (itemsToBePaidLoading && !itemsToBePaidReady) ||
- latestPaymentLoading ||
- walletDetailLoading ||
- couponLoading ||
- couponValidationLoading ||
- coinLoading,
- );
- if (loadingState !== isLoading) {
- setIsLoading(loadingState);
- }
- }, [
- itemsToBePaidLoading,
- itemsToBePaidReady,
- latestPaymentLoading,
- walletDetailLoading,
- couponLoading,
- couponValidationLoading,
- coinLoading,
- ]);
- // EndPayment Skeleton //
- // Start coupon handling //
- const [, setCouponValiData] = useLocalStorage<ICouponValidationData>(couponValidationDataKey, {});
- const [lastCoupon, setLastCoupon] = useLocalStorage<ICouponDetail | null>(couponSessionKey, null);
- const equippedCoupon = useSelector((state: IReducers) => state.couponReducers.usedCoupon);
- const lastKey = useSelector((state: IReducers) => state.couponReducers.couponLastKey);
- const totalCoupon = useSelector((state: IReducers) => state.couponReducers.couponAllCount)[lastKey];
- const [validCoupon, setValidCoupon] = useState(false);
- useEffect(() => {
- if (equippedCoupon) {
- const result = paymentSourceCouponValidation(equippedCoupon, paymentSource);
- if (result.success == false) {
- dispatch(couponObject.actions.clearUserCoupoun());
- dispatch(statusObject.actions.errorSetNew({ errorCode: result.code, errorMessage: result.message }));
- }
- }
- }, [equippedCoupon]);
- useEffect(() => {
- loadCoupons();
- }, []);
- // check if coupon is valid
- const isCouponSame = useMemo(() => {
- if (!isset(equippedCoupon) || lastCoupon?.id !== equippedCoupon?.id) {
- setLastCoupon(equippedCoupon);
- return false;
- } else {
- return true;
- }
- }, [equippedCoupon?.id]);
- useEffect(() => {
- // clear used coupon when used coupon not found
- dispatch(couponObject.actions.requestValidateSelectedCoupon());
- }, []);
- const isCouponValid = useMemo(() => {
- if (equippedCoupon && currentItemsToBePaid && !isLoading) {
- const newCouponValiData: ICouponValidationData = {
- game_ids: currentItemsToBePaid?.items?.map((item: any) => item.gameId) || [],
- item_type_ids: currentItemsToBePaid?.items?.map((item: any) => item.itemTypeId),
- total_price: totalPayment,
- };
- const isValid = validateEquippedCoupon(equippedCoupon, newCouponValiData, paymentSource);
- setValidCoupon(isValid.success);
- return isValid;
- }
- return { success: false, code: '', message: '' };
- }, [currentItemsToBePaid, equippedCoupon, isLoading]);
- const couponDiscount = useMemo(() => {
- if (isCouponValid && equippedCoupon) {
- return calculateCouponDiscount(equippedCoupon, totalPayment);
- }
- return 0;
- }, [equippedCoupon, isCouponValid]);
- // dispatch coupon error
- useEffect(() => {
- if (isLoading) {
- return;
- }
- if (equippedCoupon && !isCouponSame) {
- if (isCouponValid.success === false && isCouponValid.code && isCouponValid.message) {
- dispatch(
- statusObject.actions.errorSetNew({
- errorCode: isCouponValid.code,
- errorMessage: isCouponValid.message,
- }),
- );
- dispatch(couponObject.actions.clearUserCoupoun());
- return;
- }
- }
- }, [equippedCoupon, isCouponSame, isLoading]);
- //dispatch coupon success snackbar
- useEffect(() => {
- if (isLoading) {
- return;
- }
- if (true === validCoupon) {
- dispatch(
- statusObject.actions.errorSetNew({
- errorCode: ERR_TYPES.COUPON_EQUIP_SUCCESS_PAYMENT,
- errorMessage: COUPON_ERROR_MESSAGE[ERR_TYPES.COUPON_EQUIP_SUCCESS_PAYMENT],
- }),
- );
- }
- }, [validCoupon]);
- const handleSeeCoupon = () => {
- if (currentItemsToBePaid) {
- const newCouponValiData: ICouponValidationData = {
- game_ids: currentItemsToBePaid?.items?.map((item: any) => item.gameId) || [],
- item_type_ids: currentItemsToBePaid?.items?.map((item: any) => item.itemTypeId),
- };
- setCouponValiData(newCouponValiData);
- if (equippedCoupon !== null) {
- dispatch(
- navigationObject.actions.routeNavigateTo({
- routeName: ROUTER_NAME.MY_COUPON_ID,
- params: { id: equippedCoupon.id },
- query: { use_coupon: 1 },
- }),
- );
- } else if (coupons?.length !== 0) {
- dispatch(
- navigationObject.actions.routeNavigateTo({ routeName: ROUTER_NAME.MY_COUPON, query: { use_coupon: 1 } }),
- );
- } else {
- dispatch(
- navigationObject.actions.routeNavigateTo({
- routeName: ROUTER_NAME.POIN_EXCHANGE,
- query: { use_coupon: 1 },
- }),
- );
- }
- }
- };
- // End coupon handling //
- // BEGIN ITEMKU WORLD COIN
- // Retrieve discount games
- const [hasItemkuWorldProduct, setHasItemkuWorldProduct] = useState<boolean>(false); // as MVP will be applied only to ROX product.
- const [discountGameIds, setDiscountGameIds] = useState<number[]>([]);
- const discountGamesData = useSelector((state: IReducers) => state.coinReducers.discountGames);
- useEffect(() => {
- dispatch(coinObject.actions.requestDiscountGames());
- }, []);
- useEffect(() => {
- if (discountGamesData) {
- if (discountGamesData.length > 0) {
- const arrGameids = discountGamesData.map((item: any) => item.game_id);
- setDiscountGameIds(arrGameids);
- }
- }
- }, [discountGamesData]);
- useEffect(() => {
- const rawGameIds: number[] = currentItemsToBePaid?.items.map((item: any) => item.gameId) || [];
- if (discountGameIds.length > 0) {
- const isOrderContainDiscountedGames = arrayIntersects(discountGameIds, rawGameIds);
- if (isOrderContainDiscountedGames === true) setHasItemkuWorldProduct(true);
- }
- }, [currentItemsToBePaid, discountGameIds]);
- // Retrieve coin data
- const { userValidCoin, loadUserValidCoin, validDiscount, loadValidDiscount } = CoinHandler.useCoin();
- const [gameIdsForCoin, setGameIdsForCoin] = useState<number[]>([]);
- useEffect(() => {
- if (hasItemkuWorldProduct) {
- const rawGameIds: number[] = currentItemsToBePaid?.items.map((item: any) => item.gameId) || [];
- const rawTotalPrice: number[] = currentItemsToBePaid?.items.map((item: any) => Number(item.price * item.totalItem)) || [];
- if (rawGameIds && rawTotalPrice) {
- if (rawGameIds.length === rawTotalPrice.length && rawGameIds.length > 0 && rawTotalPrice.length > 0) {
- const param = {
- game_ids: rawGameIds,
- amounts: rawTotalPrice,
- };
- loadValidDiscount(param);
- }
- }
- const gameIds = currentItemsToBePaid?.items.map((item: any) => {
- if (item.gameId != undefined) return item.gameId;
- });
- if (gameIds != undefined) {
- const uniqueGameIds = Array.from(new Set(gameIds)) as number[];
- setGameIdsForCoin(uniqueGameIds);
- }
- }
- }, [currentItemsToBePaid, hasItemkuWorldProduct]);
- useEffect(() => {
- if (gameIdsForCoin.length > 0 && hasItemkuWorldProduct) loadUserValidCoin(gameIdsForCoin);
- }, [gameIdsForCoin, hasItemkuWorldProduct]);
- const [ownedCoin, setOwnCoin] = useState<number>(0);
- const [maxAmountOfCoin, setMaxAmountOfCoin] = useState<number>(0);
- const [coinData, setCoinData] = useState<IRequestValidCoin>();
- const [usedItemkuWorldCoin, setUsedItemkuWorlCoin] = useState<number>(0);
- const [coinDiscount, setCoinDiscount] = useState<number>(0);
- const allCoinDiscount = useSelector((state: IReducers) => state.paymentReducers.coinDiscount);
- useEffect(() => {
- if (userValidCoin) {
- if (userValidCoin.length > 0) {
- setOwnCoin(userValidCoin[0].coin_balance);
- setCoinData(userValidCoin[0]);
- }
- }
- }, [userValidCoin]);
- useEffect(() => {
- if (validDiscount) {
- if (validDiscount.length > 0) {
- let totalDiscountAmount: number = 0;
- let maxCoinCanBeUsed: number = 0;
- for (let item of validDiscount) {
- totalDiscountAmount += item.discount_amount;
- maxCoinCanBeUsed += item.coin_use;
- }
- setCoinDiscount(totalDiscountAmount);
- setMaxAmountOfCoin(maxCoinCanBeUsed);
- if (itemKey && itemToPay.length) {
- dispatch(paymentObject.actions.setCoinDiscount({
- ...allCoinDiscount,
- [itemKey]: totalDiscountAmount,
- }));
- }
- }
- }
- }, [itemToPay, validDiscount, itemKey]);
- useEffect(() => {
- if (ownedCoin <= maxAmountOfCoin) setUsedItemkuWorlCoin(ownedCoin);
- else setUsedItemkuWorlCoin(maxAmountOfCoin);
- }, [totalPayment, ownedCoin, maxAmountOfCoin]);
- // END ITEMKU WORLD COIN
- // Extra Charge //
- const setExtraPrice = (data: IAllExtraPrice) => {
- dispatch(paymentObject.actions.setExtraPrice(data));
- };
- const handleCheckPremiumOption = (checked: boolean) => {
- dispatch(paymentObject.actions.setIsPremiumTicked({
- ...premiumOption,
- [itemKey]: checked,
- }));
- };
- useEffect(() => {
- if (
- paymentSource === PAYMENT_SOURCE.OFFICIAL_STORE_VOUCHER ||
- paymentSource === PAYMENT_SOURCE.OFFICIAL_STORE_TOPUP ||
- (isGlobal && hiddenFeatureConfig[HIDDEN_FEATURE_FOR_GLOBAL.HIDE_PREMIUM])
- ) {
- dispatch(paymentObject.actions.setIsPremiumTicked({
- ...premiumOption,
- [itemKey]: false,
- }));
- }
- }, [itemKey]);
- const [cashback, setCashback] = useState(0);
- const premiumName = useLanguage('layanan_pembeli_premium') ;
- const feesName = useLanguage('biaya_admin');
- const extraPrice = useSelector((state: IReducers) => state.paymentReducers.extraPrice);
- useEffect(() => {
- if (!currentItemsToBePaid) {
- return;
- }
- const finalPremiumBuyerPrice =
- paymentSource === PAYMENT_SOURCE.CART && currentItemsToBePaid.items.length >= 4
- ? premiumBuyerPrice * 2
- : premiumBuyerPrice;
- const premiumRecap = { name: premiumName || 'Layanan Pembeli Premium', nominal: finalPremiumBuyerPrice };
- let extraChargeTemp: any = [];
- if (premiumOption[itemKey]) {
- extraChargeTemp = [premiumRecap, ...extraChargeTemp];
- }
- setExtraPrice({
- ...extraPrice,
- [itemKey]: extraChargeTemp,
- });
- let fees = 0;
- if (usedPaymentMethod?.payment_denom_item && usedPaymentMethod?.payment_denom_item.length) {
- const paymentDenomFee = paymentMethodDenomFeeHelper(usedPaymentMethod.payment_denom_item, totalPayment);
- if (paymentDenomFee) {
- const premiumFee = premiumOption[itemKey] ? finalPremiumBuyerPrice : 0;
- fees = paymentDenomFee.totalPaid - totalPayment - premiumFee;
- setCashback(fees - paymentDenomFee.fee);
- }
- } else {
- const paymentFee = paymentMethodFeeHelper(usedPaymentMethod?.payment_method_fee || [], totalPayment);
- const totalPaymentAndPremium = premiumOption[itemKey] ? totalPayment + finalPremiumBuyerPrice : totalPayment;
- const finalAmount = totalPaymentAndPremium - couponDiscount - (isUsingCoin[itemKey] ? coinDiscount : 0);
- fees = paymentFee.fixedRate ? (finalAmount * paymentFee.fixedRate) / 100 : 0;
- fees += paymentFee.fixedFee ? paymentFee.fixedFee : 0;
- }
- if (fees) {
- extraChargeTemp = [
- ...extraChargeTemp.filter((item: any) => item.name !== feesName),
- { name: feesName, nominal: Math.ceil(fees) },
- ];
- }
- setExtraCharge(extraChargeTemp);
- }, [currentItemsToBePaid, premiumOption, premiumBuyerPrice, usedPaymentMethod, totalPayment, itemKey, couponDiscount, isUsingCoin, coinDiscount]);
- useEffect(() => {
- const totalExtraChargeTemp = extraCharge.reduce((acc: number, item: any) => acc + item.nominal, 0);
- setTotalExtraCharge(totalExtraChargeTemp);
- const convertedExtraChargeTemp = extraCharge.reduce((acc: number, item: any) => exchangeRateConversionHelper(foreignExchangeRate, regionData, (acc + item.nominal)), 0);
- setConvertedExtraCharge(convertedExtraChargeTemp);
- }, [extraCharge]);
- // End Extra Charge //
- const topupTitleText = useLanguage('top_up_dompetku');
- const topupDescText = useLanguage('dompetku_tidak_cukup_top_up_sebesar_{{topup_amount}}_kelipatan_rp_1_000_atau_ubah_metode_pembayaranmu', { topup_amount: 'Rp' + moneyDot(getTopUpAmount(userDetail.dompetkuBalance, totalPayment + totalExtraCharge)) });
- const topupCancelText = useLanguage('ubah_pembayaran');
- const topupMainText = useLanguage('lanjut_top_up');
- const topupEngagementCancelText = useLanguage('batalkan');
- const withdrawTitleText = useLanguage('cairkan_dana_dompetku');
- const withdrawDescText = useLanguage('transaksi_tidak_dapat_dilanjutkan_karena_dana_dompetku_melebihi_batas_{{topup_limit}}_cairkan_sebagian_dana_dompetku_terlebih_dahulu', { topup_limit: 'Rp' + moneyDot(walletDetail.topup_limit) });
- const withdrawCancelText = useLanguage('ubah_pembayaran');
- const withdrawMainText = useLanguage('cairkan_dana_dompetku');
- // Dompetku Error //
- const showDompetkuDialog = (type: 'topup' | 'withdraw' | 'topup-engagement') => {
- let modal: IModal = {
- title: '',
- description: '',
- cancelActionTitle: '',
- mainActionTitle: '',
- cancelAction: () => {
- /* do nothing */
- },
- mainAction: () => {
- /* do nothing */
- },
- };
- if (type === 'topup') {
- modal = {
- title: topupTitleText,
- description: (
- <p>
- <DivHtmlContent data={topupDescText} draggable={false} />
- </p>
- ),
- cancelActionTitle: topupCancelText,
- mainActionTitle: topupMainText,
- cancelAction: handleGoToPaymentMethod,
- mainAction: () => dispatch(navigationObject.actions.routeNavigateTo({ routeName: ROUTER_NAME.DOMPETKU_TOPUP })),
- };
- } else if (type === 'withdraw') {
- modal = {
- title: withdrawTitleText,
- description: withdrawDescText,
- cancelActionTitle: withdrawCancelText,
- mainActionTitle: withdrawMainText,
- cancelAction: handleGoToPaymentMethod,
- mainAction: () => {
- putLocalStorage(withdrawDoneUrlKey, router.pathname);
- dispatch(
- navigationObject.actions.routeNavigateTo({
- routeName: ROUTER_NAME.DOMPETKU_WITHDRAW,
- query: {
- withdraw_amount: getWithdrawAmount(userDetail.dompetkuBalance, walletDetail.topup_limit),
- },
- }),
- );
- },
- };
- } else if (type === 'topup-engagement') {
- modal = {
- title: topupTitleText,
- description: (
- <p>
- <DivHtmlContent data={topupDescText} draggable={false} />
- </p>
- ),
- cancelActionTitle: topupEngagementCancelText,
- mainActionTitle: topupMainText,
- cancelAction: () => {},
- mainAction: () => dispatch(navigationObject.actions.routeNavigateTo({ routeName: ROUTER_NAME.DOMPETKU_TOPUP })),
- };
- }
- dispatch(
- navigationObject.actions.modalNavigateTo(Types.Dialog, {
- title: modal.title,
- type: 'multiple',
- description: modal.description,
- cancelActionTitle: modal.cancelActionTitle,
- mainActionTitle: modal.mainActionTitle,
- cancelAction: modal.cancelAction,
- mainAction: modal.mainAction,
- }),
- );
- };
- let dompetkuWithButton = false;
- let dompetkuButtonLabel = topupTitleText;
- let dompetkuOnClick = () => {
- /* do nothing */
- };
- if (userDetail.hasSetupPIN && userDetail.isEmailVerified && userDetail.isPhoneVerified) {
- if (userDetail.dompetkuBalance < totalPayment + totalExtraCharge) {
- dompetkuWithButton = true;
- dompetkuOnClick = () => showDompetkuDialog('topup');
- }
- }
- const emailVerificationLabel = useLanguage('verifikasi_email');
- const emailVerificationDesc = useLanguage('untuk_melakukan_transaksi_dengan_dompetku_kamu_harus_melakukan_verifikasi_email');
- const phoneVerificationLabel = useLanguage('verifikasi_no_handphone');
- const phoneVerificationDesc = useLanguage('untuk_melakukan_transaksi_dengan_dompetku_kamu_harus_melakukan_verifikasi_no_handphone');
- const pinVerificationLabel = useLanguage('atur_pin_sekarang');
- const pinVerificationDesc = useLanguage('atur_pin_kamu_untuk_transaksi_dengan_dompetku');
- const emptyWalletDesc = useLanguage('dana_dompetku_tidak_cukup_top_up_dana_dompetku_kamu_atau_gunakan_metode_pembayaran_lain');
- useEffect(() => {
- if (!latestPaymentLoading && !walletDetailLoading) {
- if (!userDetail.isEmailVerified || !userDetail.isPhoneVerified || !userDetail.hasSetupPIN) {
- // user dompetku inactive
- if (Object.keys(latestPayment).length === 0) {
- // user first purchase
- setIsDompetkuEngagementShown(false);
- if (!userDetail.isEmailVerified) {
- setDompetkuButton({
- ...dompetkuButton,
- label: emailVerificationLabel,
- desc: emailVerificationDesc,
- onClick: () => router.push(routes.verifikasi.route + 'email'),
- });
- } else if (!userDetail.isPhoneVerified) {
- setDompetkuButton({
- ...dompetkuButton,
- label: phoneVerificationLabel,
- desc: phoneVerificationDesc,
- onClick: () => router.push(routes.verifikasi.route + 'nomor-handphone'),
- });
- } else if (!userDetail.hasSetupPIN) {
- setDompetkuButton({
- ...dompetkuButton,
- label: pinVerificationLabel,
- desc: (
- <p>
- <DivHtmlContent data={pinVerificationDesc} draggable={false} />
- </p>
- ),
- onClick: () => {
- if (userDetail.isPhoneVerified) {
- router.push(routes.pin.route + 'add');
- } else {
- router.push(routes.verifikasi.route + 'nomor-handphone');
- }
- },
- });
- }
- } else {
- // user repurchase
- setIsDompetkuEngagementShown(true);
- setDompetkuButton(undefined);
- const paymentMethod = selectedPaymentMethod[itemKey] || latestPayment;
- let paymentInfoText = paymentMethod?.payment_information_text;
- if (paymentInfoText?.substr(0, 2) === '- ') paymentInfoText = paymentInfoText.substring(2);
- setUsedPaymentMethod({ ...paymentMethod, payment_information_text: paymentInfoText });
- }
- } else {
- // user dompetku active
- if (Object.keys(latestPayment).length === 0) {
- // user first purchase
- if (userDetail.dompetkuBalance >= totalPayment) {
- // sufficient balance
- setIsDompetkuEngagementShown(false);
- setDompetkuButton(undefined);
- } else {
- // insufficient balance
- setIsDompetkuEngagementShown(false);
- setDompetkuButton({
- ...dompetkuButton,
- label: '',
- desc: emptyWalletDesc,
- onClick: () => null,
- });
- }
- } else {
- // user repurchase
- if (latestPayment.id === 0) {
- // user latest payment using dompetku
- if (userDetail.dompetkuBalance >= totalPayment) {
- // sufficient balance
- setIsDompetkuEngagementShown(false);
- setDompetkuButton(undefined);
- } else {
- // insufficient balance
- setIsDompetkuEngagementShown(false);
- setDompetkuButton({
- ...dompetkuButton,
- label: '',
- desc: emptyWalletDesc,
- onClick: () => null,
- });
- }
- } else {
- // user latest payment using other than dompetku
- if (userDetail.dompetkuBalance >= totalPayment) {
- // sufficient balance
- setIsDompetkuEngagementShown(false);
- setDompetkuButton(undefined);
- const paymentMethod = selectedPaymentMethod[itemKey] || DEFAULT_PAYMENT;
- let paymentInfoText = paymentMethod?.payment_information_text;
- if (paymentInfoText?.substr(0, 2) === '- ') paymentInfoText = paymentInfoText.substring(2);
- setUsedPaymentMethod({ ...paymentMethod, payment_information_text: paymentInfoText });
- } else {
- // insufficient balance
- setIsDompetkuEngagementShown(true);
- setDompetkuButton(undefined);
- const paymentMethod = selectedPaymentMethod[itemKey] || latestPayment;
- let paymentInfoText = paymentMethod?.payment_information_text;
- if (paymentInfoText?.substr(0, 2) === '- ') paymentInfoText = paymentInfoText.substring(2);
- setUsedPaymentMethod({ ...paymentMethod, payment_information_text: paymentInfoText });
- }
- }
- }
- }
- }
- }, [userDetail, walletDetail, totalPayment, latestPayment, latestPaymentLoading, walletDetailLoading, itemKey]);
- // End Dompetku Error //
- // Latest Payment Error //
- const [paymentMethodError, setPaymentMethodError] = useState(false);
- const notAvailablePaymentError = useLanguage('metode_pembayaran_yang_kamu_pilih_sedang_tidak_tersedia_atau_dalam_perbaikan');
- const lessThanMinPaymentError = useLanguage('produk_yang_kamu_beli_kurang_dari_minimal_pembayaran');
- const moreThanMaxPaymentError = useLanguage('produk_yang_kamu_beli_melebihi_maksimal_pembayaran');
- useEffect(() => {
- const gameIds = currentItemsToBePaid?.items.map((item: any) => item.gameId);
- if (usedPaymentMethod) {
- const isHealthy =
- usedPaymentMethod.is_healthy ||
- usedPaymentMethod.isHealthy ||
- usedPaymentMethod.payment_method_health === null ||
- (usedPaymentMethod.payment_method_health && usedPaymentMethod.payment_method_health.health);
- const finalPremiumBuyerPrice =
- paymentSource === PAYMENT_SOURCE.CART && currentItemsToBePaid?.items && currentItemsToBePaid.items.length >= 4
- ? premiumBuyerPrice * 2
- : premiumBuyerPrice;
- const total = usedPaymentMethod.payment_denom_item?.length
- ? totalPayment + finalPremiumBuyerPrice
- : totalPayment + totalExtraCharge;
- const notSupported = arrayIntersects(gameIds || [], usedPaymentMethod?.exclude_game_id || []);
- if (
- (usedPaymentMethod.id !== DEFAULT_PAYMENT.id && !isHealthy) ||
- notSupported ||
- usedPaymentMethod.is_maintenance
- ) {
- setLatestPaymentErrorBanner(notAvailablePaymentError);
- setPaymentMethodError(true);
- } else if (usedPaymentMethod?.minimum_payment_limit !== 0 && total < usedPaymentMethod?.minimum_payment_limit) {
- setLatestPaymentErrorBanner(lessThanMinPaymentError);
- setPaymentMethodError(true);
- } else if (usedPaymentMethod?.maximum_payment_limit !== 0 && total > usedPaymentMethod?.maximum_payment_limit) {
- setLatestPaymentErrorBanner(moreThanMaxPaymentError);
- setPaymentMethodError(true);
- } else {
- setLatestPaymentErrorBanner('');
- setPaymentMethodError(false);
- }
- }
- }, [usedPaymentMethod, totalPayment, totalExtraCharge, currentItemsToBePaid]);
- // End Latest Payment Error //
- // Payment with Dompetku - Dompetku Pin //
- const [attemps, setAttemps] = useState(0);
- useEffect(() => {
- setErrorBanner(attemps > 0);
- if (usedPaymentMethod?.name === DEFAULT_PAYMENT.name && attemps > 1) {
- if (userDetail.dompetkuBalance < totalPayment) showDompetkuDialog('topup');
- }
- }, [attemps]);
- useEffect(() => {
- if (pinBottomSheet.wrongPin) {
- const timer = setTimeout(() => {
- setPinBottomSheet({ ...pinBottomSheet, wrongPin: false, pinNumber: undefined });
- setPinInteractionValue('');
- }, 1000);
- return () => clearTimeout(timer);
- }
- }, [pinBottomSheet]);
- // End Payment with Dompetku - Dompetku Pin //
- // Proceed Payment //
- const [transactionData, setTransactionData] = useState<ITransactionData>();
- const [subscriptionId, setSubscriptionId] = useState<number>();
- const { createTransaction } = TransactionHandler.useCreateTransaction();
- const { saveTransactionToStash } = TransactionHandler.useTransactionStash();
- useEffect(() => {
- if (router.query.subscription_id) {
- const subsId = parseInt(router.query.subscription_id as string);
- setSubscriptionId(!isNaN(subsId) ? subsId : undefined);
- }
- }, [router]);
- useEffect(() => {
- // populate transaction payload to be created
- if (!currentItemsToBePaid || !usedPaymentMethod || !currentItemsToBePaid.items.length) {
- return;
- }
- const cartIds: Set<number> = new Set();
- currentItemsToBePaid.items.forEach((item: any) => cartIds.add(item.cartId!));
- const paymentWalletAmount = usedPaymentMethod.name === DEFAULT_PAYMENT.name ? totalPayment + totalExtraCharge : 0;
- let payload = undefined;
- if (paymentSource === PAYMENT_SOURCE.OFFICIAL_STORE_TOPUP) {
- payload = {
- payment_method_id: usedPaymentMethod.id,
- payment_wallet_amount: paymentWalletAmount,
- product_id: currentItemsToBePaid.items[0].productId!,
- quantity: currentItemsToBePaid.items[0].totalItem!,
- price: currentItemsToBePaid.items[0].price!,
- user_information_data: currentItemsToBePaid.items[0].userInfoData,
- note: currentItemsToBePaid.items[0].notes,
- buyer_account: undefined,
- coupon_code: equippedCoupon?.code,
- pin: pinBottomSheet.pinNumber,
- server_id: currentItemsToBePaid.items[0].serverId,
- key: itemKey,
- };
- } else if (paymentSource === PAYMENT_SOURCE.OFFICIAL_STORE_VOUCHER) {
- payload = ({
- payment_method_id: usedPaymentMethod.id,
- payment_wallet_amount: paymentWalletAmount,
- product_ids: currentItemsToBePaid.items.map((item: any) => {
- return +item.productId;
- }),
- quantities: currentItemsToBePaid.items.map((item: any) => {
- return +item.totalItem;
- }),
- buyer_phone: '62' + String(voucherBuyerInfo!.phoneNumber),
- game_ids: currentItemsToBePaid.items.map((item: any) => {
- return +item.gameId;
- }),
- total_amount: totalPayment,
- buyer_account: undefined,
- pin: pinBottomSheet.pinNumber,
- coupon_code: equippedCoupon?.code,
- is_used_coin: isUsingCoin[itemKey],
- key: itemKey,
- } as ICreateVendorVoucherTransactionPayload);
- } else {
- payload = {
- is_premium: premiumOption[itemKey],
- payment_method_id: usedPaymentMethod.id,
- payment_wallet_amount: paymentWalletAmount,
- product_id: currentItemsToBePaid.items[0].productId!,
- quantity: currentItemsToBePaid.items[0].totalItem!,
- price: currentItemsToBePaid.items[0].price!,
- required_information: paymentSource !== PAYMENT_SOURCE.CART ? currentItemsToBePaid.items[0].requiredInformation : undefined,
- note: currentItemsToBePaid.items[0].notes,
- buyer_account: undefined,
- coupon_code: equippedCoupon?.code,
- pin: pinBottomSheet.pinNumber,
- cart_ids: [...cartIds],
- is_from_quickbuy: currentItemsToBePaid.items[0].fromQuickbuy,
- is_from_cheapest_product: currentItemsToBePaid.items[0].fromCheapest,
- is_used_coin: isUsingCoin[itemKey],
- is_with_subscription: paymentSource === PAYMENT_SOURCE.SUBSCRIPTION_BUY_NOW ? undefined : isSubscription,
- is_from_langganan_page: paymentSource === PAYMENT_SOURCE.SUBSCRIPTION_BUY_NOW,
- subscription_id: subscriptionId,
- key: itemKey,
- };
- }
- const transactionPayload = {
- source: paymentSource,
- payload: payload,
- };
- setTransactionData(transactionPayload);
- }, [
- paymentSource,
- currentItemsToBePaid,
- pinBottomSheet,
- premiumOption,
- usedPaymentMethod,
- userDetail,
- totalPayment,
- totalExtraCharge,
- equippedCoupon?.code,
- voucherBuyerInfo,
- isUsingCoin,
- isSubscription,
- subscriptionId,
- itemKey,
- ]);
- const gotoFinalOrderPage = (trxId: number) => {
- if (paymentSource == PAYMENT_SOURCE.OFFICIAL_STORE_VOUCHER) {
- dispatch(
- navigationObject.actions.routeNavigateTo({
- routeName: ROUTER_NAME.OFFICIAL_STORE_VOUCHER_PAYMENT_CONFIRMATION,
- params: { transaction_id: trxId },
- }),
- );
- } else if (paymentSource == PAYMENT_SOURCE.OFFICIAL_STORE_TOPUP) {
- dispatch(
- navigationObject.actions.routeNavigateTo({
- routeName: ROUTER_NAME.OFFICIAL_STORE_TOPUP_PAYMENT_CONFIRMATION,
- params: { transaction_id: trxId },
- }),
- );
- } else {
- dispatch(
- navigationObject.actions.routeNavigateReplaceTo({
- routeName: paymentConfirmationRoutes[paymentSource],
- params: { transaction_id: trxId },
- query: {
- is_premium: premiumOption[itemKey] == true ? 1 : 0,
- },
- }),
- );
- }
- };
- const handleTransactionCallback = (success: boolean, response: any) => {
- if (success) {
- // prevent clear coupon so not send double request
- if (isAlreadySuccessSendRequest.current !== success) {
- dispatch(couponObject.actions.clearUserCoupoun());
- }
- isAlreadySuccessSendRequest.current = success;
- const responseTransaction = response.data;
- if (responseTransaction.subscription) {
- dispatch(persistObject.actions.setSubscriptionStatusSuccess(responseTransaction.subscription.data.data));
- }
- if (responseTransaction.direct_payment) {
- openSandbox(
- usedPaymentMethod.name,
- responseTransaction.direct_payment?.gateway,
- responseTransaction.direct_payment?.payload,
- );
- } else {
- gotoFinalOrderPage(
- Array.isArray(responseTransaction.data) ? responseTransaction.data[0].id : responseTransaction.data.id,
- ); // removed because want to open sandbox in current tab
- }
- } else {
- // clear dompetku status when transaction fail
- if (transactionData && transactionData.payload.pin) {
- delete transactionData.payload.pin;
- setPinBottomSheet({
- ...pinBottomSheet,
- isSuccess: false,
- wrongPin: false,
- });
- setTransactionData({
- ...transactionData,
- payload: {
- ...transactionData.payload,
- },
- });
- }
- isAlreadySuccessSendRequest.current = success;
- setDialog({ ...dialog, loadPayment: false });
- }
- };
- const handleDompetkuPayment = () => {
- if (!transactionData) {
- return;
- }
- if (userDetail.dompetkuBalance < totalPayment + totalExtraCharge) {
- setAttemps(attemps + 1);
- } else {
- setTransactionData({
- ...transactionData,
- payload: {
- coupon_code: equippedCoupon?.code,
- ...transactionData.payload,
- payment_wallet_amount: totalPayment + totalExtraCharge,
- },
- });
- setPinBottomSheet({ ...pinBottomSheet, isOpen: true });
- }
- };
- useEffect(() => {
- // create dompetku transaction after pin success
- if (
- !isAlreadySuccessSendRequest.current &&
- pinBottomSheet.isSuccess &&
- !pinBottomSheet.wrongPin &&
- transactionData &&
- transactionData.payload.pin
- ) {
- setDialog({ ...dialog, loadPayment: true });
- createTransaction(transactionData, handleTransactionCallback);
- }
- }, [pinBottomSheet, transactionData]);
- const handleOvoPayment = () => {
- if (!transactionData) {
- return;
- }
- saveTransactionToStash(transactionData);
- dispatch(paymentObject.actions.setPaymentEntryUrl(router.asPath));
- dispatch(navigationObject.actions.routeNavigateTo({ routeName: paymentWithOvoRoutes[paymentSource], query: router.query }));
- };
- const handleOthersPayment = () => {
- if (!transactionData) {
- return;
- }
- if (paymentMethodError) {
- setAttemps(attemps + 1);
- return;
- }
- setDialog({ ...dialog, loadPayment: true });
- createTransaction(transactionData, handleTransactionCallback);
- };
- const doPayClickPay = () => {
- if (paymentSource === PAYMENT_SOURCE.OFFICIAL_STORE_VOUCHER) {
- voucherBuyerInfoValidation(voucherBuyerInfo);
- if (errorVoucherBuyerInfo.name || errorVoucherBuyerInfo.phoneNumber) {
- return null;
- }
- }
- if (totalPayment <= 0 || totalPayment == null || isLoading) {
- return null;
- } else if (usedPaymentMethod.id === DEFAULT_PAYMENT.id) {
- handleDompetkuPayment();
- } else if (usedPaymentMethod.name.toLowerCase() === 'ovo') {
- handleOvoPayment();
- } else {
- handleOthersPayment();
- }
- };
- // BCA VA check
- const unpaidPaymentBCAVA = useSelector((state: IReducers) => state.paymentReducers.unpaidBCAPayment);
- const transactionTypePrevBCAPayment = useSelector((state: IReducers) => state.paymentReducers.prevBCAPaymentType);
- useEffect(() => {
- if (usedPaymentMethod) {
- if (usedPaymentMethod.id === bcaPaymentMethodId) {
- dispatch(paymentObject.actions.checkBCAUnpaidPayment());
- setPaymentBCA(true);
- } else {
- setPaymentBCA(false);
- }
- }
- }, [usedPaymentMethod]);
- useEffect(() => {
- if (unpaidPaymentBCAVA) {
- if (unpaidPaymentBCAVA > 0) {
- setUnpayBCAPayment(true);
- } else {
- setUnpayBCAPayment(false);
- }
- }
- }, [unpaidPaymentBCAVA]);
- const cancelActionBCA = (transactionType: string) => {
- switch (transactionType) {
- case 'LT':
- dispatch(
- navigationObject.actions.routeNavigateTo({ routeName: ROUTER_NAME.ITEMKU_PLAY_CREDITS, query: { tab: 1 } }),
- );
- break;
- case 'TO':
- dispatch(navigationObject.actions.routeNavigateTo({ routeName: ROUTER_NAME.DOMPETKU }));
- break;
- case 'VT':
- dispatch(
- navigationObject.actions.routeNavigateTo({
- routeName: ROUTER_NAME.OFFICIAL_STORE_TRANSACTION_HISTORY,
- query: { tab: 0, chip: 1, page: 1 },
- }),
- );
- break;
- case 'DT':
- dispatch(
- navigationObject.actions.routeNavigateTo({
- routeName: ROUTER_NAME.OFFICIAL_STORE_TRANSACTION_HISTORY,
- query: { tab: 0, chip: 0, page: 1 },
- }),
- );
- break;
- default:
- dispatch(navigationObject.actions.routeNavigateTo({ routeName: ROUTER_NAME.TRANSACTION_ORDER_HISTORY }));
- }
- };
- const bcaPaymentTitleText = useLanguage('ada_transaksi_yang_belum_dibayar');
- const bcaPaymentCancelText = useLanguage('bayar_sebelumnya');
- const bcaPaymentMainText = useLanguage('lanjut_bayar');
- const bcaPaymentDescText = useLanguage('jika_melanjutkan_pembayaran_untuk_transaksi_ini_maka_transaksimu_yang_sebelumnya_akan_dibatalkan');
- const bcaVirtualAccountPaymentDialog = () => {
- dispatch(
- navigationObject.actions.modalNavigateTo(Types.Dialog, {
- type: 'multiple',
- title: bcaPaymentTitleText,
- mainActionTitle: bcaPaymentMainText,
- cancelActionTitle: bcaPaymentCancelText,
- description: (
- <p>{bcaPaymentDescText}</p>
- ),
- mainAction: () => {
- // cancel prev transaction, create new transaction
- if (transactionData) {
- transactionData.payload.cancel_previous_transaction = true;
- doPayClickPay();
- }
- },
- cancelAction: () => {
- // navigate to coresponding pending payment
- cancelActionBCA(transactionTypePrevBCAPayment ? transactionTypePrevBCAPayment : 'TR');
- },
- }),
- );
- };
- // BCA VA check end
- // show dialog when use coupon totalPayment < coupon minimum purcase
- const couponErrorTitleText = useLanguage('pesanan_kurang');
- const couponErrorCancelText = useLanguage('tambah_pesanan');
- const couponErrorMainText = useLanguage('lanjut_belanja');
- const couponErrorDescText = useLanguage('total_pesanan_kamu_belum_memenuhi_syarat_untuk_pakai_kupon_tambah_pesanan_agar_kupon_tetap_bisa_terpakai');
- const checkCartUpdates = () => {
- const cb = (data: any, sameCart?: boolean) => {
- if (!data.items?.length) {
- dispatch(
- statusObject.actions.errorSetNew({
- errorCode: ERR_TYPES.NO_CHECKOUT_ITEMS,
- errorMessage: getErrorMessage(ERR_TYPES.NO_CHECKOUT_ITEMS),
- }),
- );
- setNoItemToBePaid(true);
- } else if (sameCart == false) {
- dispatch(
- statusObject.actions.errorSetNew({
- errorCode: 'cartUpdated',
- errorMessage: 'produk_yang_akan_kamu_bayar_mengalami_perubahan_silakan_periksa_lagi_produk_pilihan_kamu',
- }),
- );
- } else {
- handleClickPay();
- }
- };
- dispatch(paymentObject.actions.requestItemsToBePaid(cb, itemKey, true));
- };
- const handleClickPay = () => {
- if (equippedCoupon) {
- const newCouponValiData: ICouponValidationData = {
- game_ids: currentItemsToBePaid?.items?.map((item: any) => item.gameId) || [],
- item_type_ids: currentItemsToBePaid?.items?.map((item: any) => item.itemTypeId),
- payment_method: usedPaymentMethod?.id,
- total_price: totalPayment,
- };
- const isPaymentValid = paymentMethodCouponValidation(equippedCoupon, newCouponValiData);
- if (!isPaymentValid.success) {
- dispatch(
- statusObject.actions.errorSetNew({
- errorCode: isPaymentValid.code,
- errorMessage: isPaymentValid.message,
- }),
- );
- } else if (equippedCoupon.minimum_purchase < totalPayment) {
- if (paymentBCA && unpayBCAPayment) {
- bcaVirtualAccountPaymentDialog();
- } else {
- doPayClickPay();
- }
- } else {
- dispatch(
- navigationObject.actions.modalNavigateTo(Types.Dialog, {
- title: couponErrorTitleText,
- mainActionTitle: couponErrorMainText,
- cancelActionTitle: couponErrorCancelText,
- description: (
- <p>
- {couponErrorDescText}
- </p>
- ),
- mainAction: () => {
- dispatch(couponObject.actions.clearUserCoupoun());
- doPayClickPay();
- },
- cancelAction: () => {
- dispatch(navigationObject.actions.routeNavigateTo({ routeName: ROUTER_NAME.HOME }));
- },
- }),
- );
- }
- } else if (paymentBCA && unpayBCAPayment) {
- bcaVirtualAccountPaymentDialog();
- } else {
- doPayClickPay();
- }
- };
- // End Proceed Payment //
- // Continue payment anyway //
- // This is for when delivery guarantee changes, but user wants to continue anyway //
- const [continuePayStart, setContinuePayStart] = useState(false);
- useEffect(() => {
- if (continuePayStart) {
- setContinuePayStart(false);
- handleClickPay();
- }
- }, [continuePayStart]);
- const handleDeliveryGuaranteeChangedContinue = () => {
- if (transactionData) {
- setTransactionData({
- source: transactionData.source,
- payload: {
- ...transactionData.payload,
- is_from_quickbuy: false,
- },
- });
- setContinuePayStart(true);
- }
- };
- // End continue payment anyway //
- // Handle Back //
- const handleBack = () => {
- dispatch(navigationObject.actions.routeGoBack());
- };
- useEffect(() => {
- if (noItemToBePaid) {
- const prevPage = new URL(location.href).searchParams.get('prev_page');
- if (prevPage) {
- router.replace(decodeURIComponent(prevPage));
- } else {
- dispatch(navigationObject.actions.routeGoBack());
- }
- }
- }, [noItemToBePaid]);
- // End Handle Back //
- const finalAmount = useMemo(() => {
- return totalPayment + totalExtraCharge - couponDiscount - (isUsingCoin[itemKey] ? coinDiscount : 0);
- }, [totalPayment, totalExtraCharge, couponDiscount, isUsingCoin, itemKey, coinDiscount]);
- const convertedFinalAmount = useMemo(() => {
- return convertedTotalPayment + convertedExtraCharge;
- }, [convertedTotalPayment, convertedExtraCharge]);
- const paymentRecapProps = () => {
- // const officialStoreItems: Payments = itemToPay.slice(0, 2).map((data: any) => {
- // return {
- // name: data.itemInfo,
- // nominal: data.price,
- // qty: data.totalItem,
- // };
- // });
- switch (paymentSource) {
- // case PAYMENT_SOURCE.OFFICIAL_STORE_TOPUP:
- case PAYMENT_SOURCE.OFFICIAL_STORE_VOUCHER:
- return {
- paymentId: selectedPaymentMethod[itemKey]?.id,
- paymentName: usedPaymentMethod?.name || '',
- totalPayment: totalPayment + totalDiscountPrice, // OS voucher base price, before Discount
- extraCharge: extraCharge,
- grandTotal: totalPayment + totalExtraCharge - couponDiscount,
- payments: [],
- discount: (totalDiscountPrice * 100) / (totalDiscountPrice + totalPayment), // Discount game
- discountCoupon: getDefault(equippedCoupon?.discount_rate, 0),
- discountPriceCoupon: couponDiscount,
- discountPrice: totalDiscountPrice,
- usedDompetkuBalance: 0,
- withPaymentInfo: false,
- };
- default:
- return {
- paymentId: selectedPaymentMethod[itemKey]?.id,
- paymentName: usedPaymentMethod?.name || '',
- totalPayment: !isGlobal ? totalPayment : convertedTotalPayment,
- extraCharge: extraCharge,
- grandTotal: !isGlobal ? finalAmount : convertedFinalAmount,
- payments: [],
- discount: getDefault(equippedCoupon?.discount_rate, 0),
- discountPrice: couponDiscount,
- usedDompetkuBalance: 0,
- withPaymentInfo: false,
- usedItemkuWorldCoin: isUsingCoin[itemKey] ? coinDiscount : 0,
- itemkuWorldCoinMaxDisc: coinData ? coinData.max_percent_discount : 0,
- };
- }
- };
- // NEW DOMPETKU ENGAGEMENT BEGIN
- const [isDompetkuEngagementShown, setIsDompetkuEngagementShown] = useState<Boolean>(false);
- const handleDompetkuEngagementButton = (dataUser: UserDetail) => {
- if (!dataUser.isEmailVerified) {
- dispatch(
- navigationObject.actions.modalNavigateTo(Types.Dialog, {
- ...dompetkuEngagementDialog.email,
- mainAction: () =>
- dispatch(navigationObject.actions.routeNavigateTo({ routeName: ROUTER_NAME.EMAIL_VERIFICATION })),
- }),
- );
- } else if (!dataUser.isPhoneVerified) {
- dispatch(
- navigationObject.actions.modalNavigateTo(Types.Dialog, {
- ...dompetkuEngagementDialog.phone,
- mainAction: () =>
- dispatch(navigationObject.actions.routeNavigateTo({ routeName: ROUTER_NAME.PHONE_VERIFICATION })),
- }),
- );
- } else if (!dataUser.hasSetupPIN) {
- dispatch(
- navigationObject.actions.modalNavigateTo(Types.Dialog, {
- ...dompetkuEngagementDialog.pin,
- mainAction: () => dispatch(navigationObject.actions.routeNavigateTo({ routeName: ROUTER_NAME.PIN_ADD })),
- }),
- );
- } else {
- showDompetkuDialog('topup-engagement');
- }
- };
- // NEW DOMPETKU ENGAGEMENT END
- // PRODUCT SUBSCRIPTION
- const [isProductSubs, setProductSubs] = useState<boolean>(false);
- const productId = currentItemsToBePaid?.items?.[0]?.productId;
- const subscriptionDetail = useSelector((state: IReducers) => state.productDetailReducers.productSubscriptionDetail);
- let expireDateSubscription = new Date();
- if (subscriptionDetail) {
- expireDateSubscription = addDays(new Date(), subscriptionDetail.subscription_day);
- }
- useEffect(() => {
- dispatch(persistObject.actions.clearSubscriptionStatus());
- }, []);
- useEffect(() => {
- if (productId) {
- dispatch(productDetailObject.actions.requestSubscriptionDetail(productId));
- }
- }, [productId]);
- useEffect(() => {
- if (paymentSource !== PAYMENT_SOURCE.QUICK_BUY
- && paymentSource !== PAYMENT_SOURCE.PRODUCT_DETAIL
- && paymentSource !== PAYMENT_SOURCE.SUBSCRIPTION_BUY_NOW) {
- setProductSubs(false);
- return;
- }
- if (subscriptionDetail == null) {
- setProductSubs(false);
- } else {
- setProductSubs(true);
- if (paymentSource === PAYMENT_SOURCE.SUBSCRIPTION_BUY_NOW) {
- setSubscription(true);
- }
- }
- }, [subscriptionDetail, paymentSource]);
- // PRODUCT SUBSCRIPTION END
- // CURRENCY
- const regionData = useSelector((state: IReducers) => state.regionReducers.regionData);
- const currency = useSelector((state: IReducers) => state.regionReducers.regionData.country_currency) || 'IDR';
- const { foreignExchangeRate, loadForeignExchangeRate } = CurrencyHandler.useForeignExchangeRate();
- React.useEffect(() => {
- loadForeignExchangeRate(currency);
- }, [currency]);
- // CURRENCY END
- const paymentError = useLanguage('terjadi_kesalahan_silakan_coba_lagi');
- const subscriptionTitle = useLanguage('langganan_produk');
- const subscriptionMessageDompetku = useLanguage('dengan_membayar_menggunakan_dompetku_pada_pembelian_ini_autodebit_dompetku_akan_otomatis_aktif_untuk_bayar_tagihan_langganan_berikutnya');
- const subscriptionMessage = useLanguage('bayar_tagihan_langganan_berikutnya_dengan_autodebit_dompetku_aktivasi_autodebit_dompetku_dapat_dilakukan_setelah_pembelian_ini_selesai');
- const paymentMethodLabel = useLanguage('metode_pembayaran');
- const viewAllLabel = useLanguage('lihat_semua');
- const lastPaymentMethodLabel = useLanguage('terakhir_dipakai');
- const suggestionPaymentMethodLabel = useLanguage('dana_yang_akan_digunakan');
- const choosePaymentMethodLabel = useLanguage('pilih_metode_pembayaran');
- const cashbackLabel = useLanguage('cashback_dompetku');
- const PaymentElement: React.ReactElement = (
- <div className='w-full max-w-600px min-h-screen pb-14'>
- <Head>
- <title>{headerTitleHelper(paymentSource)} | itemku</title>
- </Head>
- <PinBottomSheet
- show={pinBottomSheet.isOpen}
- close={() => setPinBottomSheet({ ...pinBottomSheet, isOpen: false })}
- error={pinBottomSheet.wrongPin}
- errorMsg={pinBottomSheet.errorMessage}
- handleGetPin={handleInputPin}
- forgotPIN={() =>
- requestResetPinOTP((isSuccess: boolean) => {
- if (isSuccess) router.push({ pathname: routes.pin.route + 'reset-pin' });
- else setPinBottomSheet({ ...pinBottomSheet, errorMessage: paymentError });
- })
- }
- value={pinInteractionValue}
- />
- <div className='w-full pb-14'>
- <div className='w-full sticky top-0 z-30'>
- <HeaderBack
- title={useLanguage(headerTitleHelper(paymentSource))}
- leftOnClick={() => setDialog({ ...dialog, closePayment: true })}
- />
- </div>
- {dialog.cancelPayment ? (
- <PaymentSkeleton />
- ) : (
- <>
- {paymentSource === PAYMENT_SOURCE.OFFICIAL_STORE_VOUCHER ? (
- <>
- <UserDetailInput
- value={voucherBuyerInfo}
- valueCallback={(value: any) => setVoucherBuyerInfo(value)}
- nameError={!!errorVoucherBuyerInfo.name}
- phoneNumberError={!!errorVoucherBuyerInfo.phoneNumber}
- nameErrorMsg={errorVoucherBuyerInfo.name}
- phoneNumberErrorMsg={errorVoucherBuyerInfo.phoneNumber}
- />
- <Divider variant='filled' />
- </>
- ) : null}
- <div className='w-full px-4 py-6'>
- <ShoppingRecapSection
- productItem={itemToPay as IPaidItem[]}
- paymentSource={paymentSource}
- isUsingCoin={isUsingCoin[itemKey]}
- validDiscount={validDiscount}
- coinData={coinData}
- coinDiscount={coinDiscount}
- />
- </div>
- {/* langganan produk */}
- {isGlobal && hiddenFeatureConfig[HIDDEN_FEATURE_FOR_GLOBAL.HIDE_SUBSCRIPTION] ? null : isProductSubs && paymentSource !== PAYMENT_SOURCE.SUBSCRIPTION_BUY_NOW &&
- <div>
- <Divider variant='filled' />
- <div className='p-4 space-y-4'>
- <h3 className='text-xl text-nero font-bold'>{subscriptionTitle}</h3>
- <CardProductSubscription
- checkedState={isSubscription}
- handleCheck={() => setSubscription((prev) => !prev)}
- message={usedPaymentMethod?.name === 'Dompetku'
- ? subscriptionMessageDompetku
- : subscriptionMessage}
- expiredDate={format(expireDateSubscription, 'yyyy-MM-dd hh:mm:ss')}
- subscriptionPeriod={subscriptionDetail?.subscription_day}
- />
- </div>
- </div>
- }
- <Divider variant='filled' />
- <div className='w-full px-4 py-6'>
- {latestPayment && (
- <div className='w-full flex flex-row justify-between mb-2'>
- <h3 className='text-xl text-nero font-bold'>{paymentMethodLabel}</h3>
- {Object.keys(latestPayment).length > 0 ||
- (usedPaymentMethod?.name === 'dompetku' &&
- userDetail.isEmailVerified &&
- userDetail.isPhoneVerified &&
- userDetail.hasSetupPIN) ? (
- <ButtonText label={viewAllLabel} onClick={handleGoToPaymentMethod} />
- ) : null}
- </div>
- )}
- {Object.keys(latestPayment).length > 0 && latestPayment.name === usedPaymentMethod?.name && (
- <h3 className='text-lg text-zambesi mb-3'>{lastPaymentMethodLabel}</h3>
- )}
- <CardPaymentMethod
- paymentName={usedPaymentMethod?.name || ''}
- extraChargeDesc={''} // updated reason: no longer need payment method fee text
- itemImageURL={usedPaymentMethod?.media_url}
- differentiator={usedPaymentMethod?.name === 'Dompetku' ? 'static-dompetku' : 'static-payment-method'}
- totalPayment={totalPayment + totalExtraCharge}
- walletBalance={userDetail.dompetkuBalance}
- onClick={dompetkuOnClick}
- withButton={dompetkuWithButton}
- dompetkuButtonLabel={dompetkuButtonLabel}
- paymentDisabled={false}
- paymentInformationText={usedPaymentMethod?.payment_information_text}
- withSuggestion
- suggestionDesc={suggestionPaymentMethodLabel + ' Rp' + moneyDot(finalAmount)}
- isFromPaymentPage
- isCreditCard={Boolean(usedPaymentMethod?.is_credit_card)}
- icon={usedPaymentMethod?.is_credit_card ? 'credit-card-color' : usedPaymentMethod?.icon}
- />
- {isDompetkuEngagementShown && (
- <div className='w-full mt-4'>
- <CardDompetkuEngagement
- isDompetkuActivated={
- userDetail.isEmailVerified && userDetail.isPhoneVerified && userDetail.hasSetupPIN
- }
- onButtonClick={() => handleDompetkuEngagementButton(userDetail)}
- />
- </div>
- )}
- {usedPaymentMethod?.name === 'Dompetku' &&
- dompetkuButton && ( // hide it anyway if user has sufficient balance to pay
- <div className='mt-4'>
- <Banner
- differentiator={errorBanner ? 'error' : 'alert'}
- message={dompetkuButton.desc}
- action={dompetkuButton.label}
- button={dompetkuButton.label !== ''}
- onClick={dompetkuButton.onClick}
- icon={false}
- border
- />
- </div>
- )}
- {usedPaymentMethod?.name !== 'Dompetku' && latestPaymentErrorBanner !== '' && (
- <div className='mt-4'>
- <Banner
- differentiator={errorBanner ? 'error' : 'alert'}
- message={latestPaymentErrorBanner}
- button={false}
- icon={false}
- border
- />
- </div>
- )}
- {Object.keys(latestPayment).length === 0 ||
- (usedPaymentMethod?.name === 'dompetku' &&
- !userDetail.isEmailVerified &&
- !userDetail.isPhoneVerified &&
- !userDetail.hasSetupPIN) ? (
- <div className='w-full mt-6'>
- <ButtonOutlined label={choosePaymentMethodLabel} onClick={handleGoToPaymentMethod} big full />
- </div>
- ) : null}
- </div>
- {isGlobal && hiddenFeatureConfig[HIDDEN_FEATURE_FOR_GLOBAL.HIDE_COUPON] ? null : (<>
- <Divider variant='filled' />
- <div className='w-full px-4 py-6 space-y-3'>
- <CardCoupon
- totalCoupon={totalCoupon}
- isCouponUsed={equippedCoupon !== null}
- couponName={equippedCoupon?.name}
- onClick={handleSeeCoupon}
- hasCoupon={coupons && totalCoupon !== 0}
- />
- {/* {usedPaymentMethod?.name !== 'Dompetku' && userDetail.usedCoupon.length > 0 && (
- <Banner
- differentiator={errorBanner ? 'error' : 'neutral'}
- message="Penggunaan kupon hanya dapat digunakan melalui metode pembayaran Dompetku"
- button={false}
- icon
- border
- />
- )} */}
- </div>
- </>)}
- {isGlobal && hiddenFeatureConfig[HIDDEN_FEATURE_FOR_GLOBAL.HIDE_COMMUNITY] ? null : hasItemkuWorldProduct && (
- <>
- <Divider variant='filled' />
- <ItemkuWorldCoin
- ownedCoin={ownedCoin}
- usedItemkuWorldCoin={usedItemkuWorldCoin}
- usingCoinCallback={(isUsed: boolean) => handleToggleUsingCoin(isUsed)}
- isUsingCoin={isUsingCoin[itemKey]}
- // isDisabled={ownedCoin <= 0}
- />
- </>
- )}
- <Divider variant='filled' />
- {(isGlobal && hiddenFeatureConfig[HIDDEN_FEATURE_FOR_GLOBAL.HIDE_PREMIUM]) || paymentSource === PAYMENT_SOURCE.OFFICIAL_STORE_VOUCHER ||
- paymentSource === PAYMENT_SOURCE.OFFICIAL_STORE_TOPUP ? null : (
- <>
- <div className='w-full px-4 py-6'>
- <CardPremiumOption
- disable={userData?.is_user_member}
- premiumPrice={premiumBuyerPrice}
- isChecked={premiumOption[itemKey]}
- getCheckedStatus={handleCheckPremiumOption}
- />
- </div>
- <Divider variant='filled' />
- </>
- )}
- <div className='w-full px-4 py-6 space-y-4'>
- <CardPaymentRecap {...paymentRecapProps()} />
- {/* show if any cashback */}
- {cashback ? (
- <Banner
- message={cashbackLabel + ' Rp' + moneyDot(Math.abs(cashback))}
- differentiator='dompetku-cashback'
- border
- />
- ) : null}
- </div>
- </>
- )}
- </div>
- <Dialog
- title={useLanguage('transaksi_gagal')}
- description={useLanguage('produk_yang_ingin_kamu_beli_sudah_tidak_tersedia_atau_toko_sedang_tutup')}
- isActive={dialog.failedTransaction}
- mainActionTitle={useLanguage('cari_produk_lain')}
- cancelActionTitle=''
- mainAction={() => dispatch(navigationObject.actions.routeNavigateTo({ routeName: ROUTER_NAME.PRODUCT }))}
- cancelAction={() => setDialog({ ...dialog, failedTransaction: false })}
- getChildrenActiveState={(status: boolean) => setDialog({ ...dialog, failedTransaction: status })}
- {...dialog.dialogProps}
- />
- <Dialog
- title={useLanguage('keluar_dari_halaman_pembayaran')}
- description={useLanguage('kamu_akan_keluar_dari_halaman_pembayaran_dan_membatalkan_pembelian')}
- isActive={dialog.closePayment}
- mainActionTitle={useLanguage('lanjut_bayar')}
- cancelActionTitle={useLanguage('keluar')}
- getChildrenActiveState={(isActive: boolean) => setDialog({ ...dialog, closePayment: isActive })}
- mainAction={() => setDialog({ ...dialog, closePayment: false })}
- cancelAction={handleBack}
- />
- <div className='w-full fixed bottom-0 overflow-hidden max-w-600px pt-1'>
- <StickyButtonWithText
- label={useLanguage('bayar')}
- contentTitle={useLanguage('total_pembayaran')}
- contentPrice={!isGlobal ? finalAmount : convertedFinalAmount}
- disabled={totalPayment <= 0 || totalPayment == null || isLoading}
- onClick={paymentSource == PAYMENT_SOURCE.CART ? checkCartUpdates : handleClickPay}
- />
- </div>
- </div>
- );
- const waitPaymentText = useLanguage('segera_selesaikan_pembayaranmu_menggunakan_metode_pembayaran_yang_kamu_pilih');
- // begin loading
- useEffect(() => {
- if (dialog.loadPayment) {
- dispatch(
- loadingComponentObject.actions.triggerLoading({
- type: 'payment-as-page',
- paymentWording: waitPaymentText,
- }),
- );
- } else {
- dispatch(loadingComponentObject.actions.resetLoading());
- }
- }, [dialog]);
- // end loading
- /**
- * Note:
- * Not wrapping with CheckLogin because it will cause infinite loading.
- */
- const isLogin = useLogin();
- const headerTitle = useLanguage('pembayaran');
- return !isLogin ? null : (
- <TransactionBoundary
- transactionData={transactionData}
- handleTransactionCallback={handleTransactionCallback}
- onDeliveryGuaranteeChangedContinue={handleDeliveryGuaranteeChangedContinue}>
- {isLoading ? (
- <>
- <div className='w-full sticky top-0 z-30'>
- <HeaderBack title={headerTitle} />
- </div>
- <PaymentSkeleton />
- </>
- ) : (
- PaymentElement
- )}
- </TransactionBoundary>
- );
- };
- export default PaymentTemplate;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement