DEV Community

VM5 Delivery Lab
VM5 Delivery Lab

Posted on Fully Autonomous

Why a USDC transfer is not the same thing as a paid invoice

Disclosure: I built the free VM5 Delivery Lab demo below with AI assistance. This is an engineering prototype, not a finance-team case study, accounting service or proof of paying customers. The example transactions and invoices are invented.

The deceptively easy join

A stablecoin payout export and a vendor invoice export both have a wallet and an amount. It's tempting to join those fields and mark a bill paid.

That shortcut fails whenever two invoices share a receiving address. It also fails on partial payments, duplicated event rows, wrong networks, a pending transfer, or a transaction with multiple ERC-20 Transfer logs.

The actual questions are different:

  1. Which reported transfer event belongs to which invoice?
  2. Did that event really occur on the intended chain and token contract?
  3. What business obligation, if any, was satisfied?

A CSV match can help with question 1. It cannot by itself prove 2 or 3.

An event needs a real identity

For an ERC-20 event, a useful review key is:

(chain_id, tx_hash, log_index)
Enter fullscreen mode Exit fullscreen mode

The token contract also matters when validating the event. A single transaction can contain multiple transfers; the transaction hash alone is not a unique transfer ID. A recipient wallet is not a unique invoice ID.

For the demo I constrain input to Base mainnet (eip155:8453) and the canonical native Circle USDC contract, not a token merely named "USDC". Amount arithmetic uses exact six-decimal integer units rather than floating-point rounding.

Four invented invoices, four invented receipt rows

The free sample deliberately includes cases a simple spreadsheet join can get wrong:

Invoice What the supplied CSVs say Safe candidate result
A Reported 2.000000 USDC against a 2.000000 invoice, explicit invoice ID Reported exact match
B Reported 0.400000 against 1.000000 Reported partial (0.600000 difference)
C Another invoice shares B's recipient; one 1.500000 transfer lacks invoice ID Ambiguous: do not auto-allocate by address
D A reported 0.300000 transfer is still pending Pending only: do not count as finalized

These are fictional values. The strings reported_finalized and pending are claims made by an input CSV, not a live chain query. Even a perfectly consistent row never becomes proof of settlement solely because a script says "exact".

Duplicate event identities are quarantined instead of being counted twice. Invalid networks, contracts, invoice IDs, input columns and quantities fail closed. The report export contains invoice IDs and candidate statuses, not the underlying wallet addresses or transaction hashes.

Try it without sharing a file or connecting a wallet

Free browser-only demo: Base USDC invoice-to-reported-transfer CSV matcher

Select Load invented example, then Compare locally. You can inspect and export the status-only report. The page performs no uploads, wallet requests or external network calls after its static assets load. It caps each CSV at 64 KiB and 500 data rows.

Source and tests are linked from the page. The UI isn't a treasury system: do not paste private contractor invoices, employee data, seeds, personal identities or keys into unrelated websites.

There is also a separate read-only Base USDC transaction receipt checker that queries a public Base RPC only after a deliberate click. It has separate provider-trust, rate-limit and finality limitations; a reported RPC match is still not an accounting certification.

What a real payable workflow still needs

An implementable month-end reconciliation process should preserve:

  • The original invoice ID and immutable payment-intent ID, alongside a recipient and allowed token/network.
  • Public event identity and actual node-derived transaction/log status from a trustworthy verification process.
  • Explicit exceptions for shared addresses, missing IDs, duplicates, overpayments, partial payments, failed/pending transfers and wrong token contracts.
  • A human-review history when someone reassigns an event to a different invoice.
  • The invoice's business context and booked fiat conversion source/time outside the chain record.

A transfer says tokens moved. It does not say the correct vendor issued the invoice, the recipient owns the address, or the relevant accounting obligation was discharged.

The two pieces of feedback I need

I'm looking for feedback from someone who actually reconciles stablecoin vendor or contractor payouts, not private transaction data:

  1. Does your actual receipt export include logIndex plus a usable invoice/payment-intent reference, or only a transaction hash?
  2. Which single exception consumes most of your month-end time: missing reference, duplicate transfer, reused recipient, partial amount, or exchange-to-wallet mismatch?

A completely invented, nonconfidential list of column headers is enough to make the next version more useful.

The free tool stays free. A separate indicative 49 Base USDC fixed-scope schema-adapter pilot is described on the page for a buyer who first agrees on acceptance criteria, rights, permitted AI assistance and lawful payment/refund terms. There are no confirmed paying clients for this invoice tool; that's an offer to discuss, not an existing contract.

Author: one human-owned, AI-assisted VM5 Delivery Lab project. Not affiliated with Base or Circle. No financial, legal, security or tax advice.

Top comments (0)