Skip to content
Snippets Groups Projects
Commit 1b7da6d0 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)
parent 57261e5a
No related branches found
No related tags found
No related merge requests found
...@@ -5,6 +5,7 @@ import requests ...@@ -5,6 +5,7 @@ import requests
import pprint import pprint
from requests.exceptions import HTTPError from requests.exceptions import HTTPError
from werkzeug import urls from werkzeug import urls
from collections import namedtuple
from odoo import api, fields, models, _ from odoo import api, fields, models, _
from odoo.tools.float_utils import float_round from odoo.tools.float_utils import float_round
...@@ -38,7 +39,6 @@ class PaymentAcquirerStripe(models.Model): ...@@ -38,7 +39,6 @@ class PaymentAcquirerStripe(models.Model):
base_url = self.get_base_url() base_url = self.get_base_url()
stripe_session_data = { 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[][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[][currency]': tx_values['currency'].name,
'line_items[][quantity]': 1, 'line_items[][quantity]': 1,
...@@ -49,14 +49,43 @@ class PaymentAcquirerStripe(models.Model): ...@@ -49,14 +49,43 @@ class PaymentAcquirerStripe(models.Model):
'payment_intent_data[description]': tx_values['reference'], 'payment_intent_data[description]': tx_values['reference'],
'customer_email': tx_values.get('partner_email') or tx_values.get('billing_partner_email'), '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': self._add_available_payment_method_types(stripe_session_data, tx_values)
# enable iDEAL for NL-based customers (€ payments only)
stripe_session_data['payment_method_types[1]'] = 'ideal'
tx_values['session_id'] = self._create_stripe_session(stripe_session_data) tx_values['session_id'] = self._create_stripe_session(stripe_session_data)
return tx_values 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'): def _stripe_request(self, url, data=False, method='POST'):
self.ensure_one() self.ensure_one()
url = urls.url_join(self._get_stripe_api_url(), url) url = urls.url_join(self._get_stripe_api_url(), url)
...@@ -90,6 +119,8 @@ class PaymentAcquirerStripe(models.Model): ...@@ -90,6 +119,8 @@ class PaymentAcquirerStripe(models.Model):
if resp.get('payment_intent') and kwargs.get('client_reference_id'): if resp.get('payment_intent') and kwargs.get('client_reference_id'):
tx = self.env['payment.transaction'].sudo().search([('reference', '=', kwargs['client_reference_id'])]) tx = self.env['payment.transaction'].sudo().search([('reference', '=', kwargs['client_reference_id'])])
tx.stripe_payment_intent = resp['payment_intent'] tx.stripe_payment_intent = resp['payment_intent']
if 'id' not in resp and 'error' in resp:
_logger.error(resp['error']['message'])
return resp['id'] return resp['id']
def _create_setup_intent(self, kwargs): def _create_setup_intent(self, kwargs):
......
...@@ -28,6 +28,10 @@ class StripeCommon(PaymentAcquirerCommon): ...@@ -28,6 +28,10 @@ class StripeCommon(PaymentAcquirerCommon):
@odoo.tests.tagged('post_install', '-at_install', '-standard', 'external') @odoo.tests.tagged('post_install', '-at_install', '-standard', 'external')
class StripeTest(StripeCommon): 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): def test_10_stripe_s2s(self):
self.assertEqual(self.stripe.state, 'test', 'test without test environment') self.assertEqual(self.stripe.state, 'test', 'test without test environment')
# Create transaction # Create transaction
...@@ -76,3 +80,29 @@ class StripeTest(StripeCommon): ...@@ -76,3 +80,29 @@ class StripeTest(StripeCommon):
tx.form_feedback(stripe_post_data, 'stripe') tx.form_feedback(stripe_post_data, 'stripe')
self.assertEqual(tx.state, 'done', 'Stripe: validation did not put tx into done state') 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') 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