Solavel Solavel Docs

Payments

docs/solavel-finance/payments.md

Who can use this: Owner, Manager, Accountant. URL / Route: /finance/payments (finance.payments.index) is the unified payments hub. Detail and actions: finance.payments.show, create, store, destroy, post, unpost, repost, deallocate, open-documents. AR-only customer payments live at /finance/ar/customer-payments and /finance/ar/invoice-payments (finance.ar.customer-payments.*, finance.ar.invoice-payments.*). AP-only bill payments live at /finance/ap/bill-payments (finance.ap.bill-payments.*). Plan / feature gate: customer side requires feature:tracker.record_offline_payments; supplier side requires feature:tracker.record_payments_made (both default: enabled). Permissions: AR: sales.payments.view, sales.payments.create, sales.payments.post, sales.payments.reverse, sales.payments.delete. AP: purchases.bill_payments.view, purchases.bill_payments.create, purchases.bill_payments.edit_draft, purchases.bill_payments.delete, purchases.bill_payments.post, purchases.bill_payments.reverse. Bills allocation also uses purchases.bills.allocate.

Purpose

Payments record money moving in or out of your bank/cash accounts and link those movements to specific invoices or bills. The "Payments" hub at /finance/payments is a single place to see both customer receipts and supplier payments; per-side variants exist for workflows that only care about one side.

Step by step

Browse all payments

  1. Open /finance/payments. Each row shows the payment date, the friendly source label (see below), the counterparty, bank account, amount, and posting status (Draft / Posted / Reversed).
  2. Filter by Source kind (single chip dropdown — friendlier than the legacy raw type filter), bank account, status, or date range.

Friendly source labels

Every payment is presented as the workflow it belongs to — not the raw "receipt / disbursement" enum. Each label is colour-coded so related rows are easy to scan at a glance:

Label Direction When you see it
Sales Receipt (green) Money In Posted via the Sales Receipt module (immediate cash sale, no invoice).
Invoice Payment (green) Money In Customer receipt applied against one or more invoices.
Refund Receipt (light blue) Money In Refund issued via a Refund Receipt document.
Bill Payment (indigo) Money Out Supplier disbursement applied against one or more bills.
Expense Payment (amber) Money Out Direct-pay against an Expense (the "Save expense and record payment" path).
Supplier Refund (light blue) Money Out Refund returned to a supplier via Supplier Refund.
Transfer (light blue) Transfer Bank-to-bank or cash-to-bank movement (no counterparty side).
Other Receipt / Other Payment (grey) In / Out Receipts or disbursements not tied to any of the above.

Clicking the label opens the source document (Sales Receipt / Expense / Bill / Invoice / Refund) directly.

Source-kind filter

The Source dropdown on the filter bar maps to friendly keys, not raw enums:

Filter chip What it includes
All every payment
Money In every type=receipt row
Money Out every type=disbursement row
Sales Receipts only SR-backed receipts
Invoice Payments receipts allocated to invoices
Bill Payments disbursements allocated to bills
Expense Payments disbursements tied to an Expense
Refund Receipts / Supplier Refunds / Transfers as labelled
Other Receipts / Other Payments rows that don't match any of the above

Old URLs with ?type=receipt / ?payable_type=… still work — they're kept for backward compatibility.

Record a customer payment (receipt)

Route: finance.payments.create with type "Customer Receipt", or finance.ar.customer-payments.create. Permission: sales.payments.create.

  1. Pick Customer.
  2. Pick the Bank / Cash account that received the funds.
  3. Enter the Payment date, Amount, Reference, and Method (Bank transfer, Cash, Card, Cheque).
  4. The right-hand panel shows the customer's open invoices (loaded via finance.payments.open-documents). Tick the invoices you want to allocate this payment to and enter the amount applied to each. The remainder becomes a credit on account.
  5. Save as Draft or Save and Post.

Record a supplier payment

Route: finance.payments.create with type "Supplier Payment", or finance.ap.bill-payments.create. Permission: purchases.bill_payments.create.

  1. Pick Supplier.
  2. Pick Bank / Cash account.
  3. Enter date, amount, reference, method.
  4. Open bills load on the right; tick the bills to allocate to.
  5. Save as Draft or Save and Post.

Edit, post, unpost, reverse

  • Edit a draft: finance.payments.update (only AR/AP scoped variants implement edit). Permission: sales.payments.create / purchases.bill_payments.edit_draft.
  • Post: finance.payments.post. Writes journal entries (Bank debit, AR/AP credit, or vice versa). Period must be unlocked.
  • Unpost: finance.payments.unpost. Returns the payment to Draft and unwinds the journal. Allowed only if no further dependent activity. Period must be unlocked.
  • Repost: finance.payments.repost. Re-posts after unpost without losing allocations.
  • Deallocate: finance.payments.deallocate. Removes the link to one or more invoices/bills, freeing them up for reallocation.
  • Reverse: finance.ar.customer-payments.reverse or finance.ap.bill-payments.reverse. Posts a reversing journal as of the reverse date and marks the payment as Reversed. Use when a cheque bounces or you need a permanent record of an undo.
  • Delete (draft only): finance.payments.destroy. Posted payments cannot be deleted; reverse instead.

Allocate from a bill

Route: finance.ap.bills.allocate.form / finance.ap.bills.allocate. Permission: purchases.bills.allocate.

