synapse_pay 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.travis.yml +16 -0
- data/Gemfile +8 -0
- data/LICENSE +21 -0
- data/README.md +54 -0
- data/Rakefile +8 -0
- data/VERSION +1 -0
- data/bin/synapse_pay-console +7 -0
- data/gemfiles/default-with-activesupport.gemfile +10 -0
- data/gemfiles/json.gemfile +12 -0
- data/gemfiles/yajl.gemfile +12 -0
- data/lib/synapse_pay.rb +78 -0
- data/lib/synapse_pay/apibits/api_client.rb +29 -0
- data/lib/synapse_pay/apibits/api_endpoint.rb +9 -0
- data/lib/synapse_pay/apibits/api_list.rb +88 -0
- data/lib/synapse_pay/apibits/api_method.rb +97 -0
- data/lib/synapse_pay/apibits/api_object.rb +52 -0
- data/lib/synapse_pay/apibits/api_resource.rb +127 -0
- data/lib/synapse_pay/apibits/headers_builder.rb +47 -0
- data/lib/synapse_pay/apibits/params_builder.rb +30 -0
- data/lib/synapse_pay/apibits/path_builder.rb +38 -0
- data/lib/synapse_pay/apibits/requester.rb +104 -0
- data/lib/synapse_pay/apibits/util.rb +51 -0
- data/lib/synapse_pay/client.rb +89 -0
- data/lib/synapse_pay/endpoints/bank_endpoint.rb +47 -0
- data/lib/synapse_pay/endpoints/bank_mfa_device_endpoint.rb +5 -0
- data/lib/synapse_pay/endpoints/bank_mfa_questions_endpoint.rb +5 -0
- data/lib/synapse_pay/endpoints/bank_status_endpoint.rb +11 -0
- data/lib/synapse_pay/endpoints/card_endpoint.rb +26 -0
- data/lib/synapse_pay/endpoints/deposit_endpoint.rb +23 -0
- data/lib/synapse_pay/endpoints/mass_pay_endpoint.rb +26 -0
- data/lib/synapse_pay/endpoints/order_endpoint.rb +44 -0
- data/lib/synapse_pay/endpoints/user_endpoint.rb +26 -0
- data/lib/synapse_pay/endpoints/wire_endpoint.rb +29 -0
- data/lib/synapse_pay/endpoints/withdrawal_endpoint.rb +17 -0
- data/lib/synapse_pay/errors/api_connection_error.rb +4 -0
- data/lib/synapse_pay/errors/api_error.rb +32 -0
- data/lib/synapse_pay/errors/authentication_error.rb +4 -0
- data/lib/synapse_pay/errors/synapse_pay_error.rb +13 -0
- data/lib/synapse_pay/nested_list.rb +32 -0
- data/lib/synapse_pay/resources/bank.rb +46 -0
- data/lib/synapse_pay/resources/bank_mfa_device.rb +32 -0
- data/lib/synapse_pay/resources/bank_mfa_questions.rb +28 -0
- data/lib/synapse_pay/resources/bank_status.rb +21 -0
- data/lib/synapse_pay/resources/card.rb +32 -0
- data/lib/synapse_pay/resources/deposit.rb +25 -0
- data/lib/synapse_pay/resources/mass_pay.rb +38 -0
- data/lib/synapse_pay/resources/order.rb +63 -0
- data/lib/synapse_pay/resources/user.rb +80 -0
- data/lib/synapse_pay/resources/wire.rb +31 -0
- data/lib/synapse_pay/resources/withdrawal.rb +29 -0
- data/lib/synapse_pay/version.rb +3 -0
- data/synapse_pay.gemspec +29 -0
- data/test/synapse_pay/api_list_test.rb +23 -0
- data/test/synapse_pay/api_method_test.rb +89 -0
- data/test/synapse_pay/headers_builder_test.rb +39 -0
- data/test/synapse_pay/params_builder_test.rb +57 -0
- data/test/synapse_pay/path_builder_test.rb +50 -0
- data/test/synapse_pay/requester_test.rb +86 -0
- data/test/synapse_pay/util_test.rb +51 -0
- data/test/test_data.rb +72 -0
- data/test/test_helper.rb +41 -0
- metadata +220 -0
| @@ -0,0 +1,52 @@ | |
| 1 | 
            +
            module SynapsePay
         | 
