Git Product home page Git Product logo

dwolla-v2-ruby's Issues

Converting camel/kebab case to snake case and vice versa

I've been working with the library since beginning of last week to learn how to implement our system at work with Dwolla to cover all our cases. Everything has gone great but one of the issues we have is the inconsistency in casing which would leads us to write code that utilizes the Dwolla library with mixed case, both camel (response properties) and kebab (for _links values). As is standard for Ruby projects we write code in snake case. Would the team be interested in accepting changes so requests can be provided in snake case and converted to camel case and responses the other way around? I've dealt with this before successfully with another service. Has this topic ever come up internally? Would their be any desire to have specific response objects?

I spent time on this today and came up with changes that would work with hashie, just something quick to see if it was even doable. I looked into using Dash and their property transformation extension but it requires that you define all available properties so that was a no go. The other issue is because of the mixed case and how method_missing works, I couldn't get around by just changing the SuperHash class but also had to update the Response class too. I wanted to see if I could get this to work so at least responses could use snake_case but still support the original casing too. This is what I came up with:

For the Response class:

def method_missing method, *args, &block
  if method != :_links && method != :_embedded
    method = method.to_s.gsub(/(?:_+)([a-z])/) { $1.upcase }.to_sym
  end
  # ...
end

For the SuperHash class:

def method_missing method
  dashed_method = method.to_s.gsub(/_/, "-").to_sym

  if key? dashed_method
    self[dashed_method]
  elsif key? method
    self[method]
  else
    super method
  end
end

With these changes I can for example do the following:

customer = app_token.get(customer_url)
customer.first_name
# => "Javier"
customer._links.self.resource_type
# => "customer"

Would you open to any enhancements to the library in some way to handle this? I'm happy to do the work. I'm wondering if you'd be willing to have a discussion around it and especially if its already come up amongst your team. Thanks.

Deprecation warning with Faraday v1

Since we use both Dwolla and Plaid together, Plaid recently has made major updates and with updating to Plaid v14, it requires Faraday v1 at a minimum. The Dwolla library seems to play well with Faraday v1 but can cause many reported deprecation warnings due to this line:

f.authorization :Bearer, access_token if access_token

WARNING: Faraday::Connection#authorization is deprecated; it will be removed in version 2.0.
While initializing your connection, use #request(:authorization, ...) instead.
See https://lostisland.github.io/faraday/middleware/authentication for more usage info.

I believe the affected line should be changed to the following and that should do it:

        f.request :authorization, 'Bearer', access_token if access_token

It seems this should be supported as far back as Faraday v0.15 so it should be safe for a minor or patch release.

error handling in rails

Hi, Dwolla does not permit creating multiple customers with the same email or multiple accounts with the same routing number. However, in rails, dwolla-v2-ruby returns the error below, which does not state what the cause of the error is.
screen shot 2017-05-17 at 3 22 08 pm

Odd number of arguments for hash

So I ran into an issue this morning trying to make a request to create a business customer. I thought that my hash was malformed, and passing in the wrong number of arguments, and finally threw a binding.pry in the source of the error (the hashie gem) and found the following:

` From: /Users/andrewsoep/.rvm/gems/ruby-2.4.1/gems/hashie-
3.5.7/lib/hashie/extensions/indifferent_access.rb @ line 79
Hashie::Extensions::IndifferentAccess#convert!:

77: def convert!
78:   binding.pry

=> 79: keys.each do |k|
80: regular_writer convert_key(k), indifferent_value(regular_delete(k))
81: end
82: self
83: end

[1] pry(#Pry::Config)> keys
=> ["access_token", "token_type", "expires_in"]`

It seems as if the library is passing in an odd number of arguments, which is causing the issue at hand. The odd thing is, I use this gem for a lot of requests to the API, and it works fine, so I'm confused why this would be an issue. My code can be found below, if it illustrates something I'm doing in error.

