Update payment using stripe charge object on refund failure
The refund may fail after the charge.refunded has been triggered. Closes #13355 (grafted from 024ca55cf0ab1b9eda456dce7db62b652d20b2c5) --HG-- branch : 7.0
This commit is contained in:
@@ -626,6 +626,7 @@ class Payment(StripeCustomerMethodMixin, CheckoutMixin, metaclass=PoolMeta):
|
||||
try:
|
||||
return stripe.PaymentIntent.retrieve(
|
||||
self.stripe_payment_intent_id,
|
||||
expand=['latest_charge'],
|
||||
api_key=self.journal.stripe_account.secret_key,
|
||||
stripe_version=STRIPE_VERSION)
|
||||
except (stripe.error.RateLimitError,
|
||||
@@ -651,6 +652,35 @@ class Payment(StripeCustomerMethodMixin, CheckoutMixin, metaclass=PoolMeta):
|
||||
stripe.error.APIConnectionError) as e:
|
||||
logger.warning(str(e))
|
||||
|
||||
@classmethod
|
||||
def stripe_pull(cls, payments):
|
||||
"Update payments with Stripe charges"
|
||||
for payment in payments:
|
||||
charge = payment.stripe_charge_
|
||||
if payment_intent := payment.stripe_payment_intent:
|
||||
charge = payment_intent.latest_charge
|
||||
if charge:
|
||||
payment.stripe_update(charge)
|
||||
|
||||
def stripe_update(self, charge):
|
||||
assert (
|
||||
(charge.id == self.stripe_charge_id)
|
||||
or (charge.payment_intent.id == self.stripe_payment_intent_id))
|
||||
amount = charge.amount - charge.amount_refunded
|
||||
if (self.state not in {'succeeded', 'failed'}
|
||||
or self.stripe_amount != amount
|
||||
or (not amount and self.state != 'failed')):
|
||||
if self.state == 'succeeded':
|
||||
self.__class__.proceed([self])
|
||||
self.stripe_captured = charge.captured
|
||||
self.stripe_amount = amount
|
||||
self.save()
|
||||
if self.amount:
|
||||
if charge.status == 'succeeded' and charge.captured:
|
||||
self.__class__.succeed([self])
|
||||
else:
|
||||
self.__class__.fail([self])
|
||||
|
||||
|
||||
class Refund(Workflow, ModelSQL, ModelView):
|
||||
"Stripe Payment Refund"
|
||||
@@ -1082,8 +1112,10 @@ class Account(ModelSQL, ModelView):
|
||||
|
||||
def webhook_charge_refund_updated(self, payload):
|
||||
pool = Pool()
|
||||
Payment = pool.get('account.payment')
|
||||
Refund = pool.get('account.payment.stripe.refund')
|
||||
|
||||
payments = []
|
||||
rf = payload['object']
|
||||
refunds = Refund.search([
|
||||
('stripe_refund_id', '=', rf['id']),
|
||||
@@ -1098,7 +1130,9 @@ class Account(ModelSQL, ModelView):
|
||||
elif rf['status'] in {'failed', 'canceled'}:
|
||||
refund.stripe_error_code = rf['failure_reason']
|
||||
Refund.fail([refund])
|
||||
payments.append(refund.payment)
|
||||
refund.save()
|
||||
Payment.stripe_pull(payments)
|
||||
return bool(refunds)
|
||||
|
||||
def webhook_charge_failed(self, payload, _event='charge.failed'):
|
||||
|
||||
Reference in New Issue
Block a user