braintree 2.45.0 → 2.46.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/lib/braintree.rb +5 -0
  2. data/lib/braintree/add_on_gateway.rb +2 -1
  3. data/lib/braintree/address_gateway.rb +5 -4
  4. data/lib/braintree/client_token_gateway.rb +2 -1
  5. data/lib/braintree/configuration.rb +59 -7
  6. data/lib/braintree/credentials_parser.rb +40 -0
  7. data/lib/braintree/credit_card_gateway.rb +12 -11
  8. data/lib/braintree/credit_card_verification_gateway.rb +4 -3
  9. data/lib/braintree/customer_gateway.rb +12 -11
  10. data/lib/braintree/discount_gateway.rb +2 -1
  11. data/lib/braintree/error_codes.rb +9 -0
  12. data/lib/braintree/europe_bank_account_gateway.rb +2 -1
  13. data/lib/braintree/exceptions.rb +1 -5
  14. data/lib/braintree/gateway.rb +8 -0
  15. data/lib/braintree/http.rb +8 -2
  16. data/lib/braintree/merchant.rb +19 -0
  17. data/lib/braintree/merchant_account_gateway.rb +6 -5
  18. data/lib/braintree/merchant_gateway.rb +27 -0
  19. data/lib/braintree/oauth_credentials.rb +19 -0
  20. data/lib/braintree/oauth_gateway.rb +68 -0
  21. data/lib/braintree/payment_method_gateway.rb +7 -6
  22. data/lib/braintree/payment_method_nonce_gateway.rb +3 -2
  23. data/lib/braintree/paypal_account_gateway.rb +5 -4
  24. data/lib/braintree/plan_gateway.rb +2 -1
  25. data/lib/braintree/settlement_batch_summary_gateway.rb +2 -1
  26. data/lib/braintree/subscription_gateway.rb +8 -7
  27. data/lib/braintree/successful_result.rb +1 -1
  28. data/lib/braintree/testing_gateway.rb +5 -4
  29. data/lib/braintree/transaction.rb +1 -0
  30. data/lib/braintree/transaction_gateway.rb +12 -11
  31. data/lib/braintree/transaction_search.rb +3 -0
  32. data/lib/braintree/transparent_redirect_gateway.rb +1 -0
  33. data/lib/braintree/version.rb +1 -1
  34. data/lib/braintree/webhook_notification_gateway.rb +1 -0
  35. data/lib/braintree/webhook_testing_gateway.rb +1 -0
  36. data/spec/httpsd.pid +1 -1
  37. data/spec/integration/braintree/add_on_spec.rb +12 -0
  38. data/spec/integration/braintree/customer_spec.rb +31 -0
  39. data/spec/integration/braintree/http_spec.rb +10 -6
  40. data/spec/integration/braintree/merchant_account_spec.rb +0 -7
  41. data/spec/integration/braintree/merchant_spec.rb +55 -0
  42. data/spec/integration/braintree/oauth_spec.rb +191 -0
  43. data/spec/integration/braintree/plan_spec.rb +2 -1
  44. data/spec/integration/braintree/transaction_search_spec.rb +63 -0
  45. data/spec/integration/braintree/transaction_spec.rb +73 -4
  46. data/spec/integration/spec_helper.rb +1 -1
  47. data/spec/oauth_test_helper.rb +17 -0
  48. data/spec/spec_helper.rb +8 -4
  49. data/spec/unit/braintree/configuration_spec.rb +23 -0
  50. data/spec/unit/braintree/credentials_parser_spec.rb +81 -0
  51. metadata +161 -148
  52. checksums.yaml +0 -15
@@ -32,6 +32,7 @@ require "braintree/client_token"
32
32
  require "braintree/client_token_gateway"
33
33
  require "braintree/coinbase_account"
34
34
  require "braintree/configuration"
35
+ require "braintree/credentials_parser"
35
36
  require "braintree/credit_card"
