From 608aa8ca88a087783667596daf98f9f8f4cb8c8e Mon Sep 17 00:00:00 2001 From: "Abdelouahab (abla)" Date: Mon, 12 Dec 2022 10:53:51 +0000 Subject: [PATCH] [FIX] payment_stripe: use idempotency key only when offline To Reproduce ============ - on a db with sales, website and Stripe payment aquirer activated - on the portal of a user add two payment methods, an expired card and a valid one - create a SO and generate its payment link - try to pay with the invalid card first -> and error (card was declined) - try to pay with the valid card -> error (same idempotency key) Problem ======= the generation of the idempotency key is based only on dbuuid, transaction's reference and the scope. So in this use case it will generate the same key. Solution ======== The idempotency key prevents issues where the customer is charged twice for the same thing. In this case, we don't want to prevent anything since the customer is on the page. It's suggested to use idempotency keys only for offline payment when the customer is not in front of the payment page (e.g. when the cron charges the customer for his subscription) opw-3091354 closes odoo/odoo#108163 X-original-commit: 089387087010ae917494d5072f00d72c572b7d09 Signed-off-by: Antoine Vandevenne (anv) Signed-off-by: abla001 --- addons/payment_stripe/models/payment_transaction.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/payment_stripe/models/payment_transaction.py b/addons/payment_stripe/models/payment_transaction.py index 1a60b12c658..e75526fcb6b 100644 --- a/addons/payment_stripe/models/payment_transaction.py +++ b/addons/payment_stripe/models/payment_transaction.py @@ -218,9 +218,10 @@ class PaymentTransaction(models.Model): 'payment_intents', payload=self._stripe_prepare_payment_intent_payload(payment_by_token=True), offline=self.operation == 'offline', + # Prevent multiple offline payments by token (e.g., due to a cursor rollback). idempotency_key=payment_utils.generate_idempotency_key( self, scope='payment_intents_token' - ), # Prevent multiple offline payments by token (e.g., due to a cursor rollback). + ) if self.operation == 'offline' else None, ) else: # 'online_direct' (express checkout). response = self.provider_id._stripe_make_request(