#MarcusStripe
1 messages · Page 1 of 1 (latest)
👋 Thanks for reaching out
Could you please share the details of the exception you got ?
I only have the key from prod
as it is necessary to switch on prod .. required fromt he stripe dashboard
😦
which imho is very bad style
anyway.. I guess giving you the prod event id here in this public channel wont hurt either
ye?
yes?
yeah no worries, share just the eventId
evt_1Lp6C4AfQ68zM8an6w4bRCfW
Optional<StripeObject> stripeObjectOptional = event.getDataObjectDeserializer().getObject();
if (stripeObjectOptional.isEmpty()) {
if its empty, I throw an exception on my end
since I handle the events async, stripe gets an OK still
and.. gooogling this told me, the deseralizer will return an empty object if the versions dont match
so it must be related I think
so the code on my end expects version A of the event, and stripe sends version B for the event...
Give me couple of minutes while I do some checks
ok
After analyzing that event, you endpoint responded with success and with this response:
{"stripeEventId":"evt_1Lp6C4AfQ68zM8an6w4bRCfW"}
You endpoint didn't responde with an exception
You check that from your dashboard,
https://dashboard.stripe.com/events/evt_1Lp6C4AfQ68zM8an6w4bRCfW
if its empty, I throw an exception on my end
Do you have another eventId that your endpoint responded wit this exception ?
I said that above.
since I handle the events async, stripe gets an OK still
but that does not mean that I have sucessfully processed it on my end
if its empty, I throw an exception on my end
Ok, so you mean you are throwing an exception in async but your respond directly with success status ?
I'm seeing that in your dashboard you are using latest stripe api, and the webhook is sending event using the same api version so far
In the dashboard, I switch to the 2022 version. In parallel, I switched to the newest Java stripe-hava client version: 21.10.0
Are you sure you are using the latest version ?
If so, probably you should share more details about your code
<dependency>
<groupId>com.stripe</groupId>
<artifactId>stripe-java</artifactId>
<version>21.10.0</version>
</dependency>
that's the latest java client version, AFAIK
yes?
and that was part of my question.
Other than using this dependency.. anything else I would have to do on my end?
Official search by the maintainers of Maven Central Repository
yes it is in fact
You should share more details on your code, and the difference between async and sync treatment in order to have more details
public StripeEvent toEvent(String body) {
Event event = toRawStripeEvent(body);
StripeObject stripeObject = getStripeObject(event);
StripeEventType eventType = StripeEventTypeMapper.map(event);
return StripeEvent.of(event.getId(), stripeObject, eventType);
}
private Event toRawStripeEvent(String body) {
try {
return ApiResource.GSON.fromJson(body, Event.class);
} catch (JsonSyntaxException e) {
throw new BadRequestException(e.getMessage(), e);
}
}
private StripeObject getStripeObject(Event event) {
Optional<StripeObject> stripeObjectOptional = event.getDataObjectDeserializer().getObject();
if (stripeObjectOptional.isEmpty()) {
throw new StripeExternalException("invalid invocation from stripe"); //TODO improve error message with input data?
}
return stripeObjectOptional.get();
}
so incoming is the string body as send from stripe
and with GSON, the string is converted to the expected type object
then, the object inside the event is retrieved
As of stripe-java v8, the library is pinned to a specific API version. To avoid incorrectly deserializing objects (which could result in missing fields or even crashes), by default the library will not deserialize events that are formatted with a different API version than the one it expects.
declaration: package: com.stripe.model, class: EventDataObjectDeserializer
hmm, don't do this :
ApiResource.GSON.fromJson(
why aren't you just using the constuctEvent function?
and yes, each version of the library is pinned to a specific API version and can only deserialise a webhook event that is sent in that specific version.
I'm a little lost unfortunately, could you summarise in one sentence the exact problem you're running into? Any exact exception stack traces or related event IDs evt_xxx would help!
constructEvent function... where?
ah sorry, I was thinking of a different language, that's not in stripe-java, my bad.
Other than that.. I did find an issue on my end.. not sure if that is related.. I guess not.. but still -
paymentMethodCollection.autoPagingIterable(Map.of(), requestOptions))
let's ignore that, we're talking about webhooks right?
it seems the api has changed to require the request options - api key for auto paging
we are talking about the entire stripe api.. switching the version means switching both
but the webhooks is what directly shows me the above mentioned error
I mean yes, if you updated the version of stripe-java, we might have breaking changes in major versions of the library that require changes. Changing stripe-java version can also changes the API version you use yes
above mentioned error
which one? can you post the stack trace and evt_xxx ID related to it?
trying to take this one issue at a time.
breaking changes, yes.. I can fix them, if I see them... as I am doing now above with the autoPagingIterable...
but the other thing mentioned is just that the api tells me it ignored the message send
just that the api tells me it ignored the message send
can you share the exact error/context/what you're referring to?
I reieved the event on prod:
evt_1Lp6C4AfQ68zM8an6w4bRCfW
and I am first acepting all events
and then processing async on my end
and doing this.. I got that version issue
ok give me a minute to look at that event.
Optional<StripeObject> stripeObjectOptional = event.getDataObjectDeserializer().getObject();
if (stripeObjectOptional.isEmpty()) {
if its empty, I throw an exception on my end
so that means, stripe send something in an api version that I did not expect
so we're talking about the code that is running on your server at https://backend.*****a.com/webhook/stripe correct? That's where the event was sent.
yes
I receive a string
and then I am trying to convert it to an objet
and here, the stripe client refuses to do so
because, as it seems, the versions dont match
thats what it is supposed to do
yep, I know how it works
so what version of stripe-java is running on the server hosting that URL that I posted above?
<dependency>
<groupId>com.stripe</groupId>
<artifactId>stripe-java</artifactId>
<version>21.10.0</version>
</dependency>
are you 100% sure that's what is actually being used at runtime(i.e. did the gradle file sync and the server update etc?) You can log System.out.println(Stripe.VERSION); in code to check at runtime.
that version of the library should be able to deserialise that event, they use matching API versions.
I am 99.999 sure and could of course log it out also
so I need to rule some things out
but I currently assume something else -
could it be, that in the minute of switching
there is one last thing that is send with the old version?
or my server still responding with the old
it could be yes, we send you events in both versions I think when you're in the 72 hour rollback period after a version upgrade, but that is not the case with that event at least. That event you posted, we sent to you only once, at 2022-10-04 08:09:36 UTC, using the 2022-08-01 API version, and you responded with a 200 success message.
hm... and.. I am just thinking.. I keep stored ALL events of all time send from stripe for later potential replay. Does that mean that, an event send with an old api version... I could not anymore process with the new api? How to fix that? Delete all old events? Or somewhere store the api version used and then somehow use both client versions in parallel??? that could be difficult, if not even impossible 😦
aaah
I think I found it
pe": "account.updated"
}
that is a CONNECT event, right?
well on prod I have not even yet implemented the new endpoint for that
so it would probably send this to my normal payments endpoint
and this one has a different secret key
so it would reject that in any case
hmm that's what I posted the exact URL and asked you to confirm the code you have running on that endpoint uses a certain version of stripe-java
but yes account.updated is an event sent to your Connect endpoint, indeed
and on prod, I did accidentially add the account_updated event to the normal paymenty api webhook
but actually, I would still asume it should work / or not fail with the above error??
if you have an event JSON body using e.g. some 2019 API version, you can't reliably deserialise that in the current release of stripe-java yes. You can best-effort it with the 'unsafe' option you probably saw in the deserialiser. But usually you just retrieve the actual object the events relates to from the API and get its current state. I don't know your use case for keeping historical events and replaying them.
if the version is right it might be something else
for example I note that event contains the string "city": "Grünwald", maybe your server didn't decode the string properly? (we use UTF-8, you should treat the incoming POST body as that).
I don't know your use case for keeping hisstorical events and replaying them
well that's the idea of an event processor. keeping all data, so that, if something goes wrong, you are able to reply all from start to finish. But now, with this... it seems here this approach will fail. So either I guess I have to delete old events, or find a way to also process old api version events, if needed
we use UTF-8 for everyhing too.. and this worked nicely also before I switched the api version
then you must not be running the version of stripe-java you think you are
version 21.x of stripe-java will deserialise events sent in API version 2022-08-01 correctly.
if that's not happening then either you are not using that version of stripe-java, or the event being received by your code is not using that version. Either way, adding some extensive logs and sharing some IDs and stack traces of specific failures would be the next step!
is there a way to reply an event sent on the 8th of august? It also failed, and it was an invoice paid event, not the wrong account event from before. Back then, I had already tried once to switch and then at the time rolled back because I had no time to investigate it further. It seems that in this case, the event api version was indeed not in sync with the java stripe client version.. but that would mean, if I resend it now... it should work?
evt_1LUX2DAfQ68zM8anNXwa4C1D
resending an event doesn't re-generate the contents of the data object so that won't really work I think. The way it works is when we generate an event on your account, we send it to webhooks you have set up to listen to that event type. At that point we can re-render the contents of the event in multiple API versions so that each webhook gets the version it wants.
Retrieving the event later or re-sending it won't re-generate the body. That's touched on obliquely in https://stripe.com/docs/upgrades#how-can-i-upgrade-my-api
in any case that event is over 30 days old so it's deleted and can't be resent
so how could I send another invoice paid event... or any kind of other event that wouldnt hurt on prod, to test that it might be working now?
try listening to customer.created and call the API to create a dummy Customer object
if you're testing this, add in a System.out.println(Stripe.VERSION); to toRawStripeEvent and also log the exact raw body string so we have something to look at/compare
ok
ok, to speed this up.. I just bought my smallest possible subscription and refunded it directly aftwards.. this is going to cost me something like less then 1 USD I guess after the refund.
evt_1Lp9MeAfQ68zM8anJCGovFGY
It looks like it was processed sucessfully with the 2022 api, so I assume that actually all is fine now
👍
can you please confirm it was the 2022 api version used / send?
yes it, was (it has "api_version": "2022-08-01", in the JSON)