36
37
  require "braintree/credit_card_gateway"
37
38
  require "braintree/credit_card_verification"
@@ -51,12 +52,16 @@ require "braintree/error_result"
51
52
  require "braintree/errors"
52
53
  require "braintree/gateway"
53
54
  require "braintree/http"
55
+ require "braintree/merchant"
56
+ require "braintree/merchant_gateway"
54
57
  require "braintree/merchant_account"
55
58
  require "braintree/merchant_account_gateway"
56
59
  require "braintree/merchant_account/individual_details"
57
60
  require "braintree/merchant_account/business_details"
58
61
  require "braintree/merchant_account/funding_details"
59
62
  require "braintree/merchant_account/address_details"
63
+ require "braintree/oauth_gateway"
64
+ require "braintree/oauth_credentials"
60
65
  require "braintree/payment_instrument_type"
61
66
  require "braintree/payment_method"
62
67
  require "braintree/payment_method_gateway"
@@ -3,10 +3,11 @@ module Braintree
3
3
  def initialize(gateway)
4
4
  @gateway = gateway
5
5
  @config = gateway.config
6
+ @config.assert_has_access_token_or_keys
6
7
  end
7
8
 
8
9
  def all
9
- response = @config.http.get "/add_ons"
10
+ response = @config.http.get("#{@config.base_merchant_path}/add_ons")
10
11
  attributes_collection = response[:add_ons]
11
12
  attributes_collection.map do |attributes|
12
13
  AddOn._new(attributes)
@@ -3,6 +3,7 @@ module Braintree
3
3
  def initialize(gateway)
4
4
  @gateway = gateway
5
5
  @config = gateway.config
6
+ @config.assert_has_access_token_or_keys
6
7
  end
7
8
 
8
9
  def create(attributes)
@@ -13,7 +14,7 @@ module Braintree
13
14
  unless attributes[:customer_id] =~ /\A[0-9A-Za-z_-]+\z/
14
15
  raise ArgumentError, ":customer_id contains invalid characters"
15
16
  end
16
- response = @config.http.post "/customers/#{attributes.delete(:customer_id)}/addresses", :address => attributes
17
+ response = @config.http.post("#{@config.base_merchant_path}/customers/#{attributes.delete(:customer_id)}/addresses", :address => attributes)
17
18
  if response[:address]
18
19
  SuccessfulResult.new(:address => Address._new(@gateway, response[:address]))
19
20
  elsif response[:api_error_response]
@@ -25,14 +26,14 @@ module Braintree
25
26
 
26
27
  def delete(customer_or_customer_id, address_id)
27
28
  customer_id = _determine_customer_id(customer_or_customer_id)
28
- @config.http.delete("/customers/#{customer_id}/addresses/#{address_id}")
29
+ @config.http.delete("#{@config.base_merchant_path}/customers/#{customer_id}/addresses/#{address_id}")
29
30
  SuccessfulResult.new
30
31
  end
31
32
 
32
33
  def find(customer_or_customer_id, address_id)
33
34
  customer_id = _determine_customer_id(customer_or_customer_id)
34
35
  raise ArgumentError if address_id.nil? || address_id.to_s.strip == ""
35
- response = @config.http.get("/customers/#{customer_id}/addresses/#{address_id}")
36
+ response = @config.http.get("#{@config.base_merchant_path}/customers/#{customer_id}/addresses/#{address_id}")
36
37
  Address._new(@gateway, response[:address])
37
38
  rescue NotFoundError
38
39
  raise NotFoundError, "address for customer #{customer_id.inspect} with id #{address_id.inspect} not found"
@@ -41,7 +42,7 @@ module Braintree
41
42
  def update(customer_or_customer_id, address_id, attributes)
42
43
  Util.verify_keys(AddressGateway._update_signature, attributes)
43
44
  customer_id = _determine_customer_id(customer_or_customer_id)
