Skip to content
Knowledge ERP Docs

API Reference ↗
Sales

Customer Returns

Customer returns (RMA) let you authorize, track, and receive goods back from customers — with line items, barcode-assisted receiving, and automatic credit-memo generation.

A customer return — sometimes called an RMA (return merchandise authorization) — is the formal record of a customer sending goods back. Each return is numbered automatically (e.g. CRA-0001), linked to the customer and optionally to the original sales order, and walked through a status lifecycle from Draft to Completed. As items arrive back in the warehouse the receiving workflow creates new inventory units and updates the return's progress. When the return is approved, a credit memo can be generated in one click.

RMA numbers follow the pattern CRA-XXXX and are assigned automatically on creation. You can also type your own number before saving if your process requires it.

Creating a return #

Open Sales → Customer Returns → New Return and fill in:

  • Customer — required; the dropdown is searchable. Selecting a customer filters the Sales Order picker to only that customer's orders.
  • Sales Order — optional link to the originating order. Leaving it blank is fine for over-the-counter or informal returns.
  • Status — starts at Draft and can be moved manually at any time. Status also advances automatically as items are received (see Status lifecycle).
  • ReasonDefective, Wrong Item, Damaged in Transit, No Longer Needed, or Other. Optional but useful for reporting.
  • Notes — free-form text for internal context.
  • Total Amount — read-only on the form; it is recalculated from line items every time a line is added, updated, or removed.
  • Custom fields — any extra attributes your account has defined for returns appear at the bottom of the form.

Status lifecycle #

A return moves through five statuses:

  • Draft — just created; still being set up, no items received yet.
  • Submitted — the customer has been authorized to ship the goods back.
  • Received — at least one line item has some quantity received.
  • Completed — every line item is fully received. The system sets this automatically once the last item is received; you can also set it manually.
  • Cancelled — closed without receiving. Cancelled and Completed returns block further receiving.

Draft and Submitted are set by hand; Received and Completed advance automatically as you log receipts on the receiving page.

Return line items #

The Items tab on the return lists what the customer is expected to send back. Each line records:

  • Product — which product is being returned.
  • Quantity — how many the customer is expected to return.
  • Quantity Received — how many have actually arrived. This is updated by the receiving workflow, not by hand.
  • Unit Price — the credit value per unit in dollars (stored as cents internally; see the API note below).
  • Notes — line-level comments.

The return's Total Amount is the sum of unit_price × quantity across all lines and updates automatically whenever a line changes.

Receiving items back into inventory #

Opening a return that is not yet Completed or Cancelled reveals a Receive Items button in the header. The dedicated Receive page offers a barcode-scan-first interface:

  1. Scan a barcode — scan the Product barcode (or type it) to auto-select the matching line. The field clears immediately so you can keep scanning.
  2. Enter a quantity — the quantity field is pre-filled with the remaining-to-receive amount for that line; edit it if you're only receiving a partial shipment.
  3. Confirm — the system restocks the Units (status In Stock) into the receiving bin, posts a Return In movement against them, increments quantity_received on the line, and refreshes the return's status.

The page shows a running count of received vs. total lines and a recent-receipts feed so you can verify what just came in without scrolling the full table.

Where returned stock lands #

Returned goods are stock arriving, so they land in the receiving bin of a location, exactly as a delivery does — and, exactly as with a delivery, somebody still has to put them away afterwards. The Receive page names the bin before you confirm ("Lands in Downtown Studio › Receiving") and again in the recent-receipts feed, so you always know which shelf to walk the box to.

The site is taken from whichever of these the return states first:

  1. The drop-off appointment, if the return was booked as one — where the customer actually brought the goods.
  2. The sales order's location — where the goods shipped from.
  3. The site you are working at (your active location).

If the location has no nominated receiving bin, wherever that product was last put away at that site is used instead. If none of the three names a site — a multi-location business receiving a return with no appointment and an order that names no location, with no active site selected — the units are restocked without a bin and you'll want to place them by hand.

You can receive the same line in multiple sessions. Each partial receive adds to quantity_received until it reaches the full quantity, at which point the line is considered fully received.

Credit memos #

Once a return is Received (some items back) or Completed (all items back) you can issue a credit memo from the return's view page. The credit memo's amount reflects only the value of items received so far (unit price × quantity_received), so issuing one against a partially-received return credits just the received portion — for a Completed return that equals the full total. The memo is created with status Issued. A return can have at most one credit memo; after it has been generated, the credit memo appears on the return page with a link.

Over the API, POST /customer-returns/{id}/credit-memo issues the memo for the received amount (returns 422 if nothing has been received yet, or if a memo already exists).

The return list #

Sales → Customer Returns shows every return with its RMA #, Customer, linked SO #, Status badge, Reason, and Total. Search by RMA number or customer name, sort by RMA #, Customer, Status, or Total, and use the Trashed filter to view soft-deleted records.

Doing it from the API #

# List returns for a specific customer
curl "https://your-domain.com/api/v1/customer-returns?customer_id=<id>" \
  -H "Authorization: Bearer $TOKEN"

# Create a return
curl -X POST "https://your-domain.com/api/v1/customer-returns" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_id": "<customer-id>",
    "sales_order_id": "<so-id>",
    "reason": "defective",
    "status": "submitted",
    "notes": "Customer reported faulty power switch."
  }'

# Add a line item (unit_price in cents)
curl -X POST "https://your-domain.com/api/v1/customer-return-items" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "customer_return_id": "<return-id>",
    "product_id": "<product-id>",
    "quantity": 2,
    "unit_price": 4999
  }'

Money fields are integers in centsunit_price: 4999 means $49.99, and the total_amount on the return is likewise in cents. Filter the list with customer_id and/or status query parameters; results are paginated at 50 per page.