Receipts for agent payments

Did this payment actually settle?

A flawless 402 is not a settled payment, and a 200 is not a verified delivery. Facturify reads the chain and tells you which one you got.

Any rail · no facilitator change Never touches keys or funds Apache-2.0
Live verifier · Stellar pubnet reads the chain in your browser
verdict idle
// Press Verify. This calls Horizon directly from your browser —
// no server of ours sits between you and the ledger.

Three answers, and the third one matters most

Most tools return a boolean. A boolean has to lie when the chain could not be read — and that lie is indistinguishable from a real answer.

settled exit 0

A movement on the collector's account matches the claim. Comes with a citable transaction hash — not "check the explorer".

not-settled exit 1

We read the window and nothing matched. This is an assertion, and it is only made when it has been earned.

unknown exit 2

The chain could not be read, or the payer could not be confirmed. "I could not look" is not "there is nothing."

Two ways a real payment goes missing

Both were found the expensive way, against mainnet, and both are why the obvious implementation reports settled payments as absent.

Stellar · read /effects, not /payments

The operation carries no money

A USDC transfer through a Soroban contract is an invoke_host_function with no amount, no asset and no counterparty. A consumer of /payments sees the transfer as if it were empty. Only the effects carry the figures.

GET /operations/274050365530976257
{
  "type": "invoke_host_function",
  "amount": undefined,
  "asset_code": undefined,
  "from": undefined,
  "to": undefined
}

EVM · read Transfer logs, not tx.to

The transaction went to a batcher

Settlements get batched. This one was sent to Multicall3 — which is neither the token nor the recipient. Any filter on the transaction's destination reports a real, settled payment as missing.

eth_getTransactionReceipt
to:        0xca11bde05977b3631167028862be2a173976ca11  // Multicall3
token:     0x036cbd53842c5426634e7929541ec2318f3dcf7e
recipient: 0xdf98b94653fc914124a5d1b7fa1435a40c656123
value:     20000

Install, then verify somebody else's payment

You do not need to have made the payment, or to be trusted by anyone, to check it. The chain is the arbiter.

CLI
pnpm add -g facturify

facturify verify \
  --network stellar:pubnet \
  --pay-to GDNJXCKW7ZM7GEEVP674TWPU26YJNBQ2FI4ZIPRKTPTNUEJMDHFJWWRL \
  --amount 10000 \
  --asset USDC:GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN
SDK
import { facturify } from '@facturify/sdk'
import { stellar } from '@facturify/rail-stellar'

const f = facturify({ rails: [stellar()] })

const receipt = await f.record(claim)
await receipt.awaitSettlement({ deadlineMs: 60_000 })
// → settled · not-settled · unknown · pending

const trail = await f.export()
verifyChain(trail)   // validate it without us