Page MenuHomePhabricator

Odd Refund Recording in Civi
Closed, ResolvedPublicBUG REPORT

Description

I am seeing some weirdness with some refund entries in the db and civi UI. Or I am misunderstanding.

Here is an example of a contact that looks correct to me (refunds have two entries, A positive for the initial charge and a negative for the refunds):

select
	ft.id as trxn_id,
    ft.trxn_date, 
    CASE
		WHEN ft.total_amount > 0 THEN 'inflow'
        ELSE 'outflow'
	END as designation,
    ft.total_amount as trxn_amount, 
    ft.currency,
    c.contact_id,
    c.contribution_status_id,
    c.financial_type_id,
    c.id as civi_id,
    c.receive_date
FROM civicrm.civicrm_financial_trxn ft
LEFT JOIN civicrm.civicrm_entity_financial_trxn eft ON ft.id=eft.financial_trxn_id AND entity_table='civicrm_contribution'
LEFT JOIN civicrm.civicrm_contribution c on c.id = eft.entity_id
LEFT JOIN civicrm.civicrm_option_value AS cov ON CAST(c.payment_instrument_id AS UNSIGNED) = CAST(cov.value AS UNSIGNED) AND CAST(cov.option_group_id AS UNSIGNED) = CAST(10 AS UNSIGNED)
LEFT JOIN civicrm.civicrm_value_1_gift_data_7 AS gift ON c.id = gift.entity_id
LEFT JOIN civicrm.wmf_contribution_extra AS extra ON c.id = extra.entity_id
LEFT JOIN civicrm.civicrm_contribution_tracking AS t ON c.id = t.contribution_id
WHERE c.contact_id = 3687444
    AND c.id is not null
    AND ft.is_payment=1
    AND c.financial_type_id=14;

image.png (187×1 px, 59 KB)

image.png (214×699 px, 24 KB)

And here is one where there are just positive values (which are counting towards their donation total in the civi ui) marked refund without a corresponding original charge:

select
	ft.id as trxn_id,
    ft.trxn_date, 
    CASE
		WHEN ft.total_amount > 0 THEN 'inflow'
        ELSE 'outflow'
	END as designation,
    ft.total_amount as trxn_amount, 
    ft.currency,
    c.contact_id,
    c.contribution_status_id,
    c.financial_type_id,
    c.id as civi_id,
    c.receive_date
FROM civicrm.civicrm_financial_trxn ft
LEFT JOIN civicrm.civicrm_entity_financial_trxn eft ON ft.id=eft.financial_trxn_id AND entity_table='civicrm_contribution'
LEFT JOIN civicrm.civicrm_contribution c on c.id = eft.entity_id
LEFT JOIN civicrm.civicrm_option_value AS cov ON CAST(c.payment_instrument_id AS UNSIGNED) = CAST(cov.value AS UNSIGNED) AND CAST(cov.option_group_id AS UNSIGNED) = CAST(10 AS UNSIGNED)
LEFT JOIN civicrm.civicrm_value_1_gift_data_7 AS gift ON c.id = gift.entity_id
LEFT JOIN civicrm.wmf_contribution_extra AS extra ON c.id = extra.entity_id
LEFT JOIN civicrm.civicrm_contribution_tracking AS t ON c.id = t.contribution_id
WHERE c.contact_id = 57805094
    AND c.id is not null
    AND ft.is_payment=1
     AND c.financial_type_id=14;

image.png (93×1 px, 19 KB)

image.png (409×744 px, 40 KB)

I do just exclude refunds from normal reporting, but am working on something for finance reconciliation where in and outflows are needing to be represented.

Event Timeline

Thanks for spotting this @JMando, having looked through the transactions, this seems unique to Adyen.

The original transactions for that contact was refunded due to the chargeback - the contribution IDs are 89202236 and 90304648. The likely cause for this is that Adyen sends us a different ID for the refund that causes a new contribution row to be added with the refunded financial type and contribution status of completed.

I would continue looking at other transactions and consider possible solutions.

Looks like this has actually being fixed sometime in September (2023-09-09) with this contribution with id : 93228513 for ct_id: 60580550 being the last time it occured.

Chargebacks for each contact following this date does not create another contribution row with refund status, unless the original transaction was in a different currency and discrepancies caused by currency fluctuations.

Here's the query I used in checking:

select c.id, c.trxn_id, c.receive_date, c.contact_id 
from civicrm_contribution as c 
join wmf_contribution_extra as extra on extra.entity_id=c.id 
where extra.gateway='adyen' 
and extra.original_currency="USD" 
and c.contribution_status_id=13 
and c.receive_date > "2023-08-01 00:00:00" 
and c.receive_date < "2023-10-01 12:36:27" 
order by c.id desc limit 50;

So here are the positive refunds I see since the start of this fiscal year:

select
	ft.id as trxn_id,
    ft.trxn_date, 
    ft.total_amount as trxn_amount, 
    c.total_amount,
    ft.currency,
    c.contact_id,
    c.contribution_status_id,
    c.financial_type_id,
    c.id as civi_id,
    c.receive_date,
    CASE
        WHEN (extra.gateway IS NULL OR extra.gateway = '') AND cov.name = 'Tides' THEN 'Tides'
        WHEN extra.gateway IS NULL OR extra.gateway = '' THEN 'NULL'
        WHEN extra.gateway = 'globalcollect' THEN 'ingenico'
        WHEN extra.gateway = 'astropay' THEN 'Dlocal'
        WHEN extra.gateway = 'paypal_ec' THEN 'paypal'
        ELSE extra.gateway
    END AS gateway_not_null
FROM civicrm.civicrm_financial_trxn ft
LEFT JOIN civicrm.civicrm_entity_financial_trxn eft ON ft.id=eft.financial_trxn_id AND entity_table='civicrm_contribution'
LEFT JOIN civicrm.civicrm_contribution c on c.id = eft.entity_id
LEFT JOIN civicrm.civicrm_option_value AS cov ON CAST(c.payment_instrument_id AS UNSIGNED) = CAST(cov.value AS UNSIGNED) AND CAST(cov.option_group_id AS UNSIGNED) = CAST(10 AS UNSIGNED)
LEFT JOIN civicrm.civicrm_value_1_gift_data_7 AS gift ON c.id = gift.entity_id
LEFT JOIN civicrm.wmf_contribution_extra AS extra ON c.id = extra.entity_id
LEFT JOIN civicrm.civicrm_contribution_tracking AS t ON c.id = t.contribution_id
WHERE ft.trxn_date >'2023-06-30'
    AND c.id is not null
    AND ft.is_payment=1
	AND c.financial_type_id=14
    AND c.total_amount>0;

Shouldn't these all have two entries in civicrm_financial_trxn (one positive one negative)?

Note I see paypal and adyen gateways in that query's output.

Thanks @JMando I see the stats show 568 from Adyen this year and 11 from paypal.

I've been able to trace down the bug for the Adyen transactions to an erroneous notification received from Adyen and opened this phab: T351822

Paypal seem to be sending a negative refund value, so I'm moving this phabricator to Chaos crew for my colleagues to look into the cause for 11 paypal transactions oddities.

Thanks for spotting this once again.

greg triaged this task as Medium priority.Nov 22 2023, 5:22 PM

I'm deleting the duplicate entries where the refund is the full amount and the data is already reflected on the original donation.

There will still be separate line items from different currency refunds, positive and negative based on how the conversion changed in between the original donation date and the refund.

That's great, thanks for the update @Cstone.

XenoRyet set Final Story Points to 4.