Comments (11)
Hi @wecessary ,
Thanks for pointing it out, we will investigate this soon. I am assuming that you are facing this problem on all Next 14.x versions.. Did you also test on 14.0.0?
from adyen-web.
Hi @ribeiroguilherme thanks for taking notice. I actually just tested on Next js 13.5.6 and the same issue occurred. So I think the problem has to to with at least Next js 13.5.6 and up.
from adyen-web.
@ribeiroguilherme Just to add. I just tested on Nextjs v13.5.1 and same issue also occurred. So v13.4.19 happens to be the last compatible version.
Also if it is relevant. I mount the drop in component by doing the following. Simplified code:
"use client";
import AdyenCheckout from "@adyen/adyen-web";
function Page(){
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
async function initPaymentSession() {
if (!ref.current) return;
const res = await fetch("/api/checkout/get-payment-methods", {
method: "POST",
body: JSON.stringify({ cartId, locale }),
});
const data = await res.json();
const checkout = await AdyenCheckout(
getConfig({
router,
paymentMethodsResponse: data,
cartId,
})
);
checkout.create("dropin").mount(ref.current);
}
initPaymentSession();
}, [router, cartId, locale]);
}
function getConfig({
router,
paymentMethodsResponse,
cartId,
}: {
router: AppRouterInstance;
paymentMethodsResponse: any;
cartId: string;
}) {
return {
paymentMethodsResponse,
clientKey: process.env.NEXT_PUBLIC_ADYEN_CLIENT_KEY as string,
locale: "en-US",
environment: "test",
analytics: {
enabled: true,
},
amount:{ value:1000, currency:"GBP"},
onSubmit: async (state: any, dropin: any) => {
const res = await fetch("/api/checkout/make-payment", {
method: "POST",
body: JSON.stringify({
cartId,
paymentData: state.data,
}),
});
const data = await res.json();
if (data.action) {
dropin.handleAction(data.action);
} else {
if (data.resultCode) {
router.push(
`/uk/checkout/result?resultCode=${data.resultCode}&order=${data.merchantReference}`
);
}
}
},
onAdditionalDetails: async (state: any, dropin: any) => {
const res = await fetch("/api/checkout/additional-details", {
method: "POST",
body: JSON.stringify({
additionalDetails: state.data.details,
}),
});
const data = await res.json();
if (data.action) {
dropin.handleAction(data.action);
} else {
if (data.resultCode) {
router.push(
`/uk/checkout/result?resultCode=${data.resultCode}&order=${data.merchantReference}`
);
}
}
},
setStatusAutomatically: true,
onError: (error: any, component: any) => {
console.error("fail", error.name, error.message, error.stack, component);
},
threeDS2: {
challengeWindowSize: "05",
},
paymentMethodsConfiguration: {
card: {
hasHolderName: true,
holderNameRequired: true,
billingAddressRequired: true,
name: "Credit or debit card",
},
},
};
}
from adyen-web.
Hi @wecessary
Thanks for sharing the code. Is it happening specifically with the 3DS action, or also with other action types? Can you let me know which other payment methods is this happening?
Did you try only Drop-in, or also with standalone Component?
from adyen-web.
@ribeiroguilherme When /payments
response didn't have an action object, it worked fine. It also wasn't working when action.type was redirect
. I only tested action types that have to do with 3ds. We are only planning on taking Visa, Mastercard and Amex so I think these are the only two action types I need to be concerned with...?
I only tried Drop-in.
Just a hunch so feel free to ignore it: According to the React doc, changing a ref doesn't trigger re-render. So refs are apparently not appropriate for storing information that need to change visually. But Adyen doc says to use ref. So I was actually surprised when I saw 3ds or even loading state work for the first time. Maybe something to do with this? But actually if this was the issue that even the older Next js versions should have the same problem I guess
from adyen-web.
Hey @wecessary ,
I created a repo trying to reproduce this problem using adyen-web with Nextjs 14.0.3, and everything seems to work as expected, including handleAction
part. You can check it here
Can you take a look and let me know if I am missing something?
from adyen-web.
Thanks @ribeiroguilherme! I'll look at it today - will get back to you today or tomorrow (UK time)
from adyen-web.
Hey @ribeiroguilherme, I found the issue!
In the following code, if you get rid of the if statement, and just run loadAdyen()
in the useEffect, somehow, 3ds UI will not work with NextJs 14, but will work with Next 13.4.19.
useEffect(() => {
if (!isAdyenWebInitialized.current) {
isAdyenWebInitialized.current = true;
loadAdyen();
}
}, [loadAdyen]);
I have made two branches for you to see:
I also updated React to 18.2.0 in both branches, just beacuse that's what I'm using.
This is super interesting! Keen to know your thinking! Also, may I ask your reason behind using isAdyenWebInitialized
?
FYI, the card I have been using to test is:
5454 5454 5454 5454
03/30 737
from adyen-web.
That is the reason that I added the isAdyenWebInitialized
.
I believe the issue is that React is running on strict mode , which causes the effects to re-run an extra time.
Re-running the effect can lead the library to be reinitialized twice or even multiple times depending on your implementation. This can lead to many bugs. One problem for example is a race condition situation, where you might end up rendering your checkout
using one AdyenCheckout
instance, but then handling actions using another AdyenCheckout
instance. The code is asynchronous, so you can't know which one will finish/render first.
For the reason above, we need to add a mechanism to prevent the initialization to happen multiple times.
Can you confirm that this 'check' fixes the problem on Nextjs 13 too?
from adyen-web.
That makes sense. I can also confirm that this 'check' fixes the problem on Nextjs 13.4.19 too.
I think you're right on this one. Nextjs doc says
Since Next.js 13.4, Strict Mode is true by default with app router, so the above configuration is only necessary for pages. You can still disable Strict Mode by setting reactStrictMode: false.
This explains why the issue appeared only in dev mode and only on Next 14 but not on Next 13.4. I just wasn't aware...
Perhaps the use of this 'check' is worth adding to the doc? The doc currently just warns React and Vue developers to "make sure that you use references instead of selectors" (advanced flow or simple flow)
Thank you so so much for your help @ribeiroguilherme! I learnt something in the process too!
from adyen-web.
Glad that it worked @wecessary 🙏 I will forward your feedback to the docs team so they can update the documentation accordingly. Cheers!
from adyen-web.
Related Issues (20)
- Blik svg not available after upgrade to 5.55.0. (404) HOT 5
- IFrame.scss styles not being applied HOT 3
- IMPLEMENTATION_ERROR : Could not submit payment HOT 1
- Sometimes the status check QR code doesn't wait for the previous request to complete or times out. HOT 3
- Duplicate brand image HOT 2
- Swish onComplete or OnPaymentComplete never gets fired HOT 6
- Drop-in integration - Fields are disabled HOT 7
- Must declare the property "paymentTiming" in the ApplePayLineItem interface since is needed for recurring payments HOT 1
- SecuredFields take too long to configure on CircleCI HOT 1
- Type onAdditionalDetails argument in CoreOptions HOT 6
- [Web Drop-in] challengeWindowSize type in CoreOptions.paymentMethodsConfiguration HOT 2
- [Web Drop-in] Allow hiding amount HOT 4
- `showPayButton` not working for stored ACH HOT 2
- Slash not allowed in Street and House number fields in Drop-in HOT 5
- `undefined is not an object (evaluating 'this.touchendListener')` error on Safari HOT 2
- [Web - DropIn] On iOS Safari, scanning a card is entering the wrong expiryDateField
- Ideal issuer list not showing in webcomponent HOT 3
- [Web Drop-in] Trouble generating a boleto in test account. HOT 1
- More flexibility for installmentOptionMonths HOT 2
- Placeholder text is not vertically centered when using a custom font HOT 2
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 adyen-web.