44
- response = @config.http.put "/customers/#{customer_id}/addresses/#{address_id}", :address => attributes
45
+ response = @config.http.put("#{@config.base_merchant_path}/customers/#{customer_id}/addresses/#{address_id}", :address => attributes)
45
46
  if response[:address]
46
47
  SuccessfulResult.new(:address => Address._new(@gateway, response[:address]))
47
48
  elsif response[:api_error_response]
@@ -3,6 +3,7 @@ module Braintree
3
3
  def initialize(gateway)
4
4
  @gateway = gateway
5
5
  @config = gateway.config
6
+ @config.assert_has_access_token_or_keys
6
7
  end
7
8
 
8
9
  def generate(options={})
@@ -11,7 +12,7 @@ module Braintree
11
12
  Util.verify_keys(ClientTokenGateway._generate_signature, options)
12
13
  params = {:client_token => options}
13
14
  end
14
- result = @config.http.post("/client_token", params)
15
+ result = @config.http.post("#{@config.base_merchant_path}/client_token", params)
15
16
 
16
17
  if result[:client_token]
17
18
  result[:client_token][:value]
@@ -7,6 +7,9 @@ module Braintree
7
7
  :merchant_id,
8
8
  :public_key,
9
9
  :private_key,
10
+ :client_id,
11
+ :client_secret,
12
+ :access_token,
10
13
  ]
11
14
 