| 2 | 
            +
              class APIObject
         | 
| 3 | 
            +
                include Enumerable
         | 
| 4 | 
            +
                attr_reader :json
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def self.construct(json)
         | 
| 7 | 
            +
                  if json.is_a?(Array)
         | 
| 8 | 
            +
                    return json.map{ |a| APIObject.construct(a) }
         | 
| 9 | 
            +
                  elsif json.is_a?(Hash)
         | 
| 10 | 
            +
                    return APIObject.new(json)
         | 
| 11 | 
            +
                  else
         | 
| 12 | 
            +
                    return json
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                def initialize(json=nil)
         | 
| 17 | 
            +
                  refresh_from(json)
         | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                def refresh_from(json={})
         | 
| 21 | 
            +
                  @json = Util.sorta_deep_clone(json)
         | 
| 22 | 
            +
                  @json.each do |k, v|
         | 
| 23 | 
            +
                    @json[k] = APIObject.construct(v)
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
                  self
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                def inspect
         | 
| 29 | 
            +
                  @json.inspect
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def to_json(*args)
         | 
| 33 | 
            +
                  JSON.generate(@json)
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def method_missing(name, *args, &blk)
         | 
| 37 | 
            +
                  if name.to_s.end_with?('=')
         | 
| 38 | 
            +
                    attr = name.to_s[0...-1].to_sym
         | 
| 39 | 
            +
                    @json[attr] = args[0]
         | 
| 40 | 
            +
                  else
         | 
| 41 | 
            +
                    if @json.respond_to?(name)
         | 
| 42 | 
            +
                      @json.send(name, *args, &blk)
         | 
| 43 | 
            +
                    elsif @json.has_key?(name.to_sym)
         | 
| 44 | 
            +
                      return @json[name.to_sym]
         | 
| 45 | 
            +
                    else
         | 
| 46 | 
            +
                      super
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
            end
         | 
| @@ -0,0 +1,127 @@ | |
| 1 | 
            +
            module SynapsePay
         | 
| 2 | 
            +
              class APIResource
         | 
| 3 | 
            +
                attr_reader :api_method
         | 
| 4 | 
            +
                attr_reader :json
         | 
| 5 | 
            +
                attr_reader :client
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def initialize(json=nil, api_method=nil, client=nil)
         | 
| 8 | 
            +
                  refresh_from(json, api_method, client)
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                def refresh_from(json={}, api_method=nil, client=nil)
         | 
| 12 | 
            +
                  unless json.is_a?(Hash)
         | 
| 13 | 
            +
                    json = { :id => json }
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                  json = Util.symbolize_keys(json)
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  # Clear or write over any old data
         | 
| 18 | 
            +
                  clear_api_attributes
         | 
| 19 | 
            +
                  @api_method = api_method
         | 
| 20 | 
            +
                  @json = Util.sorta_deep_clone(json)
         | 
| 21 | 
            +
                  @client = client
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  # Use json (not the @json, the cloned copy)
         | 
| 24 | 
            +
                  json.each do |k, v|
         | 
| 25 | 
            +
                    if self.class.api_attribute_names.include?(k.to_sym)
         | 
| 26 | 
            +
                      instance_variable_set("@#{k}", determine_api_attribute_value(k, v))
         | 
| 27 | 
            +
                    end
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                  self
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def inspect
         | 
| 33 | 
            +
                  id_string = (self.respond_to?(:id) && !self.id.nil?) ? " id=#{self.id}" : ""
         | 
| 34 | 
            +
                  "#<#{self.class}:0x#{self.object_id.to_s(16)}#{id_string}> Attributes: " + JSON.pretty_generate(inspect_api_attributes)
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def inspect_nested
         | 
| 38 | 
            +
                  id_string = (self.respond_to?(:id) && !self.id.nil?) ? " id=#{self.id}" : ""
         | 
| 39 | 
            +
                  "#<#{self.class}:0x#{self.object_id.to_s(16)}#{id_string}>"
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def to_json(*args)
         | 
