Merge lp:~openerp-dev/openobject-addons/trunk-payment-buckaroo-dka into lp:openobject-addons

Proposed by Thibault Delavallée (OpenERP)
Status: Needs review
Proposed branch: lp:~openerp-dev/openobject-addons/trunk-payment-buckaroo-dka
Merge into: lp:openobject-addons
Diff against target: 744 lines (+579/-19)
15 files modified
payment/models/res_config.py (+3/-0)
payment/views/res_config_view.xml (+4/-0)
payment_buckaroo/__init__.py (+23/-0)
payment_buckaroo/__openerp__.py (+17/-0)
payment_buckaroo/controllers/__init__.py (+3/-0)
payment_buckaroo/controllers/main.py (+38/-0)
payment_buckaroo/data/buckaroo.xml (+18/-0)
payment_buckaroo/models/__init__.py (+3/-0)
payment_buckaroo/models/buckaroo.py (+191/-0)
payment_buckaroo/tests/__init__.py (+7/-0)
payment_buckaroo/tests/test_buckaroo.py (+178/-0)
payment_buckaroo/views/buckaroo.xml (+34/-0)
payment_buckaroo/views/payment_acquirer.xml (+35/-0)
website_sale/controllers/main.py (+15/-19)
website_sale/static/src/js/website_sale_payment.js (+10/-0)
To merge this branch: bzr merge lp:~openerp-dev/openobject-addons/trunk-payment-buckaroo-dka
Reviewer Review Type Date Requested Status
Thibault Delavallée (OpenERP) (community) technical Needs Fixing
Review via email: mp+208589@code.launchpad.net

Description of the change

[ADD] New payment acquirer: Buckaroo.

To post a comment you must log in.
9087. By Niko (OpenERP)

[IMP] Add some video to manisfest ( website, website_blog, website_event, website_ecommerce)

9184. By Darshan Kalola(OpenERP)

[IMP]remove unnecessary code.

9185. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9186. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9187. By Darshan Kalola(OpenERP)

[ADD]payment_buckaroo: added websitekey.

9188. By Darshan Kalola(OpenERP)

[IMP]payment_buckaroo:added secretkey and improved digital signature.

9189. By Darshan Kalola(OpenERP)

[IMP]payment_buckaroo: added buckaroo_return method in controller to handel return url and added _buckaroo_form_get_tx_from_data method in payment transaction.

9190. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9191. By Darshan Kalola(OpenERP)

[IMP]payment_buckaroo:improved method name.

9192. By Darshan Kalola(OpenERP)

[IMP]payment_buckaroo: added _buckaroo_form_validate method.

9193. By Darshan Kalola(OpenERP)

[IMP]payment_buckaroo: added _buckaroo_form_get_invalid_parameters method.

9194. By Darshan Kalola(OpenERP)

[IMP]payment_buckaroo: Removed unnecessary field.

9195. By Darshan Kalola(OpenERP)

[IMP]website_sale : improved payment_transaction method to send post request to payment getway and added exception url and reject url in buckaroo parameter and removed unnecessary code.

9196. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9197. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9198. By Darshan Kalola(OpenERP)

[IMP]removed unnecessary code and typo.

9199. By Darshan Kalola(OpenERP)

[IMP]payment_buckaroo:improved code and image.

9200. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9201. By Darshan Kalola(OpenERP)

[IMP]improved typo.

9202. By Darshan Kalola(OpenERP)

[IMP]pyment_buckaroo: inherited selection to add ('buckaroo','Buckaroo')in provider list , changed code accordinglly and rename file.

9203. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9204. By Darshan Kalola(OpenERP)

[IMP]pyament_buckaroo: added separate variable for buckarro status code.

9205. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9206. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9207. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9208. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9209. By Darshan Kalola(OpenERP)

[IMP]verify the digital signature comming from buckaroo.

9210. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9211. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9212. By Darshan Kalola(OpenERP)

[IMP]payment_buckaroo: rename fields name env to environment.

Revision history for this message
Thibault Delavallée (OpenERP) (tde-openerp) wrote :

Hello,

At first sight seems quite correct. But could you write tests like the one present in paypal or ogone ? They should be disabled by default because there is no valid data in the module; but test them locally using the credentials you have.

Best regards,

9213. By Darshan Kalola(OpenERP)

[IMP]payment_buckaroo:added test case to check the module correctly work or not.

9214. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9215. By Darshan Kalola(OpenERP)

[IMP]disabled test case.

9216. By Darshan Kalola(OpenERP)

[IMP]improved spacing.

9217. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9218. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9219. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9220. By Thibault Delavallée (OpenERP)

[MERGE] Sync with upstream (trunk)

Revision history for this message
Thibault Delavallée (OpenERP) (tde-openerp) wrote :

Hello,

Some remarks :
- remove credentials from data now that the branch is about to be merged (set dummy / dummy)
- lint the module (some unused imports, space errors, ...)

One thing to add :
- management of tx_values['return_url'] (see in paypal / adyen / ...). Using custom variables (see chapter about custom variables in buckaroo documentation), put the return url of the shop like other providers, and get it back in the controller instead of having an hardcoded redirection to "/shop/payment/validate/" .

Best regards,

Thibault.

review: Needs Fixing (technical)
9221. By Darshan Kalola(OpenERP)

[IMP]remove credential information and remove unneccessary import.

9222. By Darshan Kalola(OpenERP)

[IMP]payment_buckaroo:added custome variable for return_url.

9223. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9224. By Darshan Kalola(OpenERP)

[IMP]remove unnecessary import.

