As provider model is intended to be used internally restricting the read of some private fields to the employee group avoid creating access issues.
166 lines
6.9 KiB
Python
166 lines
6.9 KiB
Python
# -*- coding: utf-'8' "-*-"
|
|
|
|
import hashlib
|
|
import hmac
|
|
import logging
|
|
import time
|
|
import urlparse
|
|
|
|
from openerp import api, fields, models
|
|
from openerp.addons.payment.models.payment_acquirer import ValidationError
|
|
from openerp.addons.payment_authorize.controllers.main import AuthorizeController
|
|
from openerp.tools.float_utils import float_compare
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class PaymentAcquirerAuthorize(models.Model):
|
|
_inherit = 'payment.acquirer'
|
|
|
|
def _get_authorize_urls(self, environment):
|
|
""" Authorize URLs """
|
|
if environment == 'prod':
|
|
return {'authorize_form_url': 'https://secure.authorize.net/gateway/transact.dll'}
|
|
else:
|
|
return {'authorize_form_url': 'https://test.authorize.net/gateway/transact.dll'}
|
|
|
|
@api.model
|
|
def _get_providers(self):
|
|
providers = super(PaymentAcquirerAuthorize, self)._get_providers()
|
|
providers.append(['authorize', 'Authorize.Net'])
|
|
return providers
|
|
|
|
authorize_login = fields.Char(string='API Login Id', required_if_provider='authorize', groups='base.group_user')
|
|
authorize_transaction_key = fields.Char(string='API Transaction Key', required_if_provider='authorize', groups='base.group_user')
|
|
|
|
def _authorize_generate_hashing(self, values):
|
|
data = '^'.join([
|
|
values['x_login'],
|
|
values['x_fp_sequence'],
|
|
values['x_fp_timestamp'],
|
|
values['x_amount'],
|
|
values['x_currency_code']])
|
|
return hmac.new(str(values['x_trans_key']), data, hashlib.md5).hexdigest()
|
|
|
|
@api.multi
|
|
def authorize_form_generate_values(self, partner_values, tx_values):
|
|
self.ensure_one()
|
|
base_url = self.env['ir.config_parameter'].get_param('web.base.url')
|
|
authorize_tx_values = dict(tx_values)
|
|
temp_authorize_tx_values = {
|
|
'x_login': self.authorize_login,
|
|
'x_trans_key': self.authorize_transaction_key,
|
|
'x_amount': str(tx_values['amount']),
|
|
'x_show_form': 'PAYMENT_FORM',
|
|
'x_type': 'AUTH_CAPTURE',
|
|
'x_method': 'CC',
|
|
'x_fp_sequence': '%s%s' % (self.id, int(time.time())),
|
|
'x_version': '3.1',
|
|
'x_relay_response': 'TRUE',
|
|
'x_fp_timestamp': str(int(time.time())),
|
|
'x_relay_url': '%s' % urlparse.urljoin(base_url, AuthorizeController._return_url),
|
|
'x_cancel_url': '%s' % urlparse.urljoin(base_url, AuthorizeController._cancel_url),
|
|
'x_currency_code': tx_values['currency'] and tx_values['currency'].name or '',
|
|
'address': partner_values['address'],
|
|
'city': partner_values['city'],
|
|
'country': partner_values['country'] and partner_values['country'].name or '',
|
|
'email': partner_values['email'],
|
|
'zip': partner_values['zip'],
|
|
'first_name': partner_values['first_name'],
|
|
'last_name': partner_values['last_name'],
|
|
'phone': partner_values['phone'],
|
|
'state': partner_values.get('state') and partner_values['state'].name or '',
|
|
}
|
|
temp_authorize_tx_values['returndata'] = authorize_tx_values.pop('return_url', '')
|
|
temp_authorize_tx_values['x_fp_hash'] = self._authorize_generate_hashing(temp_authorize_tx_values)
|
|
authorize_tx_values.update(temp_authorize_tx_values)
|
|
return partner_values, authorize_tx_values
|
|
|
|
@api.multi
|
|
def authorize_get_form_action_url(self):
|
|
self.ensure_one()
|
|
return self._get_authorize_urls(self.environment)['authorize_form_url']
|
|
|
|
|
|
class TxAuthorize(models.Model):
|
|
_inherit = 'payment.transaction'
|
|
|
|
authorize_txnid = fields.Char(string='Transaction ID')
|
|
|
|
_authorize_valid_tx_status = 1
|
|
_authorize_pending_tx_status = 4
|
|
_authorize_cancel_tx_status = 2
|
|
|
|
# --------------------------------------------------
|
|
# FORM RELATED METHODS
|
|
# --------------------------------------------------
|
|
|
|
@api.model
|
|
def _authorize_form_get_tx_from_data(self, data):
|
|
""" Given a data dict coming from authorize, verify it and find the related
|
|
transaction record. """
|
|
reference, trans_id, fingerprint = data.get('x_invoice_num'), data.get('x_trans_id'), data.get('x_MD5_Hash')
|
|
if not reference or not trans_id or not fingerprint:
|
|
error_msg = 'Authorize: received data with missing reference (%s) or trans_id (%s) or fingerprint (%s)' % (reference, trans_id, fingerprint)
|
|
_logger.error(error_msg)
|
|
raise ValidationError(error_msg)
|
|
tx = self.search([('reference', '=', reference)])
|
|
if not tx or len(tx) > 1:
|
|
error_msg = 'Authorize: received data for reference %s' % (reference)
|
|
if not tx:
|
|
error_msg += '; no order found'
|
|
else:
|
|
error_msg += '; multiple order found'
|
|
_logger.error(error_msg)
|
|
raise ValidationError(error_msg)
|
|
return tx[0]
|
|
|
|
@api.model
|
|
def _authorize_form_get_invalid_parameters(self, tx, data):
|
|
invalid_parameters = []
|
|
|
|
if tx.authorize_txnid and data.get('x_trans_id') != tx.authorize_txnid:
|
|
invalid_parameters.append(('Transaction Id', data.get('x_trans_id'), tx.authorize_txnid))
|
|
# check what is buyed
|
|
if float_compare(float(data.get('x_amount', '0.0')), tx.amount, 2) != 0:
|
|
invalid_parameters.append(('Amount', data.get('x_amount'), '%.2f' % tx.amount))
|
|
return invalid_parameters
|
|
|
|
@api.model
|
|
def _authorize_form_validate(self, tx, data):
|
|
if tx.state == 'done':
|
|
_logger.warning('Authorize: trying to validate an already validated tx (ref %s)' % tx.reference)
|
|
return True
|
|
status_code = int(data.get('x_response_code', '0'))
|
|
if status_code == self._authorize_valid_tx_status:
|
|
tx.write({
|
|
'state': 'done',
|
|
'authorize_txnid': data.get('x_trans_id'),
|
|
'acquirer_reference': data['x_invoice_num'],
|
|
})
|
|
return True
|
|
elif status_code == self._authorize_pending_tx_status:
|
|
tx.write({
|
|
'state': 'pending',
|
|
'authorize_txnid': data.get('x_trans_id'),
|
|
'acquirer_reference': data['x_invoice_num'],
|
|
})
|
|
return True
|
|
elif status_code == self._authorize_cancel_tx_status:
|
|
tx.write({
|
|
'state': 'cancel',
|
|
'authorize_txnid': data.get('x_trans_id'),
|
|
'acquirer_reference': data['x_invoice_num'],
|
|
})
|
|
return True
|
|
else:
|
|
error = data.get('x_response_reason_text')
|
|
_logger.info(error)
|
|
tx.write({
|
|
'state': 'error',
|
|
'state_message': error,
|
|
'authorize_txnid': data.get('x_trans_id'),
|
|
'acquirer_reference': data['x_invoice_num'],
|
|
})
|
|
return False
|