| 43 | 
            +
                  JSON.generate(api_attributes)
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def self.api_attribute_names
         | 
| 47 | 
            +
                  @api_attributes.map(&:first)
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                def api_attributes
         | 
| 51 | 
            +
                  ret = {}
         | 
| 52 | 
            +
                  self.class.api_attribute_names.each do |attribute|
         | 
| 53 | 
            +
                    ret[attribute] = self.send(attribute)
         | 
| 54 | 
            +
                  end
         | 
| 55 | 
            +
                  ret
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                def inspect_api_attributes
         | 
| 59 | 
            +
                  ret = {}
         | 
| 60 | 
            +
                  api_attributes.each do |k, v|
         | 
| 61 | 
            +
                    if v.is_a?(APIResource)
         | 
| 62 | 
            +
                      ret[k] = v.inspect_nested
         | 
| 63 | 
            +
                    else
         | 
| 64 | 
            +
                      ret[k] = v
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                  ret
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                # TODO(joncalhoun): Make this work for nested class construction.
         | 
| 71 | 
            +
                def changed_api_attributes
         | 
| 72 | 
            +
                  ret = {}
         | 
| 73 | 
            +
                  self.api_attributes.each do |name, value|
         | 
| 74 | 
            +
                    if @json[name] != value
         | 
| 75 | 
            +
                      ret[name] = value
         | 
| 76 | 
            +
                    end
         | 
| 77 | 
            +
                  end
         | 
| 78 | 
            +
                  ret
         | 
| 79 | 
            +
                end
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                def clear_api_attributes
         | 
| 82 | 
            +
                  self.class.api_attribute_names.each do |name|
         | 
| 83 | 
            +
                    instance_variable_set("@#{name}", nil)
         | 
| 84 | 
            +
                  end
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                def self.determine_api_attribute_value(name, raw_value)
         | 
| 88 | 
            +
                  if @api_attributes[name] && @api_attributes[name].has_key?(:constructor)
         | 
| 89 | 
            +
                    klass = Util.constantize(@api_attributes[name][:constructor])
         | 
| 90 | 
            +
                    if(klass.respond_to?(:construct))
         | 
| 91 | 
            +
                      klass.construct(raw_value)
         | 
| 92 | 
            +
                    else
         | 
| 93 | 
            +
                      klass.new(raw_value)
         | 
| 94 | 
            +
                    end
         | 
| 95 | 
            +
                  else
         | 
| 96 | 
            +
                    APIObject.construct(raw_value)
         | 
| 97 | 
            +
                  end
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
                def determine_api_attribute_value(name, raw_value)
         | 
| 100 | 
            +
                  self.class.determine_api_attribute_value(name, raw_value)
         | 
| 101 | 
            +
                end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
             | 
| 104 | 
            +
                def self.api_subclasses
         | 
| 105 | 
            +
                  return @api_subclasses ||= Set.new
         | 
| 106 | 
            +
                end
         | 
| 107 | 
            +
             | 
| 108 | 
            +
                def self.api_subclass_fetch(name)
         | 
| 109 | 
            +
                  @api_subclasses_hash ||= {}
         | 
| 110 | 
            +
                  if @api_subclasses_hash.has_key?(name)
         | 
| 111 | 
            +
                    @api_subclasses_hash[name]
         | 
| 112 | 
            +
                  end
         | 
| 113 | 
            +
                end
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                def self.register_api_subclass(subclass, name=nil)
         | 
| 116 | 
            +
                  @api_subclasses ||= Set.new
         | 
| 117 | 
            +
                  @api_subclasses << subclass
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                  unless name.nil?
         | 
| 120 | 
            +
                    @api_subclasses_hash ||= {}
         | 
| 121 | 
            +
                    @api_subclasses_hash[name] = subclass
         | 
| 122 | 
            +
                  end
         | 
| 123 | 
            +
                end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                @api_attributes = {}
         | 
| 126 | 
            +
              end
         | 
| 127 | 
            +
            end
         | 
| @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            module SynapsePay
         | 
| 2 | 
            +
              module HeadersBuilder
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                def self.build(headers)
         | 
| 5 | 
            +
                  headers ||= {}
         | 
