#Bo0013246

1 messages · Page 1 of 1 (latest)

lime shuttleBOT
glossy obsidian
#

Hello! What are you trying to build exactly? Why do you want to link them together?

arctic plaza
#

I have stripe webhooks enabled, and events can sometimes come out of order

#

so if they do come out of order, I want to be able to get the previous missing events

#

@glossy obsidian

glossy obsidian
#

Ah, gotcha.

#

Yeah, webhook order can't be guaranteed because of the nature of the Internet.

#

What a lot of people do is, when they get an Event, they fetch the object from the API to get it's current state and ignore what's in the Event payload.

#

Would that work for your use case?

arctic plaza
#

I dont think that will work for me

#

cuz I will need the .created event if I have .succeeded event

#

so I need to find a way to query the .created event

glossy obsidian
#

Why do you need the .created Event?

arctic plaza
#

we need to set some internal state with that event object in our db

glossy obsidian
#

Or you could put all the Events you receive in a queue and process the queue after a short delay, and always process the .created Events first.

arctic plaza
#

.created Events first.
I dont think that will work as there can be network outtage we may not get created event at all

#

list event is going to query too much, as the time interval between .created and .succeeded can vary and if we filter, we can miss the window

glossy obsidian
#

I'm still not sure I understand why you need the .created Event specifically?

arctic plaza
#

ok let me give you an example

#

so lets say we call Stripe to process a payment

#

we call Stripe.payment_intent.create. we update our internal payment db object as payment.submitted.

when we get payment_intent.created event, we update our db object as payment.created.

and when we get payment_intent.succeeded, we update payment object as payment.succeeded

#

each of those state has meanings for our team and other teams

glossy obsidian
#

Okay, so if you get a .succeeded Event you can update to succeeded in your DB, and then if you get .created for the same Payment Intent after that you can tell it's already marked as succeeded and you can just ignore the .created Event, right?

#

In other words, if you get something else prior to .created it's safe to assume the Payment Intent is already past the created state, so you can skip over that and record the current state.

arctic plaza
#

it works in this case for payment_intent

#

but what if we have refunds?

say I have a payment of 100 dollars, customer refund 100, cancel the refund, and refund another 100.

I missed the cancel the refund event

#

then I will have -100 payment in my system

#

so I have to have a ways to link the events

glossy obsidian
#

There's no way to cancel a Refund, so not sure what you mean?

#

I mean, there is if it's in requires_action state... is that what you're talking about?

arctic plaza
#

requires_action what does that mean, can you elaborate?

glossy obsidian
#

Well, hang on. I don't want to go down a Refund edge case rabbit hole and get too far from the main issue. Is the refund example you gave an actual situaiton you've encountered and are trying to address, or are you trying to anticipate issues that haven't happened?

arctic plaza
#

also two more questions

  1. I did a webhook local test and got ': False, 'pending_webhooks': 3, 'request': {'id': 'req_cToPDaPoDElc5g', 'idempotency_key': '0537eca5-a064-4515-80ef-6de7e0596488'}, 'type': 'charge.succeeded'}
  2. what does pending_webhooks mean? and what is 'request': {'id': ?
arctic plaza
glossy obsidian
lime shuttleBOT
glossy obsidian
#

It tells you if we're still trying to deliver the Event to a Webhook Endpoint.

arctic plaza
#

maybe ata.previous_attributes?

glossy obsidian
#

No.

#

Really, though, I recommend you stop thinking about linking Events together and think more about using the current state of the object as the canonical reference.

arctic plaza
#

I cannot do that as I mentioned that my team cannot "infer" events if certain events are missing

glossy obsidian
#

Why do you need every Event though? If you get an .updated Event before .created, for example, it's clear the object has been created, so why do you need the actual .created Event? If you can detail a specific need or use case I can probably provide guidance, but at an abstract level I don't know what to advise.

arctic plaza
#

we needed it for legal and accounting purposes

#

every event needs to be present in order to update our db models

glossy obsidian
#

Okay, so list them using the API. That way you can guarantee you're getting all of them.

arctic plaza
#

ok, I dont think that will work when you have billions of events from many customers

#

the filtering criteria becomes too difficult

glossy obsidian
#

Can you structure things so your system can store the audit trail even when Events arrive out of order?

#

Like can you add the created entry after the updated entry already exists?

arctic plaza
#

like I was saying earlier, if there is a network outage, we dont get the created event at all, I will be waiting forever

stoic egret
#

That what delivery retries are for -- if your network is out we'll retry until you acknowledge it

#

So if your system is sensitive to order of ingestion, you may need to buffer/proxy the event deliveries from Stripe

#

(in some kind of holding queue eetc)

lime shuttleBOT
arctic plaza
#

one more question, how do I use the created.gt flag?

safe remnant
#

I think whatever you put after --created is getting passed in a as a value. The request log shows a value of "--help" for "created"

#

Looking in to the CLI formatting for this

#

Can you try --created[gt] 1686098903

arctic plaza
#
{
  "object": "list",
  "data": [],
  "has_more": false,
  "url": "/v1/events"
}%                                                                                                                                                          ➜  stripe-sample-code stripe events list --type=payment_intent.created --created.gt=1688672699
unknown flag: --created.gt
➜  stripe-sample-code 

#

➜ stripe-sample-code stripe events list --type=payment_intent.created --created[gt]=1688672699
zsh: no matches found: --created[gt]=1688672699

#

@safe remnant

safe remnant
#

It looks like the syntax is stripe events list events -d "created[gt]=1688672699"

#

No need to tag, I'm bouncing between a few threads though so it may take a minute sometimes

arctic plaza
#

ty it worked

#

can you tell me how to use the -d flag?

#

I cannot find much documentations on it

safe remnant
arctic plaza
#

can I use the -d flag to do this?

I have
event
{
id:xxx
data{
something
}
}

can I do -d "event[data[something]]] = xxx?

safe remnant
#

I think the syntax would be event[data][something] but yes you should be able to double next

arctic plaza
#

{
"id":"evt_3NQtzoIKbnQP38U104emMdKA",
"object":"event",
"api_version":"2020-08-27",
"created":1688656889,
"data":{
"object":{
"id":"pi_3NQtzoIKbnQP38U10sknlet0",
.......

so I have something like this

how should I write the command? stripe events list

#

if I want to get pi_3NQtzoIKbnQP38U10sknlet0

#

stripe events list --type=payment_intent.created -d "created[gte]=1688656888" -d "created[lte]=1688656888"

This worked, but idk how to get the id

safe remnant
#

That depends on the command line that you are using. You may want to search "{your command line} json utility" to figure out how to do it for your specific environment

#

I know bash has jq which I used the other day for something similar

arctic plaza
#

sorry I dont mean to get the json

#

so I have a stripe event of type payment intent and has ID pi_3NQtzoIKbnQP38U10sknlet0

I want to be able to retrieve it with -d flag

safe remnant
#

Ah, there isn't a parameter for that unfortunately. I think there is a dashboard only one but it isn't publicly exposed at the moment

#

I can file a feedback request for this.