Reputation: 191
I've been using the stripe_event
gem for webhooks from stripe and today I found out that the webhooks seem to be not incoming in the right order. I'm storing a local copy of the charges made on stripe and I have the following setup
StripeEvent.configure do |events|
events.subscribe 'payment_intent.created', CreateChargeRecord.new
events.subscribe 'payment_intent.processing', UpdateChargeRecord.new
events.subscribe 'payment_intent.succeeded', UpdateChargeRecord.new
end
Looking at the stripe dashboard the event payment_intent.created
is always done before payment_intent.processing
. Now I'm creating the charge record as follows
class CreateChargeRecord
def call(event)
charge_object = event.data.object
Charge.create(
user: User.find_by(stripe_id: charge_object.customer),
receiver_id: User.find_by(merchant_id: charge_object.transfer_data.destination).id,
amount: charge_object.amount / 100,
currency: 'eur',
application_fee_amount: charge_object.application_fee_amount / 100,
status: charge_object.status,
stripe_id: charge_object.id
)
end
end
and updating as follows
class UpdateChargeRecord
def call(event)
charge_object = event.data.object
charge = Charge.find_by(stripe_id: charge_object.id)
charge.update!(status: charge_object.status)
end
end
the problem is that from the cli it seems that the webhook payment_intent.processing
is being recieved before payment_intent.created
2021-10-10 22:08:50 --> payment_intent.processing
2021-10-10 22:08:51 --> payment_intent.created
2021-10-10 22:08:51 <-- [200] POST http://localhost:3000/webhooks/
2021-10-10 22:08:51 <-- [500] POST http://localhost:3000/webhooks/
which results in an error NoMethodError (undefined method
update!' for nil:NilClass):` since I'm trying to update a record that doesn't exists yet.
Is there anything I can do here to prevent this since it seems that this is not a bug according to stripe?
Upvotes: 2
Views: 1427
Reputation: 7419
This is expected and documented -- events might be delivered out-of-order from the order in which they are generated.
To account for this, your application should be aware that this is possible and, for example, instead of using the payload you retrieve the latest object state directly from the API when the event is received.
Upvotes: 2