plaid / plaid-java

Java bindings for Plaid
https://plaid.com/docs
MIT License
131 stars 119 forks source link

Cannot deserialize value of type `com.plaid.client.model.WebhookEnvironmentValues` from String \"sandbox\": not one of the values accepted for Enum class: [PRODUCTION, ENUM_UNKNOWN, SANDBOX] #424

Closed jan-domozilov closed 4 months ago

jan-domozilov commented 4 months ago

Hi!

I am integrating with Plaid in sandbox envrionment.

I am using Hosted Link. I succesfully generate Hosted Link url, go through it and Plaid sends me SESSION_FINISHED event to the target webhook on my server.

On my server I have

@PostMapping("/plaid/events/session-finished") public void plaidEventsHandler(@RequestBody LinkSessionFinishedWebhook event) { // some business logic here }

Json of an event I get:

{ "environment": "sandbox", "link_session_id": "b720e907-d5c6-4fb2-9643-96b8695eb5ed", "link_token": "link-sandbox-31a8b766-e570-41ff-9e82-dea3c6d848db", "public_token": "public-sandbox-372b7759-1a16-4fa0-b37f-bb3213bd6972", "webhook_code": "ITEM_ADD_RESULT", "webhook_type": "LINK" }

Then Spring tries to deserialize above Json into LinkSessionFinishedWebhook. Here I get an error:

"JSON parse error: Cannot deserialize value of typecom.plaid.client.model.WebhookEnvironmentValuesfrom String \"sandbox\": not one of the values accepted for Enum class: [PRODUCTION, ENUM_UNKNOWN, SANDBOX]"

I checked couple of times - LinkSessionFinishedWebhook looks like the only suitable wrapper for SESSION_FINISHED event.

Am I doing something wrong?

phoenixy1 commented 4 months ago

You can see the definition of com.plaid.client.model.WebhookEnvironmentValues here https://github.com/plaid/plaid-java/blob/c8b975a3e708415b5f5f5bb04ecc97f6f7001047/src/main/java/com/plaid/client/model/WebhookEnvironmentValues.java#L30 and "sandbox" is pretty clearly an accepted value, so I don't think this is an issue with the client library.

I am not an expert on Java, but I tried asking ChatGPT and it suggested that there may be an issue with the way you have Spring configured to handle webhooks:

  1. Ensure Proper Registration of Custom JSON Adapter Make sure that the custom JSON adapter (WebhookEnvironmentValues.Adapter) is registered correctly with the Gson instance used by Spring. You can configure a GsonHttpMessageConverter to use your custom Gson instance with the appropriate type adapter.

  2. Configure Gson in Spring You need to configure Spring to use Gson with the custom type adapter for WebhookEnvironmentValues. This can be done in a configuration class:

java

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.GsonHttpMessageConverter;

@Configuration
public class GsonConfig {

    @Bean
    public Gson gson() {
        return new GsonBuilder()
                .registerTypeAdapter(WebhookEnvironmentValues.class, new WebhookEnvironmentValues.Adapter())
                .create();
    }

    @Bean
    public GsonHttpMessageConverter gsonHttpMessageConverter(Gson gson) {
        GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
        converter.setGson(gson);
        return converter;
    }
}
jan-domozilov commented 4 months ago

Okay, adding custom adapter WebhookEnvironmentValues.Adapter helped. Thanks!

But ... really? Custom adapter for a simple Enum? Well ...