From a posted bill's detail page, click Allocate. You can apply existing unallocated payments or unapplied debit notes to the bill in one transaction.

Find open documents

Route: finance.payments.open-documents (GET). Internal helper called by the new-payment forms to fetch a counterparty's outstanding invoices/bills along with their open balances.

How the journal looks

A JOD 117 customer payment fully allocated to one open invoice:

Account Debit Credit
Bank 117.00
AR — Customer control 117.00

The invoice flips to Paid and the open balance becomes zero.

A JOD 200 customer payment with only JOD 117 of open invoices — JOD 83 stays as unallocated credit:

Account Debit Credit
Bank 200.00
AR — Customer control (allocated to invoice) 117.00
AR — Customer credit on account 83.00

The invoice is paid; the customer's open balance becomes JOD 83 credit. That credit can be allocated to a future invoice without a new payment.

A JOD 117 supplier payment allocated to one open bill:

Account Debit Credit
AP — Supplier control 117.00
Bank 117.00

The bill flips to Paid.

A multi-currency receipt — a USD 1,000 invoice was posted at FX 0.710 (= JOD 710.00 on AR). The customer pays USD 1,000 today when FX has moved to 0.715 (= JOD 715.00 received):

Account Debit (JOD) Credit (JOD)
Bank (USD 1,000) 715.00
AR — Customer control 710.00
FX gain (realised) 5.00

The customer's invoice closes; the JOD 5 difference is the realised FX gain from rate movement between posting and settlement.

A bank transfer of JOD 1,000 from a current account to a savings account (no counterparty):

Account Debit Credit
Bank — Savings 1,000.00
Bank — Current 1,000.00

A bounced-cheque reversal of a JOD 117 customer payment — instead of unposting (which would erase the audit trail), Reverse posts the opposite journal dated today:

Account Debit Credit
AR — Customer control 117.00
Bank 117.00

The invoice flips back to Open and the customer's AR shows the receivable again.

Allocation behaviour

When you tick documents on a payment:

  • The total amount allocated cannot exceed the payment amount.
  • Any leftover stays as unallocated credit on that customer/supplier — it shows on their AR/AP balance and can be applied later.
  • Allocations can be partial — pay 60% of an invoice now, the remaining 40% later.
  • Multi-currency: the payment carries one exchange rate at the payment date. If the invoice currency differs, an FX gain/loss line is added to the journal automatically.
  • If the period is locked, posting and unposting both fail until the period reopens.

Reverse vs Unpost vs Deallocate

Three different ways to "undo" a payment — each leaves the books in a different state. Pick the one that matches what really happened:

Action When to use What it does Audit trail
Deallocate The payment is correct but it's applied to the wrong invoice / bill Removes the allocation row only. The payment stays posted; the document it was on is "open" again The allocation row is removed; no journal change
Unpost "I made a mistake entering the payment — let me fix the draft and re-post" Returns the payment to Draft. The original journal is voided (kept for audit, excluded from reports) Original journal kept, marked Voided
Reverse Something happened in the world — cheque bounced, transfer recalled Posts a mirror journal on the reverse date. Marks the payment Reversed Two journals visible: the original AND the reversal

If in doubt, use Reverse — it's the only one that leaves an unambiguous audit trail of what happened.

Common mistakes

  • "My payment isn't showing on the bank statement match." Check that the Source kind filter at the top of the Payments hub isn't accidentally restricting the view — set it to All to see every row. Also confirm the payment is Posted, not Draft.
  • "My customer overpaid — where did the extra go?" The leftover sits as unallocated credit on the customer record. Apply it to a future invoice from the customer's page or the new-invoice form, or refund it via a Refund receipt.
  • "Period locked" → posting and unposting are both blocked. Reverse on a later date (in an open period) is the workaround when the original date is closed.
  • Multi-currency mismatch. When a customer pays a foreign-currency invoice on a different date, the FX rate may differ. A realised gain/loss is posted automatically — see the multi-currency journal example above and Multi-currency.
  • "I unposted a payment and now its source document looks weird." Unposting a payment doesn't unpost the invoice / bill — it just unwinds the cash movement. The source document goes back to its prior status (Open / Posted), not Draft.

Tips

  • Open the Banking page side-by-side with Payments to match imported statement lines against payment rows.
  • Filter by Source kind = Sales Receipts to find every walk-in sale that landed on the books today.
  • Click a friendly source label (Sales Receipt / Bill Payment / Refund Receipt etc.) to jump straight to the originating document.

Behaviour and rules

  • Drafts don't post. Aging reports only count posted payments.
  • Reversal vs unpost. Unpost is for "I made a mistake, I'll fix the same draft and re-post". Reverse is for "this happened in the world (bounced cheque) and I need an audit trail".
  • Deallocate does not unpost the payment — it just frees up the linked documents so the same money can be re-applied.
  • Bank account integration. Posted payments appear in the bank account's transaction list and are matchable against an imported bank statement; see Bills and the Banking section.
  • Customer / supplier balances update only after posting.

Permissions / restrictions

  • AR side actions need sales.payments.*.
  • AP side actions need purchases.bill_payments.*.
  • Bill-side allocation needs purchases.bills.allocate in addition to the payment-side permissions.

Related

Source: docs/solavel-finance/payments.md ← All documentation