Rightshold™ Sign up

Answers · bookkeeping

How do I record a void or reversal of an AI agent's payment on an append-only ledger?

Last updated

TL;DR: Don't delete the original payment record, and don't edit it to zero in place. An append-only ledger is built so that changing or removing an entry breaks the hash chain, and even in ordinary books a silent overwrite hides what a reviewer needs to see. Post a new reversing entry that points at the original: its entry id, the reason, who approved the void, and when. Both entries stay visible, and their net (the original amount plus the reversing amount) is what the period should show. Everyday bookkeeping already works this way: QuickBooks Online keeps a voided transaction in your records at zero and marked void; deleting it removes it everywhere except the audit log. On the card rail the same split appears. Stripe lets you cancel a PaymentIntent that has not yet succeeded, but once it has succeeded you create a separate Refund object — you cannot cancel it, you can refund part of what is left, and you cannot refund more than remains on the charge. IAS 8 tells entities to correct material prior-period errors by restating the comparative figures and disclosing the nature and amount of the correction (paragraphs 42 and 49), not by leaving no trace that figures changed. PCAOB AS 1105 asks auditors to test the completeness of company-produced information, and names completeness as the assertion that all transactions that should be presented are included: a deleted payment drops out of the population they sample, while a linked reversal stays in it. On Rightshold, record the original with record_action, then record the reversal under a new client_event_id that names the original event id. Reusing the original key with different content is rejected as a conflict; there is no edit or delete. ledger_verify checks the public ledger those commitments sit on. This page is about reversing a recorded payment. Making the log append-only so an admin can't silently delete entries, catching backdated posts after month-end close, and matching spend to the bank feed are covered on separate pages.

What should I check, step by step?

1. Keep the original payment record as it was written: its event id, amount in minor units, currency, payee, time, approver and policy version. Do not edit those fields later.

  1. Decide what void means on the payment rail. If the charge was authorized but not captured, cancel it (Stripe: you can cancel a PaymentIntent that has not succeeded; a succeeded PaymentIntent cannot be canceled). If it has already succeeded, create a refund for some or all of the remaining amount — Stripe creates a separate Refund object and will error if you try to refund more than is left.
  2. Get a human approval for the void when the original payment needed one, bound to the original entry id, the refund or cancel reference, the amount and the reason.
  3. Write the reversal as a new entry with a new client_event_id (for example void:<original_event_id>) and action_type payment.reversed or payment.voided. Name the original event id, the reversing amount and currency, the reason, the approver and the provider's refund or cancel id.
  4. If you don't want those details in summary, put them in a private sidecar, hash its exact bytes, and send that SHA-256 as action_sha256. Keep names, emails and account numbers out of summary and client_event_id: recorded events can't be edited or deleted.
  5. Never reuse the original client_event_id for the reversal. The same key with the same content comes back as a duplicate of the first receipt (a retry), and the same key with different content is rejected because that key is already bound to different event content.
  6. When you report the period, net each original with the reversals that name it. Rightshold does not compute that net, move money or talk to your card provider.
  7. Check both receipts: the stream chain for the pair, and ledger_verify for the public commitments. Keep the pair together for as long as you keep the books.

Why shouldn't I delete or overwrite an AI agent's original payment when I void it?

A hash-chained log works because each entry commits to the one before it. Removing or editing the original payment changes every hash after it, which is exactly what the log exists to expose. Overwriting the amount to zero in place has the same problem: a later reader sees only the zero, not that a payment was once recorded and then taken back.

What should a reversing ledger entry for an AI agent's voided payment contain?

The original entry id (so a reader can join the pair without guessing).

What does Rightshold do, and not do, when I record an AI agent payment reversal?

record_action appends the event you send to your account's private stream and puts a salted commitment to it on the public ledger. The event (action_type, outcome, occurred_at, summary, action_sha256, client_event_id) can't be edited or deleted. A receipt proves what was submitted and when, and that it hasn't changed since. It does not prove the payment or the refund happened.

How do I ask Rightshold about this (free, no key)?

Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “Record a reversal of the agent payment I already logged as act_ORIGINAL. The vendor canceled the order. Name the original entry, the reason, that our Controller approved it, and the Stripe refund id, under a new event key so the original stays as it was written.”

One-click setup

{
  "tool": "record_action",
  "arguments": {
    "action_type": "payment.reversed",
    "outcome": "success",
    "occurred_at": "2026-11-08T11:04:00Z",
    "client_event_id": "void:act_ORIGINAL",
    "summary": "Reverses act_ORIGINAL, 150.00 USD, reason: vendor canceled order, approver: Controller, refund: re_STRIPE_REFUND"
  }
}

Rightshold records the events you send in a private, append-only stream and puts a salted commitment to each on its public ledger. It does not edit or delete events, compute original-plus-reversal nets, cancel or refund card charges, or connect to Stripe, your bank or your accounting software. Posting the linked reversal, getting approval and reporting the net are steps you run. Not accounting, tax, audit or legal advice.

What are the sources?

Related

Not legal advice. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.rightshold.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export RIGHTSHOLD_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.rightshold.com/v1/licenses/check -H "Authorization: Bearer $RIGHTSHOLD_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'