zinc-collective / convene

An Operating System for the Solidarity Economy
https://convene.zinc.coop
Other
57 stars 21 forks source link

The Stripe Webhook Callback should fail more gracefully #2626

Open zspencer opened 4 weeks ago

zspencer commented 4 weeks ago

Our current implementation can leave orders in strange spots if they fail in the middle.

On the one hand, this is good because we don't want to redo important steps that have already happened.

On the other, it's not great because if step B updates the order to paid and step C fails then D and E don't happen and never will.

It would probably be better to either:

  1. Put this all in a transaction, and if any part fails don't commit the transaction (not sure how to do that, since sidekiq uses redis...)
  2. Figure out a better way to ensure each piece of the order completion process can be eventually resolved if any one point fails

Thoughts?

joetho786 commented 4 weeks ago

@zspencer I would like to work on this

zspencer commented 4 weeks ago

We'd love the help!

Do you have an idea for how you'd like to go about it?

joetho786 commented 3 weeks ago

@zspencer, I was thinking to wrap the block in a transaction like you suggested and use after_commit callback to run the sidekiq jobs. This would ensure that only after the transaction succeeds the next steps would be executed.

To be specific the below lines would be placed inside the after_commit callback

Order::ReceivedMailer.notification(order).deliver_later
order.events.create(description: "Notifications to Vendor and Distributor Sent")
        Order::PlacedMailer.notification(order).deliver_later
order.events.create(description: "Notification to Buyer Sent")
SplitJob.perform_later(order: order)

We can use after_rollback callback to handle use cases when transaction gets rolled back I have referred the docs for this: https://api.rubyonrails.org/classes/ActiveRecord/Transaction.html

Do let me know if this approach would suffice or if I am missing something

Kroch4ka commented 3 weeks ago

Hello!

Can you please take a look at such a solution)

PR: https://github.com/zinc-collective/convene/pull/2634

Thanks in advance!)