Page MenuHomePhabricator

[Discussion] Proposal for Handling ACH Donations in CiviCRM
Open, Needs TriagePublic

Description

Context:
Currently, some ACH donations are marked as "complete" in CiviCRM before the transaction has actually been processed or approved by the bank. This leads to inaccurate data and potential confusion in donor communications.

Proposed Changes:
Do Not Mark ACH as Complete Prematurely:
ACH donations should not be marked as "complete" in CiviCRM until we receive a webhook notification confirming that the payment has been successfully processed.
This ensures that we only show finalized transactions and avoid premature TY (Thank You) emails.

Donor Messaging on TY Page:
For ACH donations, show a message on the TY (Thank You) page to inform donors that:
Their donation is being processed.
The thank-you email may be delayed until the payment is confirmed.
Example message:
"Thank you for your donation! ACH payments can take a few days to process. We'll send your confirmation email once your bank has completed the transfer."

Considerations on Delay:
Webhook confirmations can take up to 7 days.
We need to check with the Donor Relations team if it's acceptable to:
Delay TY emails by up to 7 days.
Or, have the ACH record in Civi marked as incomplete for that duration.

Recurring Donation Handling:
It's okay to show the monthly convert model (i.e., suggest recurring giving).
However, the recurring donation record should only be created after:
The initial ACH payment is confirmed via webhook.
The payment token is valid.
This prevents invalid or unconfirmed recurring profiles from being pushed into the queue.

Reference:
Original discussion: https://phabricator.wikimedia.org/T404446

Other considerations:
IDEAL recurring is currently working differently
Donors will be included in email sends until their have a contribution in civi

Documentation of current status: https://wikitech.wikimedia.org/wiki/Fundraising/Data_and_flow/Payment_methods/ACH

Event Timeline

AnnWF renamed this task from Do not mark gravy ACH complete until webhook to [Discussion] Do not mark gravy ACH complete until webhook.Oct 7 2025, 10:29 PM
AnnWF renamed this task from [Discussion] Do not mark gravy ACH complete until webhook to [Discussion] Proposal for Handling ACH Donations in CiviCRM.
AnnWF updated the task description. (Show Details)
AnnWF updated the task description. (Show Details)

We came to an agreement in the meeting — see details in the note below:
https://docs.google.com/document/d/1QiymgoXu2fUc_1NfgNI9NOio071z5H4FMjY1cklqLIc/edit?tab=t.0
the agreed payment flow could be (extendable for other payment methods, e.g. ideal/boleto)

[User submits payment]
          |
          v
[Payment Processor API returns "pending"]
          |
          v
+--------------------------+
| Show "Pending TY Page"   |
| (Explain payment under   |
| review; no email yet)    |
+--------------------------+
          |
          v
[Create Civi Contribution with status = Pending]
          |
          v
<-- Wait for Webhook (status update) -->
          |
   +--------------------+
   | Webhook arrives    |
   | (complete / fail)  |
   +--------------------+
          |
   +----------------------------+
   | If "complete":             |
   |  - Update Civi status -> Completed |
   |  - Send real Thank-You email      |
   |  - If recurring/MC: create recurring record |
   +----------------------------+
          |
   +----------------------------+
   | If "failed":               |
   |  - Update Civi -> Failed   |
   |  - Do NOT create recurring (Token invalid, etc.)   |
   +----------------------------+

@Eileenmcnaughton Do you know why we were not having pending status in Civi before, is that any potential risk here, thanks!

@AnnWF as to the why - that is probably more historical than meaningful

However, the main risk is that other code might not be checking the status appropriately - ie

  • thank you mail
  • triggers
  • Acoustic export

(FWIW I'm pretty sure triggers DO check for completed status & Acoustic is probably driven by that so it's mostly thank you mail & the thing we haven't thought of)

I like your asci flow chart :-)

  • At a code level you should use the Payment.create api when the payment arrives & make sure it passes the parameter (isSendNotification or similar) to prevent an email being triggered by that

Thanks Eileen for the historical explanation and juse as Elliott brings up that "we'd of course need to review all the triggers and the acoustic export."

Since you said triggers DO check for completed status could you help us to check if Acoustic is actually driven by that?

and for ty email, I see in Payment.Create is using notificationForCompleteOrder, there is a one as notificationForPayment which is false as default and notificationForCompleteOrder true as default, so should be fine, but we will test that when we actually adding 'pending' status.

Thanks again~

@AnnWF as to the why - that is probably more historical than meaningful

However, the main risk is that other code might not be checking the status appropriately - ie

  • thank you mail
  • triggers
  • Acoustic export

(FWIW I'm pretty sure triggers DO check for completed status & Acoustic is probably driven by that so it's mostly thank you mail & the thing we haven't thought of)

I like your asci flow chart :-)

  • At a code level you should use the Payment.create api when the payment arrives & make sure it passes the parameter (isSendNotification or similar) to prevent an email being triggered by that.

I see a good smattering of things like this in the triggers file

  WHERE  c.contact_id = NEW.contact_id 
    AND c.contribution_status_id = 1
    AND (c.trxn_id NOT LIKE 'RFD %' OR c.trxn_id IS NULL)
) as totals

There are quite a few checks on contribution_status_id in the Acoustic export too.

I can't say there are no gaps but the code was definitely written on the assumption that we needed to only include Completed

Good to know, we will also use contribution_status_id:name check in our code then!

One more thing to review - contribution create hooks

One more thing to review - contribution create hooks

I added couple sub tasks, feel free to add more and the concern you and Eileen pointed out were added to that QA ticket