Odoo Invoice Payment Authorize.net

Odoo – Authorize.Net Auto Reconciliation

[[https://laslabs.com|LasLabs]] has released a new [[https://www.odoo.com/|Odoo]] plugin that allows transactions to be generated for [[http://reseller.authorize.net/application/?resellerId=28136|Authorize.Net]] payments, subsequently reconciling the invoice that the payment is associated to.



== The Problem ==

Odoo’s normal credit card workflow requires that a Payment Transaction be created before a customer can actually pay for the invoice. That screen then needs to be monitored in order to determine when you are paid (or you can monitor directly within your [[http://reseller.authorize.net/application/?resellerId=28136|Authorize.Net]] account).

After the [[http://reseller.authorize.net/application/?resellerId=28136|Authorize.Net]] transaction has been realized, a payment has to be created on the correct invoice, making sure to correctly reference the [[http://reseller.authorize.net/application/?resellerId=28136|Authorize.Net]] transaction record to the invoice payment record.

== Our Solution ==

We find this workflow to be clunky, and our customers often do not correctly link the actual transaction to the transaction that is being created in the Invoices screen (yes, they’re different records).

Our new plugin eliminates this manual interaction in favor of a more automatic approach. As soon as the customer is redirected back to your website after payment, a transaction record is created.

If the payment was approved, it is added automatically to the correct invoice with the correct references. After that, either a partial or full reconciliation will take place on the invoice depending on whether the full amount was received.

== Sample Workflow ==

Here’s a sample of the workflow:

# Customer clicks [[http://reseller.authorize.net/application/?resellerId=28136|Authorize.Net]] button in invoice or sale

# Customer fills out payment info, then hits `Pay Now`

# If the payment is approved, you are paid and customer is redirected back to their account. If they paid the full invoice, they can see that it is paid. Otherwise, they can see/pay the remaining balance.

# While looking at the invoice in the employee portal, you can see the new payments that were generated in the `Payments` tab

== The Downside ==

As with everything, there is always a downside.

If a transaction is declined after the initial approval, you will have to manually intervene by reversing a lot of accounting transactions.

This can be a pretty complicated process, but we have found it to be the lesser of two evils due to the rarity of this occurrence. If you are in a high risk market, this may be more of an issue.

We are open to community suggestions when it comes to improving this module (see [[https://blog.laslabs.com/2015/09/odoo-authorize-net-auto-reconciliation/#open-source|Open Source]]) below. If you have an idea on how to circumvent this issue, please drop a comment or open an issue.

The process of reversing the reconciliation can be read [[http://www.knowledgement.ie/en_US/general/software/open-source/how-to-un-reconcile-and-cancel-a-paid-invoice-in-openerpodoo|here]].

== Download ==

As always – [[https://laslabs.com|LasLabs]] is fully committed to Open Source, so the code is available from the following sources:
* [[https://repo.laslabs.com/projects/ODOO/repos/payment|Our Repo]]
* [[https://github.com/laslabs/odoo-payment|GitHub]]

== Features/Assistance ==

If you come across a bug, or require assistance/features – drop us a line in the comments, or on our [[https://www.facebook.com/LasLabsInc|Facebook]]!

== Technical ==

=== The Error ===
Below is the error that this plugin is meant to solve:
{{{ lang=bash
2015-09-29 05:05:17,979 24363 INFO laslabs werkzeug: – – [29/Sep/2015 05:05:17] “POST /payment/authorize/return/ HTTP/1.0” 500 –
2015-09-29 05:05:17,989 24363 ERROR laslabs werkzeug: Error on request:
Traceback (most recent call last):
File “/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py”, line 180, in run_wsgi
File “/usr/local/lib/python2.7/dist-packages/werkzeug/serving.py”, line 168, in execute
application_iter = app(environ, start_response)
File “/usr/lib/python2.7/dist-packages/openerp/service/server.py”, line 290, in app
return self.app(e, s)
File “/usr/lib/python2.7/dist-packages/openerp/service/wsgi_server.py”, line 216, in application
return application_unproxied(environ, start_response)
File “/usr/lib/python2.7/dist-packages/openerp/service/wsgi_server.py”, line 202, in application_unproxied
result = handler(environ, start_response)
File “/usr/lib/python2.7/dist-packages/openerp/http.py”, line 1290, in __call__
return self.dispatch(environ, start_response)
File “/usr/lib/python2.7/dist-packages/openerp/http.py”, line 1264, in __call__
return self.app(environ, start_wrapped)
File “/usr/local/lib/python2.7/dist-packages/werkzeug/wsgi.py”, line 591, in __call__
return self.app(environ, start_response)
File “/usr/lib/python2.7/dist-packages/openerp/http.py”, line 1264, in __call__
return self.app(environ, start_wrapped)
File “/usr/local/lib/python2.7/dist-packages/werkzeug/wsgi.py”, line 591, in __call__
return self.app(environ, start_response)
File “/usr/lib/python2.7/dist-packages/openerp/http.py”, line 1435, in dispatch
result = ir_http._dispatch()
File “/usr/lib/python2.7/dist-packages/openerp/addons/crm/ir_http.py”, line 13, in _dispatch
response = super(ir_http, self)._dispatch()
File “/usr/lib/python2.7/dist-packages/openerp/addons/website/models/ir_http.py”, line 148, in _dispatch
resp = super(ir_http, self)._dispatch()
File “/usr/lib/python2.7/dist-packages/openerp/addons/base/ir/ir_http.py”, line 177, in _dispatch
return self._handle_exception(e)
File “/usr/lib/python2.7/dist-packages/openerp/addons/website/models/ir_http.py”, line 196, in _handle_exception
return super(ir_http, self)._handle_exception(exception)
File “/usr/lib/python2.7/dist-packages/openerp/addons/base/ir/ir_http.py”, line 147, in _handle_exception
return request._handle_exception(exception)
File “/usr/lib/python2.7/dist-packages/openerp/http.py”, line 666, in _handle_exception
return super(HttpRequest, self)._handle_exception(exception)
File “/usr/lib/python2.7/dist-packages/openerp/addons/base/ir/ir_http.py”, line 173, in _dispatch
result = request.dispatch()
File “/usr/lib/python2.7/dist-packages/openerp/http.py”, line 684, in dispatch
r = self._call_function(**self.params)
File “/usr/lib/python2.7/dist-packages/openerp/http.py”, line 310, in _call_function
return checked_call(self.db, *args, **kwargs)
File “/usr/lib/python2.7/dist-packages/openerp/service/model.py”, line 113, in wrapper
return f(dbname, *args, **kwargs)
File “/usr/lib/python2.7/dist-packages/openerp/http.py”, line 307, in checked_call
return self.endpoint(*a, **kw)
File “/usr/lib/python2.7/dist-packages/openerp/http.py”, line 803, in __call__
return self.method(*args, **kw)
File “/usr/lib/python2.7/dist-packages/openerp/http.py”, line 403, in response_wrap
response = f(*args, **kw)
File “/usr/lib/python2.7/dist-packages/openerp/addons/payment_authorize/controllers/main.py”, line 24, in authorize_form_feedback
request.env[‘payment.transaction’].sudo().form_feedback(post, ‘authorize’)
File “/usr/lib/python2.7/dist-packages/openerp/api.py”, line 239, in wrapper
return new_api(self, *args, **kwargs)
File “/usr/lib/python2.7/dist-packages/openerp/api.py”, line 463, in new_api
result = method(self._model, cr, uid, *args, **kwargs)
File “/usr/lib/python2.7/dist-packages/openerp/addons/payment/models/payment_acquirer.py”, line 440, in form_feedback
tx = getattr(self, tx_find_method_name)(cr, uid, data, context=context)
File “/usr/lib/python2.7/dist-packages/openerp/api.py”, line 241, in wrapper
return old_api(self, *args, **kwargs)
File “/usr/lib/python2.7/dist-packages/openerp/api.py”, line 336, in old_api
result = method(recs, *args, **kwargs)
File “/usr/lib/python2.7/dist-packages/openerp/addons/payment_authorize/models/authorize.py”, line 115, in _authorize_form_get_tx_from_data
raise ValidationError(error_msg)
ValidationError: Authorize: received data for reference SALE/2015/1234; no order found





Leave a Reply

Your email address will not be published. Required fields are marked *