Kommo + Wave: automatic invoices from the pipeline with no manual entry
A sales rep closes a deal in Kommo and then opens Wave to create an invoice manually. They type in the client name, billing details, and amount — data that already exists in the CRM. Then they go back to Kommo and create a task: “check payment.” This sequence repeats for every sale. The Kommo + Wave integration removes all manual work: a deal moves to a stage -> an invoice is created in Wave -> the client receives an email -> payment status is recorded in the CRM automatically.
Why Zapier does not cover this scenario
Wave is a free accounting platform popular among SaaS companies and freelancers. Unlike Xero or FreshBooks, Wave uses a GraphQL API rather than REST. Most no-code connectors (Zapier, Make, Albato) are built around REST architecture and do not have full Wave GraphQL support.
An official Wave connector exists in Zapier, but it is limited: you can create an invoice, but without logic such as “find the customer or create a new one,” without passing custom fields from Kommo, and without a return flow for payment status. A full end-to-end scenario requires a custom integration using the Wave GraphQL API.
What is passed from Kommo to Wave
Kommo -> Wave:
— Contact name, email, phone, company -> Customer in Wave (with deduplication by email)
— Deal amount and line items (if tracked in custom fields) -> invoice lines
— Payment due date from custom field -> invoice due date
— Invoice ID and payment link -> custom field in the deal card
Wave -> Kommo:
— Invoice status PAID -> updates the “payment status” field in the deal
— Moves the deal to the “Payment Received” stage
— Closes the “Check payment” task (if one was created)
Integration architecture
Kommo: deal moved to stage "Issue Invoice"
↓ Webhook -> Backend
1. GET /api/v4/leads/{id} - deal details
2. GET /api/v4/contacts?lead_id={id} - contact
3. Wave GraphQL: search customer by email
-> found: use existing customer
-> not found: customerCreate
4. Wave GraphQL: invoiceCreate -> invoiceSend
5. Kommo: update fields invoice_url, invoice_id in deal
6. Kommo: task "Check payment" due in N days
Wave Webhook: invoice.paid
↓ Backend
1. Find deal in Kommo by invoice_id
2. Update field payment_status = "paid"
3. Move deal to stage "Payment Received"
Wave GraphQL: key mutations
Wave API operates through the GraphQL endpoint https://gql.waveapps.com/graphql/public. Authentication uses OAuth 2.0 with a Bearer token.
Search for a customer before creating:
query SearchCustomer($businessId: ID!, $name: String) {
business(id: $businessId) {
customers(name: $name) {
edges {
node { id name email }
}
}
}
}
Create an invoice:
mutation CreateInvoice($input: InvoiceCreateInput!) {
invoiceCreate(input: $input) {
didSucceed
inputErrors { message code path }
invoice {
id
invoiceNumber
status
pdfUrl
}
}
}
Send to the client:
mutation SendInvoice($input: InvoiceSendInput!) {
invoiceSend(input: $input) {
didSucceed
invoice { id status }
}
}
GraphQL lets you create and send an invoice in two requests instead of a chain of REST calls. Customer deduplication is mandatory: Wave does not block duplicate creation — that is the responsibility of the integration layer.
Kommo -> Wave field mapping
| Kommo field | Wave field | Notes |
|---|---|---|
| contact.name | customer.name | First contact on the deal |
| contact.email | customer.email | Deduplication key |
| contact.company | customer.address.countryCode | Or a dedicated field |
| lead.price | invoice.items[0].unitAmount | If no line items |
| custom_field “Due Date” | invoice.dueDate | ISO 8601 |
| lead.name | invoice.items[0].description | Service description |
If line items are tracked in Kommo via custom fields, each item maps to a separate invoice line. If there are no line items, the full deal amount is mapped as a single line.
Real-world case
Digital agency (8 retainer clients, monthly invoices):
- Before the integration: every month the account manager manually created 8 invoices in Wave — copying data from Kommo. 45–60 minutes of work, with occasional errors in amounts and billing details.
- After: a trigger on the 1st of each month -> Kommo API fetches active deals -> Wave GraphQL creates and sends the invoices automatically.
- Result: 0 minutes of manual invoicing. The account manager sees payment status directly in Kommo — no need to open Wave.
We applied the same automation logic in integrations for Kommo and FreshBooks and Kommo and Xero — the architecture is similar; the differences lie in each platform’s API specifics.
Who this is relevant for
A Kommo + Wave integration makes sense if:
— Wave is the primary accounting system with no plans to replace it
— Invoices are issued when a deal moves to a specific pipeline stage
— Seeing payment status in the CRM without switching between systems matters
— Volume: 10+ invoices per month — below that, manual entry is faster than setting up the integration
Frequently asked questions
Wave is free — why pay for an integration?
Wave is free for invoicing. The Kommo integration is a one-time development cost. At 20+ invoices per month, the time savings (15–20 minutes per invoice × 20 = 5–7 hours per month) pay back the development cost within 2–3 months. Plus you eliminate manual entry errors.
Is the Wave API paid?
No. Wave provides its GraphQL API free to all business accounts. Rate limit — 60 requests per minute. For typical invoicing volumes this is more than sufficient.
What if the client already exists in Wave?
The integration searches for a customer by email before creating one. If found, the invoice is created for the existing customer — no duplicates. If the email differs (for example, the company domain changed), a new customer is created, which requires separate normalisation logic.
How do you pass multiple line items from Kommo?
Via custom fields of type multilist, or via separate “Item / Amount” fields for each line. Each item maps to an invoice.items line. If there are no line items, the full deal amount goes as a single line with the deal name as the description.
Does Wave work with international clients?
Yes. Wave supports invoicing in USD, EUR, CAD, and other currencies. Wave Payments (built-in payment processing) is available in the US and Canada. For issuing invoices to international clients without built-in payment processing, Wave works globally.
Summary
- Wave uses a GraphQL API — Zapier does not cover the full two-way scenario
- Custom integration: stage in Kommo -> invoice in Wave -> sent to client -> payment status back in CRM
- Customer deduplication by email is a required element
- Typical development timeline — 2–3 weeks
- Relevant for 10+ invoices per month
If you use both Wave and Kommo and want to eliminate manual invoice creation — describe your invoicing process. Exceltic.dev will work through the field mapping and propose an integration architecture.