| 6 | 
            +
                  default_headers.merge(headers)
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                def self.default_headers
         | 
| 10 | 
            +
                  headers = {
         | 
| 11 | 
            +
                    :user_agent => "SynapsePay/#{SynapsePay.api_version} RubyBindings/#{SynapsePay::VERSION}",
         | 
| 12 | 
            +
                  }.merge({
         | 
| 13 | 
            +
                    "Content-Type" => "application/json",
         | 
| 14 | 
            +
                  })
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  begin
         | 
| 17 | 
            +
                    headers.update(:x_synapse_pay_client_user_agent => JSON.generate(user_agent))
         | 
| 18 | 
            +
                  rescue => e
         | 
| 19 | 
            +
                    headers.update(:x_synapse_pay_client_raw_user_agent => user_agent.inspect,
         | 
| 20 | 
            +
                                   :error => "#{e} (#{e.class})")
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
                  headers
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
             | 
| 26 | 
            +
             | 
| 27 | 
            +
                def self.user_agent
         | 
| 28 | 
            +
                  lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  {
         | 
| 31 | 
            +
                    :bindings_version => SynapsePay::VERSION,
         | 
| 32 | 
            +
                    :lang => 'ruby',
         | 
| 33 | 
            +
                    :lang_version => lang_version,
         | 
| 34 | 
            +
                    :platform => RUBY_PLATFORM,
         | 
| 35 | 
            +
                    :publisher => 'synapse_pay',
         | 
| 36 | 
            +
                    :uname => get_uname
         | 
| 37 | 
            +
                  }
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def self.get_uname
         | 
| 41 | 
            +
                  `uname -a 2>/dev/null`.strip if RUBY_PLATFORM =~ /linux|darwin/i
         | 
| 42 | 
            +
                rescue Errno::ENOMEM => ex # couldn't create subprocess
         | 
| 43 | 
            +
                  "uname lookup failed"
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
            end
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            module SynapsePay
         | 
| 2 | 
            +
              module ParamsBuilder
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                def self.clean(params)
         | 
| 5 | 
            +
                  Util.symbolize_keys(params || {})
         | 
| 6 | 
            +
                end
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                # Clean the params, and the hash to_merge, and then merge them.
         | 
| 9 | 
            +
                # This ensures that we dont get something like { "id" => 123, :id => 321 }.
         | 
| 10 | 
            +
                def self.merge(*args)
         | 
| 11 | 
            +
                  ret = {}
         | 
| 12 | 
            +
                  args.each do |arg|
         | 
| 13 | 
            +
                    ret = ret.merge(clean(arg))
         | 
| 14 | 
            +
                  end
         | 
| 15 | 
            +
                  ret
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def self.build(params, api_key=nil, auth_key=nil)
         | 
| 19 | 
            +
                  default_params.merge(clean(params))
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                def self.default_params
         | 
| 23 | 
            +
                  params = {
         | 
| 24 | 
            +
                    :client_id => SynapsePay.client_id,
         | 
| 25 | 
            +
                    :client_secret => SynapsePay.client_secret,
         | 
| 26 | 
            +
                  }
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| @@ -0,0 +1,38 @@ | |
| 1 | 
            +
            module SynapsePay
         | 
| 2 | 
            +
              module PathBuilder
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                # Take a path like:
         | 
| 5 | 
            +
                #   ":path/:id/dogs/:dog_id"
         | 
| 6 | 
            +
                # and convert it to:
         | 
| 7 | 
            +
                #   "#{object.path}/#{object.id}/dogs/#{params[:id]}" => "/objects/1/dogs/2"
         | 
| 8 | 
            +
                #
         | 
| 9 | 
            +
                # Path priority is:
         | 
| 10 | 
            +
                #   1. Object - this will be a class or an instance of a class.
         | 
| 11 | 
            +
                #   2. Params - this is a hash of key values. All keys *must* be symbolized.
         | 
| 12 | 
            +
                def self.build(path, object, params)
         | 
| 13 | 
            +
                  ret = path.dup
         | 
| 14 | 
            +
                  if ret.include?(":")
         | 
| 15 | 
            +
                    matches = ret.scan(/:([^\/]*)/).flatten.map(&:to_sym)
         | 