` business_params = {
firstName: name[0],
lastName: name[1],
email: params[:admin_email],
type: org.client_type,
address1: org.address_line_1,
city: org.city,
state: org.region,
postalCode: org.postal_code,
businessName: org.name,
businessType: params[:business_type],
businessClassification: params[:business_classification],
ein: params[:ein]
}

  business_params = business_params.merge({ 
      controller: {
      firstName: controller_name[0],
      lastName: controller_name[1],
      title: params[:controller][:title],
      dateOfBirth: params[:controller][:date_of_birth],
      address: {
        address1: params[:controller][:address_line_1],
        address2: params[:controller][:address_line_2],
        city: params[:controller][:city],
        state: params[:controller][:stateProvinceRegion],
        postalCode: params[:controller][:postal_code],
        country: params[:controller][:country]
      }
    }
  }) if params["business_type"] != "soleProprietorship"

  begin
    response = Client.post "customers", business_params
    location = response.headers[:location]
  rescue DwollaV2::Error => e
    location = duplicate_location_for(e) || raise
  end`

Issue with $dwolla.get function and search customer with multiple statuses

According to the documentation (https://docs.dwolla.com/#list-and-search-customers), you can stack statuses for a unique query (such as getting all suspended and unverified customers). However when I use the dwolla gem, instead of sending the multiple status (as the Dwolla API documentation indicates), it overwrites and only the last one is sent.

Example: $dwolla.get "customers", status: "suspended", status: "unverified"

The result is only status=unverified gets sent.

I also tried to send the whole url as a string, same result: $dwolla.get "https://api.dwolla.com/customers?status=suspended&status=unverified"

Opened ticket with Dwolla support thinking it was an issue with the API documentation. Instead it's an issue with the Gem and its inability to handle same status without overwriting.

Is there a known workaround for this issue?

Error in getting application token

We don't want to go over OAuth path, we are going to use White Label API.

This is my config in /initializers

$dwolla = DwollaV2::Client.new(id: "4ccmHuxwlohsKxxxxxxxxxxxxxxxxxxxxxxxxx", secret: "B0SlLhSLGsOkBl8zBjxxxxxxxxxxxxxxxxx") do |optional_config|
  optional_config.environment = :sandbox
end

When I tried to get an application token I got following error.

2.2.2 :015 >  token = $dwolla.auths.client scope: "ManagerCustomers|Funding"
TypeError: no implicit conversion of Symbol into Integer
    from /home/akaruilabs/.rvm/gems/ruby-2.2.2/gems/dwolla_v2-0.1.0/lib/dwolla_v2/auth.rb:49:in `[]'
    from /home/akaruilabs/.rvm/gems/ruby-2.2.2/gems/dwolla_v2-0.1.0/lib/dwolla_v2/auth.rb:49:in `request_token'
    from /home/akaruilabs/.rvm/gems/ruby-2.2.2/gems/dwolla_v2-0.1.0/lib/dwolla_v2/auth.rb:6:in `client'
    from /home/akaruilabs/.rvm/gems/ruby-2.2.2/gems/dwolla_v2-0.1.0/lib/dwolla_v2/portal.rb:9:in `public_send'
    from /home/akaruilabs/.rvm/gems/ruby-2.2.2/gems/dwolla_v2-0.1.0/lib/dwolla_v2/portal.rb:9:in `method_missing'
    from (irb):15
    from /home/akaruilabs/.rvm/gems/ruby-2.2.2/gems/railties-4.0.13/lib/rails/commands/console.rb:90:in `start'
    from /home/akaruilabs/.rvm/gems/ruby-2.2.2/gems/railties-4.0.13/lib/rails/commands/console.rb:9:in `start'
    from /home/akaruilabs/.rvm/gems/ruby-2.2.2/gems/railties-4.0.13/lib/rails/commands.rb:62:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

Generating IAV token generates odd number of arguments error

I was sent over here by my developer relations contact. I am having a weird issue that I'm struggling to diagnose. I thought it might be something related to our codebase, but a couple things is making me think it's related to this library:

  1. This flow has worked for months now, and the code has not changed. All of a sudden, it doesn't work, but did work as of 10/18/18 (nothing has changed between then and now).
  2. There's nothing on our end that's inbetween the call being made, and the actual error being produced.

We're trying to generate an IAV token to pass to the dwolla.js widget to initialize bank authorization. The entirety of our code is as follows:

response = Client.post("customers/#{customer_id}/iav-token") response.token

Where Client.post calls

$dwolla.auths.client.post endpoint, params

Where endpoint is what's being passed in in that string. I've verified that the correct customer_id is being passed, and correlates with a valid account. I asked our contact if the account not having certified beneficial ownership yet might be causing an issue, and he said no.

Any help would be appreciate on this as it's interfering with our customers experience. I'll also post the stack trace below:

By the way, the error is coming directly from the Client.post call.

[127.0.0.1] [ip-172-28-234-124.ec2.internal] odd number of arguments for Hash excluded from capture: No project_id specified [127.0.0.1] [ip-172-28-234-124.ec2.internal] [127.0.0.1] [ip-172-28-234-124.ec2.internal] ArgumentError (odd number of arguments for Hash): [127.0.0.1] [ip-172-28-234-124.ec2.internal] [127.0.0.1] [ip-172-28-234-124.ec2.internal] hashie (3.5.7) lib/hashie/extensions/indifferent_access.rb:46:in []'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] hashie (3.5.7) lib/hashie/extensions/indifferent_access.rb:46:in []' [127.0.0.1] [ip-172-28-234-124.ec2.internal] dwolla_v2 (1.2.2) lib/dwolla_v2/super_hash.rb:9:in =='
[127.0.0.1] [ip-172-28-234-124.ec2.internal] dwolla_v2 (1.2.2) lib/dwolla_v2/error.rb:44:in ==' [127.0.0.1] [ip-172-28-234-124.ec2.internal] activesupport (5.1.6) lib/active_support/rescuable.rb:94:in include?'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] activesupport (5.1.6) lib/active_support/rescuable.rb:94:in rescue_with_handler' [127.0.0.1] [ip-172-28-234-124.ec2.internal] activesupport (5.1.6) lib/active_support/rescuable.rb:97:in rescue_with_handler'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] activesupport (5.1.6) lib/active_support/rescuable.rb:164:in rescue_with_handler' [127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_controller/metal/rescue.rb:23:in rescue in process_action'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_controller/metal/rescue.rb:20:in process_action' [127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_controller/metal/instrumentation.rb:32:in block in process_action'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] activesupport (5.1.6) lib/active_support/notifications.rb:166:in block in instrument' [127.0.0.1] [ip-172-28-234-124.ec2.internal] activesupport (5.1.6) lib/active_support/notifications/instrumenter.rb:21:in instrument'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] activesupport (5.1.6) lib/active_support/notifications.rb:166:in instrument' [127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_controller/metal/instrumentation.rb:30:in process_action'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_controller/metal/params_wrapper.rb:252:in process_action' [127.0.0.1] [ip-172-28-234-124.ec2.internal] searchkick (3.0.0) lib/searchkick/logging.rb:209:in process_action'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] activerecord (5.1.6) lib/active_record/railties/controller_runtime.rb:22:in process_action' [127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/abstract_controller/base.rb:124:in process'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] actionview (5.1.6) lib/action_view/rendering.rb:30:in process' [127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_controller/metal.rb:189:in dispatch'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_controller/metal.rb:253:in dispatch' [127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/routing/route_set.rb:49:in dispatch'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/routing/route_set.rb:31:in serve' [127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/journey/router.rb:50:in block in serve'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/journey/router.rb:33:in each' [127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/journey/router.rb:33:in serve'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/routing/route_set.rb:844:in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] rack (2.0.6) lib/rack/etag.rb:25:in call'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] rack (2.0.6) lib/rack/conditional_get.rb:25:in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] rack (2.0.6) lib/rack/head.rb:12:in call'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] rack (2.0.6) lib/rack/session/abstract/id.rb:232:in context' [127.0.0.1] [ip-172-28-234-124.ec2.internal] rack (2.0.6) lib/rack/session/abstract/id.rb:226:in call'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/middleware/cookies.rb:613:in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] activerecord (5.1.6) lib/active_record/migration.rb:556:in call'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/middleware/callbacks.rb:26:in block in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] activesupport (5.1.6) lib/active_support/callbacks.rb:97:in run_callbacks'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/middleware/callbacks.rb:24:in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/middleware/executor.rb:12:in call'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/middleware/debug_exceptions.rb:59:in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] web-console (3.5.1) lib/web_console/middleware.rb:135:in call_app'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] web-console (3.5.1) lib/web_console/middleware.rb:28:in block in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] web-console (3.5.1) lib/web_console/middleware.rb:18:in catch'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] web-console (3.5.1) lib/web_console/middleware.rb:18:in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/middleware/show_exceptions.rb:31:in call'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] railties (5.1.6) lib/rails/rack/logger.rb:36:in call_app' [127.0.0.1] [ip-172-28-234-124.ec2.internal] railties (5.1.6) lib/rails/rack/logger.rb:24:in block in call'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] activesupport (5.1.6) lib/active_support/tagged_logging.rb:69:in block in tagged' [127.0.0.1] [ip-172-28-234-124.ec2.internal] activesupport (5.1.6) lib/active_support/tagged_logging.rb:26:in tagged'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] activesupport (5.1.6) lib/active_support/tagged_logging.rb:69:in tagged' [127.0.0.1] [ip-172-28-234-124.ec2.internal] railties (5.1.6) lib/rails/rack/logger.rb:24:in call'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] sprockets-rails (3.2.1) lib/sprockets/rails/quiet_assets.rb:13:in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/middleware/remote_ip.rb:79:in call'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/middleware/request_id.rb:25:in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] rack (2.0.6) lib/rack/method_override.rb:22:in call'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] rack (2.0.6) lib/rack/runtime.rb:22:in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] activesupport (5.1.6) lib/active_support/cache/strategy/local_cache_middleware.rb:27:in call'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/middleware/executor.rb:12:in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] actionpack (5.1.6) lib/action_dispatch/middleware/static.rb:125:in call'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] rack (2.0.6) lib/rack/sendfile.rb:111:in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] rack-cors (1.0.2) lib/rack/cors.rb:97:in call'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] sentry-raven (2.7.4) lib/raven/integrations/rack.rb:51:in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] webpacker (3.5.5) lib/webpacker/dev_server_proxy.rb:22:in perform_request'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] rack-proxy (0.6.5) lib/rack/proxy.rb:57:in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] railties (5.1.6) lib/rails/engine.rb:522:in call'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] puma (3.10.0) lib/puma/configuration.rb:225:in call' [127.0.0.1] [ip-172-28-234-124.ec2.internal] puma (3.10.0) lib/puma/server.rb:605:in handle_request'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] puma (3.10.0) lib/puma/server.rb:437:in process_client' [127.0.0.1] [ip-172-28-234-124.ec2.internal] puma (3.10.0) lib/puma/server.rb:301:in block in run'
[127.0.0.1] [ip-172-28-234-124.ec2.internal] puma (3.10.0) lib/puma/thread_pool.rb:120:in block in spawn_thread'

Faraday Response Middleware - response details missing

When using faraday response middleware (for say debug logging) in the on_complete the response details (status, headers, body etc.) are missing.

For example the middleware below (the response logger that ships with faraday gives me the same results)

def call(env)
  info "#{env.method} #{env.url.to_s}"
  debug('request') { dump_headers env.request_headers }
  debug('request') { dump_body(env[:body]) } if env[:body] && log_body?(:request)
  @app.call(env).on_complete do |response_env|
    info('Status') { response_env.status.to_s }
    debug('response') { dump_headers response_env.response_headers }
    debug('response') { dump_body response_env[:body] } if env[:body] && log_body?(:response)
  end
end

When a Dwolla request is ran response_env.response_headers is nil and the response_env.body is actually the request body.

I've used this type of response middleware logging before (with other faraday setups) without issue and it's very helpful for debugging requests.

testing with rspec

Are there any examples of rspec testing with responses and errors?(using webmock of course)

Ruby 3.2+ Keywords Error In Lib/Client.rb

Our specs fail when updating to ruby 3.2. We traced the issue back to

def initialize opts
opts[:id] ||= opts[:key]
raise ArgumentError.new ":key is required" unless opts[:id].is_a? String
not being keywords compliant.

https://www.ruby-lang.org/en/news/2022/12/25/ruby-3-2-0-released/

Methods taking a rest parameter (like *args) and wishing to delegate keyword arguments through foo(*args) must now be marked with ruby2_keywords (if not already the case). In other words, all methods wishing to delegate keyword arguments through *args must now be marked with ruby2_keywords, with no exception. This will make it easier to transition to other ways of delegation once a library can require Ruby 3+. Previously, the ruby2_keywords flag was kept if the receiving method took *args, but this was a bug and an inconsistency. A good technique to find potentially missing ruby2_keywords is to run the test suite, find the last method which must receive keyword arguments for each place where the test suite fails, and use puts nil, caller, nil there. Then check that each method/block on the call chain which must delegate keywords is correctly marked with ruby2_keywords

To fix we add the '**' before the opts parameter and this resolved the issue.

Open to PR creating a links method set

One thing I've been thinking about is how there should be an easier way to access the responses of links.

Example

DWOLLA_CLIENT = DwollaV2::Client.new(params)

funding_sources_link  =
  DWOLLA_CLIENT
    .get('customers', limit: 1)
    ._embedded.dig('customers', 0 '_links', 'funding-sources', 'href')

DWOLLA_CLIENT.get("#{funding_source_link}", params)

So, granted I understand the HAL schema y'all are working off of, the fundamental basis of the schema will remain the same, but ideally my end goal would be to go

DWOLLA_CLIENT = DwollaV2::Client.new(params)

DWOLLA_CLIENT
  .get('customers', limit: 1)
  .links[0].get.funding_sources(params) # or funding_sources('get', params)

to accomplish roughly the same thing, where .links dynamcially dispatches the link information to methods to then re-call the client.

So, codewise, I'd imagine that the https://github.com/Dwolla/dwolla-v2-ruby/blob/main/lib/dwolla_v2/response.rb would contain a method that would look directly into the response maps, pull out the direct child _links and _embedded links object and create new methods based on that. The only caveat that would be tricky to work through is carrying over the same client request for both, which I think given the way token works, by adding the token to the initializer of the Response, we should (:crossed_fingers:) be able to easily pass over the request structure to the links by going

class Response
  def initialize response, token
    @response = response
    @token = token
  end

  def links
    @response.body["_links"].keys.each do |link| 
      # ideally we'd snakecase link here
      define_method(method, link, params=nil, headers=nil) do |path, params, headers|
        full_url = self.class.full_url client, path
        @token.public_send(method, full_url, params_headers)
      end
    end
  end
end

Granted I haven't tested this, but just thought it up over lunch, but if this is something amenable, I'd be happy to fork and set up a PR.

Make Dwolla Client Initialization Arguments Coherent

The Dwolla client initialization parameter name (id) is extremely confusing to someone coming into this codebase with significant OAuth experience. I strongly suggest that:

  • The id parameter be updated to read key
  • Documentation within this repository be updated, such that instead of ENV["DWOLLA_ID"] and the like, the Client is initialized with something like ENV["DWOLLA_CONSUMER_KEY"] or ENV["DWOLLA_KEY"]
  • The sample bootstrapping code at https://gist.github.com/sausman/df58a196b3bc0381b0e8 should be updated for significant clarity
  • The official Dwolla documentation should be updated for clarity. One example of this ambiguity is here: https://developers.dwolla.com/pages/sdks.html

Conflict with specifying custom middleware

If I want to create custom middleware say for parsing Dwolla responses, I can but the way the following is structured I have to specify not just the default adapter line but also the response type, otherwise my middleware receives a string, not a hash.

f.response :json, :content_type => /\bjson$/
client.faraday.call(f) if client.faraday

I have a middleware to snake_case the keys in the response body and to get it to work I have to specify:

dwolla = DwollaV2::Client.new(...) do |config|
  config.faraday do |f|
    f.use UnderscoreResponseBodyKeys
    f.response :json, :content_type => /\bjson$/
    f.adapter Faraday.default_adapter
  end
end

I don't just have to specify the default adapter as mentioned but also the response type, otherwise my middleware will receive a string, not a hash. By having the response type after it works as expected and my middleware will receive a hash that DwollaV2 had parsed earlier in the stack.

I shouldn't have to specify the response type but it has to come before specifying the default adapter. At first I tried updating the Token class to have:

    def conn
      @conn ||= Faraday.new do |f|
        # ...
        client.faraday.call(f) if client.faraday
        f.response :json, :content_type => /\bjson$/
        f.adapter Faraday.default_adapter unless client.faraday
      end
    end

But I receive a warning here, since by just specifying the client.faraday block, the default adapter isn't set but it has to be the last item otherwise you receive a warning that this won't be supported:

WARNING: Unexpected middleware set after the adapter. This won't be supported from Faraday 1.0.

While I can temporarily specify the response type on my end I don't think the library should require that and I don't think that was the intention. But it seems you can get both specifying middleware or an adapter with the current configuration setup.

I would suggest breaking off the faraday adapter into its own block or config option that way devs can specify custom middleware while still retaining the defaults. I can submit a PR for that or another solution if you prefer something else?

Method name clash for Funding Source

Hi,

when retrieving a customer's Funding Source the "status" attribute/method clashes with Response#status (HTTP status code) and the latter is returned instead of Funding Source status (e.g "verified").

From API doc:

funding_source_url = 'https://api-sandbox.dwolla.com/funding-sources/692486f8-29f6-4516-a6a5-c69fd2ce854c'

# Using DwollaV2 - https://github.com/Dwolla/dwolla-v2-ruby (Recommended)
funding_source = app_token.get funding_source_url
funding_source.name # => "Test checking account"

funding_source.status # => 200 instead of, for example "verified"

I dug a bit the code, but I didn't find an easy solution that does not interfere with the rest of the SDK...

Knowing the issue, a workaround to get Funding Source's status may be something like this:

require 'json'

fs_data = JSON.load funding_source.to_json
fs_status = fs_data["status"]  # =>  "verified"

DateOfBirth value not allowed

I am testing this on heroku in my staging env which matches key for key with production. I am running everything using sandbox for Dwolla, but keep getting this same issue.

Here is there service class I am using, the error is getting triggered by this line:
customer = @access_token.post 'customers', request_body

Any clue as to why this might be happening?

# Service for managing Dwolla customers
class DwollaCustomer
  def initialize(params)
    @dwolla = set_dwolla_instance
    @user = params[:user]
    @access_token = @dwolla.auths.client
  end

  def create
    customer = @access_token.post 'customers', request_body
    @user.update_attributes(dwolla_url: customer.headers[:location])
  end

  def funding_sources
    return unless @user.merchant? || @user.dwolla_url.nil?
    sources = @access_token.get "#{@user.dwolla_url}/funding-sources"
    sources._embedded['funding-sources']
  end

  private

  def request_body
    {
      firstName: @user.first_name,
      lastName: @user.last_name,
      businessName: @user.business_name,
      email: @user.email,
      type: 'personal',
      address1: @user.street_address,
      city: @user.city,
      state: @user.state,
      postalCode: @user.zipcode,
      dateOfBirth: @user.dob.strftime('%Y-%m-%d').to_s,
      ssn: @user.ssn.last(4)
    }
  end

  def set_dwolla_instance
    @dwolla = DwollaV2::Client.new(key: ENV['dwolla_key'], secret: ENV['dwolla_secret']) do |config|
      config.environment = ENV['dwolla_env'].to_sym
    end
  end
end

Here is the entire error produced:

DwollaV2::ValidationError: {"code"=>"ValidationError", "message"=>"Validation error(s) present. See embedded errors list for more details.", "_embedded"=>{"errors"=>[{"code"=>"NotAllowed", "message"=>"DateOfBirth value not allowed.", "path"=>"/dateOfBirth", "_links"=>{}}]}}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.