#rishi_webhooks
1 messages · Page 1 of 1 (latest)
👋 Welcome to your new thread!
⏲️ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
🔗 This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1448770751527387369
📝 Have more to share? Add more details, code, screenshots, videos, etc. below.
HI 👋
Are you storing the Subscription object only, or are you creating/updating other Stripe objects?
we listen to a ton of events! invoice, payment intent, subscription, customer, etc events are all stored in dynamo db!
We store the subscription id for a specific customer in our database, so that we can check the latest event you guys send that we have stored in DDB!
But we do not store anything else in our database other than the customer id as well
For instance, the Invoice in the Event you shared has a related Payment Intent. The Event object only contains the ID because we do not expand those properties on webhook requests. But if your DB had the Payment Intent stored and was listening for events like payment_intent.updated you could look up the PI by ID
Okay in that case, you would need to retrieve the Payment Intent using the ID to confirm the status of the Payment.
ACH payments can take up to 5 business days to complete, unfortunately.
Well the issue is that that java sdk deserializer does not have payment intent or charge
so it does not appear in the invoice object
also the new webhook does not send payment intent, it sends the charge
which is fine, but neither exist in the sdk schema
so the bigger picture problem here is that I cannot safely assume that charge will continue to be sent in the webhook, right? i would be doing custom deserialization for the charge, which is very fragile programming
Okay, yeah sorry. This was my mistake. This webhook event is on a .clover API version
apologies, the event id i linked is for an older api. i upgraded it a few hours go
So there isn't a direct relationship between Invoice and Payment Intent
So given our usecase, do you have any recommendations? Charge also works!! I see that i can check whether the charge is pending for ACH.
If you can use the Charge that is likely the most simple approach. Getting the Payment Intent from an Invoice was made more difficult as part of our support for multiple payment intents for a single Invoice
but it's the same problem haha. it was removed from invoice as well
Yeah so now you need to look up the payment intent associated with that Invoice
Our starting point is technically subscription... anywhere we could go from there to see that the customer has begun an ach transfer?
But how can we look up the payment intent without the risk of hitting rate limits? We do a lot of transaction processing, and this just adds more risk to our business. Especially because we need to get payment intents pretty often
Okay so you are looking up the Subscription from the Invoice related webhook?
No we are looking up the invoice from the subscription.
We go from
Subscription -> latest_invoice
That seems to be a deadend, however
You would need to retrieve the Invioce with the payments parameter expanded.
Hello,
Our use case is that people have overdue subscriptions, when people pay the invoice on the subscription, the subscription remains in an overdue state. We need a way to know that the subscription or invoice is pending payment because of ACH. We can listen to any stripe event and look up other objects however we cannot make an API call back to Stripe as Stripe has refused to give us a permanently TPS increase thus cannot make any API calls back to Stripe. We need a way of knowing the payment is processing on the invoice and subscription
Specfically the payments.data.payment.payment_intent https://docs.stripe.com/api/invoices/object?api-version=2025-11-17.preview&rds=1#invoice_object-payments-data-payment-payment_intent
We cannot make a call to Stripe unless we are granted extra TPS permanently
We will listen to all the events possible
You mean rate limits (RPS)?
yes
we have about 500 connected accounts less and we can't get more RPS and get dinged for every new account we sign up because of this rule
with 500 accounts, we can allocate about 0.2 RPS to each account, for every new account that number decreases. also, every call we introduce also decreases the calls available for each account
The problem is that, unless you are willing to store at least Invoices in your DB, I don't know how you get there.
You could listen to events like payment_intent.processing such as this one: evt_3SdFaiD7Vv3KEo8t1Cn3loGD
And that has the Invoice ID in the merchant_reference property
So that is how you could go from a Payment Intent with a status: "processing" to a Subscription
we have the invoice event
and the subscription event
we also store the ids
at runtime right now, we look up the subscription and customer and try to go to the payment (charge, pi, etc.), you are saying that is not possible?
Not without more API requests or unless you are willing to store the PI in your DB
As I mentioned above, the only link between the Invoice and it's Payment Intent is the long chain of properties that webhook events do not expand.
It's easier to the get the Invoice ID from the Payment Intent and work the other way.
There can be multiple. But only if you set up your integration to do that.
we were able to figure out a way by ordering the events stored and looking at the latest one and the attempt field. it is pending if attempt is > 0 unless invoice.payment_failed or succeeded occurs after it
let me know if you something glaringly wrong with this
We noticed that the attempt field is incremented when the payment is in progress and it will be the latest invoice related event until the payment processes or fails.
Hi there! Taking over for @short bluff as they had to step away, getting caught up on the thread
For the last message you mentioned that you are "ordering the events stored", can you elaborate on that? I'm asking because Stripe doesn’t guarantee the delivery of events in the order that they’re generated
https://docs.stripe.com/webhooks#event-ordering
We plan on sorting by the "created" field on stripeEvent. Is that consistent with when the event was created (not delivered)?
That could work, because the created field is the time at which the object was created, not the event
https://docs.stripe.com/api/events/object#event_object-created
perfect, thank you!
So just to be clear, our algorithm would be:
-
Get the latest_invoice from the subscription object.
-
Given a list of events on that invoice, sort by created, descending.
-
IF the most recent event is "invoice.updated" AND its attempt count is > the previous event's attempt count, then the payment is processing.
Does that make sense?
Perhaps, but doesn't that require making additional request(s)? (I may be misunderstanding here). If so then it would make more sense to make the request that @short bluff suggested
No, we have a dynamodb table that stores all the events sent to us by the stripe webhook. That's been our workaround for the low RPS we've been allocated.
Ah
I will implement this now and report back any issues I face. Thank you so much!
Sounds good, hope all goes well!
So it works for the first attempt, but not for subsequent manual payment attempts. Is there a setting to force this to increment on every payment attempt?
Hi there! I'm taking over for nobs