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' const KEY = 'FIXME-KEY-HERE' /* * 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', authorization: `Bearer ${KEY}`, }, body, }) } export const Payment = ({ amount = 25, 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 () => { const stripeClient = await loadStripe(KEY) const result = await createPaymentIntent({ amount, currency }) const json = await result.json() setStripe(stripeClient) setIntent(json) } getPaymentIntent() }, []) return intent ? (
) : ( <>

One moment please...

{JSON.stringify(options, null, 2)}
) } //
{JSON.stringify(options, null ,2)}
//
{JSON.stringify(intent, null ,2)}