#kidde_code

1 messages ¡ Page 1 of 1 (latest)

glossy stumpBOT
#

👋 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/1217434991051538492

📝 Have more to share? Add more details, code, screenshots, videos, etc. below.

humble cairnBOT
ember laurel
#

I'm guessing your elements variable is falsy

#

Probably need to look into debugging why!

livid gate
#

That's the part i can't figure out. The elements are not rendered on initial visit, but when i reload the page, they appear. I tried using the onLoadError event handler, but for some reason, that isnt triggered

ember laurel
#

You'll need to share your full code, including your <Elements> provider

livid gate
#

This is the component with the Elements provider:

import React from "react";
import { useState, useEffect } from "react";
import { loadStripe } from "@stripe/stripe-js";
import { Elements } from "@stripe/react-stripe-js";
import {
CheckoutForm,
Invoice,
Coupon,
useClientSecretStore,
useInvoiceStore
} from "@/features/stripe";
import { AnimatePresence, motion } from "framer-motion";

const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY, { locale: 'en' });

export function CheckoutPlan() {
const { clientSecret } = useClientSecretStore();
const { invoice } = useInvoiceStore();

const appearance = {
theme: 'stripe',
variables: {
colorPrimary: '#0C97FA',
colorText: '#183553',
}
}
const options = {
clientSecret,
appearance,
}
function generateRandomString(length) {
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const charactersLength = characters.length;
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
const [uniqueKey, setUniqueKey] = useState(null);
useEffect(() => {
if (!clientSecret) return;
setUniqueKey(clientSecret + generateRandomString(10));
}, [clientSecret])

return (
<motion.div
key={uniqueKey}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: 20 }}
transition={{ duration: 0.5 }}
className="w-full inline-flex flex-col-reverse gap-2 pb-10 justify-around items-center xl:gap-2 xl:items-start xl:flex-row xl:mt-10">
{clientSecret && stripePromise && (
<Elements options={options} stripe={stripePromise}>
<CheckoutForm />
<div className="flex flex-col gap-4">
<Invoice />
<Coupon marginBottom="20px" />
</div>
</Elements>
)}
</motion.div>
)
}

#

And the CheckoutForm component looks like this (I havent included all the code, since im certain that this isnt where the error comes from):

return (
<>
<Toaster />
<form id="payment-form" onSubmit={handleSubmit} className="flex flex-col gap-4 w-96 h-full">
<PaymentElement id="payment-element" options={paymentElementOptions} />
<div>
<div className="flex items-center gap-3">
<input type="checkbox" id="terms" className="h-[20px] w-[20px] text-gray-500"
onChange={() => {
setIsChecked(!isChecked)
setTermError(false);
}} />
<label htmlFor="terms" className="text-sm">
I agree to the <Link href="https://cernel.ai/en/terms-of-use" target="_blank" className="text-lightBluePrimary">terms and conditions</Link> and the
<a href="https://cernel.ai/softwarelicensaftale" target="_blank" className="text-lightBluePrimary"> softwarelicenseagreement</a>
</label>
</div>
{termError && (
<p className="text-sm text-red-500">Please agree to the terms and conditions</p>
)}
</div>
<motion.button
whileHover={!isLoading ? { scale: 1.02 } : undefined}
whileTap={!isLoading ? { scale: 0.98 } : undefined}
transition={{ duration: 0.2, ease: "easeInOut" }}
disabled={isLoading || !stripe || !elements} id="submit">
<span id="button-text">
{isLoading ? <div className="cernelGradient rounded-md text-white py-2"><Loader color="white" /></div> : <div className="cernelGradient rounded-md text-white py-2">Pay</div>}
</span>
</motion.button>
{/* Show any error or success messages */}
{message && toast.error(message) && null}
</form>
</>
)
}

ember laurel
#

That 2nd code block is different to what you initially shared

#

Are there any errors in the browser console?

livid gate
#

The 2nd code block is changed, since the conditional rendering was only added in order to test if the useElements() hook actually returned something. The bug also appeared when the conditional rendering wasnt added. Which is also the case for our production deployment

#

And no, there is no errors in the console when this bug occurs

ember laurel
#

Can I reproduce the issue somewhere?

#

My suggestion would be to remove the stripePromise conditional around your <Elements> provider as that is redundant

livid gate
#

I cant give you access to an account that experiences this issue, since i would be giving away our API key, which is against company policy unfortunately. But i can give you a screen recording of the issue

ember laurel
#

Which API key?

livid gate
#

It's an key we use to gain access to users e-commerce stores with read/write access to all their products and categories.

ember laurel
#

I just need to see the Payment Element on a page. Not sure why that would expose a secret API key but ok

livid gate
#

Yes, i was just about to reply. This didnt fix it tho.

#

This is what renders when the bug occurs

#

And this is after a page refresh

ember laurel
#

My other suggestion is likely that the clientSecret is unset and therefore conditionally blocking the rendering. Are you able to log that out in the cases the Element doesn't load?

#

Obviously some logic in your code is preventing the Element from rendering. The only conditional statements that you've shared are:

{clientSecret && stripePromise && (...)}
#

That implies to me that one of those is falsy on initial render for some reason

#

The stripePromise check is reundant, so my guess is your clientSecret is unset for whatever reason

livid gate
#

Im gonna check that out then. Thank you for your help!

#

I can tell that the clientSecret is never unset. Since the other elements (Invoice and Coupen elements) are still rendered, which means that the clienSecret is set. And from loggin my clientSecret, i can see that the value used is also correct

proud gale
#

Hi! I'm taking over from my colleague. Please, give me a moment to catch up.

livid gate
#

The only thing that isnt loading is the <PaymentElement />

#

Hey!

ember laurel
#

Why in one screenshot is the terms of service checkbox rendered and the other is not?

#
<label htmlFor="terms" className="text-sm">
              I agree to the <Link href="https://cernel.ai/en/terms-of-use" target="_blank" className="text-lightBluePrimary">terms and conditions</Link> and the
              <a href="https://cernel.ai/softwarelicensaftale" target="_blank" className="text-lightBluePrimary"> softwarelicenseagreement</a>
            </label>
#

That is wrapped in the same conditional as the <PaymentElement>

livid gate
#

Sorry, i forgot to mention that. The terms and conditions check is not yet added to the production server

ember laurel
#

So your screenshots are from different environments?

livid gate
#

The screenshot where it is visible, is from our production server. And the other is from my localhost / development server. However, i can assure you, that besides the checkbox, the code is the same

#

And the bug happens in both environments, i just had a tab open where i had refreshed the page in order to "bypass" the bug

#

So that is just due to my lazyness, i apoligize

proud gale
#

What happens if you just hardcode the client secret instead of const { clientSecret } = useClientSecretStore();? It's not clear what that hook does.

livid gate
#

I fixed the error. It appears, that if you initialize the variable that holds the clientSecret as null, and then overwrite it later on. This bug happens. But if you initialize the variable as an empty string, it doesnt happen

proud gale
#

Glad to hear that.

livid gate
#

Thank you for your help tho! And tell that to your coworker too

proud gale
#

Happy to help.