Accounts Receivable & Payable
Manage invoices, bills, payments, and aging reports with support for both fiat and crypto.
Overview
Axiomatic provides full accounts receivable (AR) and accounts payable (AP) capability through two action-oriented modules — Invoicing (/invoicing) and Purchasing (/purchasing) — backed by canonical APIs at /api/invoicing/* and /api/purchasing/*.
The terminology Accounts Receivable and Accounts Payable still applies wherever it actually means the GL control accounts: trial balance, financial statements, the chart of accounts, and period-end reconciliations. The user-facing entry points and APIs use the action-oriented names because they describe what the user is doing, not which side of the ledger ends up moving.
Migration note (Plan B, 2026-05). The legacy dual entry points
/ledger/ar,/ledger/ap,/api/ledger/ar,/api/ledger/ap, and/api/ledger/ap/matchwere consolidated onto Invoicing and Purchasing. The legacy API paths now return410 Gonewith a pointer to the canonical replacement; they will be removed entirely after one quarter.
Counterparties
Customers and vendors are managed as counterparties — every record links to a CRM companies row so relational concerns (lifecycle, contacts, addresses) live in one place and operational concerns (payment terms, 1099, AP automation) live in the relevant module. Each counterparty record carries:
- Name and contact email
- Default currency for billing
- Wallet address and blockchain network (for crypto payments)
- Tax ID (for vendors, used in 1099 tracking)
A vendor created in /purchasing/vendors and a vendor created in /crm/companies end up as the same row (companies.counterpartyId → counterparties with role = vendor or both). There is no duplicate identity.
Cross-links
| From | To | When |
|---|---|---|
/crm/companies/[id] | /invoicing?customerId=... | Company has role customer or both |
/crm/companies/[id] | /purchasing/bills?vendorId=... | Company has role vendor or both |
/crm/companies/[id] | /purchasing/vendors/[counterpartyId] | Vendor profile (operational) |
/invoicing | /crm/companies?role=customer | "Manage customers" |
/purchasing/vendors (list and detail) | /crm/companies/[companyId] | "View in CRM" |
Invoices (Accounts Receivable)
Creating an Invoice
An invoice includes one or more line items, each with a description, quantity, unit price, and optional revenue account mapping. You can set a due date, billing currency, and whether to accept crypto payments.
Invoice Lifecycle
Invoices progress through these statuses:
- Draft — being prepared, not yet sent
- Sent — delivered to the customer
- Partially Paid — some payment received
- Paid — fully settled
- Overdue — past the due date without full payment
- Void — cancelled
Recording Payments
When you record a payment against an invoice, Axiomatic:
- Updates the invoice's paid amount and status
- Emits a canonical
invoicing.payment.receivedevent - The posting engine generates the appropriate journal entry (e.g. DR Cash, CR Accounts Receivable)
Payment methods include ACH, wire, check, crypto, credit card, and other.
Credit memos
Credit memos are separate from negative invoices. They reduce customer balances via amount_credited on invoices when applied. Create drafts under Invoicing → Credit memos, issue them, then apply amounts to open invoices. The posting engine emits invoicing.credit_memo.* events (two-step GL: liability pool on issue, clear AR on apply). Export a printable HTML summary from the memo detail API (GET /api/invoicing/credit-memos/:id/pdf) or a CSV statement (GET /api/invoicing/credit-memos/statement?customerId=).
Crypto payments (USDC on Base)
- Create an operating wallet under Accounting → Treasury → Operating wallet (see Treasury).
- On the invoice, enable Accept USDC on Base (or set default accept USDC under Invoicing → Settings).
- The invoice exposes a pay link and address for the entity operating wallet; printable PDFs can include the link.
- Inbound USDC is matched to open invoices during on-chain sync when amount and memo align; you can still record payments manually with
method: "CRYPTO"and the transaction hash.
Bank deposits: ACH/wire instructions via a Bridge virtual account settle to the same operating wallet. Configure under Admin → Receiving accounts.
Bills (Accounts Payable)
Entering a Bill
A bill records an obligation from a vendor. Each bill includes line items with descriptions, quantities, unit prices, and optional expense account mappings. Bills can be linked to a purchase order via the Match PO affordance on the bill detail page (/purchasing/bills/[id]), backed by /api/purchasing/po-match.
Bill Lifecycle
Bills follow a similar lifecycle with an additional approval step:
- Draft — being entered
- Received — bill received from vendor
- Approved — approved for payment (emits
purchasing.bill.approved) - Partially Paid — some payment made
- Paid — fully settled (emits
purchasing.bill.paid) - Overdue — past due date
- Void — cancelled (emits
purchasing.bill.voided)
Paying a Bill
When you record a payment against a bill:
- The bill's paid amount and status update
- A canonical
purchasing.bill.paidevent is emitted - The posting engine generates a journal entry (e.g. DR Accounts Payable, CR Cash)
Debit memos
Debit memos (vendor adjustments) live under Purchasing → Debit memos and apply to bills via amount_debited. Issuing posts expense and AP; applying allocates to specific bills without a second GL entry. APIs: /api/purchasing/debit-memos. Events: purchasing.debit_memo.{issued,applied,voided}.
Crypto Payments
To pay a vendor in crypto:
- Set
payCryptototrueon the bill - Store the vendor's wallet address on their counterparty record or on the bill directly
- Click Pay on the bill — this creates a payment intent and navigates to
/pay - The Pay page confirms the details and executes the transfer from the entity's Axiomatic smart wallet via the bundler
- Gas fees are sponsored by the Axiomatic paymaster — no ETH balance required in the wallet
Alternatively, you can record a manual crypto payment with the outgoing transaction hash.
Smart Wallet Payments
The /ledger/pay page provides a unified payment interface for on-chain payments:
- Pay a bill — select from open bills with crypto enabled
- Upload a bill — upload a received invoice (PDF/image) and enter payment details
- Send a transfer — freeform token transfer to any address
Payments are executed from the entity's Axiomatic smart wallet (Diamond pattern, ERC-4337). The platform builds a UserOperation, the paymaster sponsors gas, and the bundler submits the transaction. The user never needs to hold ETH for gas or sign with a browser wallet.
Payment intents track the lifecycle: PENDING → SUBMITTED → CONFIRMED (or FAILED / EXPIRED).
Aging Reports
AR aging (/invoicing/aging) buckets use invoice open balance after credit applications (total − paid − credited); the page also shows unapplied credit memos (issued memos not yet fully applied).
AP aging lives at /purchasing/aging and follows the same five-bucket structure, computed via the shared computeAgingReport engine.
| Bucket | Description |
|---|---|
| Current | Not yet due |
| 1–30 days | 1 to 30 days past due |
| 31–60 days | 31 to 60 days past due |
| 61–90 days | 61 to 90 days past due |
| 90+ days | More than 90 days past due |
Overdue invoices and bills are automatically flagged when their due date passes.
Customer & Vendor Ledgers
View the complete transaction history for any customer or vendor. From /invoicing or /purchasing/bills, deep-link with ?customerId= or ?vendorId= to scope the list. From the CRM company page, the View invoices / View bills cross-links land you in the right module pre-filtered.
API Reference
Accounts Receivable (Invoicing)
| Action | Method | Description |
|---|---|---|
| List invoices | GET /api/invoicing/invoices | Optional customerId, status, source, page, pageSize filters |
| Get invoice | GET /api/invoicing/invoices/{invoiceId} | Detail with line items + redirect decision |
| Create invoice | POST /api/invoicing/invoices | Body includes line items |
| Send / void / record payment | PATCH /api/invoicing/invoices/{invoiceId} | `action: send |
| List customers | GET /api/invoicing/invoices/customers | Counterparties with role customer or both |
| Create customer | POST /api/invoicing/invoices/customers | Promotes/links a CRM company |
| Aging report | GET /api/invoicing/invoices/aging | Five-bucket AR aging |
| Credit memos | GET / POST /api/invoicing/credit-memos | List / create drafts |
| Credit memo lifecycle | PATCH / POST .../credit-memos/{id}/(issue|apply|void) | Edit draft, issue, apply, void |
| AR statement CSV | GET /api/invoicing/credit-memos/statement?customerId= | Invoices + memos per customer |
Accounts Payable (Purchasing)
| Action | Method | Description |
|---|---|---|
| List bills | GET /api/purchasing/bills | Optional vendorId, status, page, pageSize filters |
| Get bill | GET /api/purchasing/bills/{billId} | Detail with line items + PO link |
| Create bill | POST /api/purchasing/bills | Body includes line items |
| Approve / pay / cancel | PATCH /api/purchasing/bills/{billId} | `action: approve |
| List vendors | GET /api/purchasing/vendors | Counterparties with role vendor or both |
| Create vendor | POST /api/purchasing/vendors | Promotes/links a CRM company |
| Aging report | GET /api/purchasing/bills/aging | Five-bucket AP aging |
| PO match (suggestions + link/unlink) | GET / POST /api/purchasing/po-match | Backs the Match PO modal on bills |
| Debit memos | GET / POST /api/purchasing/debit-memos | List / create vendor debit memos |
| Debit memo lifecycle | PATCH / POST .../debit-memos/{id}/(issue|apply|void) | Edit, issue, apply to bills, void |
| Execute payment | POST /api/pay/execute | Execute on-chain payment from smart wallet |
| List intents | GET /api/payment-intents?entityId=... | List payment intents |
| Create intent | POST /api/payment-intents | Create a payment intent |
Deprecated paths (return 410 Gone)
| Legacy | Canonical |
|---|---|
/api/ledger/ar | /api/invoicing/* |
/api/ledger/ap | /api/purchasing/* |
/api/ledger/ap/match | /api/purchasing/po-match |
These stubs will be removed entirely one quarter after the cutover.