nm

Say hello :)

Say hello :)

nm

Say hello :)

Say hello :)

Marcus - AI-Powered Invoicing Agent

Marcus - AI-Powered Invoicing Agent

Overview

Marcus is an AI agent that automates billing management—from following up with clients after an invoice is created to reconciling payments and marking invoices as paid.


When an invoice is created in Stripe, Marcus follows up with clients, shares the invoice link, and manages personalized replies. Once payment is made, Marcus automatically closes the loop.

Users can also upload a bank statement or connect their bank via Plaid, allowing Marcus to match payments to invoices and mark them as paid—saving time and reducing manual effort.

I owned the design for this feature from 0-1, collaborating closely with the founders and engineers to bring it to life.

The goal was to create an intuitive, seamless experience that simplifies billing and invoice management for users using AI.

Role

Founding Product Designer

Company

Mesha

Timeline

2023

Who is ‘Marcus’, and why do you need him?

Meet Marcus

Marcus was created to solve the time-consuming challenge of managing invoices and chasing payments. By automating the invoicing process, follow-ups, and payment reconciliation, Marcus helps businesses streamline their billing operations, allowing users to focus on more strategic tasks.

Discovering the need

During initial user research, we uncovered a recurring pain point: business owners and teams were spending a significant amount of time manually sending invoices, following up with clients for payments, and reconciling records. This process was not only tedious but often prone to human error, leading to delayed payments and unnecessary back-and-forth communication.

The need for a solution became clear—one that could automate these repetitive tasks while ensuring accuracy and freeing up users’ time to focus on growing their business. That's where Marcus came in, designed to tackle these challenges head-on and provide seamless billing automation.

The problem we set out to solve

Managing invoices and payments was time-consuming and caused delays in cash flow.

Manually tracking hundreds of invoices is time-consuming

Too much back-and-forth with follow-ups.

Missed payments or delayed reconciliations can be frustrating

The Version One

The basic version to test our hypothesis

For the first version, we decided to keep it simple and build only the essentials. This way, we can get it faster to our users, get feedback and iterate.





Users connect their Stripe account so we can issue and track invoices. As soon as an invoice is created in Stripe, Marcus automatically sends an initial email to the client. This email serves as the first contact in the payment process, giving clients all the information they need to pay promptly. From there, the idea is for Marcus to send reminders if the invoice isn’t paid by the due date.

Shipping fast is key in startups. The quicker you launch, the faster you learn from customers, iterate, and uncover what truly delivers value.

Created default reminder sequence based on standard industry practices

We decided to add a default reminder flow that is based on standard industry practices. Marcus monitors Stripe daily for unpaid invoices. If there’s no response after 3 reminders, Marcus escalates and sends an email to inform the user.

The reminder sequence stops immediately once Stripe confirms payment.

First Reminder

A gentle nudge with an invoice summary and a Stripe payment link.

Sent 3 days before the invoice due date.

Second Reminder

Another reminder with invoice details and a Stripe payment link.

Sent 7 days after the first reminder.

Third Reminder

A more urgent reminder, restating the invoice details and including the Stripe payment link.

Sent 10 days after the second reminder.

Ability to customise

To get this out quickly, we decided not to add options for editing or adding extra steps to the default flow, except for letting users choose when to send the first email after an invoice is issued.



We also identified the need for the user to manually pause or stop the sequence because there might be cases where the client resolves the issue directly, making further follow-ups unnecessary. So we added options to reschedule, stop, or pause the flow for each client as needed. 





It’s not the best solution, but it was definitely good enough, it fit our timeline and goal to get early feedback from users as soon as possible. I believe perfect is the enemy of good and it’s always better to ship something today than something better tomorrow. This way, we can build and improve the product together with our users.

Also, Marcus learns

Marcus learns from client replies and adjusts the follow-up flow accordingly. For example, if a client says they’ll pay in 10 days, Marcus will reschedule the follow-up for the day after that.



Marcus also analyzes past payment behavior to customize reminders. For instance, if a client usually pays on Mondays, Marcus will pick up on that pattern and wait until the next Monday before starting the follow-up sequence to see if the invoice gets paid.

Edge cases

We also had to consider what happens if a client decides to stop the service midway or wants to escalate an issue to the user. We decided it makes sense for Marcus to pause the sequence and send an email to the user in such cases.

A dashboard to monitor

It’s essential to have a dashboard where users can monitor all sequences. This way, they can easily spot things that need their attention, like unpaid invoices after the follow-up flow, service stoppages, or escalated issues.

Marketing video created and prototyped in Figma

Feedback and insights

Generic flow was not sufficient

The generic flow just wasn’t enough for a lot of users. They wanted more flexibility in the reminder sequence—like being able to send reminders even before the due date and change the content to match their tone.

And since each client relationship is different, they needed the option to customize the sequence for each client individually.

This was something we anticipated, and these were the most common requests—which made a lot of sense.

Clients don’t always pay using the stripe invoice link

This was an incredibly valuable insight we hadn’t expected.

Right now, Marcus sends reminders based on the invoice status in Stripe. But not every client pays through the Stripe link - some pay via bank transfers. So even when a client pays via bank transfer, Marcus keeps sending reminders until users manually update the status to paid in Stripe.

It’d be super cool if users could connect their bank accounts (we knew Plaid could make this possible!) or upload bank statements, so Marcus can automatically match these payments in both the app and Stripe, saving users a ton of time and hassle.

I love data

I use FullStory to see how users actually interact with the product. It gives us a great picture of which features they’re using and which ones they’re not. This way, we can make the useful features even better and remove what’s not needed, keeping things simple and efficient.

In the heatmap from the past 30 days, one thing really stood out: 64% of users who used this feature clicked on 'Reschedule,' 54% on 'Pause,' and 40% on 'Stop' in the reminder sequence.

This confirmed that the product would be much better if we allowed users to set up their own custom reminder sequences and automatically reconcile payments made outside of Stripe. That way, users wouldn’t have to come back to reschedule, pause, or stop sequences manually.

v2

A more robust tool

We had a solid plan set for v2: giving users the ability to create custom reminder sequence and enabling automatic payment reconciliation. My mantra is to always focus on the essentials so users can get things done.

Custom reminder sequence

We added the ability to change dates for each reminders in the default flow and the ability to change the content based on tone. So, when Marcus tailors the next reply based on the client’s response, he’ll keep using the tone set by the user.

Automatic payment reconcillation

With Plaid’s bank transaction feed, we set up an automated system to check key details—like amount, date, and reference—and automatically mark the matching invoices as 'Paid' in Marcus and Stripe. This cuts down on manual work and reconciles payment made outside of stripe automatically.

Retrospective

Not gonna lie, when I first started out, I was intimidated by developer language (and, honestly, developers too). But over time, I learned to speak their language, get in the trenches with them in PRs, and work alongside them.

Now, I genuinely enjoy collaborating with developers and I’ve realised how crucial it is for the product—because at the end of the day, what’s in the app is what users actually experience, not just what’s in the design file.

Brigding the gap with variables. Adding Tailwind classes as Figma variables was a game changer. It cut down confusion and made design consistency way easier across the app.

Bettering your workflow/process always. No two teams, products, or engineers work the same way. I don’t follow a rigid process for everyone—I adapt my workflow based on who I’m working with. That’s helped me build stronger relationships and make collaboration smoother.

Tradeoffs. Rebuilding everything at once was too risky, so we replaced components gradually but that made the app look inconsistent in a few places for a while. But it kept our product velocity high—totally worth the trade-off