How to use the square API with ESM

I am an old school perogrammer (COBOL if youmust know) and thought I would take advantage of all the AI and vibe coding stuff available to create a web shopping app using node.js, react and a postgreSQL database. Apparantly ESM is the way to go as commonJS is being deprecated. Everything was remarkably easy until it came time to try and pay for something. Getting square ([email protected]) and all the necessary codes and ids was straightforward but trying to link it all together in my paymentsRoute has made me dizzy.
Thanks to chatGPT, I currently have
import express from ‘express’;

import auth from ‘../middleware/auth.js’;
import crypto from ‘crypto’;
import { createRequire } from ‘node:module’;

const require = createRequire(import.meta.url);
const square = require(‘square’); // Square SDK 42.3.0 — CommonJS
const { SquareClient, SquareEnvironment } = square;

const router = express.Router();

// Initialize Square client
const client = new SquareClient({

accessToken: process.env.SQUARE_ACCESS_TOKEN,

environment: SquareEnvironment.Sandbox, // Use .Production for live

});

// Get the Payments API

const paymentsApi = client.payments;

console.log(‘Square client initialized with environment:’, client.configuration.environment);
|
|
and when I try to start the server I get
file:///C:/Projects/ceramics-shop-api/src/routes/paymentRoutes.js:22
console.log(‘Square client initialized with environment:’, client.configuration.environment);
TypeError: Cannot read properties of undefined (reading ‘environment’).
Someone must have already invented this wheel and I guess I am doing it all wrong. Can someone point me in the right direction, please.

:waving_hand: I’m Square Dev AI, here to help answer your question!
Based on the information you’ve provided, the following documentation will help answer your question:

Additional Documentation

Node.js SDK
Node.js SDK
https://developer.squareup.com/docs/orders-api/quick-start/start

If this documentation helped you find a solution, please check the box indicating that this reply solves the problem.
Otherwise one of our Developer Advocates will provide additional assistance shortly.

The error you’re encountering is due to the fact that you’re trying to use the Square Node.js SDK in a mixed import style. The Square SDK documentation advises against mixing CommonJS and ES imports in the same codebase as it can lead to issues that are hard to debug.

In your case, you’re using ES module style imports for ‘express’, ‘crypto’, and ‘node:module’, but you’re using CommonJS style for importing ‘square’. This is likely causing the issue.

To resolve this, you should consistently use one style of imports. Since you’re using ES modules, you should import the Square SDK in the same style. Here’s how you can do it:

import express from 'express';
import auth from '../middleware/auth.js';
import crypto from 'crypto';
import { SquareClient, SquareEnvironment } from 'square';

const router = express.Router();

// Initialize Square client
const client = new SquareClient({
  accessToken: process.env.SQUARE_ACCESS_TOKEN,
  environment: SquareEnvironment.Sandbox, // Use .Production for live
});

// Get the Payments API
const paymentsApi = client.payments;

console.log('Square client initialized with environment:', client.configuration.environment);

This code uses ES module style imports consistently, which should resolve the issue you’re facing.

This answer was reviewed by @Bryan-Square.

Thank you for your prompt reply and code snippet.

This failed and the code looks similar to an earlier attempt of mine.

When I try to start the backend server I get the following error

node src/server.js

file:///C:/Projects/ceramics-shop-api/src/routes/paymentRoutes.js:17

console.log(‘Square client initialized with environment:’, client.configuration.environment);

^

TypeError: Cannot read properties of undefined (reading ‘environment’)

at file:///C:/Projects/ceramics-shop-api/src/routes/paymentRoutes.js:17:81

at ModuleJob.run (node:internal/modules/esm/module_job:274:25)

at async onImport.tracePromise.proto (node:internal/modules/esm/loader:644:26)

at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:116:5)

Node.js v22.15.0

The code in use is a straight copy and paste of your snippet provided in place of the original code at that point. Did I miss something?

I am using [email protected] and it has been suggested that it is CommonJs only.

How are you accessing the SDK? :slight_smile:

A very good question! I started off vibe programming this in cursor, with what I now know was a commonjs architecture, then when I struck problems whichever AI was playing at the time recommended changing to ESM. So here we are now in some sort of np man’s land between commonJs and ESM and I am currently wrestling with my models converting those to fit in with ESM. I managed to circumvent the square issue I first contacted the forum about by accessing the API directly.

From what I can make out, that while the way forward will be ESM there is so much CommonJs around it will never go away and people will end up making a mishmash of their code by using ‘require’.

I think I might just dump this project, which I am doing partly for fun and partly for my son, and find some other way to do it that is not node and not react.

Thanks for your time

Regards

Alan