I have been a long time Netlify user and fan, mostly using it for static websites (like this blog). Recently however, I had a requirement to accept donations on a site I run and started looking for ways to do this.
In this article I will describe the steps taken to implement Mollie payments on Netlify Functions for a fully serverless solution.
The full example source code can be found here: GitHub repository
Netlify Functions
A classical approach to this problem would be to build a backend to process payments and connect my Netlify frontend to it. But wouldn´t it be easier (and cheaper) if we can do this in a serverless fashion? Turns out we quite easily can!
Netlify has a concept called Functions, which is a serverless execution environment like any other. The free tier suffices for low to moderate usage.
You can write functions in Typescript, Javascript or Go and they run in a NodeJS (18 or later) environment.
This means that ideally, to save us work and time, we find a payment service provider with a NodeJS client library.
Mollie
There are always various options to choose from but in the end I settled with Mollie. Mollie is a well known European payment service provider and one of the main advantages for my use case was that there are no subscription fees, only transaction fees.
It also turns out there is an officially supported NodeJS API client library for Mollie, so let’s see if we can wire this up!
Setting things up
Mollie
You need to sign up as a business with Mollie in order to receive payments.
It takes a couple of steps and you need to supply some information, but the process is quite straightforward.
Once your account is created, you can find your API keys under https://my.mollie.com/dashboard/your_organization_id/developers/api-keys
Please make sure you use the Test API key until everything works as expected and you’re ready to receive payments.
Netlify
Getting started
If you already have a working Netlify site and are familiar with deploying there, you can skip to setting up Netlify Dev for local testing right away.
How I typically go about hosting stuff on Netlify is by linking sites to a GitHub repo, so they automatically get published whenever I merge something to main. This is a common use case on Netlify and is very easy to setup:
- sign up with Netlify
- create a new site and click “Import an existing project”
- select “Deploy with GitHub”
- you will need to authorize the Netlify application within GitHub (you can limit the repos Netlify has access to)
- select the repo that contains your website
- if your website is not in the root of the repo, configure a base directory in either netlify.toml or by going to Site Configuration -> Build & Deploy -> Build settings
Now, any time you commit something to main, your site will be published. This also goes for the function we’re about to add.
For more details and to fine tune configuration, see the documentation
Setting up Netlify Dev for local testing
While developing functions (or anything else for that matter), it’s extremely handy to be able to iteratively test your changes. Netlify CLI supports a way to run your Netlify site locally, so you can easily test without having to deploy anything.
First, install Netlify CLI:
|
|
You may or may not have to respawn your shell for path modifications before you can use the netlify command.
Now, login to Netlify from your command line:
|
|
This will open a browser so you can authorize the CLI by logging in.
Once logged in, the final step is to link your site to your local project folder:
|
|
Now, you can use commands like “netlify build” to build your project and also “netlify dev” to run a local development server for your website. The Netlify CLI also allows you to set environment variables.
For more information, see Netlify CLI
Setting up your API key in an environment variable
You need the API key from your Mollie account to communicate with the API and the safest way to do this is by storing it in an environment variable in Netlify.
There are two ways to do this:
- Go to Site Configuration -> Environment Variables
- Using Netlify CLI: https://cli.netlify.com/commands/env/
Make sure you use the Test API key supplied by Mollie while you’re testing.
In the example, the variable is called MOLLIE_API_KEY but you can obviously deviate from this.
Creating a function
Routing
In Netlify, many things work by convention (although pretty much anything can be configured to work differently).
Function code is typically stored in a netlify/functions subfolder of your webroot and once deployed, will be accessible automagically on https://yoursite.com/.netlify/functions/helloworld . However, we can configure some redirects to make them accessible through a more commonly used URL pattern, like https://yoursite.com/api/helloworld. We do this by creating a netlify.toml file in the webroot:
|
|
A netlify.toml file is picked up by Netlify during the build and deploy phases and allows you to configure your site in an expressive way.
In this case, we map everything from /api/ to /.netlify/functions/.
NPM
We need various NPM packages for things to work, so from the root of your website, run:
|
|
The validator package is optional, but I use it for some input sanitization as you’ll see later.
.gitignore
In case you don’t have one yet, now would be a good time to add a .gitignore to exclude Netlify and NPM stuff from your repository:
.netlify
node_modules
Mollie.mts
The full source code can be found here and I’ll break it down here piece by piece.
Setting up a Mollie client
This first section retrieves your Mollie API key from the environment and instantiates a Mollie client with it:
|
|
There is a payment amount limit per payment method in Mollie and you will get an error if you exceed this, so it is enforced on the backend. See this list for more information.
Entrypoint
This is the entrypoint for the Netlify function. It will get the original request and a Netlify context passed along.
It does some input validation and if the payment was succesfully created, the user is redirected to the Mollie checkout page (which is part of the created payment):
|
|
Creating a payment
Creating an actual payment is a matter of using the client library with the right request:
|
|
Some things worth mentioning:
- The amount limit is enforced on the backend, because it will result in an error
- The amount itself is broken down in currency and value; value should be a string with two decimals
- The redirectUrl is used to redirect clients after a payment was completed
- The cancelUrl is used to redirect clients after a payment was cancelled
Input sanitization
Just as good practice, input sanitization takes place in two helper functions:
|
|
Testing and deploying
Testing can be done using Netlify Dev as described above and once satisfied, deployed to Netlify automatically when merged to main.
When you go live for real, don´t forget to switch to your Live API key!
Final words
That pretty much sums up the work required to start accepting Mollie payments in a serverless environment. It can be ideal for sites to start without any monetary investment and running costs.
Enjoy!