#Craig

1 messages Β· Page 1 of 1 (latest)

foggy kilnBOT
naive heron
#

Hi there!

#

To run code when a payment is successful, we strongly recommend using webhook event. Because if you are using your frontend, then it's possible for the customer to leave your website/app after making the payment but before your code is executed.

#

This is explained here: https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements#web-post-payment

Listen for these events rather than waiting on a callback from the client. On the client, the customer could close the browser window or quit the app before the callback executes, and malicious clients could manipulate the response. Setting up your integration to listen for asynchronous events is what enables you to accept different types of payment methods with a single integration.

ionic laurel
#

Makes sense. I think we could use the webhook with either solution though.
Stripe webhook -> Salesforce, or Stripe webhook -> Custom API

#

If we use the webhook for solution #2, are there any other reasons this wouldn't work, or any reasons #1 (or some other solution) would be better?

hasty radish
#

Hi πŸ‘‹ I'm jumping in as my teammate needs to step away. If you use webhook events to drive the psot-payment process, then the two scenarios look pretty similar and I think either would work. If you go the custom-API route, then that would also (likely) give you greater control over the logic used to handle the data so you could code around concerns like race conditions.

ionic laurel
#

Thanks @hasty radish . One other idea might be to tell Salesforce to fetch the Stripe details once the records are written, that would solve the race condition. πŸ€” Would there be a way to target the correct Stripe record?

#

i.e. customer pays via custom UI -> custom API pushes records to Salesforce -> Salesforce fetches Stripe data. Not sure how that step 3 would work, it'd need to get a uuid/guid back early on somehow

hasty radish
#

Yeah, that would work. Our Event objects will contain the ID of the object that they're related to, which is indicated by the prefix of the event type. For example, invoice.payment_succeeded events will contain the associated Invoice object inside of the event, including its ID which you could use to retrieve a fresh copy of the object from us.
https://stripe.com/docs/api/events/object#event_object-data-object

Only downside that readily comes to mind with the approach is the additional time it takes for that retrieval request, but if that is happening behind the scenes then it likely isn't a major concern.

ionic laurel
#

I see your point about the delay, and it would probably need the ability to retry too. Would the custom API still have to wait on a webhook before pushing the data to SF? Or can we get the Stripe object ID right away and check on its status later?

#

Or β€” can the Stripe webhook retry?

hasty radish
#

You need someway for the API to get the ID of the associated object, so I don't think that would be able to execute prior a webhook event unless you had your frontend make the request (but that circles back to the concern of customers dropping off the page before your success scripts can finish running).

Our webhook events do have retry logic, but it's intended for use with handling scenarios where events weren't successfully received, rather than ones where an event couldn't be processed.
https://stripe.com/docs/webhooks/best-practices#retry-logic

Implement these best practices when using webhooks.

ionic laurel
#

True. That customer abandoning situation is really risky. Because of that, it seems like this flow is pretty much necessary:

Customer pays via Stripe -> customer abandons & never completes, so our API doesn't know the transaction is done -> Stripe webhook hits Custom API -> Custom API uses that Stripe event as an indication to complete the transaction & send the data to Salesforce

Does that sound right?

#

Your help talking this through is unbelievable btw, thank you again

hasty radish
#

Always happy to help, I know talking through these types of scenarios is the fastest way for me to fully grasp them, so I'm more than happy to do so for others. πŸ˜„

#

Yeah, that sounds right.

If you want to fully optimize for speed then you could implement both approaches, but that would add a layer of complexity to your logic.

ionic laurel
#

Right, makes sense. If there are more roadblocks, is best practice to reply in this thread?

hasty radish
#

It depends on when that is, I'll likely be closing this thread near the end of my shift. If there are any questions before, then you can put them here. If the thread gets closed though, then you can raise any additional questions in the #dev-help channel and one of our team members will lend a hand.

ionic laurel
#

One more β€”Β any reason Apple Pay wouldn't be supported in the flow we're talking about?

hasty radish
#

Nope, none that comes to mind.