mollie / mollie-api-node

Official Mollie API client for Node
http://www.mollie.com
BSD 3-Clause "New" or "Revised" License
228 stars 62 forks source link

nuxtjs 3 error #300

Closed maxleistner closed 1 year ago

maxleistner commented 1 year ago

I am trying to integrate mollie.com into my nuxtjs3 application. The goal is to fill button targets with checkout urls for specific products.

Therefore i integrated @mollie/api-client intro my nuxt v3.0.0 app. Within a subpage i load the script and try to generate a checkoutUrl

import createMollieClient from "@mollie/api-client";

export default defineComponent({
  name: "Product",
  async setup() {
    const mollieClient = createMollieClient({
      apiKey: "test_WpjrT**********JTV8j4zDy",
    });
    const payment = await mollieClient.payments.create({
      amount: {
        value: "10.00",
        currency: "EUR",
      },
      description: "My first API payment",
      redirectUrl: "https://url.com/order/123456",
      webhookUrl: "https://url.com/webhook",
    });

    return {
      redUrl: payment.getCheckoutUrl(),
    };
  },

but.... i get the following error:

500 Cannot read properties of undefined (reading 'custom') at http://localhost:4444/_nuxt/node_modules/.vite/deps/@mollie_api-client.js?v=dff22e71:2077:24

I have no clue what is going on here. Does anyone else tried this or has an idea how to get to the origin of this error?

Thanks!

vernaillen commented 1 year ago

I get this same error in Nuxt 3.

It seems the error is thrown from this line: https://github.com/mollie/mollie-api-node/blob/095e1c48beb477c43e3ce9ebe1f64129cb18c5f9/src/data/Helper.ts#L53

@maxleistner were you able to find what causes it?

vernaillen commented 1 year ago

Ok, so I found out that the createMollieClient method cannot be called by client side js.

Module "util" has been externalized for browser compatibility. Cannot access "util.inspect" in client code. See http://vitejs.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.

I moved the code to server/api/mollie.ts and now it's working because the mollieClient is created and called in the server api.

maxleistner commented 1 year ago

@vernaillen no i did not find a fix. I switched to shopify after multiple tries... Does everything work now for you? If yes, i will have a look at it again...

vernaillen commented 1 year ago

@maxleistner my code is still work in progress, but it definitely works to trigger the mollie payment from a server side api method like this:

server/api/mollie.ts:

import { createMollieClient } from '@mollie/api-client'
const config = useRuntimeConfig()

export default defineEventHandler(async (event) => {
  if (config.mollieApiKey) {
    const body = await readBody(event)
    const totalPrice: number = body.unitPrice * body.amount

    const mollieClient = createMollieClient({ apiKey: config.mollieApiKey })
    try {
      const paymentResponse = await mollieClient.payments.create({
        amount: {
          value: '${totalPrice}.00',
          currency: 'EUR',
        },
        description: body.description,
        redirectUrl: '${config.mollieRedirectBase}/tickets/123456',
        webhookUrl: '${config.mollieRedirectBase}/api/mollieWebhook',
        metadata: {
          order_id: '123456',
        },
      })
      return paymentResponse
    }
    catch (error) {
      console.error(error)
    }
  }
})

then you can call the api from a component:

const { data: payment } = await useFetch<Payment>('/api/mollie', {
    body: { unitPrice: 10, amount: 2, description: 'Ticket order' },
    method: 'post',
  })
  if (payment && payment.value) {
    const paymentData: Pick<Payment, any> = payment.value
    if (paymentData._links.checkout && paymentData._links.checkout?.href)
      document.location.href = paymentData._links.checkout?.href
  }
}
Pimm commented 1 year ago

Hi, thanks for the issue and comments.

As @vernaillen points out, you should call createMollieClient serverside. This library not working in the browser is by design. It is unfortunate that the error you got is so vague (and unfortunate that apparently this check didn't result in a more elaborate error).

Creating a payment requires your API key, thus creating payments from the client necessitates shipping your API key to the client (= to users). With this key, users will be able to act on your behalf (e.g. view the data of your customers, or create refunds).

You must therefore create payments ‒ and perform other interactions with the Mollie server ‒ from your server.