Back to site

Stripe invoices and pay links

Every invoice in The Contractor Codex is a real Stripe invoice. The portal doesn't run its own payment system. It builds the invoice in Stripe under your connected account and shows the client a Pay Now button that opens Stripe's checkout page. Money flows from your client straight to your bank.

Where invoices come from

Three sources.

1. Quote acceptance (automatic)

When a client accepts a quote, the portal creates the Stripe invoice for you based on the quote's billing mode. The line items, totals, and client all come from the quote.

2. An invoice you create by hand

From a client's workspace, click Billing at the right of the tab strip, then use the New Invoice panel on the Invoices tab. Full steps under "Creating an invoice by hand" below.

3. Recurring retainer billing (automatic)

When a client accepts a quote that includes one of your retainer plans, the portal switches on monthly billing for that client by itself and prepares each month's invoice as a draft for you to review. You can also switch it on for any client yourself, and change how often it runs, from the Automatic Billing card on their Invoices tab. Read "Recurring retainer billing" below before you promise a client a monthly plan.

What the client sees

Every invoice produces:

  • A Stripe-hosted invoice page at an address like https://invoice.stripe.com/.... This is what a Pay Now link opens.
  • A PDF of the invoice, downloadable from that page.
  • An email from Stripe with the invoice, plus a short note from the portal with the same pay link.

The hosted page shows the Business Name you set in Settings. The portal pushes that name to Stripe when you save it and when you finish connecting your account, so clients see your business name instead of whatever the Stripe account was registered under. The logo and colors on that page come from your own branding settings inside Stripe, not from the portal.

The client can pay by:

  • Card (Visa, Mastercard, Amex, Discover)
  • ACH bank transfer (US bank accounts)
  • Link (one-click for repeat payers)

Turn each one on or off under Card Payments, ACH Bank Payments, and Link in Settings → Payments. If you switch all three off, the portal falls back to card so the invoice is still payable.

Pay Now links, where they appear

The portal puts a pay link everywhere a client might look for one:

  • The accepted-quote page, right after they sign
  • The portal dashboard's Outstanding card
  • The client's Billing / Pay page, which lists every open invoice
  • The client's Projects page, on the project the invoice covers
  • The invoice email

They all open the same Stripe-hosted invoice page, so it doesn't matter which one the client uses.

The payment receipt email is the one exception. It goes out after the money lands, so it links to the Stripe receipt and the invoice PDF instead of a pay button.

Invoice statuses

Stripe's statuses, mirrored in the portal:

  • draft: created but not sent. The client can't see or pay it yet.
  • open: sent. The client can pay, and you can void it.
  • paid: payment received. Funds are on their way to your bank.
  • void: cancelled. It can't be paid and it drops out of your outstanding totals.
  • uncollectible: written off as bad debt.
  • payment failed: a payment attempt was declined.
  • action required: the client's bank wants extra verification, such as 3D Secure. The invoice is still payable.

The portal shows the status as a badge on every invoice card.

How the status stays current

Stripe tells the portal the moment an invoice is paid, fails, is voided, or is written off, and the portal updates the invoice and fires the matching notifications right away.

If one of those messages ever goes missing, the client's Billing / Pay page pulls the live status straight from Stripe on every visit and corrects itself. So if a client just paid and you're not seeing it yet, have them open their billing page and it will sync.

Refunds

To refund a paid invoice, open the client's workspace, go to the Invoices tab, and click Issue Refund on the invoice. You can refund the full amount or part of it. The money goes back through Stripe to the card or bank the client paid with.

Issue Refund only appears on invoices that are actually paid and still have something left to refund.

See Refunds and disputes for the full flow.

Writing off an invoice you'll never collect

The portal has no "mark uncollectible" button. Open the invoice in Stripe using the View in Stripe link on the invoice card and write it off there. Stripe tells the portal, and the invoice moves to uncollectible and drops out of your outstanding totals. Payment reminders stop.

If you have an AI assistant connected to your account (see MCP server), you can ask it to write off an open invoice instead. It asks you to confirm before it does anything.

There is no automatic "write it off after 90 days" setting. This is always a call you make per invoice.

Recurring retainer billing

This is the part most contractors get wrong, so read it carefully. Recurring billing in the portal is not something you switch on for a client. It switches itself on, and it works one specific way.

How it starts

