Skip to content
This repository has been archived by the owner on Nov 4, 2024. It is now read-only.

Commit

Permalink
fix: Add exception handling when canceling a Payment Intent (#4156)
Browse files Browse the repository at this point in the history
REV-3821
  • Loading branch information
julianajlk authored Apr 23, 2024
1 parent e63fbfa commit 73c6110
Showing 1 changed file with 24 additions and 6 deletions.
30 changes: 24 additions & 6 deletions ecommerce/extensions/payment/processors/stripe.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,26 @@ def _build_payment_intent_parameters(self, basket):

def cancel_and_create_new_payment_intent_for_basket(self, basket, payment_intent_id):
"""
Create a new Stripe payment intent to associate with the current basket.
Cancel and create a new Stripe payment intent to associate with the current basket.
This is used as a reset of the payment to allow payment retries when the intent gets into unexpected states.
"""
# Cancel existing Payment Intent
cancelled_payment_intent = stripe.PaymentIntent.cancel(payment_intent_id)
try:
# Cancel existing Payment Intent
stripe.PaymentIntent.cancel(payment_intent_id)
logger.info(
'Sucessfully cancelled Payment Intent [%s] for basket [%d] and order number [%s]',
payment_intent_id,
basket.id,
basket.order_number,
)
except stripe.error.InvalidRequestError:
logger.info(
'InvalidRequestError: Payment Intent [%s] for basket [%d] and order number [%s] '
'could not be canceled.',
payment_intent_id,
basket.id,
basket.order_number,
)

# Create a new Payment Intent and add to the basket.
# Pls note: idempotency_key is not used because we found that Stripe will "resuscitate" the
Expand All @@ -128,10 +143,10 @@ def cancel_and_create_new_payment_intent_for_basket(self, basket, payment_intent
)
new_payment_intent_id = new_payment_intent['id']
logger.info(
'Canceled Payment Intent [%s] and created new Payment Intent [%s] for basket [%d]',
cancelled_payment_intent['id'],
'Sucessfully created new Payment Intent [%s] for basket [%d] and order number [%s]',
new_payment_intent_id,
basket.id,
basket.order_number,
)
basket_add_payment_intent_id_attribute(basket, new_payment_intent_id)
basket_add_dynamic_payment_methods_enabled(basket, new_payment_intent)
Expand Down Expand Up @@ -188,8 +203,11 @@ def get_capture_context(self, request):
)
confirmable_statuses = ['requires_payment_method', 'requires_confirmation']
if status not in confirmable_statuses:
# Payment Intent is in a non-confirmable status, must create a new one
# Payment Intent is in a non-confirmable status, must create a new one.
# This includes canceled status, since if one is create with idempotency key for an existing
# payment with canceled status, it will not create a new Payment Intent.
stripe_response = self.cancel_and_create_new_payment_intent_for_basket(basket, payment_intent_id)

# If a Payment Intent exists in a confirmable status, it will skip the below else statement,
# aka not create another intent with the idempotency key this time around.

Expand Down

0 comments on commit 73c6110

Please sign in to comment.