Fix stripe. Remove fetching prices in getServerSideProps
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import {useState} from 'react'
|
||||
import {useState, useEffect} from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import {
|
||||
PaymentElement,
|
||||
@@ -9,11 +9,11 @@ import {Button, Container, LinearProgress, Paper} from '@mui/material'
|
||||
|
||||
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3001'
|
||||
|
||||
export default function CheckoutForm({prices, validMontant, setError, isLoading, setIsLoading}) {
|
||||
export default function CheckoutForm({validMontant, setError, isLoading, setIsLoading}) {
|
||||
const stripe = useStripe()
|
||||
const elements = useElements()
|
||||
const [isPaymentLoading, setIsPaymentLoading] = useState(false)
|
||||
const amount = prices.find(({id}) => id === validMontant).unit_amount
|
||||
const [prices, setPrices] = useState([])
|
||||
|
||||
const handleSubmit = async event => {
|
||||
event.preventDefault()
|
||||
@@ -44,13 +44,27 @@ export default function CheckoutForm({prices, validMontant, setError, isLoading,
|
||||
setIsLoading(false)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const fetchPrices = async () => {
|
||||
try {
|
||||
const response = await fetch(`${SITE_URL}/stripe/dons-list`)
|
||||
const pricesList = await response.json()
|
||||
setPrices(pricesList)
|
||||
} catch (error) {
|
||||
console.error('error', error)
|
||||
}
|
||||
}
|
||||
|
||||
fetchPrices()
|
||||
}, [prices])
|
||||
|
||||
return (
|
||||
<Container maxWidth='sm' sx={{marginBottom: 1}}>
|
||||
<Paper sx={{padding: 2, marginTop: 3}}>
|
||||
<PaymentElement id='payment-element' onReady={handleReady} />
|
||||
{!isLoading && (
|
||||
<Button fullWidth sx={{marginTop: 2}} variant='outlined' disabled={isPaymentLoading || !stripe || !elements} id='submit' onClick={handleSubmit}>
|
||||
Valider le don de <strong>{amount / 100} euros</strong>
|
||||
Valider le don de <strong>{prices.find(({id}) => id === validMontant).unit_amount / 100} euros</strong>
|
||||
</Button>
|
||||
)}
|
||||
{isPaymentLoading && (
|
||||
@@ -63,7 +77,6 @@ export default function CheckoutForm({prices, validMontant, setError, isLoading,
|
||||
|
||||
CheckoutForm.propTypes = {
|
||||
validMontant: PropTypes.string.isRequired,
|
||||
prices: PropTypes.array.isRequired,
|
||||
setError: PropTypes.func.isRequired,
|
||||
isLoading: PropTypes.bool.isRequired,
|
||||
setIsLoading: PropTypes.func.isRequired
|
||||
|
||||
@@ -1,14 +1,33 @@
|
||||
import {useState, useEffect} from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import ToggleButton from '@mui/material/ToggleButton'
|
||||
import ToggleButtonGroup from '@mui/material/ToggleButtonGroup'
|
||||
import Typography from '@mui/material/Typography'
|
||||
import {Box} from '@mui/material'
|
||||
import CircularProgress from '@mui/material/CircularProgress'
|
||||
|
||||
export default function Montant({selectedMontant, setSelectedMontant, validMontant, prices}) {
|
||||
const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3001'
|
||||
|
||||
export default function Montant({selectedMontant, setSelectedMontant, validMontant}) {
|
||||
const [prices, setPrices] = useState(null)
|
||||
const handleChange = (event, newMontant) => {
|
||||
setSelectedMontant(newMontant)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const fetchPrices = async () => {
|
||||
try {
|
||||
const response = await fetch(`${SITE_URL}/stripe/dons-list`)
|
||||
const pricesList = await response.json()
|
||||
setPrices(pricesList)
|
||||
} catch (error) {
|
||||
console.error('error', error)
|
||||
}
|
||||
}
|
||||
|
||||
fetchPrices()
|
||||
}, [prices])
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Typography marginTop={1} variant='button' component='div'>
|
||||
@@ -22,7 +41,11 @@ export default function Montant({selectedMontant, setSelectedMontant, validMonta
|
||||
value={selectedMontant}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{prices.map(r => (
|
||||
{!prices && (
|
||||
<CircularProgress color='primary' size={20} />
|
||||
)}
|
||||
|
||||
{prices && prices.map(r => (
|
||||
<ToggleButton key={r.id} value={r.id}>{r.unit_amount / 100} €</ToggleButton>
|
||||
))}
|
||||
|
||||
@@ -39,6 +62,5 @@ Montant.defaultProps = {
|
||||
Montant.propTypes = {
|
||||
selectedMontant: PropTypes.string,
|
||||
setSelectedMontant: PropTypes.func.isRequired,
|
||||
validMontant: PropTypes.string,
|
||||
prices: PropTypes.array.isRequired
|
||||
validMontant: PropTypes.string
|
||||
}
|
||||
|
||||
@@ -15,10 +15,7 @@ import {appearance} from '../../lib/utils/stripe-style'
|
||||
import CheckoutForm from './checkout-form'
|
||||
import StripeDialog from './stripe-dialog'
|
||||
|
||||
const stripePromise = loadStripe(
|
||||
process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY
|
||||
)
|
||||
|
||||
const STRIPE_PUBLIC_KEY = process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY
|
||||
const PAYPAL_ID = process.env.NEXT_PUBLIC_PAYPAL_DONATE_ID
|
||||
const LIBERAPAY_DONATE = process.env.NEXT_PUBLIC_LIBERAPAY_DONATE
|
||||
|
||||
@@ -55,7 +52,7 @@ function a11yProps(index) {
|
||||
}
|
||||
}
|
||||
|
||||
export default function PaymentMethod({isLoading, paymentMethod, setPaymentMethod, selectedMontant, setSelectedMontant, validMontant, setValidMontant, prices, paymentIntent, setClientSecret, setPaymentIntent, setIsLoading, setClientEmail, clientEmail, error, setError, clientSecret}) {
|
||||
export default function PaymentMethod({isLoading, paymentMethod, setPaymentMethod, selectedMontant, setSelectedMontant, validMontant, setValidMontant, paymentIntent, setClientSecret, setPaymentIntent, setIsLoading, setClientEmail, clientEmail, error, setError, clientSecret}) {
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
const options = {
|
||||
@@ -114,7 +111,6 @@ export default function PaymentMethod({isLoading, paymentMethod, setPaymentMetho
|
||||
setSelectedMontant={setSelectedMontant}
|
||||
validMontant={validMontant}
|
||||
setValidMontant={setValidMontant}
|
||||
prices={prices}
|
||||
paymentIntent={paymentIntent}
|
||||
setClientSecret={setClientSecret}
|
||||
setPaymentIntent={setPaymentIntent}
|
||||
@@ -126,9 +122,8 @@ export default function PaymentMethod({isLoading, paymentMethod, setPaymentMetho
|
||||
isLoading={isLoading}
|
||||
>
|
||||
{clientSecret && validMontant && paymentMethod === 2 && (
|
||||
<Elements options={options} stripe={stripePromise}>
|
||||
<Elements options={options} stripe={loadStripe(STRIPE_PUBLIC_KEY)}>
|
||||
<CheckoutForm
|
||||
prices={prices}
|
||||
validMontant={validMontant}
|
||||
setError={setError}
|
||||
isLoading={isLoading}
|
||||
@@ -159,7 +154,6 @@ PaymentMethod.propTypes = {
|
||||
setSelectedMontant: PropTypes.func.isRequired,
|
||||
validMontant: PropTypes.string,
|
||||
setValidMontant: PropTypes.func.isRequired,
|
||||
prices: PropTypes.array.isRequired,
|
||||
paymentIntent: PropTypes.string,
|
||||
setClientSecret: PropTypes.func.isRequired,
|
||||
setPaymentIntent: PropTypes.func.isRequired,
|
||||
|
||||
@@ -14,7 +14,6 @@ export default function StripeDialog({
|
||||
setSelectedMontant,
|
||||
validMontant,
|
||||
setValidMontant,
|
||||
prices,
|
||||
paymentIntent,
|
||||
setClientSecret,
|
||||
setPaymentIntent,
|
||||
@@ -46,7 +45,6 @@ export default function StripeDialog({
|
||||
setSelectedMontant={setSelectedMontant}
|
||||
validMontant={validMontant}
|
||||
setValidMontant={setValidMontant}
|
||||
prices={prices}
|
||||
paymentIntent={paymentIntent}
|
||||
setClientSecret={setClientSecret}
|
||||
setPaymentIntent={setPaymentIntent}
|
||||
@@ -56,6 +54,7 @@ export default function StripeDialog({
|
||||
error={error}
|
||||
setError={setError}
|
||||
isLoading={isLoading}
|
||||
handleClose={handleClose}
|
||||
/>
|
||||
{children}
|
||||
</DialogContent>
|
||||
@@ -81,7 +80,6 @@ StripeDialog.propTypes = {
|
||||
setSelectedMontant: PropTypes.func.isRequired,
|
||||
validMontant: PropTypes.string,
|
||||
setValidMontant: PropTypes.func.isRequired,
|
||||
prices: PropTypes.array.isRequired,
|
||||
paymentIntent: PropTypes.string,
|
||||
setClientSecret: PropTypes.func.isRequired,
|
||||
setPaymentIntent: PropTypes.func.isRequired,
|
||||
|
||||
@@ -12,7 +12,7 @@ import {validateEmail} from '../../lib/utils/emails'
|
||||
import Email from './email'
|
||||
import Montant from './montant'
|
||||
|
||||
export default function StripePayment({isLoading, selectedMontant, setSelectedMontant, validMontant, setValidMontant, prices, paymentIntent, setClientSecret, setPaymentIntent, setIsLoading, setClientEmail, clientEmail, error, setError}) {
|
||||
export default function StripePayment({isLoading, selectedMontant, setSelectedMontant, validMontant, setValidMontant, paymentIntent, setClientSecret, setPaymentIntent, setIsLoading, setClientEmail, clientEmail, error, setError, handleClose}) {
|
||||
const cancelPayment = async () => {
|
||||
setClientEmail('')
|
||||
setIsLoading(false)
|
||||
@@ -29,9 +29,14 @@ export default function StripePayment({isLoading, selectedMontant, setSelectedMo
|
||||
}
|
||||
|
||||
const handleCancel = async () => {
|
||||
if (validMontant) {
|
||||
setValidMontant(null)
|
||||
setSelectedMontant(null)
|
||||
await cancelPayment()
|
||||
handleClose()
|
||||
} else {
|
||||
handleClose()
|
||||
}
|
||||
}
|
||||
|
||||
const handleClick = () => {
|
||||
@@ -59,7 +64,6 @@ export default function StripePayment({isLoading, selectedMontant, setSelectedMo
|
||||
setSelectedMontant={setSelectedMontant}
|
||||
validMontant={validMontant}
|
||||
setValidMontant={setValidMontant}
|
||||
prices={prices}
|
||||
paymentIntent={paymentIntent}
|
||||
setClientSecret={setClientSecret}
|
||||
setPaymentIntent={setPaymentIntent}
|
||||
@@ -71,11 +75,10 @@ export default function StripePayment({isLoading, selectedMontant, setSelectedMo
|
||||
<Button disabled={Boolean(validMontant) || Boolean(!selectedMontant)} variant='contained' onClick={handleClick}>
|
||||
Valider les informations
|
||||
</Button>
|
||||
{validMontant && (
|
||||
<Button disabled={Boolean(!validMontant)} color='secondary' variant='contained' onClick={handleCancel}>
|
||||
|
||||
<Button color='secondary' variant='contained' onClick={handleCancel}>
|
||||
Annuler
|
||||
</Button>
|
||||
)}
|
||||
</Stack>
|
||||
</>
|
||||
{isLoading && (
|
||||
@@ -102,7 +105,6 @@ StripePayment.propTypes = {
|
||||
setSelectedMontant: PropTypes.func.isRequired,
|
||||
validMontant: PropTypes.string,
|
||||
setValidMontant: PropTypes.func.isRequired,
|
||||
prices: PropTypes.array.isRequired,
|
||||
paymentIntent: PropTypes.string,
|
||||
setClientSecret: PropTypes.func.isRequired,
|
||||
setPaymentIntent: PropTypes.func.isRequired,
|
||||
@@ -110,5 +112,6 @@ StripePayment.propTypes = {
|
||||
setClientEmail: PropTypes.func.isRequired,
|
||||
clientEmail: PropTypes.string,
|
||||
error: PropTypes.string,
|
||||
setError: PropTypes.func.isRequired
|
||||
setError: PropTypes.func.isRequired,
|
||||
handleClose: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
+3
-7
@@ -16,7 +16,7 @@ const Alert = forwardRef(function Alert(props, ref) {
|
||||
return <MuiAlert ref={ref} elevation={6} variant='filled' {...props} />
|
||||
})
|
||||
|
||||
export default function Soutyen({prices, paymentStatus}) {
|
||||
export default function Soutyen({paymentStatus}) {
|
||||
const router = useRouter()
|
||||
const scrollEvent = useRef(null)
|
||||
const [clientSecret, setClientSecret] = useState(null)
|
||||
@@ -60,7 +60,7 @@ export default function Soutyen({prices, paymentStatus}) {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (paymentMethod !== 0) {
|
||||
if (paymentMethod !== 2) {
|
||||
setClientEmail('')
|
||||
setClientSecret(null)
|
||||
setSelectedMontant(null)
|
||||
@@ -124,7 +124,7 @@ export default function Soutyen({prices, paymentStatus}) {
|
||||
>
|
||||
<Box sx={{display: 'flex', flexDirection: 'column', minHeight: '100vh'}}>
|
||||
<Box sx={{flexGrow: 1, marginTop: 1, marginBottom: 10}}>
|
||||
<Container sx={{marginTop: 1}}>
|
||||
<Container sx={{marginTop: 3}}>
|
||||
<Typography gutterBottom sx={{fontWeight: 'bold'}} textAlign='center' variant='h4' component='h1'>
|
||||
Soutenir Organisation KA Internationale !
|
||||
</Typography>
|
||||
@@ -138,7 +138,6 @@ export default function Soutyen({prices, paymentStatus}) {
|
||||
setSelectedMontant={setSelectedMontant}
|
||||
validMontant={validMontant}
|
||||
setValidMontant={setValidMontant}
|
||||
prices={prices}
|
||||
isLoading={isLoading}
|
||||
paymentIntent={paymentIntent}
|
||||
clientSecret={clientSecret}
|
||||
@@ -173,13 +172,11 @@ Soutyen.defaultProps = {
|
||||
}
|
||||
|
||||
Soutyen.propTypes = {
|
||||
prices: PropTypes.array.isRequired,
|
||||
paymentStatus: PropTypes.string
|
||||
}
|
||||
|
||||
export async function getServerSideProps({query}) {
|
||||
const {payment_intent, payment_intent_client_secret} = query
|
||||
const prices = await fetch(`${SITE_URL}/stripe/dons-list`)
|
||||
let payment
|
||||
if (payment_intent && payment_intent_client_secret) {
|
||||
const paymentResponse = await fetch(`${SITE_URL}/stripe/check-payment`, {
|
||||
@@ -198,7 +195,6 @@ export async function getServerSideProps({query}) {
|
||||
|
||||
return {
|
||||
props: {
|
||||
prices: await prices.json(),
|
||||
paymentStatus: payment?.status || null
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user