A client goes on recurring billing when they accept a quote that includes exactly one of the retainer plans from your Service Catalog (Pricing). At acceptance the portal:

  1. Sets that client's Retainer type to the plan.
  2. Turns on monthly billing, dated the 1st of the month.
  3. Bills the first month on the acceptance invoice, so the client pays it straight away.
  4. Sends you a notification saying the retainer is live and when the next invoice drafts.

Read that notification. If nothing was collected at acceptance, it says so and tells you to check the first month yourself.

It won't start recurring billing if the quote carries more than one retainer plan, if the client is already on a different retainer, or if recurring billing is already running for them. In those cases you get a notification explaining why, and nothing is switched on.

Custom retainer plans written by the AI quote drafter bill their first month at acceptance but do not start recurring billing, because they aren't in your Service Catalog. The same goes for annual line items: the first year is billed at acceptance, and renewals are on you to invoice.

What happens each month

The portal checks every 6 hours for clients whose next billing date has passed. For each one it:

  • Works out the period that just ended, one month back.
  • Adds up that client's retainer fee, any billable time logged on their projects, and any approved surcharges, minus active discounts.
  • Saves it as a draft invoice for your review. It does not send anything to the client.
  • Notifies you that it's ready, with a link straight to it.
  • Moves the client's next billing date forward one month.

To send it, open the draft from the notification (or from Billing → Invoices on the client) and click Send Invoice.

Nothing bills a client without you

Every recurring invoice lands as a draft. There is no auto-send mode in the portal today, so a retainer client is never charged until you open the draft and press Send Invoice.

It won't double-bill. If the period is already covered by an invoice you raised by hand, or by the month the client prepaid at acceptance, the run skips it and moves the date forward. If only part of the period was already covered, you get a notification telling you to capture the rest yourself.

It also skips archived clients, and it stops entirely once a cancellation takes effect.

Where to see recurring invoices

In the client's workspace, open the Invoices tab and pick the Recurring sub-tab. That's a list of what has already been billed on the retainer. It is a record, not a control panel.

Changing the amount

The retainer amount comes from the plan on your Service Catalog, so change it there:

  • To reprice the plan for everyone on it, edit its Monthly fee under Pricing → Rate Card → Retainers.
  • To move one client to a different plan, open their workspace, go to the Details tab, and change Retainer type.

Either way, the next monthly draft picks up the new amount. Invoices already sent don't move.

Stopping a retainer

Three ways:

  • Switch it off yourself. On the client's Invoices tab, turn off Bill this client on a schedule in the Automatic Billing card and press Save. Your cycle and billing day are remembered, so you can switch it back on later without setting them up again.
  • The client asks to cancel and you approve it. See "When a client asks to cancel" below.
  • Archive the client. Their monthly runs stop producing invoices.

Changing the schedule

The Automatic Billing card on the client's Invoices tab controls all of it:

  • How often: monthly or quarterly.
  • Bill on this day of the month: any day from 1 to 28. Days past 28 aren't offered, so a schedule never skips a short month.
  • Review before sending: leave it on Draft only, I review and send and each invoice waits for you on the Invoices tab. Switch it to Send automatically, no review and the invoice is emailed to the client on its own.
Before you turn on automatic sending

On Send automatically, no review nobody sees the invoice before the client does. The amount is built from their tracked billable time, approved surcharges, and the retainer fee, minus any active discounts, so an unexpected week of logged time goes out as-is. You get a notification after it sends, not before. If you are not certain the inputs are always right, leave it on draft.

When a client asks to cancel

Clients on a retainer can end it themselves. On their Billing / Pay page they click Cancel retainer and give a reason.

The end date defaults to the end of their current billing cycle. If that's less than 5 days away, it moves to the end of the following cycle so you have time to respond. The retainer keeps billing normally until that date arrives.

The request shows at the top of their workspace with two buttons:

  • Approve cancellation locks in the end date. Recurring billing switches off automatically when the date arrives, and the client is emailed.
  • Decline request keeps the retainer running and tells the client.

Either button takes an optional note that goes to the client.

If you don't respond by the end date, the cancellation applies on its own. There is no counter-offer button. If you want different terms, talk to the client and have them withdraw the request from their billing page and file a new one.

The service fee

Every invoice carries a service fee that Stripe collects automatically and routes to the platform: 0.8% on Standard, 0.1% on Pro. You see it on the Stripe side. The client never does, and the invoice total is unchanged.

Invoice memo and footer