12
15
  WRITABLE_ATTRIBUTES = [
@@ -30,7 +33,7 @@ module Braintree
30
33
  attributes.each do |attribute|
31
34
  (class << self; self; end).send(:define_method, attribute) do
32
35
  attribute_value = instance_variable_get("@#{attribute}")
33
- raise ConfigurationError.new(attribute.to_s, "needs to be set") unless attribute_value
36
+ raise ConfigurationError.new("Braintree::Configuration.#{attribute.to_s} needs to be set") unless attribute_value
34
37
  attribute_value
35
38
  end
36
39
  end
@@ -88,7 +91,36 @@ module Braintree
88
91
  instance_variable_set "@#{attr}", options[attr]
89
92
  end
90
93
 
91
- @merchant_id = options[:merchant_id] || options[:partner_id]
94
+ _check_for_mixed_credentials(options)
95
+
96
+ parser = Braintree::CredentialsParser.new
97
+ if options[:client_id] || options[:client_secret]
98
+ parser.parse_client_credentials(options[:client_id], options[:client_secret])
99
+ @client_id = parser.client_id
100
+ @client_secret = parser.client_secret
101
+ @environment = parser.environment
102
+ elsif options[:access_token]
103
+ parser.parse_access_token(options[:access_token])
104
+ @access_token = parser.access_token
105
+ @environment = parser.environment
106
+ @merchant_id = parser.merchant_id
107
+ else
108
+ @merchant_id = options[:merchant_id] || options[:partner_id]
109
+ end
110
+ end
111
+
112
+ def _check_for_mixed_credentials(options)
113
+ if (options[:client_id] || options[:client_secret]) && (options[:public_key] || options[:private_key])
114
+ raise ConfigurationError.new("Braintree::Gateway cannot be initialized with mixed credential types: client_id and client_secret mixed with public_key and private_key.")
115
+ end
116
+
117
+ if (options[:client_id] || options[:client_secret]) && (options[:access_token])
118
+ raise ConfigurationError.new("Braintree::Gateway cannot be initialized with mixed credential types: client_id and client_secret mixed with access_token.")
119
+ end
120
+
121
+ if (options[:public_key] || options[:private_key]) && (options[:access_token])
122
+ raise ConfigurationError.new("Braintree::Gateway cannot be initialized with mixed credential types: public_key and private_key mixed with access_token.")
123
+ end
92
124
  end
93
125
 
94
126
  def api_version # :nodoc:
@@ -99,8 +131,12 @@ module Braintree
99
131
  "/merchants/#{merchant_id}"
100
132
  end
101
133
 
134
+ def base_url
135
+ "#{protocol}://#{server}:#{port}"
136
+ end
137
+
102
138
  def base_merchant_url # :nodoc:
103
- "#{protocol}://#{server}:#{port}#{base_merchant_path}"
139
+ "#{base_url}#{base_merchant_path}"
104
140
  end
105
141
 
106
142
  def ca_file # :nodoc:
@@ -121,7 +157,7 @@ module Braintree
121
157
 
122
158
  def port # :nodoc:
123
159
  case @environment
124
- when :development
160
+ when :development, :integration
125
161
  ENV['GATEWAY_PORT'] || 3000
126
162
  when :production, :qa, :sandbox
127
163
  443
@@ -142,7 +178,7 @@ module Braintree
142
178
 
143
179
  def server # :nodoc:
144
180
  case @environment
145
- when :development
181
+ when :development, :integration
146
182
  "localhost"
147
183
  when :production
148
184
  "#{endpoint}.braintreegateway.com"
@@ -155,7 +191,7 @@ module Braintree
155
191
 
156
192
  def auth_url
157
193
  case @environment
158
- when :development
194
+ when :development, :integration
159
195
  "http://auth.venmo.dev:9292"
160
196
  when :production
161
197
  "https://auth.venmo.com"
@@ -168,7 +204,7 @@ module Braintree
168
204
 
169
205
  def ssl? # :nodoc:
170
206
  case @environment
171
- when :development
207
+ when :development, :integration
172
208
  false
173
209
  when :production, :qa, :sandbox
174
210
  true
@@ -190,6 +226,22 @@ module Braintree
190
226
  super.gsub(/@private_key=\".*\"/, '@private_key="[FILTERED]"')
191
227
  end
192
228
 
229
+ def client_credentials?
230
+ !client_id.nil?
231
+ end
232
+
233
+ def assert_has_client_credentials
234
+ if client_id.nil? || client_secret.nil?
235
+ raise ConfigurationError.new("Braintree::Gateway client_id and client_secret are required.")
236
+ end
237
+ end
238
+
239
+ def assert_has_access_token_or_keys
240
+ if (public_key.nil? || private_key.nil?) && access_token.nil?
241
+ raise ConfigurationError.new("Braintree::Gateway public_key and private_key are required.")
242
+ end
243
+ end
244
+
193
245
  def signature_service
194
246
  @signature_service ||= SignatureService.new(@private_key)
195
247
  end
@@ -0,0 +1,40 @@
1
+ module Braintree
2
+ class CredentialsParser
3
+ attr_reader :client_id, :client_secret, :access_token, :environment, :merchant_id
4
+
5
+ def parse_client_credentials(client_id, client_secret)
6
+ raise ConfigurationError.new("Missing client_id when constructing Braintree::Gateway") if client_id.nil?
7
+ raise ConfigurationError.new("Value passed for client_id is not a client_id") unless client_id.start_with?("client_id")
8
+
9
+ raise ConfigurationError.new("Missing client_secret when constructing Braintree::Gateway") if client_secret.nil?
10
+ raise ConfigurationError.new("Value passed for client_secret is not a client_secret") unless client_secret.start_with?("client_secret")
11
+ client_id_environment = parse_environment(client_id)
12
+ client_secret_environment = parse_environment(client_secret)
13
+
14
+ if client_id_environment != client_secret_environment
15
+ raise ConfigurationError.new("Mismatched credential environments: client_id environment is #{client_id_environment} and client_secret environment is #{client_secret_environment}")
16
+ end
17
+
18
+ @client_id = client_id
19
+ @client_secret = client_secret
20
+ @environment = client_id_environment
21
+ end
22
+
23
+ def parse_access_token(access_token)
24
+ raise ConfigurationError.new("Missing access_token when constructing Braintree::Gateway") if access_token.nil?
25
+ raise ConfigurationError.new("Value passed for access_token is not a valid access_token") unless access_token.start_with?("access_token")
26
+
27
+ @access_token = access_token
28
+ @environment = parse_environment(access_token)
29
+ @merchant_id = parse_merchant_id(access_token)
30
+ end
31
+
32
+ def parse_environment(credential)
33
+ credential.split("$")[1].to_sym
34
+ end
35
+
36
+ def parse_merchant_id(access_token)
37
+ access_token.split("$")[2]
38
+ end
39
+ end
40
+ end
@@ -3,6 +3,7 @@ module Braintree
3
3
  def initialize(gateway)
4
4
  @gateway = gateway
5
5
  @config = gateway.config
6
+ @config.assert_has_access_token_or_keys
6
7
  end
7
8
 
8
9
  def create(attributes)
@@ -25,24 +26,24 @@ module Braintree
25
26
  end
26
27
 
27
28
  def delete(token)
28
- @config.http.delete("/payment_methods/credit_card/#{token}")
29
+ @config.http.delete("#{@config.base_merchant_path}/payment_methods/credit_card/#{token}")
29
30
  end
30
31
 
31
32
  def expired(options = {})
32
- response = @config.http.post("/payment_methods/all/expired_ids")
33
+ response = @config.http.post("#{@config.base_merchant_path}/payment_methods/all/expired_ids")
33
34
  ResourceCollection.new(response) { |ids| _fetch_expired(ids) }
34
35
  end
35
36
 
36
37
  def expiring_between(start_date, end_date, options = {})
37
38
  formatted_start_date = start_date.strftime('%m%Y')
38
39
  formatted_end_date = end_date.strftime('%m%Y')
39
- response = @config.http.post("/payment_methods/all/expiring_ids?start=#{formatted_start_date}&end=#{formatted_end_date}")
40
+ response = @config.http.post("#{@config.base_merchant_path}/payment_methods/all/expiring_ids?start=#{formatted_start_date}&end=#{formatted_end_date}")
40
41
  ResourceCollection.new(response) { |ids| _fetch_expiring_between(formatted_start_date, formatted_end_date, ids) }
41
42
  end
42
43
 
43
44
  def find(token)
44
45
  raise ArgumentError if token.nil? || token.to_s.strip == ""
45
- response = @config.http.get "/payment_methods/credit_card/#{token}"
46
+ response = @config.http.get("#{@config.base_merchant_path}/payment_methods/credit_card/#{token}")
46
47
  CreditCard._new(@gateway, response[:credit_card])
47
48
  rescue NotFoundError
48
49
  raise NotFoundError, "payment method with token #{token.inspect} not found"
@@ -50,7 +51,7 @@ module Braintree
50
51
 
51
52
  def from_nonce(nonce)
52
53
  raise ArgumentError if nonce.nil? || nonce.to_s.strip == ""
53
- response = @config.http.get "/payment_methods/from_nonce/#{nonce}"
54
+ response = @config.http.get("#{@config.base_merchant_path}/payment_methods/from_nonce/#{nonce}")
54
55
  CreditCard._new(@gateway, response[:credit_card])
55
56
  rescue NotFoundError
56
57
  raise NotFoundError, "nonce #{nonce.inspect} locked, consumed, or not found"
@@ -106,8 +107,8 @@ module Braintree
106
107
  return signature
107
108
  end
108
109
 
109
- def _do_create(url, params=nil) # :nodoc:
110
- response = @config.http.post url, params
110
+ def _do_create(path, params=nil) # :nodoc:
111
+ response = @config.http.post("#{@config.base_merchant_path}#{path}", params)
111
112
  if response[:credit_card]
112
113
  SuccessfulResult.new(:credit_card => CreditCard._new(@gateway, response[:credit_card]))
113
114
  elsif response[:api_error_response]
@@ -117,8 +118,8 @@ module Braintree
117
118
  end
118
119
  end
119
120
 
120
- def _do_update(http_verb, url, params) # :nodoc:
121
- response = @config.http.send http_verb, url, params
121
+ def _do_update(http_verb, path, params) # :nodoc:
122
+ response = @config.http.send(http_verb, "#{@config.base_merchant_path}#{path}", params)
122
123
  if response[:credit_card]
123
124
  SuccessfulResult.new(:credit_card => CreditCard._new(@gateway, response[:credit_card]))
124
125
  elsif response[:api_error_response]
@@ -129,14 +130,14 @@ module Braintree
129
130
  end
130
131
 
131
132
  def _fetch_expired(ids) # :nodoc:
132
- response = @config.http.post("/payment_methods/all/expired", :search => {:ids => ids})
133
+ response = @config.http.post("#{@config.base_merchant_path}/payment_methods/all/expired", :search => {:ids => ids})
133
134
  attributes = response[:payment_methods]
134
135
  Util.extract_attribute_as_array(attributes, :credit_card).map { |attrs| CreditCard._new(@gateway, attrs) }
135
136
  end
136
137
 
137
138
  def _fetch_expiring_between(formatted_start_date, formatted_end_date, ids) # :nodoc:
138
139
  response = @config.http.post(
139
- "/payment_methods/all/expiring?start=#{formatted_start_date}&end=#{formatted_end_date}",
140
+ "#{@config.base_merchant_path}/payment_methods/all/expiring?start=#{formatted_start_date}&end=#{formatted_end_date}",
140
141
  :search => {:ids => ids}
141
142
  )
142
143
  attributes = response[:payment_methods]
@@ -3,11 +3,12 @@ module Braintree
3
3
  def initialize(gateway)
4
4
  @gateway = gateway
5
5
  @config = gateway.config
6
+ @config.assert_has_access_token_or_keys
6
7
  end
7
8
 
8
9
  def find(id)
9
10
  raise ArgumentError if id.nil? || id.strip.to_s == ""
10
- response = @config.http.get "/verifications/#{id}"
11
+ response = @config.http.get("#{@config.base_merchant_path}/verifications/#{id}")
11
12
  CreditCardVerification._new(response[:verification])
12
13
  rescue NotFoundError
13
14
  raise NotFoundError, "verification with id #{id.inspect} not found"
@@ -17,13 +18,13 @@ module Braintree
17
18
  search = CreditCardVerificationSearch.new
18
19
  block.call(search) if block
19
20
 
20
- response = @config.http.post "/verifications/advanced_search_ids", {:search => search.to_hash}
21
+ response = @config.http.post("#{@config.base_merchant_path}/verifications/advanced_search_ids", {:search => search.to_hash})
21
22
  ResourceCollection.new(response) { |ids| _fetch_verifications(search, ids) }
22
23
  end
23
24
 
24
25
  def _fetch_verifications(search, ids)
25
26
  search.ids.in ids
26
- response = @config.http.post "/verifications/advanced_search", {:search => search.to_hash}
27
+ response = @config.http.post("#{@config.base_merchant_path}/verifications/advanced_search", {:search => search.to_hash})
27
28
  attributes = response[:credit_card_verifications]
28
29
  Util.extract_attribute_as_array(attributes, :verification).map { |attrs| CreditCardVerification._new(attrs) }
29
30
  end
@@ -3,10 +3,11 @@ module Braintree
3
3
  def initialize(gateway)
4
4
  @gateway = gateway
5
5
  @config = gateway.config
6
+ @config.assert_has_access_token_or_keys
6
7
  end
7
8
 
8
9
  def all
9
- response = @config.http.post "/customers/advanced_search_ids"
10
+ response = @config.http.post("#{@config.base_merchant_path}/customers/advanced_search_ids")
10
11
  ResourceCollection.new(response) { |ids| _fetch_customers(CustomerSearch.new, ids) }
11
12
  end
12
13
 
@@ -27,14 +28,14 @@ module Braintree
27
28
  end
28
29
 
29
30
  def delete(customer_id)
30
- @config.http.delete("/customers/#{customer_id}")
31
+ @config.http.delete("#{@config.base_merchant_path}/customers/#{customer_id}")
31
32
  SuccessfulResult.new
32
33
  end
33
34
 
34
35
  def find(customer_id)
35
36
  raise ArgumentError, "customer_id contains invalid characters" unless customer_id.to_s =~ /\A[\w-]+\z/
36
37
  raise ArgumentError, "customer_id cannot be blank" if customer_id.nil?|| customer_id.to_s.strip == ""
37
- response = @config.http.get("/customers/#{customer_id}")
38
+ response = @config.http.get("#{@config.base_merchant_path}/customers/#{customer_id}")
38
39
  Customer._new(@gateway, response[:customer])
39
40
  rescue NotFoundError
40
41
  raise NotFoundError, "customer with id #{customer_id.inspect} not found"
@@ -44,12 +45,12 @@ module Braintree
44
45
  search = CustomerSearch.new
45
46
  block.call(search) if block
46
47
 
47
- response = @config.http.post "/customers/advanced_search_ids", {:search => search.to_hash}
48
+ response = @config.http.post("#{@config.base_merchant_path}/customers/advanced_search_ids", {:search => search.to_hash})
48
49
  ResourceCollection.new(response) { |ids| _fetch_customers(search, ids) }
49
50
  end
50
51
 
51
52
  def transactions(customer_id, options = {})
52
- response = @config.http.post "/customers/#{customer_id}/transaction_ids"
53
+ response = @config.http.post("#{@config.base_merchant_path}/customers/#{customer_id}/transaction_ids")
53
54
  ResourceCollection.new(response) { |ids| _fetch_transactions(customer_id, ids) }
54
55
  end
55
56
 
@@ -80,8 +81,8 @@ module Braintree
80
81
  ]
81
82
  end
82
83
 
83
- def _do_create(url, params=nil) # :nodoc:
84
- response = @config.http.post url, params
84
+ def _do_create(path, params=nil) # :nodoc:
85
+ response = @config.http.post("#{@config.base_merchant_path}#{path}", params)
85
86
  if response[:customer]
86
87
  SuccessfulResult.new(:customer => Customer._new(@gateway, response[:customer]))
87
88
  elsif response[:api_error_response]
@@ -91,8 +92,8 @@ module Braintree
91
92
  end
92
93
  end
93
94
 
94
- def _do_update(http_verb, url, params) # :nodoc:
95
- response = @config.http.send http_verb, url, params
95
+ def _do_update(http_verb, path, params) # :nodoc:
96
+ response = @config.http.send(http_verb, "#{@config.base_merchant_path}#{path}", params)
96
97
  if response[:customer]
97
98
  SuccessfulResult.new(:customer => Customer._new(@gateway, response[:customer]))
98
99
  elsif response[:api_error_response]
@@ -104,13 +105,13 @@ module Braintree
104
105
 
105
106
  def _fetch_customers(search, ids) # :nodoc:
106
107
  search.ids.in ids
107
- response = @config.http.post "/customers/advanced_search", {:search => search.to_hash}
108
+ response = @config.http.post("#{@config.base_merchant_path}/customers/advanced_search", {:search => search.to_hash})
108
109
  attributes = response[:customers]
109
110
  Util.extract_attribute_as_array(attributes, :customer).map { |attrs| Customer._new(@gateway, attrs) }
110
111
  end
111
112
 
112
113
  def _fetch_transactions(customer_id, ids) # :nodoc:
113
- response = @config.http.post "/customers/#{customer_id}/transactions", :search => {:ids => ids}
114
+ response = @config.http.post("#{@config.base_merchant_path}/customers/#{customer_id}/transactions", :search => {:ids => ids})
114
115
  attributes = response[:credit_card_transactions]
115
116
  Util.extract_attribute_as_array(attributes, :transaction).map do |transaction_attributes|
116
117
  Transaction._new @gateway, transaction_attributes