In Beta version 5, page 34, there’s the following code
Payment.transaction do purchase_tickets create_payment charge @success = payment.succeeded? end
This transaction calls the
.charge method which is this:
def charge charge = StripeCharge.charge(token: stripe_token, payment: payment) payment.update!(status: charge.status, response_id: charge.id, full_response: charge.to_json) end
This code takes place within the transaction so that if the
update! call raises an exception, the database will be rolled back. However while working I had an instance where the Stripe charge was successful, but the
update! call failed. That means the database erases everything it knows about the charge, but the customer has still had money taken.
Because Stripe won’t charge the same token twice, there isn’t a particular issue with the payment being taken twice, but it does create a scenario where the app doesn’t know about a financial transaction that has been made.
I’m guessing this is a simplified version to keep the code succinct for the book (or I’m not writing my version correctly), but I’m curious about alternative ways you’d approach handling the idea that the payment came back successfully, but our code still raises errors. Presumably, we still want to make sure we’ve kept the charge information no matter what.