Skip to content
Snippets Groups Projects
Commit 12be2875 authored by Adrien Horgnies's avatar Adrien Horgnies
Browse files

[IMP] payment: add new local payment method type for Stripe

- bancontact (be; eur)
- eps (at; eur)
- giropay (de; eur)
- p24 (pl; eur, pln)

X-original-commit: 1b7da6d0
parent 57a7d9f4
No related branches found
No related tags found
No related merge requests found
......@@ -5,6 +5,7 @@ import requests
import pprint
from requests.exceptions import HTTPError
from werkzeug import urls
from collections import namedtuple
from odoo import api, fields, models, _
from odoo.tools.float_utils import float_round
......@@ -40,7 +41,6 @@ class PaymentAcquirerStripe(models.Model):
base_url = self.get_base_url()
stripe_session_data = {
'payment_method_types[0]': 'card',
'line_items[][amount]': int(tx_values['amount'] if tx_values['currency'].name in INT_CURRENCIES else float_round(tx_values['amount'] * 100, 2)),
'line_items[][currency]': tx_values['currency'].name,
'line_items[][quantity]': 1,
......@@ -51,14 +51,43 @@ class PaymentAcquirerStripe(models.Model):
'payment_intent_data[description]': tx_values['reference'],
'customer_email': tx_values.get('partner_email') or tx_values.get('billing_partner_email'),
}
if tx_values.get('billing_partner_country').code and tx_values.get('billing_partner_country').code.lower() == 'nl' and \
tx_values.get('currency').name and tx_values.get('currency').name.lower() == 'eur':
# enable iDEAL for NL-based customers (€ payments only)
stripe_session_data['payment_method_types[1]'] = 'ideal'
self._add_available_payment_method_types(stripe_session_data, tx_values)
tx_values['session_id'] = self._create_stripe_session(stripe_session_data)
return tx_values
@api.model
def _add_available_payment_method_types(self, stripe_session_data, tx_values):
"""
Add payment methods available for the given transaction
:param stripe_session_data: dictionary to add the payment method types to
:param tx_values: values of the transaction to consider the payment method types for
"""
PMT = namedtuple('PaymentMethodType', ['name', 'countries', 'currencies', 'recurrence'])
all_payment_method_types = [
PMT('card', [], [], 'recurring'),
PMT('ideal', ['nl'], ['eur'], 'punctual'),
PMT('bancontact', ['be'], ['eur'], 'punctual'),
PMT('eps', ['at'], ['eur'], 'punctual'),
PMT('giropay', ['de'], ['eur'], 'punctual'),
PMT('p24', ['pl'], ['eur', 'pln'], 'punctual'),
]
country = (tx_values['billing_partner_country'].code or 'no_country').lower()
pmt_country_filtered = filter(lambda pmt: not pmt.countries or country in pmt.countries, all_payment_method_types)
currency = (tx_values.get('currency').name or 'no_currency').lower()
pmt_currency_filtered = filter(lambda pmt: not pmt.currencies or currency in pmt.currencies, pmt_country_filtered)
pmt_recurrence_filtered = filter(lambda pmt: tx_values.get('type') != 'form_save' or pmt.recurrence == 'recurring',
pmt_currency_filtered)
available_payment_method_types = map(lambda pmt: pmt.name, pmt_recurrence_filtered)
for idx, payment_method_type in enumerate(available_payment_method_types):
stripe_session_data[f'payment_method_types[{idx}]'] = payment_method_type
def _stripe_request(self, url, data=False, method='POST'):
self.ensure_one()
url = urls.url_join(self._get_stripe_api_url(), url)
......@@ -92,6 +121,8 @@ class PaymentAcquirerStripe(models.Model):
if resp.get('payment_intent') and kwargs.get('client_reference_id'):
tx = self.env['payment.transaction'].sudo().search([('reference', '=', kwargs['client_reference_id'])])
tx.stripe_payment_intent = resp['payment_intent']
if 'id' not in resp and 'error' in resp:
_logger.error(resp['error']['message'])
return resp['id']
def _create_setup_intent(self, kwargs):
......
......@@ -28,6 +28,10 @@ class StripeCommon(PaymentAcquirerCommon):
@odoo.tests.tagged('post_install', '-at_install', '-standard', 'external')
class StripeTest(StripeCommon):
def run(self, result=None):
with mute_logger('odoo.addons.payment.models.payment_acquirer', 'odoo.addons.payment_stripe.models.payment'):
StripeCommon.run(self, result)
def test_10_stripe_s2s(self):
self.assertEqual(self.stripe.state, 'test', 'test without test environment')
# Create transaction
......@@ -76,3 +80,29 @@ class StripeTest(StripeCommon):
tx.form_feedback(stripe_post_data, 'stripe')
self.assertEqual(tx.state, 'done', 'Stripe: validation did not put tx into done state')
self.assertEqual(tx.acquirer_reference, stripe_post_data.get('id'), 'Stripe: validation did not update tx id')
def test_add_available_payment_method_types(self):
tx_values = {
'billing_partner_country': self.env.ref('base.be'),
'currency': self.env.ref('base.EUR'),
'type': 'form'
}
stripe_session_data = {}
self.stripe._add_available_payment_method_types(stripe_session_data, tx_values)
actual = {pmt for key, pmt in stripe_session_data.items() if key.startswith('payment_method_types')}
self.assertEqual({'card', 'bancontact'}, actual)
def test_add_available_payment_method_types_recurrent(self):
tx_values = {
'billing_partner_country': self.env.ref('base.be'),
'currency': self.env.ref('base.EUR'),
'type': 'form_save'
}
stripe_session_data = {}
self.stripe._add_available_payment_method_types(stripe_session_data, tx_values)
actual = {pmt for key, pmt in stripe_session_data.items() if key.startswith('payment_method_types')}
self.assertEqual({'card'}, actual)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment