[MERGE] [ADD] module: payment_buckaroo acquirer: manage payments using Buckaroo.
authorThibault Delavallée <tde@openerp.com>
Tue, 27 May 2014 14:57:31 +0000 (16:57 +0200)
committerThibault Delavallée <tde@openerp.com>
Tue, 27 May 2014 14:57:31 +0000 (16:57 +0200)
16 files changed:
addons/payment/models/res_config.py
addons/payment/views/res_config_view.xml
addons/payment_buckaroo/__init__.py [new file with mode: 0644]
addons/payment_buckaroo/__openerp__.py [new file with mode: 0644]
addons/payment_buckaroo/controllers/__init__.py [new file with mode: 0644]
addons/payment_buckaroo/controllers/main.py [new file with mode: 0644]
addons/payment_buckaroo/data/buckaroo.xml [new file with mode: 0644]
addons/payment_buckaroo/models/__init__.py [new file with mode: 0644]
addons/payment_buckaroo/models/buckaroo.py [new file with mode: 0644]
addons/payment_buckaroo/static/description/icon.png [new file with mode: 0644]
addons/payment_buckaroo/static/src/img/buckaroo_icon.png [new file with mode: 0644]
addons/payment_buckaroo/static/src/img/logo.png [new file with mode: 0644]
addons/payment_buckaroo/tests/__init__.py [new file with mode: 0644]
addons/payment_buckaroo/tests/test_buckaroo.py [new file with mode: 0644]
addons/payment_buckaroo/views/buckaroo.xml [new file with mode: 0644]
addons/payment_buckaroo/views/payment_acquirer.xml [new file with mode: 0644]

index 70668a2..a74e595 100644 (file)
@@ -16,4 +16,7 @@ class AccountPaymentConfig(osv.TransientModel):
         'module_payment_adyen': fields.boolean(
             'Manage Payments Using Adyen',
             help='-It installs the module payment_adyen.'),
+        'module_payment_buckaroo': fields.boolean(
+            'Manage Payments Using Buckaroo',
+            help='-It installs the module payment_buckaroo.'),
     }
index 101acb7..45c0a3d 100644 (file)
                         <field name="module_payment_adyen" class="oe_inline"/>
                         <label for="module_payment_adyen"/>
                     </div>
+                    <div>
+                        <field name="module_payment_buckaroo" class="oe_inline"/>
+                        <label for="module_payment_buckaroo"/>
+                    </div>
                 </xpath>
             </field>
         </record>
diff --git a/addons/payment_buckaroo/__init__.py b/addons/payment_buckaroo/__init__.py
new file mode 100644 (file)
index 0000000..1f4b1b7
--- /dev/null
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2014-Today OpenERP SA (<http://www.openerp.com>).
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details.
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+import models
+import controllers
diff --git a/addons/payment_buckaroo/__openerp__.py b/addons/payment_buckaroo/__openerp__.py
new file mode 100644 (file)
index 0000000..526f7c3
--- /dev/null
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+
+{
+    'name': 'Buckaroo Payment Acquirer',
+    'category': 'Hidden',
+    'summary': 'Payment Acquirer: Buckaroo Implementation',
+    'version': '1.0',
+    'description': """Buckaroo Payment Acquirer""",
+    'author': 'OpenERP SA',
+    'depends': ['payment'],
+    'data': [
+        'views/buckaroo.xml',
+        'views/payment_acquirer.xml',
+        'data/buckaroo.xml',
+    ],
+    'installable': True,
+}
diff --git a/addons/payment_buckaroo/controllers/__init__.py b/addons/payment_buckaroo/controllers/__init__.py
new file mode 100644 (file)
index 0000000..bbd183e
--- /dev/null
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+import main
diff --git a/addons/payment_buckaroo/controllers/main.py b/addons/payment_buckaroo/controllers/main.py
new file mode 100644 (file)
index 0000000..d3fe5b1
--- /dev/null
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+try:
+    import simplejson as json
+except ImportError:
+    import json
+
+import logging
+import pprint
+import werkzeug
+
+from openerp import http, SUPERUSER_ID
+from openerp.http import request
+
+_logger = logging.getLogger(__name__)
+
+
+class BuckarooController(http.Controller):
+    _return_url = '/payment/buckaroo/return'
+    _cancel_url = '/payment/buckaroo/cancel'
+    _exception_url = '/payment/buckaroo/error'
+    _reject_url = '/payment/buckaroo/reject'
+
+    @http.route([
+        '/payment/buckaroo/return',
+        '/payment/buckaroo/cancel',
+        '/payment/buckaroo/error',
+        '/payment/buckaroo/reject',
+    ], type='http', auth='none')
+    def buckaroo_return(self, **post):
+        """ Buckaroo."""
+        _logger.info('Buckaroo: entering form_feedback with post data %s', pprint.pformat(post))  # debug
+        request.registry['payment.transaction'].form_feedback(request.cr, SUPERUSER_ID, post, 'buckaroo', context=request.context)
+        return_url = post.pop('return_url', '')
+        if not return_url:
+            data ='' + post.pop('ADD_RETURNDATA', '{}').replace("'", "\"")
+            custom = json.loads(data)
+            return_url = custom.pop('return_url', '/')
+        return werkzeug.utils.redirect(return_url)
diff --git a/addons/payment_buckaroo/data/buckaroo.xml b/addons/payment_buckaroo/data/buckaroo.xml
new file mode 100644 (file)
index 0000000..9d100a5
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data noupdate="1">
+
+        <record id="payment_acquirer_buckaroo" model="payment.acquirer">
+            <field name="name">Buckaroo</field>
+            <field name="provider">buckaroo</field>
+            <field name="company_id" ref="base.main_company"/>
+            <field name="view_template_id" ref="buckaroo_acquirer_button"/>
+            <field name="environment">test</field>
+            <field name="pre_msg"><![CDATA[
+<p>You will be redirected to the Buckaroo website after cliking on the payment button.</p>]]></field>
+            <field name="brq_websitekey">dummy</field>
+            <field name="brq_secretkey">dummy</field>
+        </record>
+
+    </data>
+</openerp>
diff --git a/addons/payment_buckaroo/models/__init__.py b/addons/payment_buckaroo/models/__init__.py
new file mode 100644 (file)
index 0000000..7e1780a
--- /dev/null
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+import buckaroo
diff --git a/addons/payment_buckaroo/models/buckaroo.py b/addons/payment_buckaroo/models/buckaroo.py
new file mode 100644 (file)
index 0000000..5b576a2
--- /dev/null
@@ -0,0 +1,191 @@
+# -*- coding: utf-'8' "-*-"
+from hashlib import sha1
+import logging
+import urlparse
+
+from openerp.addons.payment.models.payment_acquirer import ValidationError
+from openerp.addons.payment_buckaroo.controllers.main import BuckarooController
+from openerp.osv import osv, fields
+from openerp.tools.float_utils import float_compare
+
+_logger = logging.getLogger(__name__)
+
+
+class AcquirerBuckaroo(osv.Model):
+    _inherit = 'payment.acquirer'
+
+    def _get_buckaroo_urls(self, cr, uid, environment, context=None):
+        """ Buckaroo URLs
+        """
+        if environment == 'prod':
+            return {
+                'buckaroo_form_url': 'https://checkout.buckaroo.nl/html/',
+            }
+        else:
+            return {
+                'buckaroo_form_url': 'https://testcheckout.buckaroo.nl/html/',
+            }
+
+    def _get_providers(self, cr, uid, context=None):
+        providers = super(AcquirerBuckaroo, self)._get_providers(cr, uid, context=context)
+        providers.append(['buckaroo', 'Buckaroo'])
+        return providers
+
+    _columns = {
+        'brq_websitekey': fields.char('WebsiteKey', required_if_provider='buckaroo'),
+        'brq_secretkey': fields.char('SecretKey', required_if_provider='buckaroo'),
+    }
+
+    def _buckaroo_generate_digital_sign(self, acquirer, inout, values):
+        """ Generate the shasign for incoming or outgoing communications.
+
+        :param browse acquirer: the payment.acquirer browse record. It should
+                                have a shakey in shaky out
+        :param string inout: 'in' (openerp contacting buckaroo) or 'out' (buckaroo
+                             contacting openerp).
+        :param dict values: transaction values
+
+        :return string: shasign
+        """
+        assert inout in ('in', 'out')
+        assert acquirer.provider == 'buckaroo'
+
+        keys = "add_returndata Brq_amount Brq_culture Brq_currency Brq_invoicenumber Brq_return Brq_returncancel Brq_returnerror Brq_returnreject brq_test Brq_websitekey".split()
+
+        def get_value(key):
+            if values.get(key):
+                return values[key]
+            return ''
+
+        if inout == 'out':
+            if 'BRQ_SIGNATURE' in values:
+                del values['BRQ_SIGNATURE']
+            items = sorted((k.upper(), v) for k, v in values.items())
+            sign = ''.join('%s=%s' % (k, v) for k, v in items)
+        else:
+            sign = ''.join('%s=%s' % (k,get_value(k)) for k in keys)
+        #Add the pre-shared secret key at the end of the signature
+        sign = sign + acquirer.brq_secretkey
+        if isinstance(sign, str):
+            sign = urlparse.parse_qsl(sign)
+        shasign = sha1(sign).hexdigest()
+        return shasign
+
+
+    def buckaroo_form_generate_values(self, cr, uid, id, partner_values, tx_values, context=None):
+        base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url')
+        acquirer = self.browse(cr, uid, id, context=context)
+        buckaroo_tx_values = dict(tx_values)
+        buckaroo_tx_values.update({
+            'Brq_websitekey': acquirer.brq_websitekey,
+            'Brq_amount': tx_values['amount'],
+            'Brq_currency': tx_values['currency'] and tx_values['currency'].name or '',
+            'Brq_invoicenumber': tx_values['reference'],
+            'brq_test' : True,
+            'Brq_return': '%s' % urlparse.urljoin(base_url, BuckarooController._return_url),
+            'Brq_returncancel': '%s' % urlparse.urljoin(base_url, BuckarooController._cancel_url),
+            'Brq_returnerror': '%s' % urlparse.urljoin(base_url, BuckarooController._exception_url),
+            'Brq_returnreject': '%s' % urlparse.urljoin(base_url, BuckarooController._reject_url),
+            'Brq_culture': 'en-US',
+        })
+        if buckaroo_tx_values.get('return_url'):
+            buckaroo_tx_values['add_returndata'] = {'return_url': '%s' % buckaroo_tx_values.pop('return_url')}
+        else: 
+            buckaroo_tx_values['add_returndata'] = ''
+        buckaroo_tx_values['Brq_signature'] = self._buckaroo_generate_digital_sign(acquirer, 'in', buckaroo_tx_values)
+        return partner_values, buckaroo_tx_values
+
+    def buckaroo_get_form_action_url(self, cr, uid, id, context=None):
+        acquirer = self.browse(cr, uid, id, context=context)
+        return self._get_buckaroo_urls(cr, uid, acquirer.environment, context=context)['buckaroo_form_url']
+
+class TxBuckaroo(osv.Model):
+    _inherit = 'payment.transaction'
+
+    # buckaroo status
+    _buckaroo_valid_tx_status = [190]
+    _buckaroo_pending_tx_status = [790, 791, 792, 793]
+    _buckaroo_cancel_tx_status = [890, 891]
+    _buckaroo_error_tx_status = [490, 491, 492]
+    _buckaroo_reject_tx_status = [690]
+
+    _columns = {
+         'buckaroo_txnid': fields.char('Transaction ID'),
+    }
+    
+
+    # --------------------------------------------------
+    # FORM RELATED METHODS
+    # --------------------------------------------------
+
+    def _buckaroo_form_get_tx_from_data(self, cr, uid, data, context=None):
+        """ Given a data dict coming from buckaroo, verify it and find the related
+        transaction record. """
+        reference, pay_id, shasign = data.get('BRQ_INVOICENUMBER'), data.get('BRQ_PAYMENT'), data.get('BRQ_SIGNATURE')
+        if not reference or not pay_id or not shasign:
+            error_msg = 'Buckaroo: received data with missing reference (%s) or pay_id (%s) or shashign (%s)' % (reference, pay_id, shasign)
+            _logger.error(error_msg)
+            raise ValidationError(error_msg)
+
+        tx_ids = self.search(cr, uid, [('reference', '=', reference)], context=context)
+        if not tx_ids or len(tx_ids) > 1:
+            error_msg = 'Buckaroo: received data for reference %s' % (reference)
+            if not tx_ids:
+                error_msg += '; no order found'
+            else:
+                error_msg += '; multiple order found'
+            _logger.error(error_msg)
+            raise ValidationError(error_msg)
+        tx = self.pool['payment.transaction'].browse(cr, uid, tx_ids[0], context=context)
+
+        #verify shasign
+        shasign_check = self.pool['payment.acquirer']._buckaroo_generate_digital_sign(tx.acquirer_id, 'out' ,data)
+        if shasign_check.upper() != shasign.upper():
+            error_msg = 'Buckaroo: invalid shasign, received %s, computed %s, for data %s' % (shasign, shasign_check, data)
+            _logger.error(error_msg)
+            raise ValidationError(error_msg)
+
+        return tx 
+
+    def _buckaroo_form_get_invalid_parameters(self, cr, uid, tx, data, context=None):
+        invalid_parameters = []
+
+        if tx.acquirer_reference and data.get('BRQ_TRANSACTIONS') != tx.acquirer_reference:
+            invalid_parameters.append(('Transaction Id', data.get('BRQ_TRANSACTIONS'), tx.acquirer_reference))
+        # check what is buyed
+        if float_compare(float(data.get('BRQ_AMOUNT', '0.0')), tx.amount, 2) != 0:
+            invalid_parameters.append(('Amount', data.get('BRQ_AMOUNT'), '%.2f' % tx.amount))
+        if data.get('BRQ_CURRENCY') != tx.currency_id.name:
+            invalid_parameters.append(('Currency', data.get('BRQ_CURRENCY'), tx.currency_id.name))
+
+        return invalid_parameters
+
+    def _buckaroo_form_validate(self, cr, uid, tx, data, context=None):
+        status_code = int(data.get('BRQ_STATUSCODE','0'))
+        if status_code in self._buckaroo_valid_tx_status:
+            tx.write({
+                'state': 'done',
+                'buckaroo_txnid': data.get('BRQ_TRANSACTIONS'),
+            })
+            return True
+        elif status_code in self._buckaroo_pending_tx_status:
+            tx.write({
+                'state': 'pending',
+                'buckaroo_txnid': data.get('BRQ_TRANSACTIONS'),
+            })
+            return True
+        elif status_code in self._buckaroo_cancel_tx_status:
+            tx.write({
+                'state': 'cancel',
+                'buckaroo_txnid': data.get('BRQ_TRANSACTIONS'),
+            })
+            return True
+        else:
+            error = 'Buckaroo: feedback error'
+            _logger.info(error)
+            tx.write({
+                'state': 'error',
+                'state_message': error,
+                'buckaroo_txnid': data.get('BRQ_TRANSACTIONS'),
+            })
+            return False
diff --git a/addons/payment_buckaroo/static/description/icon.png b/addons/payment_buckaroo/static/description/icon.png
new file mode 100644 (file)
index 0000000..663fcad
Binary files /dev/null and b/addons/payment_buckaroo/static/description/icon.png differ
diff --git a/addons/payment_buckaroo/static/src/img/buckaroo_icon.png b/addons/payment_buckaroo/static/src/img/buckaroo_icon.png
new file mode 100644 (file)
index 0000000..819606d
Binary files /dev/null and b/addons/payment_buckaroo/static/src/img/buckaroo_icon.png differ
diff --git a/addons/payment_buckaroo/static/src/img/logo.png b/addons/payment_buckaroo/static/src/img/logo.png
new file mode 100644 (file)
index 0000000..663fcad
Binary files /dev/null and b/addons/payment_buckaroo/static/src/img/logo.png differ
diff --git a/addons/payment_buckaroo/tests/__init__.py b/addons/payment_buckaroo/tests/__init__.py
new file mode 100644 (file)
index 0000000..d245ab8
--- /dev/null
@@ -0,0 +1,7 @@
+# -*- coding: utf-8 -*-
+
+from openerp.addons.payment_buckaroo.tests import test_buckaroo
+
+checks = [
+    test_buckaroo,
+]
diff --git a/addons/payment_buckaroo/tests/test_buckaroo.py b/addons/payment_buckaroo/tests/test_buckaroo.py
new file mode 100644 (file)
index 0000000..b826f3b
--- /dev/null
@@ -0,0 +1,178 @@
+# -*- coding: utf-8 -*-
+
+from lxml import objectify
+import urlparse
+
+import openerp
+from openerp.addons.payment.models.payment_acquirer import ValidationError
+from openerp.addons.payment.tests.common import PaymentAcquirerCommon
+from openerp.addons.payment_buckaroo.controllers.main import BuckarooController
+from openerp.tools import mute_logger
+
+
+@openerp.tests.common.at_install(False)
+@openerp.tests.common.post_install(False)
+class BuckarooCommon(PaymentAcquirerCommon):
+
+    def setUp(self):
+        super(BuckarooCommon, self).setUp()
+        cr, uid = self.cr, self.uid
+        self.base_url = self.registry('ir.config_parameter').get_param(cr, uid, 'web.base.url')
+
+        # get the buckaroo account
+        model, self.buckaroo_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'payment_buckaroo', 'payment_acquirer_buckaroo')
+
+
+@openerp.tests.common.at_install(False)
+@openerp.tests.common.post_install(False)
+class BuckarooForm(BuckarooCommon):
+
+    def test_10_Buckaroo_form_render(self):
+        cr, uid, context = self.cr, self.uid, {}
+        # be sure not to do stupid things
+        buckaroo = self.payment_acquirer.browse(self.cr, self.uid, self.buckaroo_id, None)
+        self.assertEqual(buckaroo.environment, 'test', 'test without test environment')
+
+        # ----------------------------------------
+        # Test: button direct rendering
+        # ----------------------------------------
+
+        form_values = {
+            'add_returndata': None,
+            'Brq_websitekey': buckaroo.brq_websitekey,
+            'Brq_amount': '2240.0',
+            'Brq_currency': 'EUR',
+            'Brq_invoicenumber': 'SO004',
+            'Brq_signature': '1b8c10074c622d965272a91a9e88b5b3777d2474',  # update me
+            'brq_test': 'True',
+            'Brq_return': '%s' % urlparse.urljoin(self.base_url, BuckarooController._return_url),
+            'Brq_returncancel': '%s' % urlparse.urljoin(self.base_url, BuckarooController._cancel_url),
+            'Brq_returnerror': '%s' % urlparse.urljoin(self.base_url, BuckarooController._exception_url),
+            'Brq_returnreject': '%s' % urlparse.urljoin(self.base_url, BuckarooController._reject_url),
+            'Brq_culture': 'en-US',
+        }
+
+        # render the button
+        res = self.payment_acquirer.render(
+            cr, uid, self.buckaroo_id,
+            'SO004', 2240.0, self.currency_euro_id,
+            partner_id=None,
+            partner_values=self.buyer_values,
+            context=context)
+
+        # check form result
+        tree = objectify.fromstring(res)
+        self.assertEqual(tree.get('action'), 'https://testcheckout.buckaroo.nl/html/', 'Buckaroo: wrong form POST url')
+        for form_input in tree.input:
+            if form_input.get('name') in ['submit']:
+                continue
+            self.assertEqual(
+                form_input.get('value'),
+                form_values[form_input.get('name')],
+                'Buckaroo: wrong value for input %s: received %s instead of %s' % (form_input.get('name'), form_input.get('value'), form_values[form_input.get('name')])
+            )
+
+        # ----------------------------------------
+        # Test2: button using tx + validation
+        # ----------------------------------------
+
+        # create a new draft tx
+        tx_id = self.payment_transaction.create(
+            cr, uid, {
+                'amount': 2240.0,
+                'acquirer_id': self.buckaroo_id,
+                'currency_id': self.currency_euro_id,
+                'reference': 'SO004',
+                'partner_id': self.buyer_id,
+            }, context=context
+        )
+
+        # render the button
+        res = self.payment_acquirer.render(
+            cr, uid, self.buckaroo_id,
+            'should_be_erased', 2240.0, self.currency_euro,
+            tx_id=tx_id,
+            partner_id=None,
+            partner_values=self.buyer_values,
+            context=context)
+
+        # check form result
+        tree = objectify.fromstring(res)
+        self.assertEqual(tree.get('action'), 'https://testcheckout.buckaroo.nl/html/', 'Buckaroo: wrong form POST url')
+        for form_input in tree.input:
+            if form_input.get('name') in ['submit']:
+                continue
+            self.assertEqual(
+                form_input.get('value'),
+                form_values[form_input.get('name')],
+                'Buckaroo: wrong value for form input %s: received %s instead of %s' % (form_input.get('name'), form_input.get('value'), form_values[form_input.get('name')])
+            )
+
+    @mute_logger('openerp.addons.payment_buckaroo.models.buckaroo', 'ValidationError')
+    def test_20_buckaroo_form_management(self):
+        cr, uid, context = self.cr, self.uid, {}
+        # be sure not to do stupid thing
+        buckaroo = self.payment_acquirer.browse(self.cr, self.uid, self.buckaroo_id, None)
+        self.assertEqual(buckaroo.environment, 'test', 'test without test environment')
+
+        # typical data posted by buckaroo after client has successfully paid
+        buckaroo_post_data = {
+            'BRQ_RETURNDATA': u'',
+            'BRQ_AMOUNT': u'2240.00',
+            'BRQ_CURRENCY': u'EUR',
+            'BRQ_CUSTOMER_NAME': u'Jan de Tester',
+            'BRQ_INVOICENUMBER': u'SO004',
+            'BRQ_PAYMENT': u'573311D081B04069BD6336001611DBD4',
+            'BRQ_PAYMENT_METHOD': u'paypal',
+            'BRQ_SERVICE_PAYPAL_PAYERCOUNTRY': u'NL',
+            'BRQ_SERVICE_PAYPAL_PAYEREMAIL': u'fhe@openerp.com',
+            'BRQ_SERVICE_PAYPAL_PAYERFIRSTNAME': u'Jan',
+            'BRQ_SERVICE_PAYPAL_PAYERLASTNAME': u'Tester',
+            'BRQ_SERVICE_PAYPAL_PAYERMIDDLENAME': u'de',
+            'BRQ_SERVICE_PAYPAL_PAYERSTATUS': u'verified',
+            'BRQ_SIGNATURE': u'175d82dd53a02bad393fee32cb1eafa3b6fbbd91',
+            'BRQ_STATUSCODE': u'190',
+            'BRQ_STATUSCODE_DETAIL': u'S001',
+            'BRQ_STATUSMESSAGE': u'Transaction successfully processed',
+            'BRQ_TEST': u'true',
+            'BRQ_TIMESTAMP': u'2014-05-08 12:41:21',
+            'BRQ_TRANSACTIONS': u'D6106678E1D54EEB8093F5B3AC42EA7B',
+            'BRQ_WEBSITEKEY': u'5xTGyGyPyl',
+        }
+
+        # should raise error about unknown tx
+        with self.assertRaises(ValidationError):
+            self.payment_transaction.form_feedback(cr, uid, buckaroo_post_data, 'buckaroo', context=context)
+
+        tx_id = self.payment_transaction.create(
+            cr, uid, {
+                'amount': 2240.0,
+                'acquirer_id': self.buckaroo_id,
+                'currency_id': self.currency_euro_id,
+                'reference': 'SO004',
+                'partner_name': 'Norbert Buyer',
+                'partner_country_id': self.country_france_id,
+            }, context=context
+        )
+        # validate it
+        self.payment_transaction.form_feedback(cr, uid, buckaroo_post_data, 'buckaroo', context=context)
+        # check state
+        tx = self.payment_transaction.browse(cr, uid, tx_id, context=context)
+        self.assertEqual(tx.state, 'done', 'Buckaroo: validation did not put tx into done state')
+        self.assertEqual(tx.buckaroo_txnid, buckaroo_post_data.get('BRQ_TRANSACTIONS'), 'Buckaroo: validation did not update tx payid')
+
+        # reset tx
+        tx.write({'state': 'draft', 'date_validate': False, 'buckaroo_txnid': False})
+
+        # now buckaroo post is ok: try to modify the SHASIGN
+        buckaroo_post_data['BRQ_SIGNATURE'] = '54d928810e343acf5fb0c3ee75fd747ff159ef7a'
+        with self.assertRaises(ValidationError):
+            self.payment_transaction.form_feedback(cr, uid, buckaroo_post_data, 'buckaroo', context=context)
+
+        # simulate an error
+        buckaroo_post_data['BRQ_STATUSCODE'] = 2
+        buckaroo_post_data['BRQ_SIGNATURE'] = '4164b52adb1e6a2221d3d8a39d8c3e18a9ecb90b'
+        self.payment_transaction.form_feedback(cr, uid, buckaroo_post_data, 'buckaroo', context=context)
+        # check state
+        tx = self.payment_transaction.browse(cr, uid, tx_id, context=context)
+        self.assertEqual(tx.state, 'error', 'Buckaroo: erroneous validation did not put tx into error state')
diff --git a/addons/payment_buckaroo/views/buckaroo.xml b/addons/payment_buckaroo/views/buckaroo.xml
new file mode 100644 (file)
index 0000000..567a269
--- /dev/null
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data noupdate="1">
+
+        <template id="buckaroo_acquirer_button">
+            <form t-if="acquirer.brq_websitekey" t-att-action="tx_url" method="post" target="_self">
+                <input type="hidden" name="Brq_websitekey" t-att-value="tx_values['Brq_websitekey']"/>
+                <input type="hidden" name="Brq_amount" t-att-value="tx_values['Brq_amount'] or '0.0'"/>
+                <input type="hidden" name="Brq_currency" t-att-value="tx_values['Brq_currency']"/>
+                <input type="hidden" name="Brq_invoicenumber" t-att-value="tx_values['Brq_invoicenumber']"/>
+                <input type="hidden" name="Brq_signature" t-att-value="tx_values['Brq_signature']"/>
+                <input type="hidden" name="brq_test" t-att-value="tx_values['brq_test']"/>
+                <input type="hidden" name="Brq_culture" t-att-value="tx_values['Brq_culture']"/>
+                <!-- URLs -->
+                <input t-if="tx_values.get('Brq_return')" type='hidden' name='Brq_return'
+                    t-att-value="tx_values.get('Brq_return')"/>
+                <input t-if="tx_values.get('Brq_returncancel')" type='hidden' name='Brq_returncancel'
+                    t-att-value="tx_values.get('Brq_returncancel')"/>
+                <input t-if="tx_values.get('Brq_returnerror')" type='hidden' name='Brq_returnerror'
+                    t-att-value="tx_values.get('Brq_returnerror')"/>
+                <input t-if="tx_values.get('Brq_returnreject')" type='hidden' name='Brq_returnreject'
+                    t-att-value="tx_values.get('Brq_returnreject')"/>
+                <input type='hidden' name='add_returndata' t-att-value="tx_values.get('add_returndata')"/>
+                <!-- submit -->
+                <button type="submit" width="100px"
+                    t-att-class="submit_class">
+                    <img t-if="not submit_txt" src="/payment_buckaroo/static/src/img/buckaroo_icon.png"/>
+                    <span t-if="submit_txt"><t t-esc="submit_txt"/> <span class="fa fa-long-arrow-right"/></span>
+                </button>
+            </form>
+        </template>
+
+    </data>
+</openerp>
diff --git a/addons/payment_buckaroo/views/payment_acquirer.xml b/addons/payment_buckaroo/views/payment_acquirer.xml
new file mode 100644 (file)
index 0000000..4eb294e
--- /dev/null
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+        <record id="acquirer_form_buckaroo" model="ir.ui.view">
+            <field name="name">acquirer.form.buckaroo</field>
+            <field name="model">payment.acquirer</field>
+            <field name="inherit_id" ref="payment.acquirer_form"/>
+            <field name="arch" type="xml">
+                <xpath expr='//group[@name="acquirer_display"]' position='after'>
+                    <group attrs="{'invisible': [('provider', '!=', 'buckaroo')]}">
+                        <field name="brq_websitekey"/>
+                        <field name="brq_secretkey"/>
+                    </group>
+                </xpath>
+            </field>
+        </record>
+
+        <record id="transaction_form_buckaroo" model="ir.ui.view">
+            <field name="name">acquirer.transaction.form.buckaroo</field>
+            <field name="model">payment.transaction</field>
+            <field name="inherit_id" ref="payment.transaction_form"/>
+            <field name="arch" type="xml">
+                <xpath expr='//notebook' position='inside'>
+                    <page string="Buckaroo TX Details">
+                        <group>
+                            <field name="buckaroo_txnid"/>
+                        </group>
+                    </page>
+                </xpath>
+            </field>
+        </record>
+
+    </data>
+</openerp>