From e67a12322795da49810ee7b02e1a8d35e45890aa Mon Sep 17 00:00:00 2001 From: Benoit Socias Date: Fri, 18 Jun 2021 13:38:12 +0000 Subject: [PATCH] [IMP] website_payment: take amount change into account MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this commit amount updates were not taken into account during the payment operation. After this commit amount updates are taken into account for the actual payment operation and payment fees are updated according to the amount and the partner country. Part of #63133 task-2398403 Signed-off-by: Jérémy Kersten (jke) --- addons/website_payment/controllers/portal.py | 13 ++++ .../static/src/js/website_payment_form.js | 62 +++++++++++++++++++ .../views/donation_templates.xml | 14 +++-- 3 files changed, 84 insertions(+), 5 deletions(-) diff --git a/addons/website_payment/controllers/portal.py b/addons/website_payment/controllers/portal.py index ec275a52462..095382145b7 100644 --- a/addons/website_payment/controllers/portal.py +++ b/addons/website_payment/controllers/portal.py @@ -33,6 +33,19 @@ class PaymentPortal(payment_portal.PaymentPortal): return self.payment_pay(**kwargs) + @http.route('/donation/get_acquirer_fees', type='json', auth='public', website=True, sitemap=False) + def get_acquirer_fees(self, acquirer_ids=None, amount=None, currency_id=None, country_id=None): + acquirers_sudo = request.env['payment.acquirer'].sudo().browse(acquirer_ids) + currency = request.env['res.currency'].browse(currency_id) + country = request.env['res.country'].browse(country_id) + + # Compute the fees taken by acquirers supporting the feature + fees_by_acquirer = { + acq_sudo.id: acq_sudo._compute_fees(amount, currency, country) + for acq_sudo in acquirers_sudo.filtered('fees_active') + } + return fees_by_acquirer + @http.route('/donation/transaction/', type='json', auth='public', website=True, sitemap=False) def donation_transaction(self, amount, currency_id, partner_id, access_token, minimum_amount=0, **kwargs): if float(amount) < float(minimum_amount): diff --git a/addons/website_payment/static/src/js/website_payment_form.js b/addons/website_payment/static/src/js/website_payment_form.js index 4c3c9485fbc..b59686877e0 100644 --- a/addons/website_payment/static/src/js/website_payment_form.js +++ b/addons/website_payment/static/src/js/website_payment_form.js @@ -4,6 +4,10 @@ import {_t} from 'web.core'; import checkoutForm from 'payment.checkout_form'; checkoutForm.include({ + events: _.extend({}, checkoutForm.prototype.events || {}, { + 'change .o_wpayment_fee_impact': '_onFeeParameterChange', + }), + //-------------------------------------------------------------------------- // Private //-------------------------------------------------------------------------- @@ -75,4 +79,62 @@ checkoutForm.include({ 'donation_recipient_email': this.$('input[name="donation_recipient_email"]').val(), } : transactionRouteParams; }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * Update the fees associated to each acquirer. + * + * Called upon change of any parameter that might impact the fees (marked with + * .o_wpayment_fee_impact). + * + * @private + * @param {Event} ev + * @return {undefined} + */ + _onFeeParameterChange: function (ev) { + const targetId = ev.target.id; + if (targetId.indexOf("amount") >= 0) { + this.txContext.amount = ev.target.value; + } + const acquirerIds = []; + for (const card of this.$('.o_payment_option_card:has(.o_payment_fee)')) { + const radio = $(card).find('input[name="o_payment_radio"]'); + if (radio.data("paymentOptionType") === 'acquirer') { + acquirerIds.push(radio.data("paymentOptionId")); + } + } + const countryId = this.$('select[name="country_id"]').val(); + if (acquirerIds && this.txContext.amount) { + this._rpc({ + route: '/donation/get_acquirer_fees', + params: { + 'acquirer_ids': acquirerIds, + 'amount': this.txContext.amount !== undefined + ? parseFloat(this.txContext.amount) : null, + 'currency_id': this.txContext.currencyId + ? parseInt(this.txContext.currencyId) : null, + 'country_id': countryId, + }, + }).then(feesPerAcquirer => { + for (const card of this.$('.o_payment_option_card:has(.o_payment_fee)')) { + const radio = $(card).find('input[name="o_payment_radio"]'); + if (radio.data("paymentOptionType") === 'acquirer') { + const acquirerId = radio.data("paymentOptionId"); + const chunk = $(card).find('.o_payment_fee .oe_currency_value')[0]; + chunk.innerText = (feesPerAcquirer[acquirerId] || 0).toFixed(2); + } + } + }).guardedCatch(error => { + error.event.preventDefault(); + this._displayError( + _t("Server Error"), + _t("We could not obtain payment fees."), + error.message.data.message + ); + }); + } + }, }); diff --git a/addons/website_payment/views/donation_templates.xml b/addons/website_payment/views/donation_templates.xml index 7341664bdaa..b5a44bbdcf2 100644 --- a/addons/website_payment/views/donation_templates.xml +++ b/addons/website_payment/views/donation_templates.xml @@ -27,7 +27,7 @@ -
-