I have previously blogged (http://civicrm.org/blogs/sarahgladstone/fun-and-joy-authorizenet-code-attached) and chatted about (http://forum.civicrm.org/index.php/topic,29234.0.html) about the fun and joy related to supporting automated recurring transactions in a production environment, and started the process of restructuring that portion of the code. I have made much more progress and have been using the code attached on production for about 2 weeks now. I think this approach (which I have implemented for Authorize.net) makes a good model for any payment processor that offers automated recurring contributions. You can download the code (works with version 4.3.4) HERE
My primary goals were as follows:
1) Auditability. In a production environement it is essential to have a history of all key communication with a third-party system. This should be easily searchable by an administrator or other authorized person.
2) Testability. It must be possible to test the core functionality without involving the third-party payment processing system or a web browser.
3) Repeatable, For example: If a message gets handled improperly (such as a bug in the API, some other issue that messes up the resulting contribution) it should be possible to delete the generated contribution record, and re-create it based on the data from the payment processor message log table.
My secondary goals:
4) Standardize core behavior accross various payment processors that offer automated recurring payments. Simpilfy creation of new payment processors.
5) Eliminate what my clients consider odd accounting for automated recurring payments in light of 4.3.x. In 4.3, any "pending/pay later" status contributions show as a tranaction in the "Accounts Receivable" Financial Account. When this contribution status is updated to "completed" another transaction is created to represent the movement from Accounts Receivable to the Asset Financial Account. (In this case the Payment Proccessing Account). With a one-off contribution,this is the proper and expected behavior. However, with automated recurring contributions this creates oddness for the bookkeeper. For example: They set up an automated recurring contribution of $200 per month for 12 months. (From the bookkeeper's point of view, the person "owes" $2400. ) After the first 6 payments are completed, the bookkeeper will observe that the first installment of $200. was handled as a "receivable" (because of the result of it switching from pending to completed) but none of the other installments are treated that way. So in the code I wrote ALL installments are treated uniformly: As a contribution that started out in the "completed" status. What I do is create a brand-new completed contribution for the first installment, then delete the original pending contribution. ( The other option I thought about was treating the entire $2400 as a receivable, then reducing the Accounts Receivable by $200 each month. But this idea seemed much more complex to implement)
Looking forward to getting feedback on the code and ideas here.