Error posting to /client-tokens from drop-in component

I’m testing using the drop-in components. Per the instructions, I created an endpoint /generate_client_token that proxies requests to dwolla’s /client-tokens endpoint. I then dropped the <dwolla-business-vcr /> tag on the page. As expected it made a POST to /generate_client_token with body {"action":"customer.create"} which was proxied to dwolla’s endpoint and received a successful response. The page then showed me the bvcr creation tool and I went through the wizard. At the end of the wizard the component attempted to make another request, this time with body {"action":"customer.read","links":{"customer":{"href":"https://api-sandbox.dwolla.com/customers/1e4ecca9-5185-46e4-8d18-0a116aff6969"}}} and the response from the API was not successful. Instead, the response received from the API was { "code": "BadRequest", "message": "The request body contains bad syntax or is incomplete." }.

What could be going wrong here? It seems to me like Dwolla’s own component should never generate a request that the API rejects…

Hi @noah – would you be able to share any/all relevant code from you project for generating client-tokens and your configuration object? Also, which version of dwolla-web.js are you using?

I am seeing this same request body in our logs. I did notice the "links" object which should be "_links". That’s what seems to be causing the BadRequest error. I’m not able to recreate in Sandbox using dwolla-web.js v2.1.9, which makes me think it might be a version issue :thinking: .

Happy to share code, it’s very straightforward…

The dwolla-web script tag’s src is set to //cdn.dwolla.com/v2.1.9/dwolla-web.js so unless there’s a very funny filing system I must be using v2.1.9.

After that script tag i have another script that runs dwolla.configure:

dwolla.configure({
  environment: "sandbox",
  success: (res: any) => Promise.resolve(),
  error: (err: any) => Promise.resolve(),
  token: (req: any) => api.GenerateClientToken(req)
});

The api.GenerateClientToken function is defined in Typescript as:

public async GenerateClientToken (body: Record<string, any>) {
  const url = `${API_BASE_URI}/dwolla/generate_client_token`;
  const headers = {
    Accept: "application/json",
    "Content-Type": "application/json",
    "X-Requested-With": "Dwolla-Drop-Ins-Library",
  };
  const response = await fetch(url, { method: 'POST', body: JSON.stringify(body), headers });
  const json = await response.json();
  return json;
}

Which obviously just forwards the body to my API. The api endpoint couldn’t get much simpler (in Python with self._app_token being set to dwollav2.Client(...).Auth.client() ):

def generate_client_token(self, body):
  response = self._app_token.post('/client-tokens', body)
  return response.body

That’s about it… It’s super simple which is why I’m so flummoxed…

Thanks for sharing your code, @noah! It looks like the body just needs to be reconstructed before being sent to the API as follows:

public async GenerateClientToken (body: Record<string, any>) {
  const url = `${API_BASE_URI}/dwolla/generate_client_token`;
  const headers = {
    Accept: "application/json",
    "Content-Type": "application/json",
    "X-Requested-With": "Dwolla-Drop-Ins-Library",
  };
  const req = {
    action: body.action,
  };
  if (body.links) {
    req._links = body.links;
  }
  const response = await fetch(url, { method: 'POST', body: JSON.stringify(req), headers });
  const json = await response.json();
  return json;
}

Please try the above and let me know if you if that works or if you run into any errors!

I could do that. But it seems very odd to me that the Dwolla drop-in component wouldn’t generate the proper request for the Dwolla api endpoint…

This is definitely a bug with the request body that Dwolla is providing when using drop-ins (specifically I’m seeing the exact same bug that Noah is pointing out when using dwolla-business-vcr in sandbox). There shouldn’t be a need to reformat a request body that is originating from Dwolla itself.

Thanks @Ben_Davidson and @noah!

Agreed! We have logged this as a feedback item and will be working on an update so that the library returns and object that does not need to be reformatted before passing on to the API.

This topic was automatically closed after 365 days. New replies are no longer allowed.