You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
spa_instat_tv/src/features/BuyMatchPopup/components/IframePayment/hooks.tsx

243 lines
6.1 KiB

/* eslint-disable no-console */
import {
MouseEvent,
useCallback,
useEffect,
useMemo,
useState,
} from 'react'
// import { useQuery } from 'react-query'
import isNumber from 'lodash/isNumber'
import {
PAGES,
ProfileTypes,
// querieKeys,
} from 'config'
import { ClientNames } from 'config/clients/types'
import { payments, PaymentSystem } from 'config/payments'
import { useLexicsStore } from 'features/LexicsStore'
import { useBuyMatchPopupStore } from 'features/BuyMatchPopup/store'
import { getProfileUrl } from 'features/ProfileLink/helpers'
import { SubscriptionType } from 'features/BuyMatchPopup/types'
import {
getPaymentOTTUrl,
getPaymentPayUrl,
getMatchInfo,
SubscriptionAction,
} from 'requests'
import { redirectToUrl } from 'helpers'
import type { Props } from './index'
type ResponsePayment = {
url: string,
}
type ResponsePaymentArray = ResponsePayment | null
export const useIframePayment = ({
match,
open,
paymentSystem,
selectedPackage,
setIsOpenIframe,
}: Props) => {
const { close } = useBuyMatchPopupStore()
const [src, setSrc] = useState('')
const [error, setError] = useState('')
const [isPaymentProcessing, setIsPaymentProcessing] = useState(false)
const { translate } = useLexicsStore()
const { id, sportType } = match
const {
name,
nameLexic,
originalObject,
pass,
type,
} = selectedPackage
const teams = isNumber(nameLexic) ? translate(String(nameLexic)) : name
const pack = translate(String(pass))
const matchLink = getProfileUrl({
id,
profileType: ProfileTypes.MATCHES,
sportType,
})
const defaultAction: SubscriptionAction = useMemo(() => {
if (type === SubscriptionType.Month) {
return SubscriptionAction.CreateSubscription
}
return SubscriptionAction.OnePayment
}, [type])
const closePopup = useCallback(async (e?: MouseEvent) => {
e?.stopPropagation()
if (error) {
setIsOpenIframe(false)
setError('')
}
const accessMatch = await getMatchInfo(sportType, id)
if (accessMatch?.access) {
setIsPaymentProcessing(false)
setIsOpenIframe(false)
setError('')
close()
redirectToUrl(matchLink)
}
}, [close, error, id, matchLink, setIsOpenIframe, sportType])
const paymentRequestOTT = async () => {
let url_cancel
let url_return
let action: SubscriptionAction
switch (paymentSystem) {
case PaymentSystem.Paymee:
url_cancel = `${window.origin}${PAGES.failedPaymee}`
url_return = null
// paymee не умеет работать с подписками
action = SubscriptionAction.OnePayment
break
default:
url_return = `${window.location.origin}${PAGES.thanksForSubscribe}`
action = defaultAction
break
}
const payment: ResponsePaymentArray = await getPaymentOTTUrl({
action,
item: originalObject,
product_name: `${pack} ${teams}`,
service: paymentSystem,
url_cancel,
url_return,
})
setSrc(payment?.url || '')
}
// новое апи для оплаты, в будущем все платежки переедут на него
// временно делаем оплату на новой вкладке, а не через iframe
const paymentRequestPay = async () => {
const payment = await getPaymentPayUrl({
item: {
...originalObject,
},
// url_return: `${window.location.origin}${PAGES.thanksForSubscribe}`,
url_return: `${window.location.origin}${matchLink}`,
})
// setSrc(payment?.url || '')
redirectToUrl(payment.url)
}
if (paymentSystem === payments.brasil
|| paymentSystem === payments.india) {
// eslint-disable-next-line
window.onmessage = function (event) {
if (event.data === 'close') {
closePopup()
}
}
}
// отслеживание оплаты для Paymee
useEffect(() => {
let interval: ReturnType<typeof setInterval>
let timeout: ReturnType<typeof setTimeout>
const paymentCallback = (event: MessageEvent<{ event_id: string }>) => {
if (event.data.event_id === 'paymee.complete') {
setIsPaymentProcessing(true)
interval = setInterval(() => closePopup(), 2000)
timeout = setTimeout(() => {
clearInterval(interval)
setIsPaymentProcessing(false)
setError('failed_paymee')
setSrc('')
}, 60000)
}
}
if (paymentSystem === payments[ClientNames.Tunisia]) {
window.addEventListener(
'message',
paymentCallback,
false,
)
}
return () => {
window.removeEventListener(
'message',
paymentCallback,
false,
)
clearInterval(interval)
clearTimeout(timeout)
}
}, [closePopup, paymentSystem])
// временное решение для отслеживания доступа к матчу
// для платежки PhonePe
// const { data: matchAccess } = useQuery({
// queryFn: async () => {
// if (paymentSystem === PaymentSystem.PhonePe) {
// const matchInfo = await getMatchInfo(sportType, id)
// return matchInfo?.access
// }
// return false
// },
// queryKey: querieKeys.getMatchInfo,
// refetchInterval: 5000,
// })
// console.log('access', matchAccess)
// useEffect(() => {
// if (matchAccess) {
// setIsPaymentProcessing(false)
// setIsOpenIframe(false)
// setError('')
// close()
// redirectToUrl(matchLink)
// }
// }, [matchAccess, close, matchLink, setIsOpenIframe])
useEffect(() => {
if (open) {
(async () => {
try {
switch (paymentSystem) {
case PaymentSystem.PhonePe:
await paymentRequestPay()
break
default:
await paymentRequestOTT()
break
}
} catch (err) {
setError('error_payment_unsuccessful')
}
})()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedPackage, open])
return {
closePopup,
error,
isPaymentProcessing,
matchLink,
src,
}
}