Payments
Record a payment
Mark money you received outside the system, by transfer, cash, cheque or a QR payment, so the invoice shows the right balance.
Recording a payment tells Free Invoice Automation that money arrived for an invoice by a route we cannot see: a bank transfer, a local QR payment, cash, a cheque, or anything else. You enter the amount, date and reference, and the invoice balance goes down. It is the "audited human confirmation" in our paid rule: a named person confirms the money arrived, and the record is kept in the audit log.
When to record a payment
| Situation | Do this |
|---|---|
| A client paid by bank transfer and sent a proof | Accept the proof, which records the payment for you |
| A client paid by bank transfer, QR code, cash or cheque with no proof | Record the payment yourself |
| A client paid by card through Stripe | Nothing: Stripe's verified webhook records it automatically |
| A client paid on Whop (from February 2027) | Nothing: Whop's verified webhook records it automatically |
| A store order was paid in Shopify or WooCommerce | Nothing: the store connector records it through its verified channel |
What a payment record holds
| Field | Notes |
|---|---|
| Invoice | The document the money is for |
| Amount | Integer minor units in the invoice currency; must be greater than zero |
| Date received | When the money arrived |
| Reference | For example the bank reference, so you can find it later |
| Proof | Optional: a proof file, or the client's proof if one was submitted |
| Notes | Optional internal notes |
| Recorded by | Set automatically to you; every manual payment has a named person |
The payment's source is manual. Its rail is the instruction rail it came through, or manual when it was not through a connected rail.
Record a payment in the app
Open the invoice
Open the invoice from Invoices or Payments. Only invoices that are not void can take payments.
Record a payment
Choose to record a payment. Enter the amount that actually arrived, the date, and a reference.
Attach a proof (optional)
Attach a proof file if you have one, for example a bank statement extract.
Save
The balance goes down at once. The invoice moves to partially paid, or to paid when the balance reaches zero. The invoice timeline and the audit log show who recorded it.
Record what really arrived, not what the invoice says. If a client paid 1,000.00 of a 1,200.00 invoice, record 1,000.00. The remaining 200.00 stays open and reminders keep working on it.
Through the API and MCP
| Action | REST | MCP tool | Permission |
|---|---|---|---|
| Record a payment | POST /v1/payments | record_payment | payments.record |
| Get payment status | GET /v1/documents/{id}/payment-status | get_payment_status | payments.view |
| List payments | GET /v1/payments | none | payments.view |
| Get a payment | GET /v1/payments/{id} | none | payments.view |
| Delete a payment | DELETE /v1/payments/{id} | none | payments.record |
An Idempotency-Key is required when recording a payment with an API key or over MCP, so a retried request never records the same money twice.
curl -X POST "https://api.freeinvoiceautomation.com/v1/payments" \
-H "Authorization: Bearer $FIA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pay-inv-0042-cash" \
-d '{
"document_id": "0193f2b4-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
"amount_minor": "100000",
"currency": "USD",
"received_at": "2027-01-20T00:00:00Z",
"reference": "Cheque 004512",
"notes": "Handed over at the client meeting"
}'{
"data": {
"id": "0193f2c7-2b3c-7d4e-9f50-6a7b8c9d0e1f",
"document_id": "0193f2b4-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
"rail": "manual",
"source": "manual",
"amount_minor": "100000",
"currency": "USD",
"received_at": "2027-01-20T00:00:00Z",
"reference": "Cheque 004512",
"status": "succeeded",
"refunded_amount_minor": "0"
}
}From the week of 25 January 2027 the CLI has the same action (freeinvoiceautomation payment record; command names are proposed). When you ask an AI assistant to record a payment, it calls record_payment under your permissions; the record still names you as the person who confirmed it.
A recorded payment sends the payment.recorded webhook event, plus document.paid or document.partially_paid.
Correcting a mistake
Payments are never hard-deleted. If you recorded a payment by mistake (wrong invoice, wrong amount), delete it: this is a soft delete, allowed only for manual records, and it is marked destructive, so the app asks you to confirm and the API needs "confirm": true. The invoice balance goes back up, and the record is kept in the database rather than erased, with the deletion in the audit log.
Payments that came from Stripe, Whop or a store cannot be deleted this way, because they reflect money the provider confirmed. To give that money back, use a refund.
Rules and edge cases
- Partial payments are recorded as they arrive; several payments can add up to the total.
- From the week of 25 January 2027, payments on invoices with a payment schedule are allocated to instalments, oldest first.
- Void invoices cannot take payments. An invoice that already has payments cannot be voided; issue a credit note instead.
- Currency. A payment is recorded in the invoice's currency.
- Reminders stop when the invoice is paid (from January 2027). Late fees are worked out on the overdue balance, so recording what arrived keeps them fair.
Permissions
| Key | Needed for | Default roles |
|---|---|---|
payments.record | Recording and deleting manual payments | Owner, Admin, Editor |
payments.view | Seeing payments and payment status | Owner, Admin, Editor, Viewer, Accountant |
Errors
| Code | When |
|---|---|
validation_failed | The amount is zero or negative, or a field is missing |
document_voided | The invoice is void |
idempotency_key_reused | The same key was used with a different body |
idempotency_in_progress | The same request is still running |
confirmation_required | Deleting a payment without "confirm": true |
permission_denied | Your role lacks payments.record |