Using n8n + Automatisch to generate invoices & log expenses with alf.io, Invoice Ninja and stripe
I use Invoice ninja for the accounting of our non-profit. It’s really great, because it‘s open source and self host-able (I love self hosting💚)...
Services used in this project:
Alf.io is a free and open source event attendance management system, developed for event organizers who care about privacy, security and fair pricing policy for their customers.It features an ecosystem of tools to cover the lifecycle of an event from ticket distribution, to event management, to reporting. - alf.io
Automatisch is a business automation tool that lets you connect different services like Twitter, Slack, and more to automate your business processes.
- Automatisch
n8n is a free and source-available workflow automation tool. - n8n.io
Invoice Ninja is an invoicing application which makes sending invoices and receiving payments simple and easy. - invoiceninja.com
Stripe provides application programming interfaces that web developers can use to integrate payment processing into their websites and mobile applications. - fastcompany.com
A little backstory
I use Invoice ninja for the accounting of our non-profit. It’s really great, because it‘s open source and self host-able (I love self hosting💚). I generate all of our invoices there and also log the expenses. We also have a bigcartel shop on which we sell our band’s merchandise, and since the order numbers are generally low, I manually add customers and send them the invoices. The payment gateway we use is Stripe. Stripe also takes a small percentage of each transaction, that I manually log as an expense.
The problem(s)
The manual solution works great when dealing with a small quantity of orders and invoices. But with selling concert tickets, I anticipated a big rise in orders and consequently in invoices - Imagine having to manually add a 100 customers and generate a 100 invoices and log 100 expenses - it’s just too much work.
While setting up alf.io, I ran into a problem; alf.io supports two modes of invoicing, either it generates the invoice or it doesn’t - if it doesn’t generate the invoice you can’t use the invoice option on check out - you can’t collect the customer billing data.
At first I tried setting up custom fields, but that meant that for each ticket, customer would have to fill in the address, which isn’t really practical. You can set the fields as “not required”, but then you’re relying on the user to type in the address at least once - not good enough.
First part of the solution
Luckily alf.io supports extensions and custom invoice naming/numbering. That means that we can write custom code when certain events fire. In our case I need to get the number of the invoice from our Invoice Ninja instance, which we can get from the API, then alf.io generates an Invoice using my numbering/naming scheme and sends it to the customer.
Second part of the solution
But sending the correctly numbered invoice to the customer is only the first part. The real challenge is to get the same invoice and the Stripe fee to Invoice Ninja. For that I used Automatisch and n8n webhooks. Both support Invoice Ninja as an Intergration, but I found it to be inconsistent - i.e. while Automatisch supports creating a Client it can’t read clients directly from it, and it also has some quirks regarding dates (I couldn’t get the translation from UNIX millis to dd/MM/yyyy to work. And while all of those things work in n8n, creating an invoice with it is broken - you can’t add products.
Third part of the solution
By now you’d think that the solution should be straight forward - alf.io gets the invoice number from Invoice Ninja and then using the combination of Automatisch and n8n we create a new client (if it doesn’t already exist), generate a invoice (for accounting) and finally get the fee from Stripe’s api and log it as an expense - oh boy if only life was that simple.
The thing is, by default alf.io RESERVATION_CONFIRMED event returns a not-that-useful object - it's missing the number of tickets, types of tickets,...
I really struggled on how to get the exact number of tickets and their category, event with the API calls. The API (v1) is documented in the docs. While reading through some issues on their github, I stumbled across the mention of a feature-full, newer and advanced v2 API, that isn't yet documented in the docs. Most importantly there is a reservation endpoint, from which you can get ALL the information of the reservation (shown below).
Stripe - the fourth horseman
As mentioned before both Automatisch and n8n have their pros and cons in regards to the extension they offer. I couldn't find the option for "Recent balance transactions" from n8n's rich number of options in the Stripe intergration, but in Automatisch there was one. But of course, because life is not fair, Invoice ninja intergration in Automatisch doesn't support adding expenses.
The solution
The flow of my solution is:
- alf.io -> INVOICE_GENERATION event (GET invoice number from Invoice Ninja)
- alf.io -> Send invoice to client
- alf.io -> RESERVATION_CONFIRMED event (POST reservation_data to n8n
- n8n
- & 6. Automatisch
- n8n
Basically, alf.io gets the invoice number from Invoice Ninja’s API, sends it to the client, then when RESERVATION_CONFIRMED event fires it sends a POST request with reservation details to a webhook in the n8n workflow.
n8n then gets detailed reservation data from alfio v2 api and also in paralel extracts ticket summary and cost recieved in the webhook. After that it checks if client already exists in invoice ninja, if it doesn't it creates a new client and then sends data to a Automatisch webhook (If client already exists, it skips the client creation part). Automatisch then formats the data and creates a new invoice in Invoice Ninja.
The stripe part is solved with Automatisch checking for new balance transactions every 15 minutes. If there is a new transaction, it formats the fee amount (stripe sends it as an integer, not as a float, so Automatisch multiples the fee with 0.01), and sends the data to n8n. n8n then checks if fee is more than 0, and if it is, creates an expense in Invoice Ninja.
Conclusion
This solution saves me a ton of time when dealing with invoicing with our ticket sales. That being said, the solution is not 100% perfect - for some reason the stripe expense gets logged at a date 5/3/0001 instead of the actual date (I will fix this in the future), and I have a feeling I can still optimise it a bit more. When the solution will be completly finished I plan to release a tutorial here, but for now I just wanted to write about it.
I really hope you enjoyed this article, since it is the first one I have ever written! If you have any questions or suggestion let me know in the comments!
To view/post comments enable functionality cookies here