Everything you need to install, set up and run Clientlane, the self-hosted quotes, invoices and client portal. Want to see it first? Open the demo en vivo.
Contents
- Requisitos
- Installation
- Cron job
- First steps
- Clients and catalogue
- Quotes
- Invoices and credit notes
- Payments and reminders
- Recurring invoices
- Online payments
- Client area
- Informes
- Webhooks
- Facturas electrónicas
- Numbers
- Emails
- Team and roles
- Licence and updates
- Backups and moving
- Troubleshooting
Requisitos
- PHP 8.3 or newer with the extensions
pdo,mbstring,openssl,curl,json,tokenizer,xml,ctype,fileinfoandzip.gd(logos in PDFs) andintl(amounts written the way each language writes them) are recommended. - A database: MySQL 8 or MariaDB 10.6+ (an empty database and its user), or SQLite for small businesses (nothing to create).
- A domain or subdomain with HTTPS (needed for online payments and the client area).
- A way to run a task every minute: a cron line, or a web cron calling a secret address. It sends reminders, recurring invoices and webhooks.
The installer checks all of this and shows what is missing in red.
Installation
- Create the site in your hosting panel and point its document root to the
publicfolder of Clientlane. If your host does not let you choose the document root, upload Clientlane into the site folder anyway: the.htaccessfile at the root sends visitors topublicand blocks the private files. - MySQL only: create an empty database and a user with all rights on it.
- Upload the zip into the site folder and extract it. The
storageandbootstrap/cachefolders and the.envfile must be writable by PHP (most shared hosts already allow this). For SQLite, thedatabasefolder must be writable too. - Open
https://your-site.com/installand fill in the form: name, address, database and your owner account. The installer creates the tables, then locks itself for good. - Add the cron job shown at the end of the installer (see below).
Cron job
With a command line (cPanel “Cron Jobs”, Plesk “Scheduled Tasks”, or SSH):
* * * * * php /path/to/clientlane/artisan clientlane:cron >> /dev/null 2>&1
If your host has no cron, use a web cron service and call https://your-site.com/cron/YOURKEY every minute. The full address with its secret key is in Settings. The dashboard tells you when the cron has not run for a while.
First steps
- My account: turn on two-factor sign-in.
- Licence & updates: enter your licence key (copies bought on the Aluleth Market).
- Company: your company details and logo, how clients pay you (bank details), and the defaults of your quotes and invoices: currencies, prices before tax or tax included, tax rates, numbers, quote validity, payment delay, terms and footer.
- Settings: name, default language, time zone and sending emails.
- Team: add the people who work with you (see Team and roles).
The dashboard keeps a “Getting started” list until these steps are done. The rules for quotes and invoices are not the same in every country: check with your accountant what yours must show.
Clients and catalogue
- Clients: companies or people, with legal name, address (printed the way the client’s country writes it), tax and company numbers, currency, language, payment delay, tags and notes. Add contacts to a company and mark the one who receives the documents.
- Import a CSV file (Clients → Import): save your list from Excel, Google Sheets or your old tool as CSV. The first line must hold the column titles; Clientlane matches them (Name, Email, City, VAT number… in English, French, Spanish, German or Portuguese) and you can change each column before importing. Clients already there (same name or same email) are skipped. Export gives the list back as CSV.
- Archive a client you no longer work with: their documents stay, they leave your lists. A client with documents cannot be deleted.
- Catalogue: the products and services you sell often, with their unit, price and tax rate. You pick them when you write a quote or an invoice.
Quotes
- Quotes → New quote: pick the client, add lines from the catalogue or typed by hand, sections to group them, discounts per line or on the total, and a deposit in percent. Mark a line as an option: your client ticks it or not, and the totals follow.
- Save and send: the quote gets its number, and your client receives an email with the PDF and a link. You can also only mark it as sent and share the link yourself.
- On that page, your client chooses the options, then accepts with their name and a signature drawn with the finger or the mouse (or, with a keyboard or a screen reader, by typing their full name again: How do you sign? → Type my name as my signature), or declines with a reason. If the options or the quote change while the page is open, the client is asked to check it again before accepting; once accepted, nothing in the quote can change. You receive an email either way.
- The signed quote keeps the date, the IP address and a fingerprint of what was signed; its PDF shows the signature.
- A quote past its validity date shows as expired. Duplicate any quote to start a new one.
The rules for quotes and signatures differ from country to country: check with your accountant or lawyer what yours require.
Invoices and credit notes
- From an accepted quote: its page offers Deposit invoice (when the quote asks for a deposit), Invoice for the whole quote, then Final invoice, which takes off the deposit invoices already issued, at each tax rate. The final invoice can be made once no deposit invoice is still a draft, and Clientlane checks again when it is issued that it takes off exactly the deposits issued, so the invoices of a quote always add up to the quote. By default, when a client signs a quote that asks for a deposit, the deposit invoice is issued at once so they can pay it online (Company → Online payments).
- From scratch: Invoices → New invoice.
- Each invoice starts as a draft you can change. It gets its number when it is issued (emailed with the PDF and a link, or only issued). From then on it can no longer be changed nor deleted.
- Credit notes: to correct or cancel an issued invoice, make a credit note from it. It starts with the same lines; keep only what you credit. The invoice goes down by the same amount and shows as credited when nothing is left. Mark the credit note as refunded once you have paid the money back.
Payments and reminders
- Record a payment on the invoice page: amount, date, how (bank transfer, card, cash, check, PayPal, Stripe, other) and a reference. The invoice becomes Partly paid, then Paid. It shows as Overdue once its due date has passed.
- Your client’s invoice page shows what is left to pay and your bank details.
- Automatic reminders (Company → Quotes and invoices → Payment reminders): an email a few days before the due date and on the days after it you choose (for example 1, 7 and 14). They are written in the client’s language. Each invoice can turn them off, and you can send one by hand. A reminder counts as sent only once the mail server accepted it: if sending fails, it is tried again after 15 minutes, 1 hour, 6 hours and 24 hours, and the invoice page shows the reason.
Recurring invoices
Invoices → Recurring: write the invoice once, then pick how often (every week, month, 3 months or year), the first date and, if you want, an end date. On each date Clientlane makes the invoice and emails it, or leaves a draft for you to check. In the title and subject, {month}, {quarter} and {year} become the period (for example “Website care – {month}”). Pause it, resume it or make the next invoice now at any time. Once its first invoice is made, how often and the first date stay as they are (they decide the next dates); you can still change the lines, the client and the end date. With an end date, the invoice dated on that day is the last one; a recurring invoice paused and started again after its end date ends instead. It needs the cron job.
Online payments
In Company → Online payments. Clients pay with your own accounts: Clientlane takes no fee and never sees card numbers.
Stripe (cards)
- Paste your secret key (Stripe → Developers → API keys). A key starting with
sk_test_takes no real money. - Add a webhook (Developers → Webhooks → Add endpoint) with the address shown on the page and the events
checkout.session.completedandcheckout.session.async_payment_succeeded, then paste its signing secret (whsec_…). The payment is then recorded even if your client closes the page before coming back.
PayPal
- Create an app on developer.paypal.com (Apps & Credentials), paste its client ID and secret, and choose Live, or Sandbox for tests.
Save and check tests the keys with each service. Your clients then see Pay by card and Pay with PayPal on the invoice page; the payment is added to the invoice and you receive an email. Keys are stored encrypted; only their last 4 characters are shown. The site must be on HTTPS for real payments.
Client area
- Give your clients the address
https://your-site.com/portal(also shown in the invoice emails). They type their email and receive a sign-in link valid 30 minutes; no password to remember. - They see what they have to pay, the quotes waiting for an answer, all their documents with PDFs, and their payments.
- Turn it off for everyone in Company → Client area, or for one client from their page, where Send a sign-in link emails them a link.
Informes
Informes shows, for a period and a currency: invoiced (before tax, credit notes taken off), received, still to be paid and overdue, the share of quotes accepted, a 12-month chart, the tax per rate and your best clients. Export for the accountant downloads the invoices and credit notes of the period as a CSV file (credit notes as negative amounts, ready for Excel).
Webhooks
Webhooks in the menu sends events to Zapier (Webhooks by Zapier → Catch Hook), Make (Custom webhook), n8n (Webhook node) or your own code. Add up to 10 addresses, pick the events and use Send a test.
| Event | When |
|---|---|
client.created | A client is added |
quote.sent | A quote is sent |
quote.accepted | A quote is accepted (with the name of the signer) |
quote.declined | A quote is declined |
invoice.issued | An invoice is issued |
invoice.paid | An invoice is fully paid |
payment.received | A payment is recorded, by hand or online |
credit.issued | A credit note is issued |
Each call is a POST with a JSON body:
{
"id": "6c0f3a1e-…",
"event": "invoice.issued",
"created_at": "2026-10-25T09:14:03+00:00",
"data": {
"invoice": {
"id": 42, "type": "invoice", "number": "INV-2026-0042", "status": "sent",
"issue_date": "2026-10-25", "due_date": "2026-11-09", "currency": "USD",
"subtotal": 1200, "tax_total": 0, "total": 1200,
"amount_paid": 0, "amount_due": 1200,
"client": { "id": 7, "name": "Riverside Bakery", "email": "…", "country": "US" },
"lines": [ { "name": "Website care", "quantity": 1, "unit_price": 1200, "tax_rate": 0, "amount": 1200 } ],
"public_url": "https://your-site.com/i/…", "admin_url": "https://your-site.com/admin/invoices/42"
}
}
}
The header X-Clientlane-Signature holds sha256= followed by the HMAC-SHA256 of the raw body with the webhook’s secret. To check it in PHP:
$body = file_get_contents('php://input');
$expected = 'sha256=' . hash_hmac('sha256', $body, 'YOUR_SECRET');
if (! hash_equals($expected, $_SERVER['HTTP_X_CLIENTLANE_SIGNATURE'] ?? '')) {
http_response_code(401);
exit;
}
A call that fails is tried again after 1, 5 and 30 minutes; the last 100 calls are listed with their answer. Webhooks are sent by the cron job. Addresses inside your server network are refused; set CLIENTLANE_PRIVATE_WEBHOOKS=true in .env only if you really need one.
Facturas electrónicas
- In Company → E-invoices: if you have a Peppol address, type its scheme (for example
0009for a French SIRET) and identifier; otherwise your email is used. Choose what your lines at 0 % are (exempt, zero rated, reverse charge, intra-EU, export…) and the reason to print. Add a client’s Peppol address on their page when they have one. - Each issued invoice and credit note then has Factur-X PDF, UBL (Peppol BIS 3.0) and CII downloads. Reports → E-invoices (ZIP) gives them for a whole period. Tick Make every invoice PDF a Factur-X file to send Factur-X PDFs in your emails and downloads.
- Clientlane tells you what is missing before making a file (for example the client’s country or VAT number).
Clientlane makes the files in the European standard EN 16931; it does not send them to a government or approved platform. Where e-invoicing is required (in France, invoices between businesses are moving to approved platforms), ask your platform how to send it these files, and check with your accountant which dates and rules apply to your business.
Numbers
In Company → Quotes and invoices → Numbers, each kind of document has its start (for example INV-{YYYY}-, where {YYYY} becomes the year, {YY} the short year and {MM} the month), its number of digits and its next number, with an optional reset each year. Numbers follow each other with no gap and are given only when a document is sent or issued, so drafts never leave holes. Once a number is used, Clientlane refuses a next number that would give it again. Invoices and credit notes must start differently.
Emails
Settings → Sending emails: choose SMTP server and enter the details your host gives in “Email accounts” (server, port 465 with SSL or 587 with TLS, user name, password). Use a sender address of your own domain, then click Send a test email to me. Until this is set up, emails are only written to storage/logs. Quote, invoice, reminder and sign-in emails are written in the client’s language (English, French, Spanish, German, Portuguese or Tagalog).
Team and roles
| Role | Can |
|---|---|
| Owner | Everything, including licence, updates and other owners. |
| Admin | Everything except licence, updates and owners. |
| Editor | Clients, catalogue, quotes, invoices and payments. |
| Viewer | Reads clients and their documents. |
Each person picks their own language for the admin. The activity log shows who did what.
Licence and updates
- Licence: Standard covers one domain, Agency up to ten. Free a domain with Deactivate before moving Clientlane to another one. After 12 months Clientlane keeps working; you renew only to get new versions and support.
- Update with an active licence: Licence & updates → Update to x.y.z.
- Update from a zip: download the new full zip, then Licence & updates → Update from a zip.
- If the server refuses the upload (the zip is about 16 MB and some hosts allow less): extract it on your computer and upload its files over the old ones by FTP, keeping your
.envfile andstoragefolder. Database changes apply on the next visit.
Before copying, Clientlane checks the zip and saves the files it replaces in storage/app/updates (the 3 newest backups are kept). Your .env file, storage folder and database are never replaced.
Backups and moving
- Back up the database (or
database/*.sqlitefor SQLite), thestoragefolder (logo, signatures) and the.envfile: it holds the encryption key of the installation. Without it, saved payment keys and SMTP passwords cannot be read. - To move to another server: copy the files and the database, keep the same
.env(changeAPP_URLand the database details if needed), then add the cron job again.
Troubleshooting
| Problem | What to do |
|---|---|
| “Your changes were not saved” on a quote or an invoice | Someone issued, sent or answered the document while you were editing it (or the client accepted the quote). Open it again: an issued invoice is corrected with a credit note, an answered quote can be copied. |
| “Deposit invoice … is still a draft” on a quote | Issue the deposit invoice (or delete the draft), then make the final invoice. |
| A credit note is refused | A credit note cannot be more than what is left on its invoice (the other credit notes are taken off). Lower its lines. |
| The client cannot draw a signature | On the quote page: How do you sign? → Type my name as my signature. The typed name is recorded like a drawn signature. |
| Reminders or recurring invoices are not sent | The cron job never ran: add the cron line or web cron (see Cron job), then wait one minute. |
| Emails do not arrive | Send a test from Settings. Check the spam folder, use a sender address of your own domain, and ask your host for the right port and security (SSL 465 or TLS 587). |
| A payment made online is not on the invoice | For Stripe, add the webhook with its signing secret (see Online payments). Check that the site is on HTTPS. |
| Blank page or error 500 | Check that PHP is 8.3 or newer and that storage, bootstrap/cache and .env are writable. Details are in storage/logs. |
| Locked out and no email set up | On the server, run php artisan clientlane:reset-password you@example.com: it prints a new password and turns off two-factor sign-in for that account. |
| Where is the admin? | At /admin. Change it with CLIENTLANE_ADMIN_PATH= in .env. |
| An issued invoice has a mistake | Make a credit note from it, then a new invoice. |
Still stuck? Write to us from the Soporte page with your order number.