#oskarinmix_api
1 messages ยท Page 1 of 1 (latest)
๐ 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/1361811083416961259
๐ Have more to share? Add more details, code, screenshots, videos, etc. below.
Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
- oskarinmix_api, 1 hour ago, 13 messages
Hi! Can you share your code please? Or a URL where I can see it in action?
Can you please share text and not an image? Thanks.
it says message is too long
"use client";
import { createStripeCheckoutSession, recreateCheckoutSession } from '@/server-actions/stripe';
import { useCartStore } from '@/store/cart';
import { CheckoutProvider } from '@stripe/react-stripe-js';
import { loadStripe } from '@stripe/stripe-js';
import React, { useCallback, useEffect } from 'react';
const stripe = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY!, {
// betas: ['custom_checkout_beta_6'],
developerTools: {
assistant: {
enabled: false
}
},
stripeAccount: process.env.NEXT_PUBLIC_STRIPE_ACCOUNT!
});
const ArchitectCheckoutProvider = ({ children, email }: { children: React.ReactNode, email: string }) => {
const cart = useCartStore()
const emailIsValid = (email: string) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
useEffect(() => {
console.log('email changed', email)
if (email && emailIsValid(email)) {
fetchClientSecret();
}
}, [email])
const fetchClientSecret = useCallback(async () => {
const lineItems = cart.items.map((item: any) => ({
price: item.product.default_price?.id,
quantity: item.quantity,
}))
if (lineItems.length > 0 && (emailIsValid(email) || email === "")) {
return await createStripeCheckoutSession(lineItems, email)
} else {
return;
}
}, [email, cart.items]);
return (
<CheckoutProvider stripe={stripe} options={{
fetchClientSecret: fetchClientSecret as () => Promise<string>
}}>
{children}
</CheckoutProvider>
)
}
export default ArchitectCheckoutProvider
each time i change the email it creates a new checkout session with an email associated its working fine
but when i use checkout = useCheckout()
checkout.email is not updating, is always null
Nowhere in there are you calling useCheckout() or updateEmail() so I'm not really sure what's blocking you here.
But did you use updateEmail()?
no, because i can not update the email to a checkoutSession
i can not update a checkoutSesssion email once created
https://docs.stripe.com/js/custom_checkout/react/update_email seems to imply otherwise; have you tried it?
but that is what i dont want
because ordering with same email create customers repeated with same email
i want to link the orders to already registered customers or create a new one if is first time
New one if it's an email address you haven't seen before, you mean?
yes
Your fetchClientSecret function always creates a new Checkout Session no matter what.
yes
i know it because session id
but in the useCheckOut that id is not updating,
it keeps always the old session
when the hook callback runs, it create a new session but not updating the useCheckout
just create a checkouit session
cs_test_b1VJUTPcC4fnWmtj584ogkTdryzBIUiyaYQ4MupuDFXIJzIWZXRRcjBAg4
then email change and it return another checkout session
Ya, that's what the logic in your code says. Any valid email or any empty email will result in a new Checkout Session. If it's not valid or empty, it'll return nothing (and presumably fail).
cs_test_b1EgwMNfLUSsHtP0XcxjovGThSHHelyPvDgwPr0anbWctLPZDNkEuebEhm
new id
but useChekout still showing the old
seem like checkout provider is now using the new state with the new session
its using the first one
Still digging; not super up on this part of our React code.
in previous versions you passed the clientSectre to the provider
and you could handle it separate in your own state
now you pass the function to fetch it but you can not handle the state
probable something in the checkout provider is not updating the state
I think all this stuff you're doing is supposed to be done inside the CheckoutProvider component.
yeah it is
(or rather, in components inside that component)
if i were out, it throw an error that it can not find the provider
Right.
I'm not entirely sure how to update the cached value at useCheckout, or if it even does get updated. It's possible that you'd need to re-initialize the CheckoutProvider to get a new Checkout Session.
(as far as React is concerned, at least)
i did it but checkout = useCheckout is not updating
Why are you using useCallback?
to recreate the session when customer change the email
because i want to track customers orders
if change the email and customer exists, i use customer: customerId , intead email
Right, but why are you using useCallback there?
then stripe not create a new customer with same email each time
if i only use updateEmail() it creates a new customer each time with same email
useCallback specifically caches the function and I'm not sure what consequences that would have here - but it might in fact cause useCheckout to return the previous value. I don't believe it's applicable here.
i know it caches but you specify in the dependancies array that if x value change then refetch
Right, but ... why are you doing it at all?
i still thing is a bug handle the provider state
What happens if you remove it and just use a regular function there?
Have you tried reproducing this (or tried accomplishing your task) in a simpler example react app?
i removed the useCallback and then a new sesion is creating
but still the useCheckout is not changing the state
Can you share the code please?
"use client";
import { createStripeCheckoutSession, recreateCheckoutSession } from '@/server-actions/stripe';
import { useCartStore } from '@/store/cart';
import { CheckoutProvider } from '@stripe/react-stripe-js';
import { loadStripe } from '@stripe/stripe-js';
import React, { useCallback, useEffect } from 'react';
const stripe = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY!, {
// betas: ['custom_checkout_beta_6'],
developerTools: {
assistant: {
enabled: false
}
},
stripeAccount: process.env.NEXT_PUBLIC_STRIPE_ACCOUNT!
});
const ArchitectCheckoutProvider = ({ children, email }: { children: React.ReactNode, email: string }) => {
const cart = useCartStore()
const emailIsValid = (email: string) => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
const fetchClientSecret = async () => {
const lineItems = cart.items.map((item: any) => ({
price: item.product.default_price?.id,
quantity: item.quantity,
}))
if (lineItems.length > 0 && (emailIsValid(email) || email === "")) {
return await createStripeCheckoutSession(lineItems, email)
} else {
return;
}
};
return (
<CheckoutProvider stripe={stripe} options={{
fetchClientSecret: fetchClientSecret as () => Promise<string>,}}>
{children}
</CheckoutProvider>
export const createStripeCheckoutSession = async (line_items: Stripe.Checkout.SessionCreateParams.LineItem[], email: string) => {
console.log('CREATE CHECKOUT SESSION')
let customer
if (email) {
customer = await customerStripeExists(email)
}
const createOptions: any = {
line_items,
mode: 'payment',
ui_mode: 'custom',
automatic_tax: {
enabled: true,
},
invoice_creation: {
enabled: true,
},
return_url: ${(await headers()).get('origin')}/checkout/success?session_id={CHECKOUT_SESSION_ID}&payment_status={PAYMENT_STATUS}&payment_intent={PAYMENT_INTENT_ID}&email={EMAIL},
payment_method_types: ['card', 'affirm', 'klarna'],
allow_promotion_codes: true,
shipping_address_collection: {
allowed_countries: ['US'],
},
tax_id_collection: {
enabled: true,
},
}
if (customer) {
createOptions.customer = customer.id
createOptions.customer_update = {
address: "auto",
shipping: "auto",
name: "auto"
}
}
try {
const session = await stripe.checkout.sessions.create(createOptions);
console.log(session)
return session.client_secret
} catch (error) {
console.error("error creating checkout session", error);
throw error;
}
};
I hear you. I don't think you're going to get <CheckoutProvider> (where the hook is) to be associated with a random new Checkout Session you create, but again, still trying to figure this out.
im using the react component dev tools, and in the provider, the state is not changing when a new checkout session changer
internally the provider uses a useMemo that maybe is caching the state
I don't think this particular integration route is designed for multiple Checkout Sessions like this, but let me see if I can find someone who knows more about this than I do.
CheckoutContext.provider in the value is not updating
There is useMemo usage happening internally. I don't think this is meant to be 'reused' like this.
I'm going to have to forward you to Support as I can't get anyone that knows about this.
Hello @serene zenith, we have sent you a direct message, please check it at https://discord.com/channels/@me/1361831991800234154
- ๐The message has instructions on how to open a direct support case with our Developer Support team, in order to help you more effectively.