56 lines
2.0 KiB
TypeScript
56 lines
2.0 KiB
TypeScript
import { useCallback, useEffect, useId } from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import { useNavigate } from 'react-router-dom'
|
|
import { PaymentIntent } from '@chargebee/chargebee-js-types'
|
|
import { useApi, useApiCall } from '../../../../api'
|
|
import { usePayment, ApplePayButtonOptions } from '../../../../payment'
|
|
import { useAuth } from '../../../../auth'
|
|
import Loader from '../../../Loader'
|
|
import ErrorText from '../../../ErrorText'
|
|
import routes from '../../../../routes'
|
|
|
|
const currencyCode = 'USD'
|
|
const paymentMethod = 'apple_pay'
|
|
|
|
export function ApplePayButton(): JSX.Element {
|
|
const api = useApi()
|
|
const navigate = useNavigate()
|
|
const buttonId = useId()
|
|
const { i18n } = useTranslation()
|
|
const { token } = useAuth()
|
|
const { applePay } = usePayment()
|
|
const loadData = useCallback(() => {
|
|
return api.createPaymentIntent({ token, paymentMethod, currencyCode })
|
|
.then(({ payment_intent }) => payment_intent)
|
|
}, [api, token])
|
|
const { data, error, isPending } = useApiCall<PaymentIntent>(loadData)
|
|
|
|
if (error) console.error(error)
|
|
|
|
useEffect(() => {
|
|
if (data === null) return
|
|
const buttonOptions: ApplePayButtonOptions = {
|
|
buttonColor: 'black',
|
|
buttonType: 'pay',
|
|
locale: i18n.language
|
|
}
|
|
applePay?.setPaymentIntent(data)
|
|
applePay?.mountPaymentButton(`#${buttonId}`, buttonOptions)
|
|
.then(() => applePay?.handlePayment())
|
|
.then((paymentIntent) => {
|
|
console.log('Success payment by ApplePay', paymentIntent)
|
|
return api.createSubscriptionReceipt({
|
|
token, receiptData: paymentIntent.id, autorenewable: true, sandbox: true,
|
|
})
|
|
})
|
|
.then(() => navigate(routes.client.wallpaper()))
|
|
.catch(console.error)
|
|
}, [data, applePay, buttonId, navigate, i18n.language, api, token])
|
|
|
|
return isPending ? <Loader /> : (
|
|
<div id={buttonId} style={{ height: 60 }}>{
|
|
error ? <ErrorText message={error.message} isShown={true} size='large'/> : null
|
|
}</div>
|
|
)
|
|
}
|