diff --git a/addons/payment/__openerp__.py b/addons/payment/__openerp__.py
index a3843a872c1..071218f7b5d 100644
--- a/addons/payment/__openerp__.py
+++ b/addons/payment/__openerp__.py
@@ -11,6 +11,7 @@
'data': [
'views/payment_acquirer.xml',
'views/res_config_view.xml',
+ 'views/res_partner_view.xml',
'security/ir.model.access.csv',
'security/payment_security.xml',
],
diff --git a/addons/payment/models/__init__.py b/addons/payment/models/__init__.py
index cd7858767fc..02ea486041a 100644
--- a/addons/payment/models/__init__.py
+++ b/addons/payment/models/__init__.py
@@ -2,3 +2,4 @@
import payment_acquirer
import res_config
+import res_partner
diff --git a/addons/payment/models/payment_acquirer.py b/addons/payment/models/payment_acquirer.py
index d7e7e79e14e..33ce5482568 100644
--- a/addons/payment/models/payment_acquirer.py
+++ b/addons/payment/models/payment_acquirer.py
@@ -1,5 +1,4 @@
# -*- coding: utf-'8' "-*-"
-
import logging
from openerp.osv import osv, fields
@@ -64,13 +63,16 @@ class PaymentAcquirer(osv.Model):
'provider': fields.selection(_provider_selection, string='Provider', required=True),
'company_id': fields.many2one('res.company', 'Company', required=True),
'pre_msg': fields.html('Message', translate=True,
- help='Message displayed to explain and help the payment process.'),
+ help='Message displayed to explain and help the payment process.'),
'post_msg': fields.html('Thanks Message', help='Message displayed after having done the payment process.'),
'validation': fields.selection(
[('manual', 'Manual'), ('automatic', 'Automatic')],
string='Process Method',
help='Static payments are payments like transfer, that require manual steps.'),
'view_template_id': fields.many2one('ir.ui.view', 'Form Button Template', required=True),
+ 'registration_view_template_id': fields.many2one('ir.ui.view', 'S2S Form Template',
+ domain=[('type', '=', 'qweb')],
+ help="Template for method registration"),
'environment': fields.selection(
[('test', 'Test'), ('prod', 'Production')],
string='Environment', oldname='env'),
@@ -273,11 +275,41 @@ class PaymentAcquirer(osv.Model):
'partner_values': partner_values,
'tx_values': tx_values,
'context': context,
+ 'type': tx_values.get('type') or 'form',
}
# because render accepts view ids but not qweb -> need to use the xml_id
return self.pool['ir.ui.view'].render(cr, uid, acquirer.view_template_id.xml_id, qweb_context, engine='ir.qweb', context=context)
+ def _registration_render(self, cr, uid, id, partner_id, qweb_context=None, context=None):
+ acquirer = self.browse(cr, uid, id, context=context)
+ if qweb_context is None:
+ qweb_context = {}
+ qweb_context.update(id=id, partner_id=partner_id)
+ method_name = '_%s_registration_form_generate_values' % (acquirer.provider,)
+ if hasattr(self, method_name):
+ method = getattr(self, method_name)
+ qweb_context.update(method(cr, uid, id, qweb_context, context=context))
+ return self.pool['ir.ui.view'].render(cr, uid, acquirer.registration_view_template_id.xml_id, qweb_context, engine='ir.qweb', context=context)
+
+ def s2s_process(self, cr, uid, id, data, context=None):
+ acquirer = self.browse(cr, uid, id, context=context)
+ cust_method_name = '%s_s2s_form_process' % (acquirer.provider)
+ if not self.s2s_validate(cr, uid, id, data, context=context):
+ return False
+ if hasattr(self, cust_method_name):
+ method = getattr(self, cust_method_name)
+ return method(cr, uid, data, context=context)
+ return True
+
+ def s2s_validate(self, cr, uid, id, data, context=None):
+ acquirer = self.browse(cr, uid, id, context=context)
+ cust_method_name = '%s_s2s_form_validate' % (acquirer.provider)
+ if hasattr(self, cust_method_name):
+ method = getattr(self, cust_method_name)
+ return method(cr, uid, id, data, context=context)
+ return True
+
def _wrap_payment_block(self, cr, uid, html_block, amount, currency_id, context=None):
payment_header = _('Pay safely online')
amount_str = float_repr(amount, self.pool.get('decimal.precision').precision_get(cr, uid, 'Account'))
@@ -342,7 +374,7 @@ class PaymentTransaction(osv.Model):
required=True,
),
'type': fields.selection(
- [('server2server', 'Server To Server'), ('form', 'Form')],
+ [('server2server', 'Server To Server'), ('form', 'Form'), ('form_save', 'Form with credentials storage')],
string='Type', required=True),
'state': fields.selection(
[('draft', 'Draft'), ('pending', 'Pending'),
@@ -377,6 +409,11 @@ class PaymentTransaction(osv.Model):
'partner_phone': fields.char('Phone'),
'partner_reference': fields.char('Partner Reference',
help='Reference of the customer in the acquirer database'),
+ 'html_3ds': fields.char('3D Secure HTML'),
+
+ 's2s_cb_eval': fields.char('S2S Callback', help="""\
+ Will be safe_eval with `self` being the current transaction. i.e.:
+ self.env['my.model'].payment_validated(self)"""),
}
def _check_reference(self, cr, uid, ids, context=None):
@@ -467,62 +504,16 @@ class PaymentTransaction(osv.Model):
# --------------------------------------------------
# SERVER2SERVER RELATED METHODS
# --------------------------------------------------
-
def s2s_create(self, cr, uid, values, cc_values, context=None):
tx_id, tx_result = self.s2s_send(cr, uid, values, cc_values, context=context)
self.s2s_feedback(cr, uid, tx_id, tx_result, context=context)
return tx_id
- def s2s_send(self, cr, uid, values, cc_values, context=None):
- """ Create and send server-to-server transaction.
-
- :param dict values: transaction values
- :param dict cc_values: credit card values that are not stored into the
- payment.transaction object. Acquirers should
- handle receiving void or incorrect cc values.
- Should contain :
-
- - holder_name
- - number
- - cvc
- - expiry_date
- - brand
- - expiry_date_yy
- - expiry_date_mm
- """
- tx_id, result = None, None
-
- if values.get('acquirer_id'):
- acquirer = self.pool['payment.acquirer'].browse(cr, uid, values.get('acquirer_id'), context=context)
- custom_method_name = '_%s_s2s_send' % acquirer.provider
- if hasattr(self, custom_method_name):
- tx_id, result = getattr(self, custom_method_name)(cr, uid, values, cc_values, context=context)
-
- if tx_id is None and result is None:
- tx_id = super(PaymentTransaction, self).create(cr, uid, values, context=context)
- return (tx_id, result)
-
- def s2s_feedback(self, cr, uid, tx_id, data, context=None):
- """ Handle the feedback of a server-to-server transaction. """
- tx = self.browse(cr, uid, tx_id, context=context)
- invalid_parameters = None
-
- invalid_param_method_name = '_%s_s2s_get_invalid_parameters' % tx.acquirer_id.provider
- if hasattr(self, invalid_param_method_name):
- invalid_parameters = getattr(self, invalid_param_method_name)(cr, uid, tx, data, context=context)
-
- if invalid_parameters:
- _error_message = '%s: incorrect tx data:\n' % (tx.acquirer_id.name)
- for item in invalid_parameters:
- _error_message += '\t%s: received %s instead of %s\n' % (item[0], item[1], item[2])
- _logger.error(_error_message)
- return False
-
- feedback_method_name = '_%s_s2s_validate' % tx.acquirer_id.provider
- if hasattr(self, feedback_method_name):
- return getattr(self, feedback_method_name)(cr, uid, tx, data, context=context)
-
- return True
+ def s2s_do_transaction(self, cr, uid, id, context=None, **kwargs):
+ tx = self.browse(cr, uid, id, context=context)
+ custom_method_name = '%s_s2s_do_transaction' % tx.acquirer_id.provider
+ if hasattr(self, custom_method_name):
+ return getattr(self, custom_method_name)(cr, uid, id, context=context, **kwargs)
def s2s_get_tx_status(self, cr, uid, tx_id, context=None):
""" Get the tx status. """
@@ -533,3 +524,32 @@ class PaymentTransaction(osv.Model):
return getattr(self, invalid_param_method_name)(cr, uid, tx, context=context)
return True
+
+
+class PaymentMethod(osv.Model):
+ _name = 'payment.method'
+ _order = 'partner_id'
+
+ _columns = {
+ 'name': fields.char('Name', help='Name of the payment method'),
+ 'partner_id': fields.many2one('res.partner', 'Partner', required=True),
+ 'acquirer_id': fields.many2one('payment.acquirer', 'Acquirer Account', required=True),
+ 'acquirer_ref': fields.char('Acquirer Ref.', required=True),
+ 'active': fields.boolean('Active')
+ }
+
+ _defaults = {
+ 'active': True
+ }
+
+ def create(self, cr, uid, values, context=None):
+ # call custom create method if defined (i.e. ogone_create for ogone)
+ if values.get('acquirer_id'):
+ acquirer = self.pool['payment.acquirer'].browse(cr, uid, values.get('acquirer_id'), context=context)
+
+ # custom create
+ custom_method_name = '%s_create' % acquirer.provider
+ if hasattr(self, custom_method_name):
+ values.update(getattr(self, custom_method_name)(cr, uid, values, context=context))
+
+ return super(PaymentMethod, self).create(cr, uid, values, context=context)
diff --git a/addons/payment/models/res_partner.py b/addons/payment/models/res_partner.py
new file mode 100644
index 00000000000..e688b89a4dd
--- /dev/null
+++ b/addons/payment/models/res_partner.py
@@ -0,0 +1,9 @@
+from openerp.osv import fields, osv
+
+
+class res_partner(osv.osv):
+ _name = 'res.partner'
+ _inherit = 'res.partner'
+ _columns = {
+ 'payment_method_ids': fields.one2many('payment.method', 'partner_id', 'Payment Methods'),
+ }
diff --git a/addons/payment/security/ir.model.access.csv b/addons/payment/security/ir.model.access.csv
index f52f9a44d4e..942718807d5 100644
--- a/addons/payment/security/ir.model.access.csv
+++ b/addons/payment/security/ir.model.access.csv
@@ -4,4 +4,8 @@ payment_acquirer_user,payment.acquirer.user,model_payment_acquirer,base.group_us
payment_acquirer_system,payment.acquirer.system,model_payment_acquirer,base.group_system,1,1,1,1
payment_transaction_all,payment.transaction.all,model_payment_transaction,,1,0,0,0
payment_transaction_user,payment.transaction.user,model_payment_transaction,base.group_user,1,1,1,0
-payment_transaction_system,payment.transaction.system,model_payment_transaction,base.group_system,1,1,1,1
\ No newline at end of file
+payment_transaction_system,payment.transaction.system,model_payment_transaction,base.group_system,1,1,1,1
+payment_method_all,payment.method.all,model_payment_method,,1,0,0,0
+payment_method_user,payment.method.user,model_payment_method,base.group_user,1,1,1,0
+payment_method_portal,payment.method.portal,model_payment_method,base.group_portal,1,1,1,0
+payment_method_system,payment.method.system,model_payment_method,base.group_system,1,1,1,1
diff --git a/addons/payment/security/payment_security.xml b/addons/payment/security/payment_security.xml
index 7bae346c648..f2dedd5e6ee 100644
--- a/addons/payment/security/payment_security.xml
+++ b/addons/payment/security/payment_security.xml
@@ -20,5 +20,18 @@
+
+ Access own payment methods only
+
+ [('partner_id','=',user.partner_id.id)]
+
+
+
+
+ Access every payment method
+
+
+
+
diff --git a/addons/payment/views/payment_acquirer.xml b/addons/payment/views/payment_acquirer.xml
index a83e475c1da..933a4fb6e3c 100644
--- a/addons/payment/views/payment_acquirer.xml
+++ b/addons/payment/views/payment_acquirer.xml
@@ -58,6 +58,7 @@
+
@@ -189,5 +190,33 @@
parent='root_payment_menu'
sequence='20' />
+
+
+ payment.method.tree
+ payment.method
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Saved Payment Data
+ payment.method
+ form
+ tree
+
+
+
+
diff --git a/addons/payment/views/res_partner_view.xml b/addons/payment/views/res_partner_view.xml
new file mode 100644
index 00000000000..193018e74e1
--- /dev/null
+++ b/addons/payment/views/res_partner_view.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+ view.res.partner.form.payment.defaultcreditcard
+ res.partner
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+