Handle payment_intent.succeeded event#222
Conversation
rainerdema
left a comment
There was a problem hiding this comment.
Looks great! Just a small consideration 👀
| def complete_payment(event) | ||
| payment_intent_id = event.data.object.id | ||
| payment = Spree::Payment.find_by!(response_code: payment_intent_id) | ||
| payment.complete! unless payment.completed? |
There was a problem hiding this comment.
After the event has been processed, how about saving a SolidusStripe::LogEntries.payment_log related to the event on the payment?
By doing so, it would enable the admin side to display a timeline of events related to the payment, allowing for a clearer understanding of why, in this case, the payment is marked as completed 🤔 WDYT?
There was a problem hiding this comment.
Makes total sense. I just added that. Thanks for your suggestion 👍
kennyadsl
left a comment
There was a problem hiding this comment.
Nice and simple. I left a question about a method name that I don't fully understand, but it's most likely me.
| @stripe_object ||= Stripe::Event.construct_from(data) | ||
| end | ||
|
|
||
| def solidus_stripe_object |
There was a problem hiding this comment.
Can you please help me understand why this method is called solidus_stripe_object and returns a Webhook Event?
There was a problem hiding this comment.
The EventWithContext class can return a Stripe event in different representations:
#json: A JSON string representation#signature_header: How it looks signed in the request header#stripe_object: As aStripe::Eventobject.#solidus_stripe_object: As aSolidusStripe::Webhook::Eventobject.
I know it's a bit cryptic, but I can't find better candidates. We can't call the #stripe_object method #stripe_event, because all those methods return representations of a Stripe event. Once we have that method, the most logical candidate for the new addition is #solidus_stripe_object.
Happy to change it if we find a better solution!!
e49258b to
c897dd6
Compare
A `payment_intent.successful` event is published [1] when capturing a payment intent from the Stripe dashboard. At that point, we need to update the associated Solidus payment to be marked as completed. However, the webhook could also be received after capturing the payment from the Solidus admin interface, as it updates through Stripe's API. Therefore, we need to do nothing if the payment is already completed. The unit tests on the subscriber cover the handler's behavior, while at the integration layer, we're making sure that it's actually reached when the "payment_intent.succeeded" event is published. Besides, this PR has been manually tested for different checkout flows. Closes #179 [1] - https://stripe.com/docs/payments/payment-intents/verifying-status#webhooks
c897dd6 to
2a50f80
Compare
…t creation On #222, we're handling the `payment_intent.succeeded` webhook by fetching the associated payment via the `Spree::Payment#response_code` field. However, the response code wasn't filled until after the authorization was completed on Stripe. Once we implement auto-capture (see #178), that could be an issue, as we could receive the webhook before the column update. We're now filling `response_code` just after the payment intent creation, which always happens before confirmation on Stripe (see #231). Closes #238
…t creation On #222, we're handling the `payment_intent.succeeded` webhook by fetching the associated payment via the `Spree::Payment#response_code` field. However, the response code wasn't filled until after the authorization was completed on Stripe. Once we implement auto-capture (see #178), that could be an issue, as we could receive the webhook before the column update. We're now filling `response_code` just after the payment intent creation, which always happens before confirmation on Stripe (see #231). Closes #238
…t creation On #222, we're handling the `payment_intent.succeeded` webhook by fetching the associated payment via the `Spree::Payment#response_code` field. However, the response code wasn't filled until after the authorization was completed on Stripe. Once we implement auto-capture (see #178), that could be an issue, as we could receive the webhook before the column update. We're now filling `response_code` just after the payment intent creation, which always happens before confirmation on Stripe (see #231). Closes #238
Summary
A
payment_intent.successfulevent is published when capturing a payment intent from the Stripe dashboard. At that point, we need to update the associated Solidus payment to be marked as completed.However, the webhook could also be received after capturing the payment from the Solidus admin interface, as it updates through Stripe's API. Therefore, we need to do nothing if the payment is already completed.
The unit tests on the subscriber cover the handler's behavior, while at the integration layer, we're making sure that it's actually reached when the "payment_intent.succeeded" event is published. Besides, this PR has been manually tested for different checkout flows.
Closes #179
Checklist
Check out our PR guidelines for more details.
The following are mandatory for all PRs:
The following are not always needed: