Vanvora

Invoicing and payments

How we invoice and get paid, without a spreadsheet of who owes what

Our invoices come out of the same system as our quotes. Clients see what they owe, pay by UPI or bank transfer, tell us when they have paid, and get one reminder when an instalment falls due. This is how the pieces fit together.

, Founder

Published

The system at a glance

Created from
An accepted quote or proposal
Default terms
14 days
Ways to pay
UPI, bank transfer, international checkout
Reminders
One per due instalment, never repeated

What it replaces

Most small firms do this job by hand, with the tools already on the desk. This is that version, next to the system.

Without it

The usual version

  • Retype the agreed quote into an invoice template, and hope the figures still match
  • Keep a spreadsheet of who has paid, who has part-paid and who is late
  • Ask for a screenshot of the UPI payment, then match it against the bank statement by hand
  • Remember to send reminders, and put off sending the second one
  • Start the project once somebody notices the money has arrived

With it

With the system

  • An invoice is created from an accepted quote or proposal, copying its lines and totals
  • Clients see the balance and pay by UPI with a QR code, bank transfer or an international checkout
  • Clients tell us they have paid with a short form, and our team confirms it
  • A daily job sends one reminder for the earliest instalment that is due and unpaid
  • The first confirmed payment creates the client's project and tells them it has started

How it works

Step by step, in the order it happens.

  1. Raise it from what was agreed

    From an accepted quote, the lines and totals are copied when the invoice is created, so a later edit to the quote never changes it. From a proposal, each module becomes a line, the payment schedule becomes instalments and any early-payment discount carries over.

  2. Issue it

    Issuing emails the client the PDF, showing what has been paid, the balance, and a Paid or Overdue callout. Payment terms default to 14 days, and overdue is worked out live from the due date and the balance.

  3. The client pays

    In the portal they see only the payment account assigned to their invoice: UPI with a QR code for the amount due, bank transfer with IFSC or SWIFT details, or a hosted international checkout. Each option can be switched off everywhere.

  4. The client tells us

    They submit the amount, the method and the UPI transaction ID or bank reference, with an optional note. This is a claim, not a payment, so the balance does not move yet.

  5. We confirm or reject

    Claims wait in a queue, oldest first. Confirming records the payment; rejecting returns it with a note. For a claim to pay in full, the server works out the amount itself, discount included, rather than using the figure the client typed.

  6. The follow-up runs itself

    Once a day, the system sends one reminder for the earliest unpaid instalment that is due, and stamps it so it is never sent twice. Staff can also send one by hand. A confirmed payment emails the client, and the first one starts their project.

Safeguards we built in

The parts nobody sees until something goes wrong. They are what make it safe to use with real clients and real money.

  • A payment claim never touches the balance until our team confirms it
  • Only one pending claim is allowed per invoice
  • Overpayments are rejected, and two people updating the same invoice at once cannot overwrite each other
  • The UPI amount is capped at the outstanding balance
  • Lines and totals are copied at creation, so editing the quote later cannot change what was billed
  • Each reminder is stamped when sent, so the same one never goes out twice
  • Clients only see the payment account assigned to their own invoice
  • Every client-facing endpoint requires sign-in, and accounts lock for 15 minutes after five failed attempts

The stack

  • React portal
  • ASP.NET Core API
  • PostgreSQL
  • QuestPDF
  • Scheduled background jobs
  • UPI QR codes
  • Azure Communication Services email

What we learned

What building it taught us, and what we would tell anyone building the same thing.

  1. 01

    A client saying they have paid is not the same as being paid. Keeping the claim as its own record, confirmed by a person, is what stops a mistyped reference from marking an invoice paid.

  2. 02

    Store as little as possible that can go out of date. Overdue is calculated when it is needed rather than saved, so there is no status to correct by hand when a payment lands.

  3. 03

    We chose one reminder per instalment, sent once, over an escalating sequence. It keeps the tone polite and predictable, and staff can still send one by hand when a relationship needs a personal word.

  4. 04

    Copy at the moment of invoicing; do not link. An invoice that quietly changed because someone tidied up the quote would be worse than no system at all.

The same system, built around how you get paid

Most small businesses already have the pieces: an invoice template, a bank account, a UPI ID and a lot of patience. The work is joining them up, so invoices, payment checks and reminders move on their own while your team confirms the parts that need a person.

Want a system like this in your business?

The first conversation is free. We look at how the work runs today and send a written summary of what we would build first, whether or not you go ahead.