| 16 | 
            +
                    missing = Set.new(matches)
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    matches.each do |match|
         | 
| 19 | 
            +
                      value = determine_value(match, object, params)
         | 
| 20 | 
            +
                      missing.delete(match) unless value.nil?
         | 
| 21 | 
            +
                      ret.sub!(match.inspect, "#{value}")
         | 
| 22 | 
            +
                    end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                    if missing.any?
         | 
| 25 | 
            +
                      raise ArgumentError.new("Could not determine the full URL. The following values of the path are missing: #{missing.to_a.join(', ')}. Try setting them in your params.")
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
                  end
         | 
| 28 | 
            +
                  ret
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                def self.determine_value(match, object, params)
         | 
| 32 | 
            +
                  value = object.send(match) if object && object.respond_to?(match)
         | 
| 33 | 
            +
                  value ||= params[match] if params && params.has_key?(match)
         | 
| 34 | 
            +
                  value
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
            end
         | 
| @@ -0,0 +1,104 @@ | |
| 1 | 
            +
            module SynapsePay
         | 
| 2 | 
            +
              module Requester
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                def self.request(method, url, params, headers)
         | 
| 5 | 
            +
                  method = method.to_sym
         | 
| 6 | 
            +
                  url, params = prepare_params(method, url, params, headers)
         | 
| 7 | 
            +
                  request_opts = {
         | 
| 8 | 
            +
                    :method => method,
         | 
| 9 | 
            +
                    :url => url,
         | 
| 10 | 
            +
                    :headers => headers,
         | 
| 11 | 
            +
                    :payload => params,
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    :verify_ssl => false,
         | 
| 14 | 
            +
                    :open_timeout => 30,
         | 
| 15 | 
            +
                    :timeout => 60
         | 
| 16 | 
            +
                  }
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  execute_request(request_opts)
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def self.execute_request(opts)
         | 
| 22 | 
            +
                  RestClient::Request.execute(opts)
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def self.get(url, params, headers)
         | 
| 26 | 
            +
                  self.request(:get, url, params, headers)
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def self.delete(url, params, headers)
         | 
| 30 | 
            +
                  self.request(:delete, url, params, headers)
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def self.put(url, params, headers)
         | 
| 34 | 
            +
                  self.request(:put, url, params, headers)
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def self.post(url, params, headers)
         | 
| 38 | 
            +
                  self.request(:post, url, params, headers)
         | 
| 39 | 
            +
                end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                def self.prepare_params(method, url, params, headers)
         | 
| 42 | 
            +
                  if [:get, :head, :delete].include?(method)
         | 
| 43 | 
            +
                    unless params.empty?
         | 
| 44 | 
            +
                      url += URI.parse(url).query ? '&' : '?' + query_string(params)
         | 
| 45 | 
            +
                    end
         | 
| 46 | 
            +
                    params = nil
         | 
| 47 | 
            +
                  else
         | 
| 48 | 
            +
                    if headers["Content-Type"] == "application/json"
         | 
| 49 | 
            +
                      params = JSON.generate(params)
         | 
| 50 | 
            +
                    else
         | 
| 51 | 
            +
                      headers["Content-Type"] = "application/x-www-form-urlencoded"
         | 
| 52 | 
            +
                      if !RestClient::Payload.has_file?(params)
         | 
| 53 | 
            +
                        params = query_string(params)
         | 
| 54 | 
            +
                      end
         | 
| 55 | 
            +
                    end
         | 
| 56 | 
            +
                  end
         | 
| 57 | 
            +
                  [url, params]
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                def self.query_string(params)
         | 
| 61 | 
            +
                  params ||= {}
         | 
| 62 | 
            +
                  if params.any?
         | 
| 63 | 
            +
                    query_array(params).join('&')
         | 
| 64 | 
            +
                  else
         | 
| 65 | 
            +
                    ""
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                # Three major use cases (and nesting of them needs to be supported):
         | 
| 70 | 
            +
                #   { :a => { :b => "bvalue" } }  => ["a[b]=bvalue"]
         | 
| 71 | 
            +
                #   { :a => [1, 2] }           => ["a[]=1", "a[]=2"]
         | 
