From 235985733570fbd8e53489bd75df81059db6fa17 Mon Sep 17 00:00:00 2001 From: kcv-odoo Date: Mon, 22 Jan 2024 18:45:05 +0530 Subject: [PATCH] [FIX] payment_razorpay: fix mandate max amount error Steps: - Install subscription and razorpay app. - Configure razorpay provider with tokenizable razorpay account. - Enable allow tokenize field. - create subscription with more then 100k and less then 500k amount. - Try to pay that subscription with razorpay. Issue: - Throwing limit exceed warning even though amount is less then 500k which can create token and paid normally. Cause: - We forgot to check minimum of method max amount and amount * 5 to send proper mandate max amount while creating token and because of that paying more then 100k via subscription raise error even to it should processed normally. Fix: - Check minimum of `method max amount` and `amount * 5` to send proper mandate max amount so it'll not raise error while paying amount in between 100k to 500k. closes odoo/odoo#150410 Related: odoo/enterprise#55009 Signed-off-by: Antoine Vandevenne (anv) --- addons/payment_razorpay/const.py | 2 +- .../models/payment_transaction.py | 21 +++++++++++-------- .../tests/test_payment_transaction.py | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/addons/payment_razorpay/const.py b/addons/payment_razorpay/const.py index 1b5e1a2842d..443e6aec606 100644 --- a/addons/payment_razorpay/const.py +++ b/addons/payment_razorpay/const.py @@ -113,7 +113,7 @@ DEFAULT_PAYMENT_METHODS_CODES = [ # The maximum amount in INR that can be paid through an eMandate. MANDATE_MAX_AMOUNT = { - 'card': 500000, + 'card': 1000000, 'upi': 100000, } diff --git a/addons/payment_razorpay/models/payment_transaction.py b/addons/payment_razorpay/models/payment_transaction.py index e360ec2c171..97cc27c23a1 100644 --- a/addons/payment_razorpay/models/payment_transaction.py +++ b/addons/payment_razorpay/models/payment_transaction.py @@ -125,7 +125,7 @@ class PaymentTransaction(models.Model): if self.tokenize: payload['token'] = { 'max_amount': payment_utils.to_minor_currency_units( - self._get_mandate_max_amount(), self.currency_id + self._razorpay_get_mandate_max_amount(), self.currency_id ), 'expire_at': time.mktime( (datetime.today() + relativedelta(years=10)).timetuple() @@ -147,20 +147,23 @@ class PaymentTransaction(models.Model): }) return payload - def _get_mandate_max_amount(self): + def _razorpay_get_mandate_max_amount(self): """ Return the eMandate's maximum amount to define. :return: The eMandate's maximum amount. :rtype: int """ - mandate_values = self._get_mandate_values() - if 'amount' in mandate_values: - max_amount = mandate_values['amount'] * 5 # FP's rule of thumb for a good max amount. + pm_code = ( + self.payment_method_id.primary_payment_method_id or self.payment_method_id + ).code + pm_max_amount = const.MANDATE_MAX_AMOUNT.get(pm_code, 100000) + mandate_values = self._get_mandate_values() # The linked document's values. + if 'amount' in mandate_values and 'MRR' in mandate_values: + max_amount = min( + pm_max_amount, max(mandate_values['amount'] * 1.5, mandate_values['MRR'] * 5) + ) else: - pm_code = ( - self.payment_method_id.primary_payment_method_id or self.payment_method_id - ).code - max_amount = const.MANDATE_MAX_AMOUNT.get(pm_code, 100000) + max_amount = pm_max_amount return max_amount def _send_payment_request(self): diff --git a/addons/payment_razorpay/tests/test_payment_transaction.py b/addons/payment_razorpay/tests/test_payment_transaction.py index 81f56ce699c..de38282f5dd 100644 --- a/addons/payment_razorpay/tests/test_payment_transaction.py +++ b/addons/payment_razorpay/tests/test_payment_transaction.py @@ -89,7 +89,7 @@ class TestPaymentTransaction(RazorpayCommon): 'token': { "expire_at": token_expiry_timeslamp, "frequency": "as_presented", - 'max_amount': 50000000, + 'max_amount': 100000000, }, 'amount': converted_amount, 'currency': tx.currency_id.name,