Paisa · What it does
Product · Integrations

Data in. Judgement stays yours.

Ingestion is idempotent by external id, because webhooks retry and exports overlap. Nothing posts to the ledger on arrival, because the revenue treatment of a deal is an accounting judgement, not a CRM field.

Implemented in src/erp/connectors.ts
Idempotenta replayed sync creates nothing
Why it is built this way

3 decisions that carry the weight.

Replay-safe

Every inbound record carries an external id. Re-running a sync creates nothing — a finance system that double-books on a retry is worse than one that never synced.

Nothing auto-posts

A closed-won deal becomes a draft contract for a person to review and activate. The ledger is reached by approval, never by webhook.

Transport-agnostic

The same code path runs against a live API, a nightly file or a test fixture, so what you test is what runs.

Capabilities

What it does, in full.

CRM

Closed-won deals become draft revenue contracts with their performance obligations mapped from line items — or one ratable obligation when the deal has no split.

Billing

Charges and invoices deduplicated on arrival, with voided records rejected at the boundary rather than reconciled away later.

Banking

Statement lines deduplicated and handed to the reconciliation and categorisation engines, which decide nothing on their own that a person would want to see.

Payroll

Runs ingested with gross, employer taxes, net and headcount, validated before they can become entries.

Sync visibility

Per-connector counts of what was ingested, what was skipped as a duplicate and what was rejected with the reason.

Rejections are reported

A record that fails validation is returned with its reason rather than dropped. Silent partial syncs are how ledgers quietly go wrong.

Related

Works with

See it against a real ledger.

The demo runs on a seeded company with a live close waiting — two real blockers and agents holding proposals.