1
0
Fork 0
freesewing/sites/shared/components/patrons/payment.mjs

81 lines
2.4 KiB
JavaScript
Raw Normal View History

2023-07-30 18:52:32 +02:00
import { stripeConfig } from 'shared/config/stripe.mjs'
import { useEffect, useState } from 'react'
import { useTheme } from 'shared/hooks/use-theme.mjs'
import { Elements, PaymentElement } from '@stripe/react-stripe-js'
import { loadStripe } from '@stripe/stripe-js'
/*
* The stripe API docs will emphasize to always handle this server-side because
* doing this client-side allows nefarious users to modify the payment amount.
* Which is great advice, but FreeSewing uses a pay-whatever-you-want model so
* if people want to muck about with JS to change the amount rather than change
* it in the input field for the amount, let them.
*
* This is also why we need to use fetch and talk to the API directly, because
* the stripe client-side SDK does not include this functionality.
*/
const createPaymentIntent = async ({ amount, currency }) => {
const body = new URLSearchParams()
body.append('amount', amount)
body.append('currency', currency)
return await fetch('https://api.stripe.com/v1/payment_intents', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
2023-07-30 18:52:32 +02:00
authorization: `Bearer ${stripeConfig.apiKey}`,
},
body,
})
}
2023-07-30 18:52:32 +02:00
export const Payment = ({ amount = 2500, currency = 'eur' }) => {
const appearance = useTheme().stripe
const [stripe, setStripe] = useState(false)
const [intent, setIntent] = useState(false)
const options = intent
? {
mode: 'payment',
layout: {
type: 'accordion',
radios: true,
spacedAccordianItems: true,
},
business: {
name: 'FreeSewing',
},
amount,
currency,
appearance,
}
: null
useEffect(() => {
const getPaymentIntent = async () => {
2023-07-30 18:52:32 +02:00
const stripeClient = await loadStripe(stripeConfig.apiKey)
const result = await createPaymentIntent({ amount, currency })
const json = await result.json()
setStripe(stripeClient)
setIntent(json)
}
getPaymentIntent()
}, [])
return intent ? (
<Elements stripe={stripe} options={options} layout="accordion">
<form>
<PaymentElement options={options} />
2023-07-30 18:52:32 +02:00
<pre>{JSON.stringify(intent, null, 2)}</pre>
</form>
</Elements>
) : (
<>
<p>One moment please...</p>
<pre>{JSON.stringify(options, null, 2)}</pre>
</>
)
}
//<pre>{JSON.stringify(options, null ,2)}</pre>
//<pre>{JSON.stringify(intent, null ,2)}</pre>