Fundraising/Data and flow/Recurring

== Overview ==
Recurring donations are supported via PayPal (both legacy and Express Checkout integrations), Adyen, Dlocal, Braintree (venmo), and Gravy.
In CiviCRM, recurring donations are stored in the civicrm_contribution_recur table and each installment has an entry in civicrm_contribution with a value in the contribution_recur_id pointing to the civicrm_contribution_recur row. We store them slightly idiosyncratically - while core CiviCRM's payment processors interpret the 'Completed' status to mean that there are no more installments expected, we use 'Completed' to mean that the subscription is in a good state.
== Frequencies - Monthly and Annual ==
Historically recurring donations were every month, in late 2024 we added an annual recurring option which would be every year.
url parameters for monthly
recurring=1&frequency_unit=month
url parameters for yearly
recurring=1&frequency_unit=year
== Setup ==
At Payments-wiki, we interpret any truthy value sent for the query string parameter 'recurring' to mean we should set up a recurring payment for the donor.
Will start a recurring
recurring=1 recurring=true 
Will not start a recurring
recurring=0 recurring=false
==PayPal==
PayPal recurring donations are all driven by PayPal - that is, we indicate that we want to set up a monthly donation for a specific amount, and PayPal takes care of the scheduling, charging, and retry attempts on failed charges.
For PayPal Express Checkout, we use the MAXFAILEDPAYMENTS parameter to instruct PayPal to stop trying to charge the donor after N failed attempts. Express Checkout subscriptions set up prior to October 15th, 2019 had this value set to 3, and after that date have the value set to 0, meaning to retry indefinitely. On failure, PayPal retries every 5 days.
PayPal's documentation
== Adyen ==
Adyen recurring donations are driven by us - after setting up a recurring donation, Adyen gives us a recurring_payment_tokento store and refer to in future donation attempts. We schedule the donations and make API calls to charge them once each month. Our hourly scheduled jobs check the civicrm_contribution_recur table for rows where the next_sched_contribution_date is now or before, and charge a batch of them.
Adyen recurring donations (coded as gateway=adyen) are tokenized. That is, we receive a payment token at the time of the setup and store it in the civicrm_payment_token table. The code to charge each monthly installment is in the CiviCRM extension org.wikimedia.smashpig, which uses the SmashPig library to interface with the Connect API. The scheduled job is configured in recurring_smashpig_charge.yaml, which runs drush cvapi job.process_smashpig_recurring.
There is more information on the details of Adyen recurring on the main Adyen page.
== Dlocal ==
Like Adyen, Dlocal recurring jobs are driven by us.
More information on dlocal recurring on the main dlocal page
== Recurring Convert/Monthly Convert ==
Recurring Convert is a system to give the donor an option to start a recurring donation after a one time donation. They do not need to reinput their payment information.
We started with offering monthly convert and have added yearly convert
There is more information on the main monthly convert page.
== Recurring queue ==
A somewhat misleading name, the recurring queue mainly handles Paypal recurrings. It also is where initial monthly convert messages are sent as well as [something for the dlocal flow figure out exactly what.]
== Smashpig civi extension/Smashing recurring charge job/Recurring charge job ==
We call this many different things but it is the nightly job that charges all the donations we have control over the charging of. It lives in the civi extension org.wikimedia.smashpig
More documentation here: https://wikitech.wikimedia.org/wiki/Fundraising/SmashPig
==Failures and retry logic==
If we get a failure charging a recurring contribution, we set the contribution_recur status to 'Failed', increment the failure_count column, and set a failure_retry_date. The maximum number of failures and the retry interval is configurable. For Ingenico Connect, settings are in the Civi top menu under Administer->System Settings->SmashPig Settings. For WebCollect, see the 'Recurring GlobalCollect Processor' link in the left-hand menu. Both are currently set to retry failed payments 1 day later, and to stop retrying after 3 failures.
After 3 failures a recurring failure message is sent. The templates for this message can be found in Civi under Mailings -> Message Templates. On the Message Template page click on the System Workflow Message tab. The templates are named WMF Recurring failure message. The 'from' address and name used are the default CiviCRM core FROM address. This is configured under Admininster->Communications->FROM Email Addresses (the failure email uses the one marked as default).
=== Testing ===
You can send a test failure email by going to a recurring record in civi and clicking on the ... menu on the right hand side. This brings up the option to Send Failure Notification.
=== Failure Reasons ===
civicrm_contribution_recur
column 	description 	 	
cancel_reason 	
{| class="wikitable" 	(auto) maximum failures reached	cancelled automatically after three retries
(auto) un-retryable card decline reason 	cancelled automatically when the processor returns a decline reason that is not retryable (fraud, lost card)	 	
(auto) Expiration notification 	PayPal only, we were sent a message from PayPal that the recuring is expired 	 	
(auto) User Cancelled via Gateway 	PayPal only, we were sent a message from PayPal that the donor cancelled their recurring 	 	
(auto) backfilled automated cancel 	 	 	
(auto) backfilled automated Expiration notification