diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/payment_payumoney/models | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/payment_payumoney/models')
| -rw-r--r-- | addons/payment_payumoney/models/__init__.py | 4 | ||||
| -rw-r--r-- | addons/payment_payumoney/models/payment.py | 137 |
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 |