| 72 | 
            +
                #   { :a => "value" }          => ["a=value"]
         | 
| 73 | 
            +
                def self.query_array(params, key_prefix=nil)
         | 
| 74 | 
            +
                  ret = []
         | 
| 75 | 
            +
                  params.each do |key, value|
         | 
| 76 | 
            +
                    if params.is_a?(Array)
         | 
| 77 | 
            +
                      value = key
         | 
| 78 | 
            +
                      key = ''
         | 
| 79 | 
            +
                    end
         | 
| 80 | 
            +
                    key_suffix = escape(key)
         | 
| 81 | 
            +
                    full_key = key_prefix ? "#{key_prefix}[#{key_suffix}]" : key_suffix
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                    if value.is_a?(Hash) || value.is_a?(Array)
         | 
| 84 | 
            +
                      # Handles the following cases:
         | 
| 85 | 
            +
                      #   { :a => { :b => "bvalue" } }  => ["a[b]=bvalue"]
         | 
| 86 | 
            +
                      #   { :a => [1, 2] }           => ["a[]=1", "a[]=2"]
         | 
| 87 | 
            +
                      ret += query_array(value, full_key)
         | 
| 88 | 
            +
                    elsif value.is_a?(APIObject)
         | 
| 89 | 
            +
                      ret += query_array(value.json, full_key)
         | 
| 90 | 
            +
                    else
         | 
| 91 | 
            +
                      # Handles the base case with just key and value:
         | 
| 92 | 
            +
                      #   { :a => "value" } => ["a=value"]
         | 
| 93 | 
            +
                      ret << "#{full_key}=#{escape(value)}"
         | 
| 94 | 
            +
                    end
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
                  ret
         | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                def self.escape(val)
         | 
| 100 | 
            +
                  URI.escape(val.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
         | 
| 101 | 
            +
                end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
              end
         | 
| 104 | 
            +
            end
         | 
| @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            module SynapsePay
         | 
| 2 | 
            +
              module Util
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                def self.symbolize_keys(obj)
         | 
| 5 | 
            +
                  if obj.is_a?(Hash)
         | 
| 6 | 
            +
                    ret = {}
         | 
| 7 | 
            +
                    obj.each do |key, value|
         | 
| 8 | 
            +
                      ret[(key.to_sym rescue key) || key] = symbolize_keys(value)
         | 
| 9 | 
            +
                    end
         | 
| 10 | 
            +
                    return ret
         | 
| 11 | 
            +
                  elsif obj.is_a?(Array)
         | 
| 12 | 
            +
                    return obj.map{ |value| symbolize_keys(value) }
         | 
| 13 | 
            +
                  else
         | 
| 14 | 
            +
                    return obj
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                def self.sorta_deep_clone(json)
         | 
| 19 | 
            +
                  if json.is_a?(Hash)
         | 
| 20 | 
            +
                    ret = {}
         | 
| 21 | 
            +
                    json.each do |k, v|
         | 
| 22 | 
            +
                      ret[k] = sorta_deep_clone(v)
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
                    ret
         | 
| 25 | 
            +
                  elsif json.is_a?(Array)
         | 
| 26 | 
            +
                    json.map{ |j| sorta_deep_clone(j) }
         | 
| 27 | 
            +
                  else
         | 
| 28 | 
            +
                    begin
         | 
| 29 | 
            +
                      json.dup
         | 
| 30 | 
            +
                    rescue
         | 
| 31 | 
            +
                      json
         | 
| 32 | 
            +
                    end
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def self.constantize(str, prefix=false)
         | 
| 37 | 
            +
                  str = str.to_s
         | 
| 38 | 
            +
                  begin
         | 
| 39 | 
            +
                    str.split('::').reduce(Module, :const_get)
         | 
| 40 | 
            +
                  rescue NameError => e
         | 
| 41 | 
            +
                    if prefix
         | 
| 42 | 
            +
                      raise e
         | 
| 43 | 
            +
                    else
         | 
| 44 | 
            +
                      p = "#{self.name}".split("::").first
         | 
| 45 | 
            +
                      constantize("#{p}::#{str}", true)
         | 
| 46 | 
            +
                    end
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
            end
         |