def create(self, values_list): for values in values_list: acquirer = self.env['payment.acquirer'].browse(values['acquirer_id']) if not values.get('reference'): values['reference'] = self._compute_reference(acquirer.provider, **values) # Duplicate partner values partner = self.env['res.partner'].browse(values['partner_id']) values.update({ 'partner_name': partner.name, 'partner_lang': partner.lang, 'partner_email': partner.email, 'partner_address': payment_utils.format_partner_address( partner.street, partner.street2 ), 'partner_zip': partner.zip, 'partner_city': partner.city, 'partner_state_id': partner.state_id.id, 'partner_country_id': partner.country_id.id, 'partner_phone': partner.phone, }) # Compute fees currency = self.env['res.currency'].browse(values.get('currency_id')).exists() values['fees'] = acquirer._compute_fees( values.get('amount', 0), currency, partner.country_id ) # Include acquirer-specific create values values.update(self._get_specific_create_values(acquirer.provider, values)) # Generate the hash for the callback if one has be configured on the tx values['callback_hash'] = self._generate_callback_hash( values.get('callback_model_id'), values.get('callback_res_id'), values.get('callback_method'), ) txs = super().create(values_list) # Monetary fields are rounded with the currency at creation time by the ORM. Sometimes, this # can lead to inconsistent string representation of the amounts sent to the providers. # E.g., tx.create(amount=1111.11) -> tx.amount == 1111.1100000000001 # To ensure a proper string representation, we invalidate this request's cache values of the # `amount` and `fees` fields for the created transactions. This forces the ORM to read the # values from the DB where there were stored using `float_repr`, which produces a result # consistent with the format expected by providers. # E.g., tx.create(amount=1111.11) ; tx.invalidate_cache() -> tx.amount == 1111.11 txs.invalidate_cache(['amount', 'fees']) return txs
def test_redirect_form_values(self): """ Test the values of the redirect form inputs for online payments. """ return_url = self._build_url(OgoneController._hosted_payment_page_return_url) expected_values = { 'PSPID': self.ogone.ogone_pspid, 'ORDERID': self.reference, 'AMOUNT': str(payment_utils.to_minor_currency_units(self.amount, None, 2)), 'CURRENCY': self.currency.name, 'LANGUAGE': self.partner.lang, 'EMAIL': self.partner.email, 'OWNERZIP': self.partner.zip, 'OWNERADDRESS': payment_utils.format_partner_address( self.partner.street, self.partner.street2 ), 'OWNERCTY': self.partner.country_id.code, 'OWNERTOWN': self.partner.city, 'OWNERTELNO': self.partner.phone, 'OPERATION': 'SAL', # direct sale 'USERID': self.ogone.ogone_userid, 'ACCEPTURL': return_url, 'DECLINEURL': return_url, 'EXCEPTIONURL': return_url, 'CANCELURL': return_url, 'ALIAS': None, 'ALIASUSAGE': None, } expected_values['SHASIGN'] = self.ogone._ogone_generate_signature( expected_values, incoming=False ).upper() tx = self.create_transaction(flow='redirect') self.assertEqual(tx.tokenize, False) with mute_logger('odoo.addons.payment.models.payment_transaction'): processing_values = tx._get_processing_values() form_info = self._extract_values_from_html_form(processing_values['redirect_form_html']) self.assertEqual(form_info['action'], 'https://ogone.test.v-psp.com/ncol/test/orderstandard_utf8.asp') inputs = form_info['inputs'] self.assertEqual(len(expected_values), len(inputs)) for rendering_key, value in expected_values.items(): form_key = rendering_key.replace('_', '.') self.assertEqual( inputs[form_key], value, f"received value {inputs[form_key]} for input {form_key} (expected {value})" )