summaryrefslogtreecommitdiff
path: root/addons/payment_payumoney/models
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/payment_payumoney/models
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/payment_payumoney/models')
-rw-r--r--addons/payment_payumoney/models/__init__.py4
-rw-r--r--addons/payment_payumoney/models/payment.py137
2 files changed, 141 insertions, 0 deletions
diff --git a/addons/payment_payumoney/models/__init__.py b/addons/payment_payumoney/models/__init__.py
new file mode 100644
index 00000000..2ec5b9cd
--- /dev/null
+++ b/addons/payment_payumoney/models/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from . import payment
diff --git a/addons/payment_payumoney/models/payment.py b/addons/payment_payumoney/models/payment.py
new file mode 100644
index 00000000..efba9677
--- /dev/null
+++ b/addons/payment_payumoney/models/payment.py
@@ -0,0 +1,137 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import hashlib
+
+from werkzeug import urls
+
+from odoo import api, fields, models, _
+from odoo.addons.payment.models.payment_acquirer import ValidationError
+from odoo.tools.float_utils import float_compare
+
+import logging
+
+_logger = logging.getLogger(__name__)
+
+
+class PaymentAcquirerPayumoney(models.Model):
+ _inherit = 'payment.acquirer'
+
+ provider = fields.Selection(selection_add=[
+ ('payumoney', 'PayUmoney')
+ ], ondelete={'payumoney': 'set default'})
+ payumoney_merchant_key = fields.Char(string='Merchant Key', required_if_provider='payumoney', groups='base.group_user')
+ payumoney_merchant_salt = fields.Char(string='Merchant Salt', required_if_provider='payumoney', groups='base.group_user')
+
+ def _get_payumoney_urls(self, environment):
+ """ PayUmoney URLs"""
+ if environment == 'prod':
+ return {'payumoney_form_url': 'https://secure.payu.in/_payment'}
+ else:
+ return {'payumoney_form_url': 'https://sandboxsecure.payu.in/_payment'}
+
+ def _payumoney_generate_sign(self, inout, values):
+ """ Generate the shasign for incoming or outgoing communications.
+ :param self: the self browse record. It should have a shakey in shakey out
+ :param string inout: 'in' (odoo contacting payumoney) or 'out' (payumoney
+ contacting odoo).
+ :param dict values: transaction values
+
+ :return string: shasign
+ """
+ if inout not in ('in', 'out'):
+ raise Exception("Type must be 'in' or 'out'")
+
+ if inout == 'in':
+ keys = "key|txnid|amount|productinfo|firstname|email|udf1|||||||||".split('|')
+ sign = ''.join('%s|' % (values.get(k) or '') for k in keys)
+ sign += self.payumoney_merchant_salt or ''
+ else:
+ keys = "|status||||||||||udf1|email|firstname|productinfo|amount|txnid".split('|')
+ sign = ''.join('%s|' % (values.get(k) or '') for k in keys)
+ sign = self.payumoney_merchant_salt + sign + self.payumoney_merchant_key
+
+ shasign = hashlib.sha512(sign.encode('utf-8')).hexdigest()
+ return shasign
+
+ def payumoney_form_generate_values(self, values):
+ self.ensure_one()
+ base_url = self.get_base_url()
+ payumoney_values = dict(values,
+ key=self.payumoney_merchant_key,
+ txnid=values['reference'],
+ amount=values['amount'],
+ productinfo=values['reference'],
+ firstname=values.get('partner_name'),
+ email=values.get('partner_email'),
+ phone=values.get('partner_phone'),
+ service_provider='payu_paisa',
+ surl=urls.url_join(base_url, '/payment/payumoney/return'),
+ furl=urls.url_join(base_url, '/payment/payumoney/error'),
+ curl=urls.url_join(base_url, '/payment/payumoney/cancel')
+ )
+
+ payumoney_values['udf1'] = payumoney_values.pop('return_url', '/')
+ payumoney_values['hash'] = self._payumoney_generate_sign('in', payumoney_values)
+ return payumoney_values
+
+ def payumoney_get_form_action_url(self):
+ self.ensure_one()
+ environment = 'prod' if self.state == 'enabled' else 'test'
+ return self._get_payumoney_urls(environment)['payumoney_form_url']
+
+
+class PaymentTransactionPayumoney(models.Model):
+ _inherit = 'payment.transaction'
+
+ @api.model
+ def _payumoney_form_get_tx_from_data(self, data):
+ """ Given a data dict coming from payumoney, verify it and find the related
+ transaction record. """
+ reference = data.get('txnid')
+ pay_id = data.get('mihpayid')
+ shasign = data.get('hash')
+ if not reference or not pay_id or not shasign:
+ raise ValidationError(_('PayUmoney: received data with missing reference (%s) or pay_id (%s) or shasign (%s)') % (reference, pay_id, shasign))
+
+ transaction = self.search([('reference', '=', reference)])
+
+ if not transaction:
+ error_msg = (_('PayUmoney: received data for reference %s; no order found') % (reference))
+ raise ValidationError(error_msg)
+ elif len(transaction) > 1:
+ error_msg = (_('PayUmoney: received data for reference %s; multiple orders found') % (reference))
+ raise ValidationError(error_msg)
+
+ #verify shasign
+ shasign_check = transaction.acquirer_id._payumoney_generate_sign('out', data)
+ if shasign_check.upper() != shasign.upper():
+ raise ValidationError(_('PayUmoney: invalid shasign, received %s, computed %s, for data %s') % (shasign, shasign_check, data))
+ return transaction
+
+ def _payumoney_form_get_invalid_parameters(self, data):
+ invalid_parameters = []
+
+ if self.acquirer_reference and data.get('mihpayid') != self.acquirer_reference:
+ invalid_parameters.append(
+ ('Transaction Id', data.get('mihpayid'), self.acquirer_reference))
+ #check what is buyed
+ if float_compare(float(data.get('amount', '0.0')), self.amount, 2) != 0:
+ invalid_parameters.append(
+ ('Amount', data.get('amount'), '%.2f' % self.amount))
+
+ return invalid_parameters
+
+ def _payumoney_form_validate(self, data):
+ status = data.get('status')
+ result = self.write({
+ 'acquirer_reference': data.get('payuMoneyId'),
+ 'date': fields.Datetime.now(),
+ })
+ if status == 'success':
+ self._set_transaction_done()
+ elif status != 'pending':
+ self._set_transaction_cancel()
+ else:
+ self._set_transaction_pending()
+ return result