[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: 1b7da6d0fe06fcab623f06508cee1093b10273a4
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user