[FIX] payment_stripe: hide disabled local payment methods

If a merchants didn't enable a local Payment Method Type (PMT) on Stripe
 side (such as bancontact), his customers eligible for it (ex.: Belgian
 and paying in EUR) won't be able to pay using it.

This commit fixes this issue by adding a condition on the payment icons
 assigned to Stripe: if the payment icon related to a given payment
 method is not listed as a supported payment icon, the related payment
 method is not offered to customers, unless the payment icon does not
 exist at all.

User can enable PMTs through (Payment Acquirers > Stripe
 > Configuration > Supported Payment Icons). This concerns: ideal,
 bancontact, eps, giropay and p24.

 This solution is not entirely satisfactory but it isn't possible to
  fetch enabled PMT from Stripe.

opw-2335482

closes odoo/odoo#60740

X-original-commit: 1d0f23599bbd425c81131a5f6c1c22531ffcd0ee
Signed-off-by: Antoine Vandevenne (anv) <AntoineVDV@users.noreply.github.com>
This commit is contained in:
Adrien Horgnies
2020-10-26 13:26:21 +00:00
parent 532a22667f
commit 6adac428b4
6 changed files with 88 additions and 4 deletions
+15
View File
@@ -50,6 +50,21 @@
<field name="image" type="base64" file="payment/static/img/bancontact.png"/>
</record>
<record id="payment_icon_cc_eps" model="payment.icon">
<field name="name">EPS</field>
<field name="image" type="base64" file="payment/static/img/eps.png"/>
</record>
<record id="payment_icon_cc_giropay" model="payment.icon">
<field name="name">Giropay</field>
<field name="image" type="base64" file="payment/static/img/giropay.png"/>
</record>
<record id="payment_icon_cc_p24" model="payment.icon">
<field name="name">P24</field>
<field name="image" type="base64" file="payment/static/img/p24.png"/>
</record>
<record id="payment_icon_cc_codensa_easy_credit" model="payment.icon">
<field name="name">Codensa Easy Credit</field>
<field name="image" type="base64" file="payment/static/img/codensa_easy_credit.png"/>
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

+8 -1
View File
@@ -88,8 +88,15 @@ class PaymentAcquirerStripe(models.Model):
PMT('p24', ['pl'], ['eur', 'pln'], 'punctual'),
]
existing_icons = [icon.name.lower() for icon in self.env['payment.icon'].search([])]
linked_icons = [icon.name.lower() for icon in self.payment_icon_ids]
# We don't filter out pmt in the case the icon doesn't exist at all as it would be **implicit** exclusion
icon_filtered = filter(lambda pmt: pmt.name == 'card' or
pmt.name in linked_icons or
pmt.name not in existing_icons, all_payment_method_types)
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)
pmt_country_filtered = filter(lambda pmt: not pmt.countries or country in pmt.countries, icon_filtered)
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',
+65 -3
View File
@@ -29,6 +29,13 @@ class StripeCommon(PaymentAcquirerCommon):
'partner_id': cls.buyer.id,
'verified': True,
})
cls.ideal_icon = cls.env.ref("payment.payment_icon_cc_ideal")
cls.bancontact_icon = cls.env.ref("payment.payment_icon_cc_bancontact")
cls.p24_icon = cls.env.ref("payment.payment_icon_cc_p24")
cls.eps_icon = cls.env.ref("payment.payment_icon_cc_eps")
cls.giropay_icon = cls.env.ref("payment.payment_icon_cc_giropay")
cls.all_icons = [cls.ideal_icon, cls.bancontact_icon, cls.p24_icon, cls.eps_icon, cls.giropay_icon]
cls.stripe.write({'payment_icon_ids': [(5, 0, 0)]})
@odoo.tests.tagged('post_install', '-at_install', '-standard', 'external')
@@ -87,7 +94,8 @@ class StripeTest(StripeCommon):
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):
def test_add_available_payment_method_types_local_enabled(self):
self.stripe.payment_icon_ids = [(6, 0, [i.id for i in self.all_icons])]
tx_values = {
'billing_partner_country': self.env.ref('base.be'),
'currency': self.env.ref('base.EUR'),
@@ -100,6 +108,61 @@ class StripeTest(StripeCommon):
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_local_enabled_2(self):
self.stripe.payment_icon_ids = [(6, 0, [i.id for i in self.all_icons])]
tx_values = {
'billing_partner_country': self.env.ref('base.pl'),
'currency': self.env.ref('base.PLN'),
'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', 'p24'}, actual)
def test_add_available_payment_method_types_pmt_does_not_exist(self):
self.bancontact_icon.unlink()
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_local_disabled(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'}, actual)
def test_add_available_payment_method_types_local_all_but_bancontact(self):
self.stripe.payment_icon_ids = [(4, icon.id) for icon in self.all_icons if icon.name.lower() != 'bancontact']
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'}, actual)
def test_add_available_payment_method_types_recurrent(self):
tx_values = {
'billing_partner_country': self.env.ref('base.be'),
@@ -114,8 +177,7 @@ class StripeTest(StripeCommon):
self.assertEqual({'card'}, actual)
def test_discarded_webhook(self):
with self.assertRaises(ValidationError):
self.env['payment.acquirer']._handle_stripe_webhook(dict(type='payment.intent.succeeded'))
self.assertFalse(self.env['payment.acquirer']._handle_stripe_webhook(dict(type='payment.intent.succeeded')))
def test_handle_checkout_webhook_no_secret(self):
self.stripe.stripe_webhook_secret = None