Skip to main content

Purchasing in ERPClaw

How purchase orders, goods receipts, vendor invoices, and payments flow in ERPClaw. Three-way matching, GL postings at each step, supplier setup.

The purchasing flow in ERPClaw is procure to pay: PO, goods receipt, vendor invoice, payment. Three-way matching happens before the invoice is approved. Every step writes the right GL entries automatically.

The four-step flow

  1. Create a purchase order with the items and quantities you want to buy.
  2. Receive the goods when they arrive at your warehouse.
  3. Match the vendor invoice against the PO and receipt (three-way matching).
  4. Pay the vendor when the invoice is due.

Each step is a separate document in ERPClaw with its own GL postings.

Step 1, supplier setup

Before you can buy from a supplier, the supplier must exist:

add-supplier name="Acme Steel" [email protected] payment_terms="Net 30"
list-suppliers

Supplier records hold contact info, default payment terms, default currency, tax IDs, and bank details if you want to ACH payments. You can store a dedicated email and phone on each supplier (and on each customer) when you add or update the record, so the people you bill and the people you buy from each keep their own contact details.

Step 2, the purchase order

A purchase order is an offer to buy. It does not post to GL on its own (no goods received, no invoice yet). It just commits you to the vendor in writing.

add-purchase-order supplier="Acme Steel" delivery_date=2026-04-30 items='[
  {"item": "Steel Beam, 10ft", "quantity": 5, "rate": 200.00},
  {"item": "Bolts, 1/4 inch", "quantity": 100, "rate": 0.50}
]'
submit-purchase-order id=<id>

The submit step locks the PO. To cancel, post a cancellation; to amend, create a new PO and reference the old one.

You do not have to match a product name exactly. Refer to an item loosely or in the plural (“5 Steel Beams”) and ERPClaw resolves it to the stored product (“Steel Beam, 10ft”), so everyday phrasing works without you hunting for the exact name on file.

Step 3, goods receipt

When the goods arrive, log the receipt:

create-purchase-receipt purchase_order_id=<po-id> received='[
  {"item": "Steel Beam, 10ft", "quantity": 5},
  {"item": "Bolts, 1/4 inch", "quantity": 100}
]'
submit-purchase-receipt id=<receipt-id>

The receipt posts to GL:

AccountDebitCredit
Inventory$1,050.00
Goods Received Not Invoiced$1,050.00

The “Goods Received Not Invoiced” (GRNI) account is a temporary holding account that clears when the vendor invoice arrives. This is a clearing-account pattern and it is the right way to handle the timing gap between receipt and invoice.

When you receive stock you bought, ERPClaw values it from the unit cost on the purchase order or bill, so your inventory is costed and booked correctly with no $0 surprises. If a receipt arrives with no cost to work from, ERPClaw refuses it rather than booking the stock at zero.

Step 4, vendor invoice with three-way matching

When the vendor sends the invoice, match it against the PO and receipt:

create-purchase-invoice purchase_order_id=<po-id> purchase_receipt_id=<receipt-id> invoice_amount=1050.00

Three-way matching compares:

  1. PO quantity vs receipt quantity (did we receive what we ordered?)
  2. Receipt quantity vs invoice quantity (is the vendor billing for what arrived?)
  3. PO unit price vs invoice unit price (is the vendor honoring the agreed price?)

If all three match within tolerance, the invoice can be submitted. If not, you get a mismatch report and the invoice stays in draft until reconciled.

On submit:

AccountDebitCredit
Goods Received Not Invoiced$1,050.00
Accounts Payable$1,050.00

The GRNI account clears. AP now owes the vendor.

Step 5, payment

Pay the vendor when the invoice is due:

add-payment-entry payment_type=pay party_type=supplier party_id=<supplier-id> paid_amount=1050.00 reference_number=ACH-12345
submit-payment-entry id=<payment-id>

GL posting:

AccountDebitCredit
Accounts Payable$1,050.00
Cash$1,050.00

AP balance now zero for that invoice. Cash account drops. Recording the payment also marks the vendor bill paid and clears its outstanding balance, so the bill no longer shows as owing.

When goods arrive without a PO

Sometimes a one-off purchase has no PO. ERPClaw lets you skip the PO step:

create-purchase-invoice supplier="Office Depot" line_items='[{"description": "office chairs", "amount": 800.00, "expense_account": "Office Supplies"}]'
submit-purchase-invoice id=<id>

The invoice posts directly to the expense account and AP. No three-way matching because there is nothing to match against.

Returns and credit notes

To return goods to a vendor, post a credit note that references the original invoice:

create-purchase-credit-note purchase_invoice_id=<id> items='[{"item": "Steel Beam, 10ft", "quantity": 1, "rate": 200.00}]'
submit-purchase-credit-note id=<cn-id>

The credit note reverses the partial GL impact and reduces AP by the credit amount.

Reports

  • Open POs (list-open-purchase-orders)
  • AP aging (ap-aging)
  • Vendor balance (vendor-balance )
  • Three-way match exceptions (three-way-match-exceptions)
  • Purchase register (purchase-register)

What is next