#MarcusStripe

1 messages · Page 1 of 1 (latest)

white wingBOT
strong berry
#

👋 Thanks for reaching out
Could you please share the details of the exception you got ?

misty lily
#

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?

strong berry
#

yeah no worries, share just the eventId

misty lily
#

evt_1Lp6C4AfQ68zM8an6w4bRCfW

strong berry
#

and what stacktrace are you getting from the exception in your Java

#

?

misty lily
#

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...

strong berry
#

Give me couple of minutes while I do some checks

misty lily
#

ok

strong berry
#

After analyzing that event, you endpoint responded with success and with this response:

{"stripeEventId":"evt_1Lp6C4AfQ68zM8an6w4bRCfW"}

#

You endpoint didn't responde with an exception

#

if its empty, I throw an exception on my end
Do you have another eventId that your endpoint responded wit this exception ?

misty lily
#

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

strong berry
#

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

misty lily
#

<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?

strong berry
#

You should share more details on your code, and the difference between async and sync treatment in order to have more details

misty lily
#

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.

covert siren
#

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!

misty lily
#

constructEvent function... where?

covert siren
#

ah sorry, I was thinking of a different language, that's not in stripe-java, my bad.

misty lily
#

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))

covert siren
#

let's ignore that, we're talking about webhooks right?

misty lily
#

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

covert siren
#

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.

misty lily
#

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

covert siren
#

just that the api tells me it ignored the message send
can you share the exact error/context/what you're referring to?

misty lily
#

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

covert siren
#

ok give me a minute to look at that event.

misty lily
#

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

covert siren
misty lily
#

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

covert siren
#

yep, I know how it works

#

so what version of stripe-java is running on the server hosting that URL that I posted above?

misty lily
#

<dependency>
<groupId>com.stripe</groupId>
<artifactId>stripe-java</artifactId>
<version>21.10.0</version>
</dependency>

covert siren
#

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.

misty lily
#

I am 99.999 sure and could of course log it out also

covert siren
#

so I need to rule some things out

misty lily
#

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

covert siren
#

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.

misty lily
#

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

covert siren
#

but yes account.updated is an event sent to your Connect endpoint, indeed

misty lily
#

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??

covert siren
# misty lily hm... and.. I am just thinking.. I keep stored ALL events of all time send from ...

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.

covert siren
#

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).

misty lily
#

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

covert siren
#

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!

misty lily
#

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

covert siren
#

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

misty lily
#

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?

covert siren
#

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

misty lily
#

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

covert siren
#

👍

misty lily
#

can you please confirm it was the 2022 api version used / send?

covert siren
#

yes it, was (it has "api_version": "2022-08-01", in the JSON)

misty lily
#

Thanks!

#

ok