Refunds in Virtuous Sync
Virtuous keeps a gift once it has been recorded. A refund in BetterUnite therefore reaches Virtuous in one of two ways, and which one you see depends entirely on whether the payment had already synced when the refund happened.
A refund is never an edit
Virtuous treats giving history as a ledger. You do not lower a gift that has already been recorded, and you do not delete it. You post a second, negative entry against it, called a reversing transaction, and the two lines sit side by side on the donor record. It is the only gift type in Virtuous that accepts a negative amount.
That gives BetterUnite two honest ways to represent a refund, and one rule for choosing between them:
- The payment has not synced yet. No gift exists, so there is nothing to reverse. The gift is created for what the payment is now worth.
- The gift already exists in Virtuous. The original stays exactly as it was, and a reversing gift is posted for the refund.
Both arrive at the same place: the donor's giving total in Virtuous matches what your organization actually kept.
When the refund comes first, the gift is created net
A $400 payment, refunded $75, that syncs afterward reaches Virtuous as a single $325 gift. The gift note records what happened, so the figure is never a mystery to whoever opens the record months later.
| Entry | Gift type | Amount |
|---|---|---|
| Payment from BetterUnite, refunded 75.00 of 400.00 | Credit | 325.00 |
| Counted for this payment | 325.00 | |
Designations follow the same figure. They are calculated against the full amount charged, so they are trimmed back to the gift total, taking the reduction out of processing fees first, then unrestricted giving, and only then a designated line item. Without that step, a refunded payment would arrive in Virtuous with designations claiming more money than the gift contains.
A recurring gift is deliberately left alone. If one payment in a series is refunded, the commitment recorded in Virtuous still reflects what the donor signed up to give.
When the gift already exists, a reversing gift is posted
Once Virtuous holds the gift, BetterUnite adds to the record rather than rewriting it.
Full refund
The whole gift is reversed, and Virtuous calculates the offsetting amount itself.
| Entry | Gift type | Amount |
|---|---|---|
| Payment from BetterUnite | Credit | 400.00 |
| Refunded payment in BetterUnite | Reversing transaction | -400.00 |
| Counted for this payment | 0.00 | |
Partial refund
A reversing gift is posted for the refunded amount only, linked back to the original gift. Refund again later and a second reversing entry appears, so the record reads as a history rather than a quietly corrected total.
| Entry | Gift type | Amount |
|---|---|---|
| Payment from BetterUnite | Credit | 400.00 |
| Partial refund in BetterUnite against gift 21728 | Reversing transaction | -75.00 |
| Counted for this payment | 325.00 | |
One deduction, never two
The risk in having two mechanisms is that both fire for the same refund and the donor's history drops by double. They are kept mutually exclusive. Once a reversing gift has been posted for a payment, that payment is treated as already carrying its deduction, so re-syncing it sends the full amount and lets the reversal stand instead of netting the gift a second time.
The same protection covers repeated events. A refund issued in BetterUnite also arrives back from Stripe as a webhook a moment later, and a webhook can be delivered more than once. A full reversal is recorded and skipped on any repeat. A partial reversal is filed under the running refunded total for that payment, so a duplicate of the same refund updates the one entry, while a genuine second refund gets its own.
Which refunds are covered
Every way money goes back to a donor now reaches Virtuous:
- A refund issued in BetterUnite, full or partial, from the payment record.
- Deleting or removing an offline payment, which is a refund as far as the ledger is concerned.
- Reducing a line item quantity on a purchase, which refunds the difference.
- A refund taken directly in Stripe. This one used to be invisible to Virtuous entirely, because it never passed through BetterUnite's refund screen.
- Peer-to-peer payments. A gift given through a fundraiser page is mirrored into child and grandchild payments that each sync as their own gift in Virtuous, so each one is reversed too.
A refund never waits on Virtuous
By the time Virtuous is contacted, the money has already gone back to the donor. A problem on the Virtuous side is therefore never allowed to look like a failed refund.
If the reversal cannot be posted, the refund still stands. BetterUnite raises an alert activity, "Virtuous gift not reversed after refund", naming the payment and the error Virtuous returned, and asking for a reversing transaction to be entered by hand. The same detail is written onto the payment's Virtuous sync note.
This matters more than it sounds. Previously a Virtuous error during a refund surfaced to whoever clicked the button as a refund failure, after the refund had already been committed to the database and processed by Stripe.
The gap where a gift has no id yet
Virtuous imports gifts asynchronously. BetterUnite sends the payment, Virtuous accepts it for processing, and the gift's id only becomes available on a later lookup. Until then, a refund has nothing to point a reversal at.
That lookup now runs at both ends of every scheduled sync, and the "check pending" action on the Virtuous setup page uses the same routine. When it resolves a gift, it also compares what Virtuous holds against what the payment is currently worth and posts a reversing gift for the difference. A refund that arrived during the gap is caught up automatically, and a refund that predated the sync leaves no difference, so nothing is deducted twice.
Until this change, that lookup only ever ran when someone happened to open the Virtuous setup page, which is why a refunded payment could sit in Virtuous at its full value indefinitely.
Payments that never sync at all
- Fully refunded before the first sync. The payment is excluded from selection, so no gift is created and no reversal is needed. Virtuous never hears about it.
- Refunded to nothing in installments. Two partial refunds that add up to the whole payment leave it marked partially refunded, so it stays eligible for sync. Rather than create a zero gift, the sync reports the payment as fully refunded and stops.
- A genuinely free registration still syncs at zero, because that is real activity worth recording.
Two things to keep an eye on
Repeated partial refunds on an offline payment. BetterUnite records the refunded amount for an offline payment by replacing the previous figure rather than adding to it, so two partial refunds on the same offline payment leave only the most recent one on the record. Refunds processed through Stripe are unaffected, because that figure comes from Stripe's own running total. This is existing refund bookkeeping, and it affects BetterUnite's own totals as much as the Virtuous figure.
Partial reversals are new. A full reversal uses the dedicated Virtuous reversing-transaction call, which has been in use for some time. A partial reversal is imported as a reversing gift with a negative amount, which is how Virtuous documents refunds arriving from an integration, but the link back to the original gift is worth confirming on the first live partial refund. If that link does not take, the negative entry still stands on its own and the donor's total is still right.