[FIX] payment_adyen: add 'amount' to adyen checkout configuration
Steps to reproduce: 1. Create a company with currency as Euros. 2. Set up Adyen on that company with the test credentials and enable paypal. 3. Create an invoice with the currency in Euros. 4. Generate a payment link. 5. Attempt to pay on that payment link with paypal. After this commit the Adyen checkout configuration is correctly set up which allows to pay with PayPal opw-3543970 Part-of: odoo/odoo#140711
This commit is contained in:
committed by
Antoine Vandevenne (anv)
parent
09df480c3e
commit
b024dd76d4
@@ -16,7 +16,6 @@ from odoo.http import request
|
||||
|
||||
from odoo.addons.payment import utils as payment_utils
|
||||
from odoo.addons.payment_adyen import utils as adyen_utils
|
||||
from odoo.addons.payment_adyen.const import CURRENCY_DECIMALS
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -26,22 +25,16 @@ class AdyenController(http.Controller):
|
||||
_webhook_url = '/payment/adyen/notification'
|
||||
|
||||
@http.route('/payment/adyen/payment_methods', type='json', auth='public')
|
||||
def adyen_payment_methods(self, provider_id, amount=None, currency_id=None, partner_id=None):
|
||||
def adyen_payment_methods(self, provider_id, formatted_amount=None, partner_id=None):
|
||||
""" Query the available payment methods based on the payment context.
|
||||
|
||||
:param int provider_id: The provider handling the transaction, as a `payment.provider` id
|
||||
:param float amount: The transaction amount
|
||||
:param int currency_id: The transaction currency, as a `res.currency` id
|
||||
:param dict formatted_amount: The Adyen-formatted amount.
|
||||
:param int partner_id: The partner making the transaction, as a `res.partner` id
|
||||
:return: The JSON-formatted content of the response
|
||||
:rtype: dict
|
||||
"""
|
||||
provider_sudo = request.env['payment.provider'].sudo().browse(provider_id)
|
||||
currency = request.env['res.currency'].browse(currency_id)
|
||||
currency_code = currency_id and currency.name
|
||||
converted_amount = amount and currency_code and payment_utils.to_minor_currency_units(
|
||||
amount, currency, CURRENCY_DECIMALS.get(currency_code)
|
||||
)
|
||||
partner_sudo = partner_id and request.env['res.partner'].sudo().browse(partner_id).exists()
|
||||
# The lang is taken from the context rather than from the partner because it is not required
|
||||
# to be logged in to make a payment, and because the lang is not always set on the partner.
|
||||
@@ -52,7 +45,7 @@ class AdyenController(http.Controller):
|
||||
shopper_reference = partner_sudo and f'ODOO_PARTNER_{partner_sudo.id}'
|
||||
data = {
|
||||
'merchantAccount': provider_sudo.adyen_merchant_account,
|
||||
'amount': converted_amount,
|
||||
'amount': formatted_amount,
|
||||
'countryCode': partner_sudo.country_id.code or None, # ISO 3166-1 alpha-2 (e.g.: 'BE')
|
||||
'shopperLocale': lang_code, # IETF language tag (e.g.: 'fr-BE')
|
||||
'shopperReference': shopper_reference,
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
import json
|
||||
import requests
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
from odoo.addons.payment import utils as payment_utils
|
||||
from odoo.addons.payment_adyen import const
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@@ -144,12 +145,14 @@ class PaymentProvider(models.Model):
|
||||
|
||||
#=== BUSINESS METHODS - GETTERS ===#
|
||||
|
||||
def _adyen_get_inline_form_values(self, pm_code):
|
||||
def _adyen_get_inline_form_values(self, pm_code, amount=None, currency=None):
|
||||
""" Return a serialized JSON of the required values to render the inline form.
|
||||
|
||||
Note: `self.ensure_one()`
|
||||
|
||||
:param str pm_code: The code of the payment method whose inline form to render.
|
||||
:param float amount: The transaction amount.
|
||||
:param res.currency currency: The transaction currency.
|
||||
:return: The JSON serial of the required values to render the inline form.
|
||||
:rtype: str
|
||||
"""
|
||||
@@ -158,5 +161,25 @@ class PaymentProvider(models.Model):
|
||||
inline_form_values = {
|
||||
'client_key': self.adyen_client_key,
|
||||
'adyen_pm_code': const.PAYMENT_METHODS_MAPPING.get(pm_code, pm_code),
|
||||
'formatted_amount': self._adyen_get_formatted_amount(amount, currency),
|
||||
}
|
||||
return json.dumps(inline_form_values)
|
||||
|
||||
def _adyen_get_formatted_amount(self, amount=None, currency=None):
|
||||
""" Return the amount in the format required by Adyen.
|
||||
|
||||
The formatted amount is a dict with keys 'value' and 'currency'.
|
||||
|
||||
:param float amount: The transaction amount.
|
||||
:param res.currency currency: The transaction currency.
|
||||
:return: The Adyen-formatted amount.
|
||||
:rtype: dict
|
||||
"""
|
||||
currency_code = currency and currency.name
|
||||
converted_amount = amount and currency_code and payment_utils.to_minor_currency_units(
|
||||
amount, currency, const.CURRENCY_DECIMALS.get(currency_code)
|
||||
)
|
||||
return {
|
||||
'value': converted_amount,
|
||||
'currency': currency_code,
|
||||
}
|
||||
|
||||
@@ -48,24 +48,22 @@ paymentForm.include({
|
||||
// Extract and deserialize the inline form values.
|
||||
const radio = document.querySelector('input[name="o_payment_radio"]:checked');
|
||||
const inlineFormValues = JSON.parse(radio.dataset['inlineFormValues']);
|
||||
const formatted_amount = inlineFormValues['formatted_amount'];
|
||||
const formattedAmount = inlineFormValues['formatted_amount'];
|
||||
|
||||
// Create the checkout object if not already done for another payment method.
|
||||
if (!this.adyenCheckout) {
|
||||
await this.rpc('/payment/adyen/payment_methods', { // Await the RPC to let it create AdyenCheckout before using it.
|
||||
'provider_id': providerId,
|
||||
'partner_id': parseInt(this.paymentContext['partnerId']),
|
||||
'amount': this.paymentContext['amount']
|
||||
? parseFloat(this.paymentContext['amount'])
|
||||
: undefined,
|
||||
'currency_id': this.paymentContext['currencyId']
|
||||
? parseInt(this.paymentContext['currencyId'])
|
||||
: undefined,
|
||||
'formatted_amount': formattedAmount,
|
||||
}).then(async response => {
|
||||
// Create the Adyen Checkout SDK.
|
||||
const providerState = this._getProviderState(radio);
|
||||
const configuration = {
|
||||
paymentMethodsResponse: response,
|
||||
clientKey: inlineFormValues['client_key'],
|
||||
amount: formattedAmount,
|
||||
locale: (this._getContext().lang || 'en-US').replace('_', '-'),
|
||||
environment: providerState === 'enabled' ? 'live' : 'test',
|
||||
onAdditionalDetails: this._adyenOnSubmitAdditionalDetails.bind(this),
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<template id="payment_adyen.method_form" inherit_id="payment.method_form">
|
||||
<xpath expr="//input[@name='o_payment_radio']" position="attributes">
|
||||
<attribute name="t-att-data-inline-form-values">
|
||||
provider_sudo._adyen_get_inline_form_values(pm_sudo.code)
|
||||
provider_sudo._adyen_get_inline_form_values(pm_sudo.code, amount, currency)
|
||||
</attribute>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user