What breaks when a voided Stripe invoice doesn't clear from AR aging?
Voiding a Stripe invoice is terminal, but Loopfour's Stripe integration has no webhook handler — it's poll-only. The status change only reaches AR aging if the workflow re-polls via getInvoice after creation. Read status once, at creation, and the invoice stays open in AR aging even though Stripe itself now shows it as void.
Part of the finance integrations guide.
| Symptom | A voided Stripe invoice still shows as open on the AR aging report |
|---|---|
| Root cause | Loopfour's Stripe integration has no webhook handler; a status change after creation only reaches AR aging if something re-polls getInvoice |
| What voiding actually does in Stripe | Marks a finalized invoice void permanently, treats it as zero-value, and is only possible from open or uncollectible status |
| What voiding is not | Not the same as a refund — a paid invoice can't be voided, only refunded or credited |
What voiding actually changes in Stripe
Stripe's void action is terminal — once an invoice is void, its status can never change again. Voided invoices are treated as zero-value for reporting and can't be paid; you can only void an invoice that's currently open or uncollectible, not one that's already been paid. A paid invoice needs a refund or credit note instead, which is a different operation with different accounting implications.
Why the void doesn't always reach AR
Loopfour's Stripe integration covers invoice creation, finalization, sending, and voiding, plus getInvoice for reading current status — but it has no webhook handler at all, unlike Airwallex's or HubSpot's integrations in this same matrix. There's no invoice.voided event to subscribe to, because nothing in this integration listens for Stripe events; every status read is a poll. If the workflow that populates AR aging calls getInvoice once at creation and never again, a status change that happens afterward — voiding, marking uncollectible, a later payment — simply isn't seen until something calls getInvoice again.
How to check whether this is happening
Compare Stripe's own invoice list, filtered to void status, against the AR aging report for the same period. Any invoice that shows void in Stripe but still open in AR aging is a case where the workflow's last getInvoice call predates the void — not a case where Stripe and the books actually disagree about the invoice's status. A scheduled re-poll of open invoices, not a one-time read at creation, is what closes that gap.
Next step
Map the finance workflow with the most exposure and prove the automation path.
Bring the invoice, contract, payment reconciliation, or customer finance workflow you have to defend at audit. Loopfour can map the trigger, controls, integrations, and approval loop.
Worked example
A $3,400 invoice that's void in Stripe and open in AR
A customer's plan changes mid-month, so a $3,400 invoice gets voided in Stripe and replaced with a corrected one. Stripe's own record is unambiguous: the original invoice is void, zero-value, and permanently closed, visible on Stripe's invoice list with a voided_at timestamp. But the AR aging report was populated by a single getInvoice call when the invoice was first created and finalized — nothing calls getInvoice again after that — so it keeps showing the same $3,400 as open and aging. The fix isn't in Stripe; it's scheduling a periodic getInvoice re-check on open invoices, since polling once at creation is structurally the same as never checking again.
Frequently Asked Questions
Sources
Related
Topic
AR & Collections
Accounts receivable is the money customers owe a business for goods or services already delivered on credit — a current asset on the balance sheet until it's collected. AR and collections, as a practi…
Read moreDefinition
What is an AR aging report and how do I read it?
An AR aging report lists every open invoice grouped by how long it's been outstanding — current, 1-30, 31-60, 61-90, and 90+ days past due. Read it by tracking the bucket distribution over time, not just the total; a shrinking current bucket and growing 90+ bucket signal a collections problem before it shows up in a blended DSO figure.
Read moreTopic
Integrations
Every finance automation vendor publishes an integrations page: a grid of logos, a claim of "seamless" connectivity, and not much else. That page answers a marketing question — does this vendor touch…
Read moreDiagnostic
Why is Avalara rejecting a sales invoice with a DocumentCodeConflict error?
A DocumentCodeConflict means the document code you sent already belongs to a committed transaction in AvaTax. The fix is not a fresh code — retrying with a new code every time is exactly what creates duplicate tax transactions on a real network retry. Keep the code stable, derived from the source invoice, and call the adjust or void endpoint if the original genuinely needs to change.
Read more