Netlify Functions TypeError: does not export a function

I’m getting the TypeError:
/src/api/create-payment-intent.js does not export a function.
gatsby-node.ts:542
[site-name]/[gatsby]/src/internal-plugins/functions/gatsby-node.ts:542: 33

On a Stripe.js implementation using Gatsby v4 and Netlify functions. This same code runs just fine in Gatsby v3 implementations. Changing exports.handler to module.exports executes the function but doesn’t return a response.

create-payment-intent.js:

const stripe = require("stripe")('sk_test_xxx);

exports.handler = async (event) => {
    const paymentObject = (event.body);
    console.log(paymentObject)

    const amount = paymentObject.amount * 100;
    const description = paymentObject.description;
    
    try {
        const paymentIntent = await stripe.paymentIntents.create({
            amount,
            currency: 'usd',
            description,
            receipt_email: paymentObject.email,
                metadata: {
                businessName: paymentObject.businessName,
                },
            automatic_payment_methods: {
                enabled: true,
                },
        });
        console.log(paymentIntent.client_secret);
        return {
            statusCode: 200,
            body: { 
              paymentIntent, 
              clientSecret: paymentIntent.client_secret
            }
          };
    } catch (error) {
        console.log({ error });
        return {
            statusCode: 400,
            body: { error },
    };
    }
};

Hi @jgunderson,

That code looks good to me. If you’re still having issues, could you send us a reproduction repo so we can see what might be happening?

Hi @hrishikesh,

I’ll try to get a repo spun up today. I was able to solve this using export default async function handler as shown below, but I’d still like to figure out why this code isn’t working in our Gatsby v4 site.

const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);

export default async function handler(req, res){  
    const paymentObject = req.body;
  
    const amount = paymentObject.amount * 100;
    const description = paymentObject.description
    const businessOwner = paymentObject.metadata.Business_Owner;
    const businessName = paymentObject.metadata.Business_Name;
    const businessPhone = paymentObject.metadata.Business_Phone;
    const ownerOfShortTermRental = paymentObject.metadata.Owner_of_Short_Term_Rental;
    const email = paymentObject.email;
  
    const paymentIntent = await stripe.paymentIntents.create({
        amount,
        currency: 'usd',
        description,
        receipt_email: email,
        metadata: {
          businessOwner,
          businessName,
          ownerOfShortTermRental,
          businessPhone,
        }
      });
      const customer = await stripe.customers.create({
        name: businessName,
        email: email,
      });
      

      // JSON must be stringified before being sent to the client or it fails in production
      res.status(200)
        .send(JSON.stringify({ 
        paymentIntent, 
        clientSecret: paymentIntent.client_secret,
        customer,
      })
      );
  };

I’ll try to get some ideas about that. Thanks for sharing.

I haven’t looked into it in depth yet, but I think the problem could be that Gatsby requires some middleware to parse the data:
Gatsby Middleware and Helpers

Can we bypass Gatsby Functions to simply use Netlify Functions so that we don’t need middleware?

Hey @jgunderson,

Our Gatsby experts (and most of the company) is out for holidays, so my previous confirmation might take time. But, I think you can skip Gatsby functions by specifically deploying functions as Netlify functions instead of making the plugin do it for you. Does this sound doable?