Sales docs
Clients are integrated directly in the Sales domain model. This page keeps recurring billing and client records in one continuous documentation flow from overview to technical details.
Recurring payments
One section with the two things operators need: Overview and Sequences.
Overview
Kulanz supports Stripe auto-charge and bank transfer receive flows with Plaid-assisted auto-match to invoices when confidence is high.
For recurring memberships, operators define templates per customer (amount, cadence, and collection rail). On each due date, Kulanz creates the invoice from the template and tracks the run status so teams can verify what executed and what needs attention.
The Stripe path targets automatic collection, while bank-transfer memberships rely on transaction matching to close the invoice once funds arrive. This keeps membership billing and accounting in one consistent workflow even when payment rails differ.
At MVP stage, the focus is reliable generation, collection tracking, and AR posting support; advanced lifecycle controls (complex dunning, retries by segment, and bespoke contract rules) remain future enhancements.
Architecture: This diagram shows the high-level recurring membership system flow: scheduler-driven invoice generation, collection channels, and how payment outcomes connect back into sales/accounting posting.
Architecture
Bank transfer flow (non-Stripe): This sequence explains how a non-card membership payment moves from invoice creation to Plaid transaction detection, matching, and either auto-posting or manual review.
Bank transfer flow (non-Stripe)
Sequences
Recurring membership execution is template-driven: a scheduler checks due templates daily, creates run records, generates invoices, and hands collection/posting signals into the existing sales and accounting pipelines. This gives auditability for each billing cycle and a clear failure surface when a run cannot complete.
- Core schemas: recurring templates/runs, payment settings, and plaid transaction payment links.
- Core APIs: recurring templates CRUD/run-now, deposit auto-match, payment settings, Stripe webhook.
- Scheduler: daily due-template runner with next-run advancement and run tracking.
Stripe sequence: This sequence details the webhook-driven happy path where successful Stripe collection triggers accounting ingestion, sales payment allocation, and AR journal effects.
Stripe sequence
Bank transfer sequence: This sequence shows the asynchronous transfer path, where deposit evidence arrives later and matching logic determines whether posting is automatic or requires review.
Bank transfer sequence
Clients in the current architecture
Clients are not a separate "Client DB service" in the current system. They live in the core sales data model as sales_clients and are referenced by recurring templates, invoices, quote lines, and payments through client_external_id.
- Source of truth: sales_clients in the Sales schema with organization-scoped identity, client number, accountant metadata, and optional Stripe customer ID.
- Related records: contacts and addresses live in sales_client_contacts and sales_client_addresses.
- Domain linkage: recurring templates, invoice lines, quotes, and payments all carry client_external_id to keep joins consistent.
- API surface: client creation is handled by the backend through /api/v1/organizations/{slug}/sales/clients, with the online app acting as a thin proxy.
UML domain view: this shows how a client record anchors all downstream sales operations: who to bill, where to bill, how recurring runs are configured, and how invoices/payments stay connected in AR workflows.
Clients domain UML
| Table | Purpose | Key fields |
|---|---|---|
| sales_clients | Core customer identity per organization. | external_client_id, client_number, name, stripe_customer_id |
| sales_client_contacts | Contacts linked to a client profile. | client_external_id, external_contact_id, email, phone, is_default |
| sales_client_addresses | Billing and shipping addresses. | client_external_id, kind, region, postal_code, is_default_billing |
| sales_recurring_templates | Recurring definitions tied to clients. | client_external_id, frequency, next_run_date, collection_mode |
| Operation | Route | Notes |
|---|---|---|
| Create client | POST /api/organizations/:slug/sales-clients | Online BFF validates and proxies to backend v1. |
| Backend write | POST /api/v1/organizations/:slug/sales/clients | Creates client + optional primary contact + addresses. |
UML API flow: this sequence explains responsibility boundaries: dashboard input and auth checks in the online app, then canonical client writes in backend v1.
Clients API UML sequence
The join key to watch is client_external_id. It is propagated into invoice lines, payments, and recurring templates so sales, AR, and reporting all resolve against the same client identity without duplicate mapping layers.
Practical implication
Documentation should describe clients as a first-class Sales entity that powers recurring billing and AR workflows, not as a standalone addon module.