Free trial
Colour

Invoices and payments

Read invoices, record a payment safely and understand how paid, balance and status stay in step.

For
Service advisorAccountantAdministrator
Hosting
Any hosting
Devices
All devices
Business
All businesses

Checked against Pop Street Dispatch 0.1.0

An invoice lists what a customer owes. You will be able to read an invoice, record a payment that posts once and stays within the balance, and opt customers out of marketing.

Before you start #

You need the owner, manager or advisor role. Invoices stay closed to dispatchers, technicians and drivers.

Steps #

An invoice page with its lines table, the Payments section with the Method, Amount and Reference boxes and the Record a payment button, and the balance line.
An invoice with demo data.
  1. Open Invoices. Filter by status (open, paid or void), customer or recently issued. The open filter includes partly paid invoices.
  2. Open an invoice to see its lines, its payments, its subtotal, tax, total, amount paid and balance.
  3. Record a payment: choose the method (card, cash, check, ach or other), enter the amount in cents, and add a reference up to 80 characters if you have one.
  4. Send an Idempotency-Key with the payment. If the connection drops after you press save, send the same payment again with the same key. Dispatch returns the first payment and posts nothing new. See "Safe retries (idempotency)".
  5. Check the invoice. Paid equals the sum of its payments. When paid reaches a total above zero, the status becomes paid.

Rules #

  • A payment must be above zero and at most the balance. A payment over the balance answers with the balance left.
  • A void invoice takes no payments.
  • A partly paid invoice keeps the status open, with paid_cents and balance_cents showing the split.
  • A zero or negative total stays open, takes no payment, and stays out of receivables.
  • Two payments sent at the same moment pass the balance check one after the other, because the check and the insert are one step.
  • Each payment, with its audit entry and the invoice.paid event for a fully paid invoice, saves in one transaction, so all three exist or none does.

Wrong money never shows #

Every invoice that the API returns passes an integrity check: each line total, the subtotal, total (subtotal plus tax), paid (the sum of payments) and the status. If a check fails, the call answers server_error and the details go to the log. A payment that would leave an invoice failing the check is rolled back. If it happens, restore the latest backup. See "Backups and restore".

Opt a customer out of marketing #

Send an email address or a phone number. Dispatch opts out every customer that matches and says how many it updated.

Technical details
  • Endpoints: GET /invoices, GET /invoices/{id}, POST /invoices/{id}/payments, POST /marketing/suppress.
  • A valid Idempotency-Key is also kept on the payment row as <token id>:<key>, so a retry after the stored response was lost returns the first payment.
  • Invoice numbers start at INV-2001.
  • Money is held as whole cents. Typed amounts are read exactly, so 0.005 reads as 1 cent.
  • Storage names differ from API names in places: the payment method ach is stored as transfer, and partial reads as open.

If something goes wrong #

  • validation_failed (422) on amount_cents: the amount is zero, negative or above the balance.
  • validation_failed (422) on method: use card, cash, check, ach or other.
  • conflict (409) for a void invoice: a void invoice takes no payments, so choose the right invoice.
  • conflict (409) about the idempotency key: the same key was used for a different request. Use a new key.
  • not_found (404) "No such invoice.": check the number.