Set a Default Invoice Memo and Default Invoice Footer in Settings → Payments. They appear on every Stripe-hosted invoice page and PDF. Useful for lines like "Thanks for your business" or "Payment due Net 30."

Creating an invoice by hand

For one-off billing, such as hourly work outside a quote:

  1. Open the client at /admin/clients.
  2. Click Billing at the right of the tab strip.
  3. On the Invoices tab, find the New Invoice panel.
  4. Pick a Project and a Billing month.
  5. Click Create Snapshot.

The portal freezes that month's billable hours, rates, approved surcharges, and discounts into an invoice you can review before anything goes out.

On the invoice you can still adjust each line: project name, summary, total minutes, billable minutes, included minutes, overage minutes, and the dollar value. When it looks right, click Send Invoice.

After it's sent you get two more buttons: Resend, which voids the current invoice and issues a fresh one, and Void, which cancels it so the client can't pay it. Voiding returns those hours to unbilled so you can invoice them again later.

The date range and the currency aren't per-invoice choices. The range is the billing month you picked, and the currency is your organization's, set in Settings.

Quick-billing any email (Send Invoice)

Sometimes you need to bill someone who isn't a client yet and doesn't need a project: a friend-of-a-friend job, a single consult, a deposit before you commit to onboarding. Send invoice (from the dashboard's New menu, or /admin/send-invoice) bills any email address a fixed amount with line items you type in.

  • A brand-new email gets a lightweight billing-only contact behind the scenes. It stays out of your Clients list, but the money counts in your revenue like any other payment.
  • If the email already belongs to a client, the invoice attaches to them normally.

Snapshots, the record behind each invoice

Every invoice the portal raises is backed by a snapshot: a frozen capture of the billable work and amounts at the moment it was created. The snapshot is what the Stripe invoice is built from. Stripe itself only ever sees the line items and the total.

You can reopen a snapshot in the portal to see exactly which hours, dates, and rates went into it. That stays true even if the project changes afterwards, which is what makes it useful when a client questions a bill.

Invoice status badges across the portal

Every place an invoice shows up uses the same badge, so the same status always reads the same way:

  • paid → green "Paid"
  • open → amber "Invoice Sent"
  • draft → grey "Draft"
  • void → red "Voided"
  • uncollectible → red "Uncollectible"
  • payment failed → red "Payment Failed"
  • action required → red "Action Required"

If you see different labels for the same status in different places, that's a bug. Report it.

If the portal and Stripe disagree

The client's Billing / Pay page pulls live status from Stripe on every visit, so asking the client to open it will resolve most drift.

There is no "sync now" button on the admin side. The next update from Stripe, or the client opening their billing page, will bring it in line. If you're still stuck more than 10 minutes after a payment, contact support.

Invoice numbering

Stripe assigns invoice numbers automatically. You can change the format in your Stripe dashboard under Invoices → Settings. The portal uses whatever Stripe generates.

For your records, invoice numbers are unique within your Stripe account, never reused, and stay the same even if the invoice is voided or refunded.

Payment terms

Set Invoice Due Days in Settings → Payments. The default is 30 days and the highest the portal accepts is 120. Every invoice it creates uses that number, unless the project the invoice came from has its own terms attached through a service plan, which win.

To change the due date on one invoice only, open it with View in Stripe and edit it there.

Email and in-app notifications

Around an invoice you'll see:

  1. Invoice sent. Stripe emails the invoice, and the portal sends the client a short note with the pay link.
  2. Invoice paid. You get an alert in the portal, the client gets a receipt email.
  3. Payment failed. Both of you are told in the portal, and the overdue reminder ladder takes over from there.
  4. Action required. Both of you are told the client's bank wants extra verification.
  5. Invoice voided. The client sees a note in their portal saying they no longer owe it. No email goes out.

There is no "client opened the invoice" alert. That exists for quotes, not invoices.

You can't switch the invoice emails themselves off. Settings → Notifications covers client onboarding and approval responses only, and the reminder timing for overdue invoices lives in Settings → Payments. See Late fees and dunning.

Currency

Currency is set once for your whole organization under Default Currency in Settings. The choices are USD, EUR, GBP, CAD, and AUD. Every invoice the portal raises uses it. There is no per-invoice or per-line currency.

The client is charged in that currency, and Stripe converts it to your account's currency at their rate when they pay out. The service fee is taken in the invoice currency before conversion.