Comments (18)
Guys, I've opened a PR that should solve this issue.
Added in a StripeContext
provider that returns true
when the Elements context is ready. You can hook into this context to conditionally render Stripe elements in your checkout form.
This way, no Stripe element component should ever render before the Elements context is ready.
Tested and confirmed working locally. Could anyone give this a spin and confirm if it solves the issue?
from nextjs-starter-medusa.
Oddly, when i refresh the page when i get the error, I was able to get into the checkout page.
from nextjs-starter-medusa.
I am facing the same issue.
Checkout throws the same error on first load.
After a few refreshes - loads correctly.
With this error in the server logs:
....
data: {
code: 'invalid_request_error',
type: 'duplicate_error',
message: 'Payment_session with cart_id, provider_id cart_xxx, stripe already exists.'
}
....
Also it says paymentSession
on line 20 of (payment-wrapper/index.tsx) is undefined
Probably this is some nonsense related to next.js rendering "use client" files on the server...
So I butchered it and used useEffect to set provider id and it seems to have fixe the issue..
const Wrapper: React.FC<WrapperProps> = ({ cart, children }) => {
const [providerId, setProviderId] = useState<string | null>(null)
const isStripe = providerId?.includes("stripe")
useEffect(() => {
const paymentSession = cart.payment_session as PaymentSession
setProviderId(paymentSession?.provider_id)
}, [])
if (!providerId) return null
if (isStripe && providerId && stripePromise) {
return (
<StripeWrapper
paymentSession={cart.payment_session!}
stripeKey={stripeKey}
stripePromise={stripePromise}
>
{children}
</StripeWrapper>
)
}
if (providerId === "paypal" && paypalClientId !== undefined && cart) {
return (
<PayPalScriptProvider
options={{
"client-id": "test",
currency: cart?.region.currency_code.toUpperCase(),
intent: "authorize",
components: "buttons",
}}
>
{children}
</PayPalScriptProvider>
)
}
return <div>{children}</div>
}
But it would great for some one to come up with a legit solution.
from nextjs-starter-medusa.
This is happening when you enter the checkout from the cart page right? Is Stripe the only enabled payment provider when this issue occurs?
Because if there's multiple payment providers enabled, cart.payment_session
should be null
until a provider is selected in the checkout flow.
If there's only one provider enabled, Medusa will select it by default, resulting in cart.payment_session
being populated when you enter the checkout - even though Stripe context might not be fully loaded yet. I suspect this is causing the issue.
from nextjs-starter-medusa.
If there's only one provider enabled, Medusa will select it by default, resulting in
cart.payment_session
being populated when you enter the checkout - even though Stripe context might not be fully loaded yet. I suspect this is causing the issue.
Confirmed. After adding a second payment provider, the issue disappears.
from nextjs-starter-medusa.
I'm annoyed by this issue awkwardly while there is only one payment method (stripe) in my portal. Is there any sophisticated way to solve it elegantly at the side of storefront?
There is a similar issue at #218, but the corresponding codes were marked as outdated. In fact, the issue seems to happen again in the latest version.
from nextjs-starter-medusa.
Thanks @VariableVic. This has solved it for me.
from nextjs-starter-medusa.
@bqst I tried with the versions you mention, but I can't replicate this issue. I'm able to finish a test order using Stripe just fine. The component containing <CardElement>
shouldn't unmount, but get a hidden
class when it's not active.
Did you make any changes to the render conditions in the src/modules/checkout/components/payment/index.tsx
component?
from nextjs-starter-medusa.
You're right, I was conditionally rendering like :
{isOpen ? ( <CardElement /> ) : (<>{paymentInfoMap[cart?.payment_session?.provider_id || '']?.title}</>)
That's where the problem was coming from, my bad ! Thank you for the quick answer !
from nextjs-starter-medusa.
Hey @leonwangg1,
Let's see if we can figure this out.
- Did you properly set up the
NEXT_PUBLIC_STRIPE_KEY
environment variable on your live storefront project? - What is the
provider_id
for the Stripe payment method you're trying to use? Insrc/modules/checkout/components/payment-wrapper/index.tsx
: line 22 we're checking if the provider_id contains 'stripe', and render the Elements wrapper based on this condition. Could be that your specific provider does not contain this string. In that case, edit line 22 to match your provider id.
Edit: the latter seems unlikely as you mention that it's working on your local server. Sounds like your Stripe session isn't properly initializing on the live server.
from nextjs-starter-medusa.
It looks like the paymentSession and isStripe values are empty
And when I reload the page they have values
from nextjs-starter-medusa.
"use client" files on the server...
So I butchered it and used useEffect to set provider id and it seems to have fixe the issue..
This unfortunately hasn't fixed it for me as on the first load the providerId is null and doesn't update. Only updates after refreshing the page.
from nextjs-starter-medusa.
That's right. This is exactly how it happens. Stripe is the only enabled provider and I enter the checkout from the cart page. @VariableVic could you point me to the method does the default selection and how can I listen to the Stripe context load event?
from nextjs-starter-medusa.
what if the store only provides one payment provider? is there an WA for that?
from nextjs-starter-medusa.
Yeah I understand this is super annoying. I'm working on a fix. Keep you posted!
from nextjs-starter-medusa.
@VariableVic , I did tests, and the issue was solved. Thanks for your reinforcing!
from nextjs-starter-medusa.
@VincentDevp Thanks for confirming!
I'm gonna merge the fix and close this issue. LMK if anyone is still experiencing difficulties with Stripe after this.
from nextjs-starter-medusa.
FIY, with the following versions :
"@stripe/react-stripe-js": "^2.5.0",
"@stripe/stripe-js": "^3.0.4",
I still had the same issue despite the @VariableVic fix.
Please make sure the Element you are attempting to use is still mounted.
To fix it, I had to simply remove the review step and implement the PaymentButton directly at the Payment stage so that the Stripe Element would still be mounted. Btw, I use CardElement.
from nextjs-starter-medusa.
Related Issues (20)
- Build error for Next.js Starter Storefront (axios-fetch-adapter) HOT 2
- Store front: Module not found: Package path ./lib/core/settle is not exported from package HOT 1
- Question: How to integrate i18n and [locale] path HOT 1
- "Explore products" link in empty cart popup has wrong route, should be /us/store instead of /usstore
- Nested URL-path does not exist in starter HOT 3
- Filters on the template HOT 1
- Unable to Login to Admin Panel in Production Environment after Vercel Deploy - Possible CORS and Database Connection Issue HOT 4
- Billing address saved in profile doesn't show up in checkout form HOT 1
- Ambiguity about which addresses are being used on the checkout page
- Default phone number in profile not used in checkout form HOT 2
- checkout breaks when Paystack is the only payment provider HOT 1
- App won't build with yarn build HOT 3
- Slow API fetch, both in dev and prod HOT 5
- Unsecured Cookie Allows Unauthorized Access to Discounts and Shipping Address in This Template HOT 1
- bug: Click to log out, unable to login again
- Installation error on latest macOS (number-float64-base-normalize)
- Error: A "use server" file can only export async functions. HOT 4
- Javascript HOT 1
- SyntaxError: Unexpected token < in JSON at position 0 HOT 4
- MeiliSearch Instantsearch RefinementList is not working HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from nextjs-starter-medusa.