opencollective icon indicating copy to clipboard operation
opencollective copied to clipboard

Virtual card refunds are missing `ExpenseId`

Open Betree opened this issue 1 year ago • 1 comments

To do:

  • [ ] Fix
  • [ ] Migrate past data
select kind, * from "Transactions" WHERE "ExpenseId" IS NULL AND "OrderId" IS NULL
AND "deletedAt" IS NULL
ORDER BY id DESC

Betree avatar Jul 09 '24 13:07 Betree

This issue turns out to be a bit more complex to address than initially expected, and in reality impossible to completely solve. According to https://docs.stripe.com/issuing/purchases/transactions:

When we create a transaction representing a refund or credit, we try to link it to the original payment authorization. Refunds aren’t necessarily tied to the original payment transaction or authorization, so linking them is an inexact science. As a result, we might link to an unrelated authorization or be unable to link to an authorization at all (for example, if the card is credited rather than refunded). In these cases, the authorization field of the transaction is set to null, and the transaction won’t be linked to the authorization. We process all refunds and credits the same way, regardless of their linkage to a payment authorization.

This is likely the root cause for https://github.com/opencollective/opencollective/issues/6523.

There is, however, something we can probably improve in the logic: in https://github.com/opencollective/opencollective-api/blob/28803a1fc616d8cbab258951cf5c09310253a2fe/server/paymentProviders/utils.js#L159, we try to match the expense by (Virtual Card ID + amount + status=PAID). This is inaccurate because there's no guarantee that the amount will perfectly match, nor that it will be the right expense, nor that the expense will be PAID (it could be PROCESSING). Could we, maybe, look for the original expense by looking for the refund authorization field to better match the expense?

cc @kewitz

Betree avatar Jul 10 '24 09:07 Betree