Process payments
Record a customer's payment (full, part or over-payment) against open invoices, pay a vendor's bills, turn an existing deposit into a payment, and write off a bad debt.
Posting an invoice records that a customer owes you money, in a lot on your Receivable account. A payment is the transaction that settles it: money arrives in the bank and the Receivable lot shrinks. For bills it is the other way round: money leaves the bank, and the Payable lot shrinks.
A payment can cover one document, part of one, several, or more than is owed. What is left over from an over-payment stays with the customer as a pre-payment, which a later document can use.
Steps
- See what is open for the party with payment.openItems: the owner and the Receivable or Payable account. It lists each open document, with its balance, and any pre-payments.
- Pay one document in full or in part with invoice.pay: the document, the
transferAccount(your bank account), theamountand thedate. A smaller amount leaves the rest open. - Pay several at once with payment.process: the
owner({"type": "customer", "id": ...}), theaccount, thetransferAccount, theamount, thedate, and optionallyapplyTo, the documents to apply it to in order. WithoutapplyToit pays the oldest first only if you setautoPay; otherwise the amount waits as a pre-payment. The result'spaymentLotis set when a pre-payment is left. - Over-payment. Pay more than is owed and the extra remains as a pre-payment lot, shown by payment.openItems, ready to be applied to the next document.
- Vendors and employees. Use the same calls with the owner type
vendororemployee. Theamountis signed: positive when a customer pays you or when you pay a vendor or an employee, as the reference page for payment.process explains. - A deposit already in the book. If a transaction was entered as a plain deposit, turn it into a payment with payment.fromTransaction, naming the owner and the documents.
- Bad debt. When a customer will not pay, pay the rest of the invoice with invoice.pay, with
an expense account such as
Bad debtsas thetransferAccount. The invoice closes and the expense records the loss.
Example
Example: with a copy of the synthetic/business-editable example book open as book.gnucash, at 2024-03-25T12:00:00Z.
JSON-RPC
Request:
{"jsonrpc":"2.0","id":1,"method":"payment.openItems","params":{"owner":{"type":"customer","id":"5b22073fa4e34411b07c14a77147ce6b"},"account":"Assets:Receivable"}}
Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"items": [
{
"invoice": "aa210b7131de44c48b8513cd27c00e95",
"balance": {
"num": "87300",
"denom": "100"
},
"…": "…"
}
]
}
}
Request:
{"jsonrpc":"2.0","id":2,"method":"payment.process","params":{"owner":{"type":"customer","id":"5b22073fa4e34411b07c14a77147ce6b"},"account":"Assets:Receivable","transferAccount":"Assets:Bank","amount":"300.00","date":"2024-03-25","applyTo":["aa210b7131de44c48b8513cd27c00e95"]}}
Response:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"transaction": "…",
"paymentLot": null
}
}
Request:
{"jsonrpc":"2.0","id":3,"method":"payment.openItems","params":{"owner":{"type":"customer","id":"5b22073fa4e34411b07c14a77147ce6b"},"account":"Assets:Receivable"}}
Response:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"items": [
{
"invoice": "aa210b7131de44c48b8513cd27c00e95",
"balance": {
"num": "57300",
"denom": "100"
},
"…": "…"
}
]
}
}
Request:
{"jsonrpc":"2.0","id":4,"method":"invoice.pay","params":{"invoice":"95e2e7416db94eb3a7de7433f3e7875f","transferAccount":"Assets:Bank","amount":"20.00","date":"2024-03-25","memo":"Part payment"}}
Response:
{
"jsonrpc": "2.0",
"id": 4,
"result": {
"transaction": "…",
"paymentLot": null
}
}
Request:
{"jsonrpc":"2.0","id":5,"method":"payment.process","params":{"owner":{"type":"vendor","id":"9697710198334d558a9bfde219bb1e41"},"account":"Liabilities:Payable","transferAccount":"Assets:Bank","amount":"10.00","date":"2024-03-25"}}
Response:
{
"jsonrpc": "2.0",
"id": 5,
"result": {
"transaction": "…",
"paymentLot": "…"
}
}
Command line
red-ale exec --book book.gnucash --script - <<'EOF'
payment.openItems {"owner":{"type":"customer","id":"5b22073fa4e34411b07c14a77147ce6b"},"account":"Assets:Receivable"}
payment.process {"owner":{"type":"customer","id":"5b22073fa4e34411b07c14a77147ce6b"},"account":"Assets:Receivable","transferAccount":"Assets:Bank","amount":"300.00","date":"2024-03-25","applyTo":["aa210b7131de44c48b8513cd27c00e95"]}
payment.openItems {"owner":{"type":"customer","id":"5b22073fa4e34411b07c14a77147ce6b"},"account":"Assets:Receivable"}
invoice.pay {"invoice":"95e2e7416db94eb3a7de7433f3e7875f","transferAccount":"Assets:Bank","amount":"20.00","date":"2024-03-25","memo":"Part payment"}
payment.process {"owner":{"type":"vendor","id":"9697710198334d558a9bfde219bb1e41"},"account":"Liabilities:Payable","transferAccount":"Assets:Bank","amount":"10.00","date":"2024-03-25"}
EOF
It prints:
[
{
"items": [
{
"invoice": "aa210b7131de44c48b8513cd27c00e95",
"balance": {
"num": "87300",
"denom": "100"
},
"…": "…"
}
]
},
{
"transaction": "…",
"paymentLot": null
},
{
"items": [
{
"invoice": "aa210b7131de44c48b8513cd27c00e95",
"balance": {
"num": "57300",
"denom": "100"
},
"…": "…"
}
]
},
{
"transaction": "…",
"paymentLot": null
},
{
"transaction": "…",
"paymentLot": "…"
}
]
MCP tool call
Tool call:
{"name":"payment.openItems","arguments":{"owner":{"type":"customer","id":"5b22073fa4e34411b07c14a77147ce6b"},"account":"Assets:Receivable"}}
Result:
{
"structuredContent": {
"items": [
{
"invoice": "aa210b7131de44c48b8513cd27c00e95",
"balance": {
"num": "87300",
"denom": "100"
},
"…": "…"
}
]
}
}
Tool call:
{"name":"payment.process","arguments":{"owner":{"type":"customer","id":"5b22073fa4e34411b07c14a77147ce6b"},"account":"Assets:Receivable","transferAccount":"Assets:Bank","amount":"300.00","date":"2024-03-25","applyTo":["aa210b7131de44c48b8513cd27c00e95"]}}
Result:
{
"structuredContent": {
"transaction": "…",
"paymentLot": null
}
}
Tool call:
{"name":"payment.openItems","arguments":{"owner":{"type":"customer","id":"5b22073fa4e34411b07c14a77147ce6b"},"account":"Assets:Receivable"}}
Result:
{
"structuredContent": {
"items": [
{
"invoice": "aa210b7131de44c48b8513cd27c00e95",
"balance": {
"num": "57300",
"denom": "100"
},
"…": "…"
}
]
}
}
Tool call:
{"name":"invoice.pay","arguments":{"invoice":"95e2e7416db94eb3a7de7433f3e7875f","transferAccount":"Assets:Bank","amount":"20.00","date":"2024-03-25","memo":"Part payment"}}
Result:
{
"structuredContent": {
"transaction": "…",
"paymentLot": null
}
}
Tool call:
{"name":"payment.process","arguments":{"owner":{"type":"vendor","id":"9697710198334d558a9bfde219bb1e41"},"account":"Liabilities:Payable","transferAccount":"Assets:Bank","amount":"10.00","date":"2024-03-25"}}
Result:
{
"structuredContent": {
"transaction": "…",
"paymentLot": "…"
}
}