#thallescomh_code

1 messages ยท Page 1 of 1 (latest)

wide notchBOT
#

๐Ÿ‘‹ Welcome to your new thread!

โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

๐Ÿ”— This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1319403689626042419

๐Ÿ“ Have more to share? Add more details, code, screenshots, videos, etc. below.

junior socket
#

sorry, messed up the code part, here it is:

export function FillPayment(props: FillPaymentProps) {
 const { theme } = useTheme()

 const appearance =
   theme === 'dark'
     ? {
         variables: {
           colorBackground: '#000',
           colorText: '#fff',
         },
       }
     : undefined

 return (
   <Elements
     options={{
       mode: props.mode,
       amount: props.mode === 'payment' ? props.amount : undefined,
       currency: props.currency,
       paymentMethodTypes: ['card'],
       appearance,
     }}
     stripe={stripePromise}
   >
     {props.children}
   </Elements>
 )
}
quaint echoBOT
broken zephyr
#

Hi ๐Ÿ‘‹ I'm not too familiar with the Next framework, so I may need more context on what is going wrong.

I see the Payment Element is rendering, so am I correct in understanding that the problem is encountered when the code for your Save Payment Method button is run?

junior socket
#

yep! you can see the full code in here:

'use client'

type SetupMode = {
  mode: 'setup'
}

type PaymentMode = {
  mode: 'payment'
  amount: number
}

type BaseProps = {
  children: React.ReactNode
  currency: string
}

type FillPaymentProps = BaseProps & (SetupMode | PaymentMode)

const stripePromise = loadStripe(env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!)

export function FillPayment(props: FillPaymentProps) {
  const { theme } = useTheme()

  const appearance =
    theme === 'dark'
      ? {
          variables: {
            colorBackground: '#000',
            colorText: '#fff',
          },
        }
      : undefined

  return (
    <Elements
      options={{
        mode: props.mode,
        amount: props.mode === 'payment' ? props.amount : undefined,
        currency: props.currency,
        paymentMethodTypes: ['card'],
        appearance,
      }}
      stripe={stripePromise}
    >
      {props.children}
    </Elements>
  )
}

export type FillPaymentFormProps = {
  children: React.ReactNode
  className?: string
  onReady: () => void
  handleSubmit: ({
    confirm,
  }: {
    confirm: ({
      clientSecret,
    }: {
      clientSecret: string
    }) => Promise<SetupIntent>
  }) => void
}

export function FillPaymentForm({
  handleSubmit,
  onReady,
  className,
  children,
}: FillPaymentFormProps) {
  const stripe = useStripe()
  const elements = useElements()

  const submit = useCallback(
    async (e: React.FormEvent<HTMLFormElement>) => {
      e.preventDefault()
      // stripe and elements will be null when submitting
      if (!stripe || !elements) return

      await elements.submit()

      handleSubmit({
        confirm: async ({ clientSecret }) => {
          try {
            const { error, setupIntent } = await stripe.confirmSetup({
              clientSecret,
              elements,
              redirect: 'if_required',
            })

            if (error) throw error

            return setupIntent
          } catch (error) {
            if (
              typeof error === 'object' &&
              error &&
              'message' in error &&
              typeof error.message === 'string'
            )
              throw new Error(error.message)

            throw new Error(
              'Unable to confirm your payment method. Try again later or another payment method.',
            )
          }
        },
      })
    },
    [handleSubmit],
  )

  return (
    <form onSubmit={submit} className={cn('space-y-4', className)}>
      <PaymentElement onReady={onReady} />
      {children}
    </form>
  )
}
#

I really don't know why the useStripe and useElements are being null, I'm calling the loadStripe function correctly

broken zephyr
#

Do they still need to be imported the way they do when working in React? Are the imports elsewhere in your code if so?

junior socket
#

and no, they're in the same file

#

even tho I tried to move it elsewhere to see if it worked but no success

broken zephyr
#

I'm taking a look through the sample code on this page to see if anything jumps out at me about what could be going wrong here.

junior socket
#

okay! thanks for the help ๐Ÿ˜ƒ

broken zephyr
#

Having a teammate take a look since I'm not too familiar with this environment.

blissful marten
#

Hello, still looking in to this. Do any errors appear in your console when you call useStripe or useElements?

#

Also if you haven't already, can you try rendering the payment element outside of that dialog?