diff --git a/addons/payment_stripe/models/payment_provider.py b/addons/payment_stripe/models/payment_provider.py index d778729ea23..8f179dd2680 100644 --- a/addons/payment_stripe/models/payment_provider.py +++ b/addons/payment_stripe/models/payment_provider.py @@ -270,7 +270,8 @@ class PaymentProvider(models.Model): # Stripe can send 4XX errors for payment failures (not only for badly-formed requests). # Check if an error code is present in the response content and raise only if not. # See https://stripe.com/docs/error-codes. - # If the request originates from an offline operation, don't raise and return the resp. + # If the request originates from an offline operation, don't raise to avoid a cursor + # rollback and return the response as-is for flow-specific handling. if not response.ok \ and not offline \ and 400 <= response.status_code < 500 \ diff --git a/addons/payment_stripe/models/payment_transaction.py b/addons/payment_stripe/models/payment_transaction.py index 32ff3957cd3..5065f9138ec 100644 --- a/addons/payment_stripe/models/payment_transaction.py +++ b/addons/payment_stripe/models/payment_transaction.py @@ -203,6 +203,8 @@ class PaymentTransaction(models.Model): "payment request response for transaction with reference %s:\n%s", self.reference, pprint.pformat(payment_intent) ) + if not payment_intent: # The PI might be missing if Stripe failed to create it. + return # There is nothing to process; the transaction is in error at this point. self.stripe_payment_intent = payment_intent['id'] # Handle the payment request response @@ -242,7 +244,14 @@ class PaymentTransaction(models.Model): if 'error' not in response: payment_intent = response else: # A processing error was returned in place of the payment intent + # The request failed and no error was raised because we are in an offline payment flow. + # Extract the error from the response, log it, and set the transaction in error to let + # the calling module handle the issue without rolling back the cursor. error_msg = response['error'].get('message') + _logger.error( + "The creation of the payment intent failed.\n" + "Stripe gave us the following info about the problem:\n'%s'", error_msg + ) self._set_error("Stripe: " + _( "The communication with the API failed.\n" "Stripe gave us the following info about the problem:\n'%s'", error_msg