Square node.js SDK installed in Amplify project throws Module not found error

Hi there.
I have a clean (auth, api are enabled and provisioned) Amplify React javascript project on which I installed the npm package square.

As soon as I add this line of code

const { ApiError, Client, Environment } = require('square');

I receive the following error:

Compiled with problems:

ERROR in ./node_modules/@apimatic/convert-to-stream/lib/convertToStream.js 12:16-42
Module not found: Error: Can’t resolve ‘stream’ in ‘C:\path_to_project\node_modules@apimatic\convert-to-stream\lib’
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback ‘resolve.fallback: { “stream”: require.resolve(“stream-browserify”) }’
- install ‘stream-browserify’
If you don’t want to include a polyfill, you can use an empty module like this:
resolve.fallback: { “stream”: false }

ERROR in ./node_modules/square/dist/square.esm.js 5:0-28
Module not found: Error: Can’t resolve ‘crypto’ in ‘C:\path_to_project\node_modules\square\dist’
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback ‘resolve.fallback: { “crypto”: require.resolve(“crypto-browserify”) }’
- install ‘crypto-browserify’
If you don’t want to include a polyfill, you can use an empty module like this:
resolve.fallback: { “crypto”: false }

The first error can be removed by installing the stream package, but the second one can’t go away as the crypto package is no longer available on npm, and it says that it is now a native module of node.js (or something like that).

How can I mitigate this issue? Thank you

Hey @yurivaskovski,

RE: ERROR in ./node_modules/square/dist/square.esm.js 5:0-28

I believe this is happening because your code is trying to execute in the browser, but the browser runtime doesn’t know what Crypto is. If the code was executing in the Node runtime it would be okay.

I don’t know if Amplify comes with a webpack.config.js file but if it does you can edit the object in that file to contain the fallback specified in the error message here.

resolve: {
  fallback: {
    crypto: require.resolve("crypto-browserify")
  }
}

You can then npm install crypto-browserify and then this error should go away.

The other solution is if you can include Square somewhere else in your project so you are not running the SDK in the browser and instead have it running somewhere that Node is active. After looking at AWS Amplify, it looks like it uses lambda functions to act as your ‘server’. In these lambda functions is where you should be including Square and using the SDK. As the frontend code of your application makes calls to those lambda functions, the lambda’s will create the Square client and use the methods on the SDK.

Happy to dive in a bit deeper on this if you need!

1 Like

Hi @Jordan-Square

Thank you for a swift reply. Thanks for pointing out the browser runtime issue. As now you said it I realize the issue with this. I will be playing around with Amplify further as I need to set up express for it, and will get back here with more details on how it works.

Thanks again.

1 Like

I moved everything to lambda and it works as intended. I’m not even using Square SDK for now, I’m just making regular API calls, as those functions are hosting OAuth logic. Thank you for the suggestion.

One additional question has arose so far - I have created a refresh flow and when I try to make an API call to refresh the token, I’m receiving an “invalid refresh token” error. Is it due to call being made on sandbox, or there is an issue with my code?

Thank you

Hey @yurivaskovski

I need a few more details in order to let you know what’s going on.

Can you confirm that you are first obtaining an access token and a refresh token using the obtainToken oAuth endpoint?

If your flow uses squareupsandbox.com as the base URL for the call to the initial obtainToken request as well as the later obtainToken request where you supply the refresh token, this should be working. https://developer.squareup.com/reference/square/o-auth/obtain-token

However if your access and refresh tokens were obtained using the sandbox endpoint (squareupsandbox.com), and then you are calling obtainToken refresh token on the production endpoint (squareup.com) that could be the issue.

Please confirm that your whole flow is using either the squareupsandbox.com or squareup.com for the obtainToken calls. Reminder that the obtainToken endpoint is used for both getting your initial access and refresh tokens as well as used to refresh your tokens. You pass different parameters to the endpoint when doing the refresh.

1 Like

hey @Jordan-Square

I apologize for such a delayed response to your message. There was an issue with my code not supplying the refresh token. It’s all good now.

I’ve got another issue though lol, that is not related to the subject topic. Maybe you can help me with this one.

I currently reside in Ukraine and a few days ago the Square website and payment forms are no longer available to be accessed from Ukraine. The website shows a ban for the country/region on Cloudflare and when I try to open a website that contains an integrated web payments sdk form, it is not loaded up as again the access is restricted from Ukraine, so it shows a bunch of I think 403s in the console of a browser.

What could be an issue and is there any way to tackle it?
Thank you