Adyencheckout is not a constructor - NextJS

Viewed 984

I'm trying to implement the Adyen dropin payment UI using NextJS but I'm having trouble initializing the Adyen dropin component.

I'm need to dynamically import Adyen web or I get the error window is not defined however, after reading through the NextJS docs, dynamic import creates a component which I can't figure out how to use as a constructor.

I tried the code below but receive the error TypeError: AdyenCheckout is not a constructor

I'm new to NextJS and am at a total loss as to how I should import and initialize Adyen.

Can anyone point me in the right direction?

import Head from 'next/head';
import { useRef, useEffect, useState } from 'react';
import {callServer, handleSubmission} from '../util/serverHelpers';
//dynamic import below. Imports as a component 
//import dynamic from 'next/dynamic';
//const AdyenCheckout = dynamic(() => import('@adyen/adyen-web'), {ssr: false});
import '@adyen/adyen-web/dist/adyen.css';

export default function Dropin(){

  const dropinContainer = useRef(null);
  const [paymentMethods, setPaymentMethods] = useState();
  //const [dropinHolder, setDropinHolder] = useState();

  //Get payment methods after page render
  useEffect( async () => {
    const response = await callServer(`${process.env.BASE_URL}/api/getPaymentMethods`);
    setPaymentMethods(prev => prev = response);
  },[]);
   
  //Adyen config object to be passed to AdyenCheckout
  const configuration = {
    paymentMethodsResponse: paymentMethods,
    clientKey: process.env.CLIENT_KEY,
    locale: "en_AU",
    environment: "test",
    paymentMethodsConfiguration: {
      card: {
        showPayButton: true,
        hasHolderName: true,
        holderNameRequired: true,
        name: "Credit or debit card",
        amount: {
          value: 2000,
          currency: "AUD"
        }
      }
    },
    onSubmit: (state, component) => {
      if (state.isValid) {
        handleSubmission(state, component, "/api/initiatePayment");
      }
    },
    onAdditionalDetails: (state, component) => {
      handleSubmission(state, component, "/api/submitAdditionalDetails");
    },
  };

  //const checkout = new AdyenCheckout(configuration);
  const AdyenCheckout = import('@adyen/adyen-web').default;
  const adyenCheckout = new AdyenCheckout(configuration);
  const dropin = adyenCheckout.create('dropin').mount(dropinContainer.current);

  return (
      <div>
        <Head>
        <title>Dropin</title>
        
        </Head>
        <div ref={dropin}></div>
      </div>
  )
}
1 Answers

I was able to resolve the issue by importing the module using the default value inside an async function nested in the useEffect function.

import Head from 'next/head';
import { useRef, useEffect, useState } from 'react';
import {callServer, handleSubmission} from '../util/serverHelpers'; 
import '@adyen/adyen-web/dist/adyen.css';

export default function Dropin(){

  const dropinContainer = useRef();
  const [paymentMethods, setPaymentMethods] = useState({});

  useEffect(() => {
    const init = async () => {
      const response = await callServer(`${process.env.BASE_URL}/api/getPaymentMethods`)
      .then(setPaymentMethods(response));

      console.log(paymentMethods);

      const configuration = {
        paymentMethodsResponse: paymentMethods,
        clientKey: process.env.CLIENT_KEY,
        locale: "en_AU",
        environment: "test",
        paymentMethodsConfiguration: {
          card: {
            showPayButton: true,
            hasHolderName: true,
            holderNameRequired: true,
            name: "Credit or debit card",
            amount: {
              value: 2000,
              currency: "AUD"
            }
          }
        },
        onSubmit: (state, component) => {
          if (state.isValid) {
            handleSubmission(state, component, "/api/initiatePayment");
          }
        },
        onAdditionalDetails: (state, component) => {
          handleSubmission(state, component, "/api/submitAdditionalDetails");
        },
      };

      console.log(configuration.paymentMethodsResponse);
      const AdyenCheckout = (await import('@adyen/adyen-web')).default;
      const checkout = new AdyenCheckout(configuration);
      checkout.create('dropin').mount(dropinContainer.current);
    }
    init();
  },[]);

  return (
      <div>
        <Head>
        <title>Dropin</title>
        </Head>
        <div ref={dropinContainer}></div>
      </div>
  )
}
Related