9225. By Thibault Delavallée (OpenERP)

[MERGE] Sync with trunk

9226. By Thibault Delavallée (OpenERP)

[CLEAN] payment_buckaroo: cleaned a bit the file for the tests, according
to new tests specifications in post-saas-4.

9227. By Darshan Kalola(OpenERP)

[IMP]payment_buckaroo:improved digital signature in test case.

9228. By Thibault Delavallée (OpenERP)

[MERGE] Sync with trunk

9229. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9230. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9231. By Darshan Kalola(OpenERP)

[MERGE]merged lp:~openerp-dev/openobject-addons/trunk-ecommerce-post-tde and removed unnecessary code which handle the post request as got better solution in trunk-ecommerce-post-tde branch.

9232. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk and resolve conflicts from website_sale controller/ in payment_transaction method.

9233. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

Unmerged revisions

9233. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9232. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk and resolve conflicts from website_sale controller/ in payment_transaction method.

9231. By Darshan Kalola(OpenERP)

[MERGE]merged lp:~openerp-dev/openobject-addons/trunk-ecommerce-post-tde and removed unnecessary code which handle the post request as got better solution in trunk-ecommerce-post-tde branch.

9230. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9229. By Darshan Kalola(OpenERP)

[MERGE]sync with trunk.

9228. By Thibault Delavallée (OpenERP)

[MERGE] Sync with trunk

9227. By Darshan Kalola(OpenERP)

[IMP]payment_buckaroo:improved digital signature in test case.

9226. By Thibault Delavallée (OpenERP)

[CLEAN] payment_buckaroo: cleaned a bit the file for the tests, according
to new tests specifications in post-saas-4.

9225. By Thibault Delavallée (OpenERP)

[MERGE] Sync with trunk

9224. By Darshan Kalola(OpenERP)

[IMP]remove unnecessary import.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'payment/models/res_config.py'
--- payment/models/res_config.py 2014-03-05 16:37:37 +0000
+++ payment/models/res_config.py 2014-05-21 05:25:49 +0000
@@ -16,4 +16,7 @@
16 'module_payment_adyen': fields.boolean(16 'module_payment_adyen': fields.boolean(
17 'Manage Payments Using Adyen',17 'Manage Payments Using Adyen',
18 help='-It installs the module payment_adyen.'),18 help='-It installs the module payment_adyen.'),
19 'module_payment_buckaroo': fields.boolean(
20 'Manage Payments Using Buckaroo',
21 help='-It installs the module payment_buckaroo.'),
19 }22 }
2023
=== modified file 'payment/views/res_config_view.xml'
--- payment/views/res_config_view.xml 2014-01-23 15:01:35 +0000
+++ payment/views/res_config_view.xml 2014-05-21 05:25:49 +0000
@@ -20,6 +20,10 @@
20 <field name="module_payment_adyen" class="oe_inline"/>20 <field name="module_payment_adyen" class="oe_inline"/>
21 <label for="module_payment_adyen"/>21 <label for="module_payment_adyen"/>
22 </div>22 </div>
23 <div>
24 <field name="module_payment_buckaroo" class="oe_inline"/>
25 <label for="module_payment_buckaroo"/>
26 </div>
23 </xpath>27 </xpath>
24 </field>28 </field>
25 </record>29 </record>
2630
=== added directory 'payment_buckaroo'
=== added file 'payment_buckaroo/__init__.py'
--- payment_buckaroo/__init__.py 1970-01-01 00:00:00 +0000
+++ payment_buckaroo/__init__.py 2014-05-21 05:25:49 +0000
@@ -0,0 +1,23 @@
1# -*- coding: utf-8 -*-
2##############################################################################
3#
4# OpenERP, Open Source Management Solution
5# Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU Affero General Public License as
9# published by the Free Software Foundation, either version 3 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU Affero General Public License for more details.
16#
17# You should have received a copy of the GNU Affero General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20##############################################################################
21
22import models
23import controllers
024
=== added file 'payment_buckaroo/__openerp__.py'
--- payment_buckaroo/__openerp__.py 1970-01-01 00:00:00 +0000
+++ payment_buckaroo/__openerp__.py 2014-05-21 05:25:49 +0000
@@ -0,0 +1,17 @@
1# -*- coding: utf-8 -*-
2
3{
4 'name': 'Payment Buckaroo',
5 'category': 'Hidden',
6 'summary': 'Payment Acquirer: Buckaroo Implementation',
7 'version': '1.0',
8 'description': """Payment Buckaroo""",
9 'author': 'OpenERP SA',
10 'depends': ['payment'],
11 'data': [
12 'views/buckaroo.xml',
13 'views/payment_acquirer.xml',
14 'data/buckaroo.xml',
15 ],
16 'installable': True,
17}
018
=== added directory 'payment_buckaroo/controllers'
=== added file 'payment_buckaroo/controllers/__init__.py'
--- payment_buckaroo/controllers/__init__.py 1970-01-01 00:00:00 +0000
+++ payment_buckaroo/controllers/__init__.py 2014-05-21 05:25:49 +0000
@@ -0,0 +1,3 @@
1# -*- coding: utf-8 -*-
2
3import main
04
=== added file 'payment_buckaroo/controllers/main.py'
--- payment_buckaroo/controllers/main.py 1970-01-01 00:00:00 +0000
+++ payment_buckaroo/controllers/main.py 2014-05-21 05:25:49 +0000
@@ -0,0 +1,38 @@
1# -*- coding: utf-8 -*-
2try:
3 import simplejson as json
4except ImportError:
5 import json
6
7import logging
8import pprint
9import werkzeug
10
11from openerp import http, SUPERUSER_ID
12from openerp.http import request
13
14_logger = logging.getLogger(__name__)
15
16
17class BuckarooController(http.Controller):
18 _return_url = '/payment/buckaroo/return'
19 _cancel_url = '/payment/buckaroo/cancel'
20 _exception_url = '/payment/buckaroo/error'
21 _reject_url = '/payment/buckaroo/reject'
22
23 @http.route([
24 '/payment/buckaroo/return',
25 '/payment/buckaroo/cancel',
26 '/payment/buckaroo/error',
27 '/payment/buckaroo/reject',
28 ], type='http', auth='none')
29 def buckaroo_return(self, **post):
30 """ Buckaroo."""
31 _logger.info('Buckaroo: entering form_feedback with post data %s', pprint.pformat(post)) # debug
32 request.registry['payment.transaction'].form_feedback(request.cr, SUPERUSER_ID, post, 'buckaroo', context=request.context)
33 return_url = post.pop('return_url', '')
34 if not return_url:
35 data ='' + post.pop('ADD_RETURNDATA', '{}').replace("'", "\"")
36 custom = json.loads(data)
37 return_url = custom.pop('return_url', '/')
38 return werkzeug.utils.redirect(return_url)
039
=== added directory 'payment_buckaroo/data'
=== added file 'payment_buckaroo/data/buckaroo.xml'
--- payment_buckaroo/data/buckaroo.xml 1970-01-01 00:00:00 +0000
+++ payment_buckaroo/data/buckaroo.xml 2014-05-21 05:25:49 +0000
@@ -0,0 +1,18 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data noupdate="1">
4
5 <record id="payment_acquirer_buckaroo" model="payment.acquirer">
6 <field name="name">Buckarro</field>
7 <field name="provider">buckaroo</field>
8 <field name="company_id" ref="base.main_company"/>
9 <field name="view_template_id" ref="buckaroo_acquirer_button"/>
10 <field name="environment">test</field>
11 <field name="pre_msg"><![CDATA[
12<p>You will be redirected to the Buckaroo website after cliking on the payment button.</p>]]></field>
13 <field name="brq_websitekey">dummy</field>
14 <field name="brq_secretkey">dummy</field>
15 </record>
16
17 </data>
18</openerp>
019
=== added directory 'payment_buckaroo/models'
=== added file 'payment_buckaroo/models/__init__.py'
--- payment_buckaroo/models/__init__.py 1970-01-01 00:00:00 +0000
+++ payment_buckaroo/models/__init__.py 2014-05-21 05:25:49 +0000
@@ -0,0 +1,3 @@
1# -*- coding: utf-8 -*-
2
3import buckaroo
04
=== added file 'payment_buckaroo/models/buckaroo.py'
--- payment_buckaroo/models/buckaroo.py 1970-01-01 00:00:00 +0000
+++ payment_buckaroo/models/buckaroo.py 2014-05-21 05:25:49 +0000
@@ -0,0 +1,191 @@
1# -*- coding: utf-'8' "-*-"
2from hashlib import sha1
3import logging
4import urlparse
5
6from openerp.addons.payment.models.payment_acquirer import ValidationError
7from openerp.addons.payment_buckaroo.controllers.main import BuckarooController
8from openerp.osv import osv, fields
9from openerp.tools.float_utils import float_compare
10
11_logger = logging.getLogger(__name__)
12
13
14class AcquirerBuckaroo(osv.Model):
15 _inherit = 'payment.acquirer'
16
17 def _get_buckaroo_urls(self, cr, uid, environment, context=None):
18 """ Buckaroo URLs
19 """
20 if environment == 'prod':
21 return {
22 'buckaroo_form_url': 'https://checkout.buckaroo.nl/html/',
23 }
24 else:
25 return {
26 'buckaroo_form_url': 'https://testcheckout.buckaroo.nl/html/',
27 }
28
29 def _get_providers(self, cr, uid, context=None):
30 providers = super(AcquirerBuckaroo, self)._get_providers(cr, uid, context=context)
31 providers.append(['buckaroo', 'Buckaroo'])
32 return providers
33
34 _columns = {
35 'brq_websitekey': fields.char('WebsiteKey', required_if_provider='buckaroo'),
36 'brq_secretkey': fields.char('SecretKey', required_if_provider='buckaroo'),
37 }
38
39 def _buckaroo_generate_digital_sign(self, acquirer, inout, values):
40 """ Generate the shasign for incoming or outgoing communications.
41
42 :param browse acquirer: the payment.acquirer browse record. It should
43 have a shakey in shaky out
44 :param string inout: 'in' (openerp contacting buckaroo) or 'out' (buckaroo
45 contacting openerp).
46 :param dict values: transaction values
47
48 :return string: shasign
49 """
50 assert inout in ('in', 'out')
51 assert acquirer.provider == 'buckaroo'
52
53 keys = "add_returndata Brq_amount Brq_culture Brq_currency Brq_invoicenumber Brq_return Brq_returncancel Brq_returnerror Brq_returnreject brq_test Brq_websitekey".split()
54
55 def get_value(key):
56 if values.get(key):
57 return values[key]
58 return ''
59
60 if inout == 'out':
61 if 'BRQ_SIGNATURE' in values:
62 del values['BRQ_SIGNATURE']
63 items = sorted((k.upper(), v) for k, v in values.items())
64 sign = ''.join('%s=%s' % (k, v) for k, v in items)
65 else:
66 sign = ''.join('%s=%s' % (k,get_value(k)) for k in keys)
67 #Add the pre-shared secret key at the end of the signature
68 sign = sign + acquirer.brq_secretkey
69 if isinstance(sign, str):
70 sign = urlparse.parse_qsl(sign)
71 shasign = sha1(sign).hexdigest()
72 return shasign
73
74
75 def buckaroo_form_generate_values(self, cr, uid, id, partner_values, tx_values, context=None):
76 base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url')
77 acquirer = self.browse(cr, uid, id, context=context)
78 buckaroo_tx_values = dict(tx_values)
79 buckaroo_tx_values.update({
80 'Brq_websitekey': acquirer.brq_websitekey,
81 'Brq_amount': tx_values['amount'],
82 'Brq_currency': tx_values['currency'] and tx_values['currency'].name or '',
83 'Brq_invoicenumber': tx_values['reference'],
84 'brq_test' : True,
85 'Brq_return': '%s' % urlparse.urljoin(base_url, BuckarooController._return_url),
86 'Brq_returncancel': '%s' % urlparse.urljoin(base_url, BuckarooController._cancel_url),
87 'Brq_returnerror': '%s' % urlparse.urljoin(base_url, BuckarooController._exception_url),
88 'Brq_returnreject': '%s' % urlparse.urljoin(base_url, BuckarooController._reject_url),
89 'Brq_culture': 'en-US',
90 })
91 if buckaroo_tx_values.get('return_url'):
92 buckaroo_tx_values['add_returndata'] = {'return_url': '%s' % buckaroo_tx_values.pop('return_url')}
93 else:
94 buckaroo_tx_values['add_returndata'] = ''
95 buckaroo_tx_values['Brq_signature'] = self._buckaroo_generate_digital_sign(acquirer, 'in', buckaroo_tx_values)
96 return partner_values, buckaroo_tx_values
97
98 def buckaroo_get_form_action_url(self, cr, uid, id, context=None):
99 acquirer = self.browse(cr, uid, id, context=context)
100 return self._get_buckaroo_urls(cr, uid, acquirer.environment, context=context)['buckaroo_form_url']
101
102class TxBuckaroo(osv.Model):
103 _inherit = 'payment.transaction'
104
105 # buckaroo status
106 _buckaroo_valid_tx_status = [190]
107 _buckaroo_pending_tx_status = [790, 791, 792, 793]
108 _buckaroo_cancel_tx_status = [890, 891]
109 _buckaroo_error_tx_status = [490, 491, 492]
110 _buckaroo_reject_tx_status = [690]
111
112 _columns = {
113 'buckaroo_txnid': fields.char('Transaction ID'),
114 }
115
116
117 # --------------------------------------------------
118 # FORM RELATED METHODS
119 # --------------------------------------------------
120
121 def _buckaroo_form_get_tx_from_data(self, cr, uid, data, context=None):
122 """ Given a data dict coming from buckaroo, verify it and find the related
123 transaction record. """
124 reference, pay_id, shasign = data.get('BRQ_INVOICENUMBER'), data.get('BRQ_PAYMENT'), data.get('BRQ_SIGNATURE')
125 if not reference or not pay_id or not shasign:
126 error_msg = 'Buckaroo: received data with missing reference (%s) or pay_id (%s) or shashign (%s)' % (reference, pay_id, shasign)
127 _logger.error(error_msg)
128 raise ValidationError(error_msg)
129
130 tx_ids = self.search(cr, uid, [('reference', '=', reference)], context=context)
131 if not tx_ids or len(tx_ids) > 1:
132 error_msg = 'Buckaroo: received data for reference %s' % (reference)
133 if not tx_ids:
134 error_msg += '; no order found'
135 else:
136 error_msg += '; multiple order found'
137 _logger.error(error_msg)
138 raise ValidationError(error_msg)
139 tx = self.pool['payment.transaction'].browse(cr, uid, tx_ids[0], context=context)
140
141 #verify shasign
142 shasign_check = self.pool['payment.acquirer']._buckaroo_generate_digital_sign(tx.acquirer_id, 'out' ,data)
143 if shasign_check.upper() != shasign.upper():
144 error_msg = 'Buckaroo: invalid shasign, received %s, computed %s, for data %s' % (shasign, shasign_check, data)
145 _logger.error(error_msg)
146 raise ValidationError(error_msg)
147
148 return tx
149
150 def _buckaroo_form_get_invalid_parameters(self, cr, uid, tx, data, context=None):
151 invalid_parameters = []
152
153 if tx.acquirer_reference and data.get('BRQ_TRANSACTIONS') != tx.acquirer_reference:
154 invalid_parameters.append(('Transaction Id', data.get('BRQ_TRANSACTIONS'), tx.acquirer_reference))
155 # check what is buyed
156 if float_compare(float(data.get('BRQ_AMOUNT', '0.0')), tx.amount, 2) != 0:
157 invalid_parameters.append(('Amount', data.get('BRQ_AMOUNT'), '%.2f' % tx.amount))
158 if data.get('BRQ_CURRENCY') != tx.currency_id.name:
159 invalid_parameters.append(('Currency', data.get('BRQ_CURRENCY'), tx.currency_id.name))
160
161 return invalid_parameters
162
163 def _buckaroo_form_validate(self, cr, uid, tx, data, context=None):
164 status_code = int(data.get('BRQ_STATUSCODE','0'))
165 if status_code in self._buckaroo_valid_tx_status:
166 tx.write({
167 'state': 'done',
168 'buckaroo_txnid': data.get('BRQ_TRANSACTIONS'),
169 })
170 return True
171 elif status_code in self._buckaroo_pending_tx_status:
172 tx.write({
173 'state': 'pending',
174 'buckaroo_txnid': data.get('BRQ_TRANSACTIONS'),
175 })
176 return True
177 elif status_code in self._buckaroo_cancel_tx_status:
178 tx.write({
179 'state': 'cancel',
180 'buckaroo_txnid': data.get('BRQ_TRANSACTIONS'),
181 })
182 return True
183 else:
184 error = 'Buckaroo: feedback error'
185 _logger.info(error)
186 tx.write({
187 'state': 'error',
188 'state_message': error,
189 'buckaroo_txnid': data.get('BRQ_TRANSACTIONS'),
190 })
191 return False
0192
=== added directory 'payment_buckaroo/static'
=== added directory 'payment_buckaroo/static/description'
=== added file 'payment_buckaroo/static/description/icon.png'
1Binary files payment_buckaroo/static/description/icon.png 1970-01-01 00:00:00 +0000 and payment_buckaroo/static/description/icon.png 2014-05-21 05:25:49 +0000 differ193Binary files payment_buckaroo/static/description/icon.png 1970-01-01 00:00:00 +0000 and payment_buckaroo/static/description/icon.png 2014-05-21 05:25:49 +0000 differ
=== added directory 'payment_buckaroo/static/src'
=== added directory 'payment_buckaroo/static/src/img'
=== added file 'payment_buckaroo/static/src/img/buckaroo_icon.png'
2Binary files payment_buckaroo/static/src/img/buckaroo_icon.png 1970-01-01 00:00:00 +0000 and payment_buckaroo/static/src/img/buckaroo_icon.png 2014-05-21 05:25:49 +0000 differ194Binary files payment_buckaroo/static/src/img/buckaroo_icon.png 1970-01-01 00:00:00 +0000 and payment_buckaroo/static/src/img/buckaroo_icon.png 2014-05-21 05:25:49 +0000 differ
=== added file 'payment_buckaroo/static/src/img/logo.png'
3Binary files payment_buckaroo/static/src/img/logo.png 1970-01-01 00:00:00 +0000 and payment_buckaroo/static/src/img/logo.png 2014-05-21 05:25:49 +0000 differ195Binary files payment_buckaroo/static/src/img/logo.png 1970-01-01 00:00:00 +0000 and payment_buckaroo/static/src/img/logo.png 2014-05-21 05:25:49 +0000 differ
=== added directory 'payment_buckaroo/tests'
=== added file 'payment_buckaroo/tests/__init__.py'
--- payment_buckaroo/tests/__init__.py 1970-01-01 00:00:00 +0000
+++ payment_buckaroo/tests/__init__.py 2014-05-21 05:25:49 +0000
@@ -0,0 +1,7 @@
1# -*- coding: utf-8 -*-
2
3from openerp.addons.payment_buckaroo.tests import test_buckaroo
4
5checks = [
6 test_buckaroo,
7]
08
=== added file 'payment_buckaroo/tests/test_buckaroo.py'
--- payment_buckaroo/tests/test_buckaroo.py 1970-01-01 00:00:00 +0000
+++ payment_buckaroo/tests/test_buckaroo.py 2014-05-21 05:25:49 +0000
@@ -0,0 +1,178 @@
1# -*- coding: utf-8 -*-
2
3from lxml import objectify
4import urlparse
5
6import openerp
7from openerp.addons.payment.models.payment_acquirer import ValidationError
8from openerp.addons.payment.tests.common import PaymentAcquirerCommon
9from openerp.addons.payment_buckaroo.controllers.main import BuckarooController
10from openerp.tools import mute_logger
11
12
13@openerp.tests.common.at_install(False)
14@openerp.tests.common.post_install(False)
15class BuckarooCommon(PaymentAcquirerCommon):
16
17 def setUp(self):
18 super(BuckarooCommon, self).setUp()
19 cr, uid = self.cr, self.uid
20 self.base_url = self.registry('ir.config_parameter').get_param(cr, uid, 'web.base.url')
21
22 # get the buckaroo account
23 model, self.buckaroo_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'payment_buckaroo', 'payment_acquirer_buckaroo')
24
25
26@openerp.tests.common.at_install(False)
27@openerp.tests.common.post_install(False)
28class BuckarooForm(BuckarooCommon):
29
30 def test_10_Buckaroo_form_render(self):
31 cr, uid, context = self.cr, self.uid, {}
32 # be sure not to do stupid things
33 buckaroo = self.payment_acquirer.browse(self.cr, self.uid, self.buckaroo_id, None)
34 self.assertEqual(buckaroo.environment, 'test', 'test without test environment')
35
36 # ----------------------------------------
37 # Test: button direct rendering
38 # ----------------------------------------
39
40 form_values = {
41 'add_returndata': None,
42 'Brq_websitekey': buckaroo.brq_websitekey,
43 'Brq_amount': '2240.0',
44 'Brq_currency': 'EUR',
45 'Brq_invoicenumber': 'SO004',
46 'Brq_signature': '1b8c10074c622d965272a91a9e88b5b3777d2474', # update me
47 'brq_test': 'True',
48 'Brq_return': '%s' % urlparse.urljoin(self.base_url, BuckarooController._return_url),
49 'Brq_returncancel': '%s' % urlparse.urljoin(self.base_url, BuckarooController._cancel_url),
50 'Brq_returnerror': '%s' % urlparse.urljoin(self.base_url, BuckarooController._exception_url),
51 'Brq_returnreject': '%s' % urlparse.urljoin(self.base_url, BuckarooController._reject_url),
52 'Brq_culture': 'en-US',
53 }
54
55 # render the button
56 res = self.payment_acquirer.render(
57 cr, uid, self.buckaroo_id,
58 'SO004', 2240.0, self.currency_euro_id,
59 partner_id=None,
60 partner_values=self.buyer_values,
61 context=context)
62
63 # check form result
64 tree = objectify.fromstring(res)
65 self.assertEqual(tree.get('action'), 'https://testcheckout.buckaroo.nl/html/', 'Buckaroo: wrong form POST url')
66 for form_input in tree.input:
67 if form_input.get('name') in ['submit']:
68 continue
69 self.assertEqual(
70 form_input.get('value'),
71 form_values[form_input.get('name')],
72 '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')])
73 )
74
75 # ----------------------------------------
76 # Test2: button using tx + validation
77 # ----------------------------------------
78
79 # create a new draft tx
80 tx_id = self.payment_transaction.create(
81 cr, uid, {
82 'amount': 2240.0,
83 'acquirer_id': self.buckaroo_id,
84 'currency_id': self.currency_euro_id,
85 'reference': 'SO004',
86 'partner_id': self.buyer_id,
87 }, context=context
88 )
89
90 # render the button
91 res = self.payment_acquirer.render(
92 cr, uid, self.buckaroo_id,
93 'should_be_erased', 2240.0, self.currency_euro,
94 tx_id=tx_id,
95 partner_id=None,
96 partner_values=self.buyer_values,
97 context=context)
98
99 # check form result
100 tree = objectify.fromstring(res)
101 self.assertEqual(tree.get('action'), 'https://testcheckout.buckaroo.nl/html/', 'Buckaroo: wrong form POST url')
102 for form_input in tree.input:
103 if form_input.get('name') in ['submit']:
104 continue
105 self.assertEqual(
106 form_input.get('value'),
107 form_values[form_input.get('name')],
108 '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')])
109 )
110
111 @mute_logger('openerp.addons.payment_buckaroo.models.buckaroo', 'ValidationError')
112 def test_20_buckaroo_form_management(self):
113 cr, uid, context = self.cr, self.uid, {}
114 # be sure not to do stupid thing
115 buckaroo = self.payment_acquirer.browse(self.cr, self.uid, self.buckaroo_id, None)
116 self.assertEqual(buckaroo.environment, 'test', 'test without test environment')
117
118 # typical data posted by buckaroo after client has successfully paid
119 buckaroo_post_data = {
120 'BRQ_RETURNDATA': u'',
121 'BRQ_AMOUNT': u'2240.00',
122 'BRQ_CURRENCY': u'EUR',
123 'BRQ_CUSTOMER_NAME': u'Jan de Tester',
124 'BRQ_INVOICENUMBER': u'SO004',
125 'BRQ_PAYMENT': u'573311D081B04069BD6336001611DBD4',
126 'BRQ_PAYMENT_METHOD': u'paypal',
127 'BRQ_SERVICE_PAYPAL_PAYERCOUNTRY': u'NL',
128 'BRQ_SERVICE_PAYPAL_PAYEREMAIL': u'fhe@openerp.com',
129 'BRQ_SERVICE_PAYPAL_PAYERFIRSTNAME': u'Jan',
130 'BRQ_SERVICE_PAYPAL_PAYERLASTNAME': u'Tester',
131 'BRQ_SERVICE_PAYPAL_PAYERMIDDLENAME': u'de',
132 'BRQ_SERVICE_PAYPAL_PAYERSTATUS': u'verified',
133 'BRQ_SIGNATURE': u'175d82dd53a02bad393fee32cb1eafa3b6fbbd91',
134 'BRQ_STATUSCODE': u'190',
135 'BRQ_STATUSCODE_DETAIL': u'S001',
136 'BRQ_STATUSMESSAGE': u'Transaction successfully processed',
137 'BRQ_TEST': u'true',
138 'BRQ_TIMESTAMP': u'2014-05-08 12:41:21',
139 'BRQ_TRANSACTIONS': u'D6106678E1D54EEB8093F5B3AC42EA7B',
140 'BRQ_WEBSITEKEY': u'5xTGyGyPyl',
141 }
142
143 # should raise error about unknown tx
144 with self.assertRaises(ValidationError):
145 self.payment_transaction.form_feedback(cr, uid, buckaroo_post_data, 'buckaroo', context=context)
146
147 tx_id = self.payment_transaction.create(
148 cr, uid, {
149 'amount': 2240.0,
150 'acquirer_id': self.buckaroo_id,
151 'currency_id': self.currency_euro_id,
152 'reference': 'SO004',
153 'partner_name': 'Norbert Buyer',
154 'partner_country_id': self.country_france_id,
155 }, context=context
156 )
157 # validate it
158 self.payment_transaction.form_feedback(cr, uid, buckaroo_post_data, 'buckaroo', context=context)
159 # check state
160 tx = self.payment_transaction.browse(cr, uid, tx_id, context=context)
161 self.assertEqual(tx.state, 'done', 'Buckaroo: validation did not put tx into done state')
162 self.assertEqual(tx.buckaroo_txnid, buckaroo_post_data.get('BRQ_TRANSACTIONS'), 'Buckaroo: validation did not update tx payid')
163
164 # reset tx
165 tx.write({'state': 'draft', 'date_validate': False, 'buckaroo_txnid': False})
166
167 # now buckaroo post is ok: try to modify the SHASIGN
168 buckaroo_post_data['BRQ_SIGNATURE'] = '54d928810e343acf5fb0c3ee75fd747ff159ef7a'
169 with self.assertRaises(ValidationError):
170 self.payment_transaction.form_feedback(cr, uid, buckaroo_post_data, 'buckaroo', context=context)
171
172 # simulate an error
173 buckaroo_post_data['BRQ_STATUSCODE'] = 2
174 buckaroo_post_data['BRQ_SIGNATURE'] = '4164b52adb1e6a2221d3d8a39d8c3e18a9ecb90b'
175 self.payment_transaction.form_feedback(cr, uid, buckaroo_post_data, 'buckaroo', context=context)
176 # check state
177 tx = self.payment_transaction.browse(cr, uid, tx_id, context=context)
178 self.assertEqual(tx.state, 'error', 'Buckaroo: erroneous validation did not put tx into error state')
0179
=== added directory 'payment_buckaroo/views'
=== added file 'payment_buckaroo/views/buckaroo.xml'
--- payment_buckaroo/views/buckaroo.xml 1970-01-01 00:00:00 +0000
+++ payment_buckaroo/views/buckaroo.xml 2014-05-21 05:25:49 +0000
@@ -0,0 +1,34 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data noupdate="1">
4
5 <template id="buckaroo_acquirer_button">
6 <form t-if="acquirer.brq_websitekey" t-att-action="tx_url" method="post" target="_self">
7 <input type="hidden" name="Brq_websitekey" t-att-value="tx_values['Brq_websitekey']"/>
8 <input type="hidden" name="Brq_amount" t-att-value="tx_values['Brq_amount'] or '0.0'"/>
9 <input type="hidden" name="Brq_currency" t-att-value="tx_values['Brq_currency']"/>
10 <input type="hidden" name="Brq_invoicenumber" t-att-value="tx_values['Brq_invoicenumber']"/>
11 <input type="hidden" name="Brq_signature" t-att-value="tx_values['Brq_signature']"/>
12 <input type="hidden" name="brq_test" t-att-value="tx_values['brq_test']"/>
13 <input type="hidden" name="Brq_culture" t-att-value="tx_values['Brq_culture']"/>
14 <!-- URLs -->
15 <input t-if="tx_values.get('Brq_return')" type='hidden' name='Brq_return'
16 t-att-value="tx_values.get('Brq_return')"/>
17 <input t-if="tx_values.get('Brq_returncancel')" type='hidden' name='Brq_returncancel'
18 t-att-value="tx_values.get('Brq_returncancel')"/>
19 <input t-if="tx_values.get('Brq_returnerror')" type='hidden' name='Brq_returnerror'
20 t-att-value="tx_values.get('Brq_returnerror')"/>
21 <input t-if="tx_values.get('Brq_returnreject')" type='hidden' name='Brq_returnreject'
22 t-att-value="tx_values.get('Brq_returnreject')"/>
23 <input type='hidden' name='add_returndata' t-att-value="tx_values.get('add_returndata')"/>
24 <!-- submit -->
25 <button type="image" name="submit" width="100px"
26 t-att-class="submit_class">
27 <img t-if="not submit_txt" src="/payment_buckaroo/static/src/img/buckaroo_icon.png"/>
28 <span t-if="submit_txt"><t t-esc="submit_txt"/> <span class="fa fa-long-arrow-right"/></span>
29 </button>
30 </form>
31 </template>
32
33 </data>
34</openerp>
035
=== added file 'payment_buckaroo/views/payment_acquirer.xml'
--- payment_buckaroo/views/payment_acquirer.xml 1970-01-01 00:00:00 +0000
+++ payment_buckaroo/views/payment_acquirer.xml 2014-05-21 05:25:49 +0000
@@ -0,0 +1,35 @@
1<?xml version="1.0" encoding="utf-8"?>
2<openerp>
3 <data>
4
5 <record id="acquirer_form_buckaroo" model="ir.ui.view">
6 <field name="name">acquirer.form.buckaroo</field>
7 <field name="model">payment.acquirer</field>
8 <field name="inherit_id" ref="payment.acquirer_form"/>
9 <field name="arch" type="xml">
10 <xpath expr='//group[@name="acquirer_display"]' position='after'>
11 <group attrs="{'invisible': [('provider', '!=', 'buckaroo')]}">
12 <field name="brq_websitekey"/>
13 <field name="brq_secretkey"/>
14 </group>
15 </xpath>
16 </field>
17 </record>
18
19 <record id="transaction_form_buckaroo" model="ir.ui.view">
20 <field name="name">acquirer.transaction.form.buckaroo</field>
21 <field name="model">payment.transaction</field>
22 <field name="inherit_id" ref="payment.transaction_form"/>
23 <field name="arch" type="xml">
24 <xpath expr='//notebook' position='inside'>
25 <page string="Buckaroo TX Details">
26 <group>
27 <field name="buckaroo_txnid"/>
28 </group>
29 </page>
30 </xpath>
31 </field>
32 </record>
33
34 </data>
35</openerp>
036
=== modified file 'website_sale/controllers/main.py'
--- website_sale/controllers/main.py 2014-05-19 10:12:46 +0000
+++ website_sale/controllers/main.py 2014-05-21 05:25:49 +0000
@@ -489,7 +489,6 @@
489 values['acquirers'] = payment_obj.browse(cr, uid, acquirer_ids, context=context)489 values['acquirers'] = payment_obj.browse(cr, uid, acquirer_ids, context=context)
490 render_ctx = dict(context, submit_class='btn btn-primary', submit_txt='Pay Now')490 render_ctx = dict(context, submit_class='btn btn-primary', submit_txt='Pay Now')
491 for acquirer in values['acquirers']:491 for acquirer in values['acquirers']:
492 render_ctx['tx_url'] = '/shop/payment/transaction/%s' % acquirer.id
493 acquirer.button = payment_obj.render(492 acquirer.button = payment_obj.render(
494 cr, SUPERUSER_ID, acquirer.id,493 cr, SUPERUSER_ID, acquirer.id,
495 order.name,494 order.name,
@@ -503,32 +502,35 @@
503502
504 return request.website.render("website_sale.payment", values)503 return request.website.render("website_sale.payment", values)
505504
506 @http.route(['/shop/payment/transaction/<int:acquirer_id>'], type='http', methods=['POST'], auth="public", website=True)505 @http.route(['/shop/payment/transaction/<int:acquirer_id>'], type='json', auth="public", website=True)
507 def payment_transaction(self, acquirer_id, **post):506 def payment_transaction(self, acquirer_id):
508 """ Hook method that creates a payment.transaction and redirect to the507 """ Json method that creates a payment.transaction, used to create a
509 acquirer, using post values to re-create the post action.508 transaction when the user clicks on 'pay now' button. After having
509 created the transaction, the event continues and the user is redirected
510 to the acquirer website.
510511
511 :param int acquirer_id: id of a payment.acquirer record. If not set the512 :param int acquirer_id: id of a payment.acquirer record. If not set the
512 user is redirected to the checkout page513 user is redirected to the checkout page
513 :param dict post: should coutain all post data for the acquirer
514 """514 """
515 # @TDEFIXME: don't know why we received those data, but should not be send to the acquirer
516 post.pop('submit.x', None)
517 post.pop('submit.y', None)
518 cr, uid, context = request.cr, request.uid, request.context515 cr, uid, context = request.cr, request.uid, request.context
519 payment_obj = request.registry.get('payment.acquirer')
520 transaction_obj = request.registry.get('payment.transaction')516 transaction_obj = request.registry.get('payment.transaction')
521 sale_order_obj = request.registry['sale.order']517 sale_order_obj = request.registry['sale.order']
522 order = request.website.sale_get_order(context=context)518 order = request.website.sale_get_order(context=context)
523519
524 if not order or not order.order_line or acquirer_id is None:520 if not order or not order.order_line or acquirer_id is None:
525 return request.redirect("/shop/checkout")521 return False
526522
527 assert order.partner_id.id != request.website.partner_id.id523 assert order.partner_id.id != request.website.partner_id.id
528524
529 # find an already existing transaction525 # find an already existing transaction
530 tx = request.website.sale_get_transaction()526 tx = request.website.sale_get_transaction()
531 if not tx:527 if tx:
528 if tx.state == 'draft': # button cliked but no more info -> rewrite on tx or create a new one ?
529 tx.write({
530 'acquirer_id': acquirer_id,
531 })
532 tx_id = tx.id
533 else:
532 tx_id = transaction_obj.create(cr, SUPERUSER_ID, {534 tx_id = transaction_obj.create(cr, SUPERUSER_ID, {
533 'acquirer_id': acquirer_id,535 'acquirer_id': acquirer_id,
534 'type': 'form',536 'type': 'form',
@@ -540,10 +542,6 @@
540 'sale_order_id': order.id,542 'sale_order_id': order.id,
541 }, context=context)543 }, context=context)
542 request.session['sale_transaction_id'] = tx_id544 request.session['sale_transaction_id'] = tx_id
543 elif tx and tx.state == 'draft': # button cliked but no more info -> rewrite on tx or create a new one ?
544 tx.write({
545 'acquirer_id': acquirer_id,
546 })
547545
548 # update quotation546 # update quotation
549 sale_order_obj.write(547 sale_order_obj.write(
@@ -554,9 +552,7 @@
554 # confirm the quotation552 # confirm the quotation
555 sale_order_obj.action_button_confirm(cr, SUPERUSER_ID, [order.id], context=request.context)553 sale_order_obj.action_button_confirm(cr, SUPERUSER_ID, [order.id], context=request.context)
556554
557 acquirer_form_post_url = payment_obj.get_form_action_url(cr, uid, acquirer_id, context=context)555 return tx_id
558 acquirer_total_url = '%s?%s' % (acquirer_form_post_url, werkzeug.url_encode(post))
559 return request.redirect(acquirer_total_url)
560556
561 @http.route('/shop/payment/get_status/<int:sale_order_id>', type='json', auth="public", website=True)557 @http.route('/shop/payment/get_status/<int:sale_order_id>', type='json', auth="public", website=True)
562 def payment_get_status(self, sale_order_id, **post):558 def payment_get_status(self, sale_order_id, **post):
563559
=== modified file 'website_sale/static/src/js/website_sale_payment.js'
--- website_sale/static/src/js/website_sale_payment.js 2014-01-24 11:42:24 +0000
+++ website_sale/static/src/js/website_sale_payment.js 2014-05-21 05:25:49 +0000
@@ -9,4 +9,14 @@
9 })9 })
10 .find("input[name='acquirer']:checked").click();10 .find("input[name='acquirer']:checked").click();
1111
12 // When clicking on payment button: create the tx using json then continue to the acquirer
13 $payment.on("click", "button[name='submit']", function (ev) {
14 var acquirer_id = $(ev.currentTarget).parents('div.oe_sale_acquirer_button').first().data('id');
15 if (! acquirer_id) {
16 return false;
17 }
18 return openerp.jsonRpc('/shop/payment/transaction/' + acquirer_id, 'call', {}).then(function (data) {
19 return true;
20 });
21 });
12});22});

Subscribers

People subscribed via source and target branches

to all changes: