braintree 4.33.0 → 4.35.0

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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/lib/braintree/credit_card_verification_gateway.rb +4 -2
  3. data/lib/braintree/customer.rb +1 -1
  4. data/lib/braintree/payment_instrument_type.rb +1 -0
  5. data/lib/braintree/payment_method_parser.rb +1 -0
  6. data/lib/braintree/test/nonce.rb +1 -0
  7. data/lib/braintree/test/transaction_amounts.rb +1 -0
  8. data/lib/braintree/transaction/visa_checkout_card_details.rb +2 -0
  9. data/lib/braintree/transaction.rb +6 -2
  10. data/lib/braintree/transaction_gateway.rb +7 -3
  11. data/lib/braintree/version.rb +1 -1
  12. data/lib/braintree/visa_checkout_card.rb +2 -0
  13. data/lib/braintree/xml/nokogiri.rb +5 -3
  14. data/spec/integration/braintree/apple_pay_spec.rb +6 -7
  15. data/spec/integration/braintree/customer_spec.rb +0 -16
  16. data/spec/integration/braintree/merchant_account_spec.rb +19 -17
  17. data/spec/integration/braintree/merchant_spec.rb +4 -4
  18. data/spec/integration/braintree/payment_method_spec.rb +4 -4
  19. data/spec/integration/braintree/payment_method_us_bank_account_spec.rb +1 -1
  20. data/spec/integration/braintree/test_transaction_spec.rb +6 -6
  21. data/spec/integration/braintree/transaction_search_spec.rb +1 -1
  22. data/spec/integration/braintree/transaction_spec.rb +36 -13
  23. data/spec/integration/braintree/transaction_transfer_type_spec.rb +25 -1
  24. data/spec/integration/braintree/transaction_us_bank_account_spec.rb +41 -0
  25. data/spec/integration/braintree/us_bank_account_verification_spec.rb +1 -1
  26. data/spec/integration/braintree/visa_checkout_card_spec.rb +4 -100
  27. data/spec/spec_helper.rb +34 -6
  28. data/spec/unit/braintree/client_token_spec.rb +11 -0
  29. data/spec/unit/braintree/error_result_spec.rb +28 -0
  30. data/spec/unit/braintree/transaction_gateway_spec.rb +7 -3
  31. data/spec/unit/braintree/transaction_spec.rb +19 -0
  32. data/spec/unit/braintree/visa_checkout_card_spec.rb +1 -0
  33. data/spec/unit/braintree/xml/parser_spec.rb +57 -0
  34. metadata +6 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2e524f55d0d9990e6d2c25d6dbd81b3d75833ef145a624c70af52119d2b71fd8
4
- data.tar.gz: c060e46e74b749cd934e7eecef42f4d783e6e8252ed59aff41acf574379141a3
3
+ metadata.gz: b265c2399fc0ef51a35bfdd1b804ec05e1173b9f1ee04a8fd47b29ee7494062c
4
+ data.tar.gz: b52c492b7b84c343a287d60d27b63f9813aa7a5c099cfc52d91a7590285d739f
5
5
  SHA512:
6
- metadata.gz: 2796040657fc77358e616b12dea6b8e1e9ebb1b06bd0d0d284b7ee2cb14f2e12d34e5570ed9d512b07293ef5605751ba2116a637077b0b19f0a2d6fd11704ada
7
- data.tar.gz: 31ce1b5335dd36150b8f2dc46df425e17ea4e10bf2e8d0a6b44d2d0f72732c72e3d3b6f9f0a9362de56ded2ca70037a707210f72cff45955947407a8bc61273a
6
+ metadata.gz: 964368649d781437f2f2c5bdbdc75e953c577ab637baa9e5df9c6498c3e70ac3da83e1583540451505fedef5688e49373b3831ff01c2c18f15a229643e77c15b
7
+ data.tar.gz: ca2a9f488eca05e47ec7bf5b52e27db811bcffbb80c972a5a313522bfce5373a245de8c0a202319babfaebe9655f73960f1f1d1d5b57822b4694c0003aa74789
@@ -18,7 +18,8 @@ module Braintree
18
18
  search = CreditCardVerificationSearch.new
19
19
  block.call(search) if block
20
20
 
21
- response = @config.http.post("#{@config.base_merchant_path}/verifications/advanced_search_ids", {:search => search.to_hash})
21
+ search_params = search.to_hash.merge({:verification_type => ["credit_card"]})
22
+ response = @config.http.post("#{@config.base_merchant_path}/verifications/advanced_search_ids", {:search => search_params})
22
23
  ResourceCollection.new(response) { |ids| _fetch_verifications(search, ids) }
23
24
  end
24
25
 
@@ -39,7 +40,8 @@ module Braintree
39
40
 
40
41
  def _fetch_verifications(search, ids)
41
42
  search.ids.in ids
42
- response = @config.http.post("#{@config.base_merchant_path}/verifications/advanced_search", {:search => search.to_hash})
43
+ search_params = search.to_hash.merge({:verification_type => ["credit_card"]})
44
+ response = @config.http.post("#{@config.base_merchant_path}/verifications/advanced_search", {:search => search_params})
43
45
  attributes = response[:credit_card_verifications]
44
46
  Util.extract_attribute_as_array(attributes, :verification).map { |attrs| CreditCardVerification._new(attrs) }
45
47
  end
@@ -90,7 +90,7 @@ module Braintree
90
90
  @google_pay_cards = (@google_pay_cards || []).map { |pm| GooglePayCard._new gateway, pm }
91
91
  @venmo_accounts = (@venmo_accounts || []).map { |pm| VenmoAccount._new gateway, pm }
92
92
  @us_bank_accounts = (@us_bank_accounts || []).map { |pm| UsBankAccount._new gateway, pm }
93
- @visa_checkout_cards = (@visa_checkout_cards|| []).map { |pm| VisaCheckoutCard._new gateway, pm }
93
+ @visa_checkout_cards = (@visa_checkout_cards|| []).map { |pm| VisaCheckoutCard._new gateway, pm } # Deprecated
94
94
  @sepa_direct_debit_accounts = (@sepa_debit_accounts || []).map { |pm| SepaDirectDebitAccount._new gateway, pm }
95
95
  @samsung_pay_cards = (@samsung_pay_cards|| []).map { |pm| SamsungPayCard._new gateway, pm } # Deprecated
96
96
  @addresses = (@addresses || []).map { |addr| Address._new gateway, addr }
@@ -13,6 +13,7 @@ module Braintree
13
13
  SepaDirectDebitAccount = "sepa_debit_account"
14
14
  UsBankAccount = "us_bank_account"
15
15
  VenmoAccount = "venmo_account"
16
+ # NEXT_MAJOR_VERSION remove VisaCheckoutCard
16
17
  VisaCheckoutCard = "visa_checkout_card"
17
18
  end
18
19
  end
@@ -15,6 +15,7 @@ module Braintree
15
15
  elsif attributes[:venmo_account]
16
16
  VenmoAccount._new(gateway, attributes[:venmo_account])
17
17
  elsif attributes[:visa_checkout_card]
18
+ warn "[DEPRECATED] VisaCheckoutCard is no longer a supported payment method type"
18
19
  VisaCheckoutCard._new(gateway, attributes[:visa_checkout_card])
19
20
  elsif attributes[:samsung_pay_card]
20
21
  warn "[DEPRECATED] SamsungPayCard is no longer a supported payment method type"
@@ -65,6 +65,7 @@ module Braintree
65
65
  PayPalFuturePaymentRefreshToken = "fake-paypal-future-refresh-token-nonce"
66
66
  GatewayRejectedFraud = "fake-gateway-rejected-fraud-nonce"
67
67
  GatewayRejectedRiskThresholds = "fake-gateway-rejected-risk-thresholds-nonce"
68
+ # NEXT_MAJOR_VERSION VisaCheckoutCard is deprecated, remove associated nonces
68
69
  VisaCheckoutAmEx = "fake-visa-checkout-amex-nonce"
69
70
  VisaCheckoutDiscover = "fake-visa-checkout-discover-nonce"
70
71
  VisaCheckoutMasterCard = "fake-visa-checkout-mastercard-nonce"
@@ -3,6 +3,7 @@ module Braintree
3
3
  # NEXT_MAJOR_VERSION are these even being used anymore? Can we remove this class??
4
4
  module TransactionAmounts
5
5
  Authorize = "1000.00"
6
+ PartiallyAuthorized = "1004.00"
6
7
  Decline = "2000.00"
7
8
  HardDecline = "2015.00"
8
9
  Fail = "3000.00"
@@ -1,5 +1,7 @@
1
1
  module Braintree
2
2
  class Transaction
3
+ # DEPRECATED: Visa Checkout is no longer supported for creating new transactions.
4
+ # This class is retained for search functionality and historical transaction data only.
3
5
  class VisaCheckoutCardDetails
4
6
  include BaseModule
5
7
 
@@ -86,6 +86,7 @@ module Braintree
86
86
  attr_reader :ach_reject_reason
87
87
  attr_reader :ach_return_code
88
88
  attr_reader :ach_return_responses
89
+ attr_reader :ach_type
89
90
  attr_reader :acquirer_reference_number
90
91
  attr_reader :add_ons
91
92
  attr_reader :additional_processor_response # The raw response from the processor.
@@ -133,6 +134,7 @@ module Braintree
133
134
  attr_reader :order_id
134
135
  attr_reader :packages
135
136
  attr_reader :partial_settlement_transaction_ids
137
+ attr_reader :partially_authorized
136
138
  attr_reader :payment_instrument_type
137
139
  attr_reader :payment_receipt
138
140
  attr_reader :paypal_details
@@ -150,6 +152,7 @@ module Braintree
150
152
  attr_reader :refund_ids
151
153
  attr_reader :refunded_installments
152
154
  attr_reader :refunded_transaction_id
155
+ attr_reader :requested_ach_type
153
156
  attr_reader :retried
154
157
  attr_reader :retried_transaction_id # the primary/parent transaction id of any retried transaction
155
158
  attr_reader :retrieval_reference_number
@@ -310,7 +313,7 @@ module Braintree
310
313
  @payment_receipt = PaymentReceipt.new(attributes[:payment_receipt]) if attributes[:payment_receipt]
311
314
  @paypal_details = PayPalDetails.new(@paypal)
312
315
  @paypal_here_details = PayPalHereDetails.new(@paypal_here)
313
- @samsung_pay_card_details = SamsungPayCardDetails.new(attributes[:samsung_pay_card]) #Deprecated
316
+ @samsung_pay_card_details = SamsungPayCardDetails.new(attributes[:samsung_pay_card]) # Deprecated
314
317
  @sca_exemption_requested = attributes[:sca_exemption_requested]
315
318
  @sepa_direct_debit_account_details = SepaDirectDebitAccountDetails.new(@sepa_debit_account_detail)
316
319
  @service_fee_amount = Util.to_big_decimal(service_fee_amount)
@@ -318,9 +321,10 @@ module Braintree
318
321
  @shipping_details = AddressDetails.new(@shipping)
319
322
  @status_history = attributes[:status_history] ? attributes[:status_history].map { |s| StatusDetails.new(s) } : []
320
323
  @subscription_details = SubscriptionDetails.new(@subscription)
324
+ @partially_authorized = %w[1004].include?(processor_response_code)
321
325
  @tax_amount = Util.to_big_decimal(tax_amount)
322
326
  @venmo_account_details = VenmoAccountDetails.new(@venmo_account)
323
- @visa_checkout_card_details = VisaCheckoutCardDetails.new(attributes[:visa_checkout_card])
327
+ @visa_checkout_card_details = VisaCheckoutCardDetails.new(attributes[:visa_checkout_card]) # Deprecated
324
328
 
325
329
  @facilitated_details = FacilitatedDetails.new(attributes[:facilitated_details]) if attributes[:facilitated_details]
326
330
  @facilitator_details = FacilitatorDetails.new(attributes[:facilitator_details]) if attributes[:facilitator_details]
@@ -194,7 +194,7 @@ module Braintree
194
194
  # three_d_secure_token has been deprecated in favor of three_d_secure_authentication_id
195
195
  def self._create_signature
196
196
  [
197
- :amount, :billing_address_id, :channel, :currency_iso_code, :customer_id, :device_data,
197
+ :accept_partial_authorization, :amount, :billing_address_id, :channel, :currency_iso_code, :customer_id, :device_data,
198
198
  :discount_amount, :exchange_rate_quote_id, :foreign_retailer,
199
199
  :merchant_account_id, :order_id, :payment_method_nonce, :payment_method_token, :processing_merchant_category_code,
200
200
  :product_sku, :purchase_order_number, :service_fee_amount, :shared_billing_address_id,
@@ -250,6 +250,7 @@ module Braintree
250
250
  :store_shipping_address_in_vault,
251
251
  :submit_for_settlement,
252
252
  {:three_d_secure => [:required]},
253
+ {:us_bank_account => [:ach_type]},
253
254
  {:venmo => [:profile_id]},
254
255
  :venmo_sdk_session, # Deprecated
255
256
  ]
@@ -285,18 +286,21 @@ module Braintree
285
286
  :type,
286
287
  {
287
288
  :sender => [
289
+ :account_reference_number,
290
+ :date_of_birth,
288
291
  :first_name,
289
292
  :last_name,
290
- :account_reference_number,
293
+ :middle_name,
291
294
  :tax_id,
292
295
  {:address => AddressGateway._address_attributes}
293
296
  ]
294
297
  },
295
298
  {
296
299
  :receiver => [
300
+ :account_reference_number,
297
301
  :first_name,
298
302
  :last_name,
299
- :account_reference_number,
303
+ :middle_name,
300
304
  :tax_id,
301
305
  {:address => AddressGateway._address_attributes}
302
306
  ]
@@ -1,7 +1,7 @@
1
1
  module Braintree
2
2
  module Version
3
3
  Major = 4
4
- Minor = 33
4
+ Minor = 35
5
5
  Tiny = 0
6
6
 
7
7
  String = "#{Major}.#{Minor}.#{Tiny}"
@@ -1,4 +1,6 @@
1
1
  module Braintree
2
+ # DEPRECATED: Visa Checkout is no longer supported for creating new transactions.
3
+ # This class is retained for search functionality and historical transaction data only.
2
4
  class VisaCheckoutCard
3
5
  include BaseModule
4
6
  include Braintree::Util::TokenEquality
@@ -12,12 +12,14 @@ module Braintree
12
12
  end
13
13
 
14
14
  def self._node_to_hash(node, hash = {})
15
+ sub_hash = node.text? ? hash : _build_sub_hash(hash, node.name)
16
+
15
17
  if node.text? || (node.children.size == 1 && node.children.first.text?)
16
18
  content = node.text? ? node.content : node.children.first.content
17
19
  raise "Content too large" if content.length >= NOKOGIRI_XML_LIMIT
18
- hash[CONTENT_ROOT] = content
20
+ sub_hash[CONTENT_ROOT] = content
21
+ _attributes_to_hash(node, sub_hash) unless node.text?
19
22
  else
20
- sub_hash = _build_sub_hash(hash, node.name)
21
23
  _attributes_to_hash(node, sub_hash)
22
24
  if _array?(node)
23
25
  _children_array_to_hash(node, sub_hash)
@@ -66,4 +68,4 @@ module Braintree
66
68
  end
67
69
  end
68
70
  end
69
- end
71
+ end
@@ -2,20 +2,19 @@ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
2
2
 
3
3
  describe Braintree::ApplePayGateway do
4
4
  before(:each) do
5
- gateway = Braintree::Gateway.new(
5
+ oauth_gateway = Braintree::Gateway.new(
6
6
  :client_id => "client_id$#{Braintree::Configuration.environment}$integration_client_id",
7
7
  :client_secret => "client_secret$#{Braintree::Configuration.environment}$integration_client_secret",
8
8
  :logger => Logger.new("/dev/null"),
9
9
  )
10
10
 
11
- result = gateway.merchant.create(
12
- :email => "name@email.com",
13
- :country_code_alpha3 => "GBR",
14
- :payment_methods => ["credit_card", "paypal"],
15
- )
11
+ access_token = Braintree::OAuthTestHelper.create_token(oauth_gateway, {
12
+ :merchant_public_id => "integration_merchant_id",
13
+ :scope => "read_write"
14
+ }).credentials.access_token
16
15
 
17
16
  @gateway = Braintree::Gateway.new(
18
- :access_token => result.credentials.access_token,
17
+ :access_token => access_token,
19
18
  :logger => Logger.new("/dev/null"),
20
19
  )
21
20
  end
@@ -1979,20 +1979,4 @@ describe Braintree::Customer do
1979
1979
  end
1980
1980
  end
1981
1981
 
1982
- it "returns bin fields from VisaCheckoutCard" do
1983
- result = Braintree::Customer.create(
1984
- :payment_method_nonce => Braintree::Test::Nonce::VisaCheckoutVisa,
1985
- )
1986
- expect(result.success?).to eq(true)
1987
-
1988
- found_customer = Braintree::Customer.find(result.customer.id)
1989
- expect(found_customer.visa_checkout_cards).not_to be_nil
1990
- visa_checkout_card = found_customer.visa_checkout_cards.first
1991
- expect(visa_checkout_card).to be_a Braintree::VisaCheckoutCard
1992
- expect(visa_checkout_card.business).not_to be_nil
1993
- expect(visa_checkout_card.consumer).not_to be_nil
1994
- expect(visa_checkout_card.corporate).not_to be_nil
1995
- expect(visa_checkout_card.prepaid_reloadable).not_to be_nil
1996
- expect(visa_checkout_card.purchase).not_to be_nil
1997
- end
1998
1982
  end
@@ -95,10 +95,14 @@ describe Braintree::MerchantAccount do
95
95
  :logger => Logger.new("/dev/null"),
96
96
  )
97
97
 
98
- result = gateway.merchant.create(
99
- :email => "name@email.com",
100
- :country_code_alpha3 => "GBR",
101
- :payment_methods => ["credit_card", "paypal"],
98
+ code = Braintree::OAuthTestHelper.create_grant(gateway, {
99
+ :merchant_public_id => "integration_merchant_id",
100
+ :scope => "read_write"
101
+ })
102
+
103
+ result = gateway.oauth.create_token_from_code(
104
+ :code => code,
105
+ :scope => "read_write",
102
106
  )
103
107
 
104
108
  gateway = Braintree::Gateway.new(
@@ -108,10 +112,8 @@ describe Braintree::MerchantAccount do
108
112
 
109
113
  result = gateway.merchant_account.all
110
114
  expect(result).to be_success
111
- expect(result.merchant_accounts.count).to eq(1)
112
- expect(result.merchant_accounts.first.currency_iso_code).to eq("GBP")
115
+ expect(result.merchant_accounts.count).to be > 0
113
116
  expect(result.merchant_accounts.first.status).to eq("active")
114
- expect(result.merchant_accounts.first.default).to eq(true)
115
117
  end
116
118
 
117
119
  it "returns all merchant accounts for read_only scoped grants" do
@@ -144,7 +146,7 @@ describe Braintree::MerchantAccount do
144
146
 
145
147
  describe "create_for_currency" do
146
148
  it "creates a new merchant account for currency" do
147
- result = SpecHelper::create_merchant
149
+ result = SpecHelper::get_merchant
148
150
  expect(result).to be_success
149
151
 
150
152
  gateway = Braintree::Gateway.new(
@@ -153,14 +155,14 @@ describe Braintree::MerchantAccount do
153
155
  )
154
156
 
155
157
  result = gateway.merchant_account.create_for_currency(
156
- :currency => "JPY",
158
+ :currency => "AUD",
157
159
  )
158
160
  expect(result).to be_success
159
- expect(result.merchant_account.currency_iso_code).to eq("JPY")
161
+ expect(result.merchant_account.currency_iso_code).to eq("AUD")
160
162
  end
161
163
 
162
164
  it "returns error if a merchant account already exists for that currency" do
163
- result = SpecHelper::create_merchant
165
+ result = SpecHelper::get_merchant
164
166
  expect(result).to be_success
165
167
 
166
168
  gateway = Braintree::Gateway.new(
@@ -169,12 +171,12 @@ describe Braintree::MerchantAccount do
169
171
  )
170
172
 
171
173
  result = gateway.merchant_account.create_for_currency(
172
- :currency => "USD",
174
+ :currency => "CAD",
173
175
  )
174
176
  expect(result).to be_success
175
177
 
176
178
  result = gateway.merchant_account.create_for_currency(
177
- :currency => "USD",
179
+ :currency => "CAD",
178
180
  )
179
181
  expect(result).not_to be_success
180
182
 
@@ -183,7 +185,7 @@ describe Braintree::MerchantAccount do
183
185
  end
184
186
 
185
187
  it "returns error if no currency is provided" do
186
- result = SpecHelper::create_merchant
188
+ result = SpecHelper::get_merchant
187
189
  expect(result).to be_success
188
190
 
189
191
  gateway = Braintree::Gateway.new(
@@ -207,7 +209,7 @@ describe Braintree::MerchantAccount do
207
209
  end
208
210
 
209
211
  it "returns error if a currency is not supported" do
210
- result = SpecHelper::create_merchant
212
+ result = SpecHelper::get_merchant
211
213
  expect(result).to be_success
212
214
 
213
215
  gateway = Braintree::Gateway.new(
@@ -225,7 +227,7 @@ describe Braintree::MerchantAccount do
225
227
  end
226
228
 
227
229
  it "returns error if id is passed and already taken" do
228
- result = SpecHelper::create_merchant
230
+ result = SpecHelper::get_merchant
229
231
  expect(result).to be_success
230
232
 
231
233
  gateway = Braintree::Gateway.new(
@@ -235,7 +237,7 @@ describe Braintree::MerchantAccount do
235
237
 
236
238
  merchant = result.merchant
237
239
  result = gateway.merchant_account.create_for_currency(
238
- :currency => "USD",
240
+ :currency => "GBP",
239
241
  :id => merchant.merchant_accounts.first.id,
240
242
  )
241
243
  expect(result).not_to be_success
@@ -2,7 +2,7 @@ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
2
2
 
3
3
  describe Braintree::MerchantGateway do
4
4
  describe "create" do
5
- it "creates a merchant" do
5
+ xit "creates a merchant" do
6
6
  gateway = Braintree::Gateway.new(
7
7
  :client_id => "client_id$#{Braintree::Configuration.environment}$integration_client_id",
8
8
  :client_secret => "client_secret$#{Braintree::Configuration.environment}$integration_client_secret",
@@ -59,7 +59,7 @@ describe Braintree::MerchantGateway do
59
59
  Braintree::Configuration.merchant_id = old_merchant_id_value
60
60
  end
61
61
 
62
- it "allows using a merchant_id passed in through Gateway" do
62
+ xit "allows using a merchant_id passed in through Gateway" do
63
63
  Braintree::Configuration.merchant_id = nil
64
64
 
65
65
  gateway = Braintree::Gateway.new(
@@ -87,7 +87,7 @@ describe Braintree::MerchantGateway do
87
87
  )
88
88
  end
89
89
 
90
- it "creates an EU multi currency merchant for paypal and credit_card" do
90
+ xit "creates an EU multi currency merchant for paypal and credit_card" do
91
91
  result = @gateway.merchant.create(
92
92
  :email => "name@email.com",
93
93
  :country_code_alpha3 => "GBR",
@@ -123,7 +123,7 @@ describe Braintree::MerchantGateway do
123
123
  end
124
124
 
125
125
 
126
- it "creates a paypal-only merchant that accepts multiple currencies" do
126
+ xit "creates a paypal-only merchant that accepts multiple currencies" do
127
127
  result = @gateway.merchant.create(
128
128
  :email => "name@email.com",
129
129
  :country_code_alpha3 => "GBR",
@@ -207,9 +207,9 @@ describe Braintree::PaymentMethod do
207
207
  expect(google_pay_card.image_url).to match(/android_pay/)
208
208
  expect(google_pay_card.is_network_tokenized?).to eq(true)
209
209
  expect(google_pay_card.source_card_type).to eq(Braintree::CreditCard::CardType::MasterCard)
210
- expect(google_pay_card.source_card_last_4).to eq("4444")
210
+ expect(google_pay_card.source_card_last_4).to eq("0005")
211
211
  expect(google_pay_card.google_transaction_id).to eq("google_transaction_id")
212
- expect(google_pay_card.source_description).to eq("MasterCard 4444")
212
+ expect(google_pay_card.source_description).to eq("MasterCard 0005")
213
213
  expect(google_pay_card.customer_id).to eq(customer.id)
214
214
  expect(google_pay_card.commercial).not_to be_nil
215
215
  expect(google_pay_card.country_of_issuance).not_to be_nil
@@ -1337,9 +1337,9 @@ describe Braintree::PaymentMethod do
1337
1337
  expect(google_pay_card.image_url).to match(/android_pay/)
1338
1338
  expect(google_pay_card.is_network_tokenized?).to eq(true)
1339
1339
  expect(google_pay_card.source_card_type).to eq(Braintree::CreditCard::CardType::MasterCard)
1340
- expect(google_pay_card.source_card_last_4).to eq("4444")
1340
+ expect(google_pay_card.source_card_last_4).to eq("0005")
1341
1341
  expect(google_pay_card.google_transaction_id).to eq("google_transaction_id")
1342
- expect(google_pay_card.source_description).to eq("MasterCard 4444")
1342
+ expect(google_pay_card.source_description).to eq("MasterCard 0005")
1343
1343
  expect(google_pay_card.customer_id).to eq(customer.id)
1344
1344
  end
1345
1345
  end
@@ -96,7 +96,7 @@ describe Braintree::PaymentMethod do
96
96
  expect(us_bank_account.routing_number).to eq("123456789")
97
97
  expect(us_bank_account.last_4).to eq("0000")
98
98
  expect(us_bank_account.account_type).to eq("checking")
99
- expect(us_bank_account.account_holder_name).to eq("Dan Schulman")
99
+ expect(us_bank_account.account_holder_name).to eq("Marty McFly")
100
100
  expect(us_bank_account.bank_name).to match(/Wells Fargo/)
101
101
  expect(us_bank_account.default).to eq(true)
102
102
  expect(us_bank_account.ach_mandate.accepted_at).to be_a Time
@@ -6,7 +6,7 @@ describe Braintree::TestTransaction do
6
6
  it "changes transaction status to settled" do
7
7
  sale_result = Braintree::Transaction.sale(
8
8
  :amount => "100",
9
- :payment_method_nonce => Braintree::Test::Nonce::VisaCheckoutVisa,
9
+ :payment_method_nonce => Braintree::Test::Nonce::ApplePayVisa,
10
10
  :options => {
11
11
  :submit_for_settlement => true
12
12
  },
@@ -22,7 +22,7 @@ describe Braintree::TestTransaction do
22
22
  it "changes transaction status to settlement_confirmed" do
23
23
  sale_result = Braintree::Transaction.sale(
24
24
  :amount => "100",
25
- :payment_method_nonce => Braintree::Test::Nonce::VisaCheckoutVisa,
25
+ :payment_method_nonce => Braintree::Test::Nonce::ApplePayVisa,
26
26
  :options => {
27
27
  :submit_for_settlement => true
28
28
  },
@@ -38,7 +38,7 @@ describe Braintree::TestTransaction do
38
38
  it "changes transaction status to settlement_declined" do
39
39
  sale_result = Braintree::Transaction.sale(
40
40
  :amount => "100",
41
- :payment_method_nonce => Braintree::Test::Nonce::VisaCheckoutVisa,
41
+ :payment_method_nonce => Braintree::Test::Nonce::ApplePayVisa,
42
42
  :options => {
43
43
  :submit_for_settlement => true
44
44
  },
@@ -54,7 +54,7 @@ describe Braintree::TestTransaction do
54
54
  it "changes transaction status to settlement_pending" do
55
55
  sale_result = Braintree::Transaction.sale(
56
56
  :amount => "100",
57
- :payment_method_nonce => Braintree::Test::Nonce::VisaCheckoutVisa,
57
+ :payment_method_nonce => Braintree::Test::Nonce::ApplePayVisa,
58
58
  :options => {
59
59
  :submit_for_settlement => true
60
60
  },
@@ -70,7 +70,7 @@ describe Braintree::TestTransaction do
70
70
  it "returns a validation error when invalid transition is specified" do
71
71
  sale_result = Braintree::Transaction.sale(
72
72
  :amount => "100",
73
- :payment_method_nonce => Braintree::Test::Nonce::VisaCheckoutVisa,
73
+ :payment_method_nonce => Braintree::Test::Nonce::ApplePayVisa,
74
74
  )
75
75
  expect(sale_result.success?).to eq(true)
76
76
 
@@ -110,7 +110,7 @@ describe Braintree::TestTransaction do
110
110
 
111
111
  sale_result = transaction_gateway.sale(
112
112
  :amount => "100",
113
- :payment_method_nonce => Braintree::Test::Nonce::VisaCheckoutVisa,
113
+ :payment_method_nonce => Braintree::Test::Nonce::ApplePayVisa,
114
114
  )
115
115
  testing_gateway.settle(sale_result.transaction.id)
116
116
  end
@@ -856,7 +856,7 @@ describe Braintree::Transaction, "search" do
856
856
  search.ach_return_responses_created_at.between(DateTime.now - 1.0, DateTime.now + 1.0)
857
857
  end
858
858
 
859
- expect(date_search.maximum_size).to eq(4)
859
+ expect(date_search.maximum_size).to be >= 1
860
860
  end
861
861
 
862
862
  it "it does not find records not within date range of the custom field" do
@@ -812,6 +812,22 @@ describe Braintree::Transaction do
812
812
  expect(result.transaction.foreign_retailer).to be_nil
813
813
  end
814
814
 
815
+ it "returns true for partial_authorization if the processor_response_code is 1004" do
816
+ result = Braintree::Transaction.create(
817
+ :type => "sale",
818
+ :amount => Braintree::Test::TransactionAmounts::PartiallyAuthorized,
819
+ :accept_partial_authorization => true,
820
+ :credit_card => {
821
+ :number => Braintree::Test::CreditCardNumbers::Visa,
822
+ :expiration_date => "05/2029"
823
+ },
824
+ )
825
+
826
+ expect(result.success?).to eq(true)
827
+ expect(result.transaction.processor_response_code).to eq("1004")
828
+ expect(result.transaction.partially_authorized).to eq(true)
829
+ end
830
+
815
831
  it "returns nil when foreign_retailer param is nil" do
816
832
  result = Braintree::Transaction.create(
817
833
  :type => "sale",
@@ -1216,27 +1232,32 @@ describe Braintree::Transaction do
1216
1232
  :client_secret => "client_secret$#{Braintree::Configuration.environment}$integration_client_secret",
1217
1233
  :logger => Logger.new("/dev/null"),
1218
1234
  )
1219
- result = gateway.merchant.create(
1220
- :email => "name@email.com",
1221
- :country_code_alpha3 => "GBR",
1222
- :payment_methods => ["credit_card", "paypal"],
1235
+
1236
+ code = Braintree::OAuthTestHelper.create_grant(gateway, {
1237
+ :merchant_public_id => "partner_merchant_id",
1238
+ :scope => "read_write"
1239
+ })
1240
+
1241
+ result = gateway.oauth.create_token_from_code(
1242
+ :code => code,
1243
+ :scope => "read_write",
1223
1244
  )
1224
1245
 
1225
- gateway = Braintree::Gateway.new(
1246
+ merchant_gateway = Braintree::Gateway.new(
1226
1247
  :access_token => result.credentials.access_token,
1227
1248
  :logger => Logger.new("/dev/null"),
1228
1249
  )
1229
1250
 
1230
- result = gateway.transaction.create(
1251
+ transaction_result = merchant_gateway.transaction.create(
1231
1252
  :type => "sale",
1232
- :amount => "4000.00",
1253
+ :amount => "5001.00",
1233
1254
  :credit_card => {
1234
1255
  :number => Braintree::Test::CreditCardNumbers::Visa,
1235
1256
  :expiration_date => "05/2020"
1236
1257
  },
1237
1258
  )
1238
- expect(result.success?).to eq(false)
1239
- expect(result.transaction.gateway_rejection_reason).to eq(Braintree::Transaction::GatewayRejectionReason::ApplicationIncomplete)
1259
+ expect(transaction_result.success?).to eq(false)
1260
+ expect(transaction_result.transaction.gateway_rejection_reason).to eq(Braintree::Transaction::GatewayRejectionReason::ApplicationIncomplete)
1240
1261
  end
1241
1262
 
1242
1263
  it "exposes the avs gateway rejection reason" do
@@ -2335,8 +2356,9 @@ describe Braintree::Transaction do
2335
2356
  expect(google_pay_details).not_to be_nil
2336
2357
  expect(google_pay_details.card_type).to eq(Braintree::CreditCard::CardType::MasterCard)
2337
2358
  expect(google_pay_details.virtual_card_type).to eq(Braintree::CreditCard::CardType::MasterCard)
2338
- expect(google_pay_details.last_4).to eq("0005")
2339
- expect(google_pay_details.virtual_card_last_4).to eq("0005")
2359
+ expect(google_pay_details.last_4).to eq("4444")
2360
+ expect(google_pay_details.virtual_card_last_4).to eq("4444")
2361
+ expect(google_pay_details.source_card_last_4).to eq("0005")
2340
2362
  expect(google_pay_details.source_description).to eq("MasterCard 0005")
2341
2363
  expect(google_pay_details.expiration_month.to_i).to be > 0
2342
2364
  expect(google_pay_details.expiration_year.to_i).to be > 0
@@ -3038,8 +3060,9 @@ describe Braintree::Transaction do
3038
3060
  :ds_transaction_id => "some_ds_id",
3039
3061
  },
3040
3062
  )
3063
+
3041
3064
  expect(result.success?).to eq(false)
3042
- expect(result.errors.for(:transaction).for(:three_d_secure_pass_thru).on(:cavv_algorithm)[0].code).to eq(Braintree::ErrorCodes::Transaction::ThreeDSecureCavvAlgorithmIsInvalid)
3065
+ expect(result.errors.for(:transaction).for(:credit_card).on(:cvv)[0].code).to eq(Braintree::ErrorCodes::CreditCard::CvvIsRequired)
3043
3066
  end
3044
3067
  end
3045
3068
 
@@ -7768,7 +7791,7 @@ describe Braintree::Transaction do
7768
7791
 
7769
7792
  expect(adjustment_transaction.success?).to eq(false)
7770
7793
  expect(adjustment_transaction.transaction.amount).to eq(BigDecimal("75.50"))
7771
- expect(adjustment_transaction.errors.for(:authorization_adjustment).on(:amount).first.code).to eq(Braintree::ErrorCodes::Transaction::AdjustmentAmountMustBeGreaterThanZero)
7794
+ expect(adjustment_transaction.errors.for(:transaction).on(:amount).first.code).to eq(Braintree::ErrorCodes::Transaction::AmountMustBeGreaterThanZero)
7772
7795
  end
7773
7796
 
7774
7797
  it "returns failure response, when adjusted amount submitted same as authorized amount" do
@@ -15,7 +15,31 @@ describe Braintree::Transaction do
15
15
  },
16
16
  :transfer => {
17
17
  :type => "wallet_transfer",
18
- },
18
+ :receiver => {
19
+ :first_name => "John",
20
+ :last_name => "Smith",
21
+ :middle_name => "D",
22
+ :address => {
23
+ :country_code_alpha2 => "US",
24
+ :locality => "LA",
25
+ :region => "CA",
26
+ :street_address => "1st Main"
27
+ }
28
+ },
29
+ :sender => {
30
+ :account_reference_number => "123456789",
31
+ :date_of_birth => Date.new(2002, 1, 2),
32
+ :first_name => "Lisa",
33
+ :last_name => "Ray",
34
+ :middle_name => "D",
35
+ :address => {
36
+ :country_code_alpha2 => "US",
37
+ :locality => "LA",
38
+ :region => "CA",
39
+ :street_address => "12th Main"
40
+ }
41
+ },
42
+ }
19
43
  }
20
44
 
21
45
  result = Braintree::Transaction.sale(transaction_params)
@@ -143,6 +143,24 @@ describe Braintree::Transaction do
143
143
  expect(transaction.us_bank_account_details.ach_mandate.accepted_at).to be_a Time
144
144
  end
145
145
 
146
+ it "returns ach_type and requested_ach_type on transaction create" do
147
+ result = Braintree::Transaction.create(
148
+ :type => "sale",
149
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
150
+ :merchant_account_id => SpecHelper::UsBankMerchantAccountId,
151
+ :payment_method_nonce => non_plaid_nonce,
152
+ :options => {
153
+ :submit_for_settlement => true,
154
+ :us_bank_account => {
155
+ :ach_type => "same_day",
156
+ },
157
+ },
158
+ )
159
+ expect(result.success?).to eq(true)
160
+ expect(result.transaction.ach_type).to eq("same_day")
161
+ expect(result.transaction.requested_ach_type).to eq("same_day")
162
+ end
163
+
146
164
  it "sale fails for invalid nonce" do
147
165
  result = Braintree::Transaction.create(
148
166
  :type => "sale",
@@ -192,4 +210,27 @@ describe Braintree::Transaction do
192
210
  end
193
211
  end
194
212
  end
213
+
214
+ describe "self.find" do
215
+ it "returns ach_type and requested_ach_type for same_day ach with same_day requested" do
216
+ transaction = Braintree::Transaction.find("sameday_ach_sameday_requested")
217
+
218
+ expect(transaction.ach_type).to eq("same_day")
219
+ expect(transaction.requested_ach_type).to eq("same_day")
220
+ end
221
+
222
+ it "returns ach_type and requested_ach_type for standard ach with same_day requested" do
223
+ transaction = Braintree::Transaction.find("standard_ach_sameday_requested")
224
+
225
+ expect(transaction.ach_type).to eq("standard")
226
+ expect(transaction.requested_ach_type).to eq("same_day")
227
+ end
228
+
229
+ it "returns ach_type and requested_ach_type for standard ach with standard requested" do
230
+ transaction = Braintree::Transaction.find("standard_ach_standard_requested")
231
+
232
+ expect(transaction.ach_type).to eq("standard")
233
+ expect(transaction.requested_ach_type).to eq("standard")
234
+ end
235
+ end
195
236
  end
@@ -50,7 +50,7 @@ describe Braintree::UsBankAccountVerification do
50
50
  expect(response).to be_success
51
51
  expect(response.us_bank_account_verification.status).to eq(Braintree::UsBankAccountVerification::Status::Verified)
52
52
 
53
- us_bank_account = Braintree::UsBankAccount.find(response.us_bank_account_verification.us_bank_account[:token])
53
+ us_bank_account = Braintree::UsBankAccount.find(response.us_bank_account_verification.us_bank_account.token)
54
54
 
55
55
  expect(us_bank_account.verified).to be_truthy
56
56
  end
@@ -1,110 +1,14 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
2
  require File.expand_path(File.dirname(__FILE__) + "/client_api/spec_helper")
3
3
 
4
+ # DEPRECATED: Visa Checkout is no longer supported for creating new transactions.
5
+ # Search functionality is retained for historical transactions only.
4
6
  describe Braintree::VisaCheckoutCard do
5
- it "can create from payment method nonce" do
6
- customer = Braintree::Customer.create!
7
-
8
- result = Braintree::PaymentMethod.create(
9
- :payment_method_nonce => Braintree::Test::Nonce::VisaCheckoutDiscover,
10
- :customer_id => customer.id,
11
- )
12
- expect(result).to be_success
13
-
14
- visa_checkout_card = result.payment_method
15
- expect(visa_checkout_card).to be_a(Braintree::VisaCheckoutCard)
16
- expect(visa_checkout_card.call_id).to eq("abc123")
17
- expect(visa_checkout_card.billing_address).not_to be_nil
18
- expect(visa_checkout_card.bin).not_to be_nil
19
- expect(visa_checkout_card.card_type).not_to be_nil
20
- expect(visa_checkout_card.cardholder_name).not_to be_nil
21
- expect(visa_checkout_card.commercial).not_to be_nil
22
- expect(visa_checkout_card.country_of_issuance).not_to be_nil
23
- expect(visa_checkout_card.created_at).not_to be_nil
24
- expect(visa_checkout_card.customer_id).not_to be_nil
25
- expect(visa_checkout_card.customer_location).not_to be_nil
26
- expect(visa_checkout_card.debit).not_to be_nil
27
- expect(visa_checkout_card.default?).not_to be_nil
28
- expect(visa_checkout_card.durbin_regulated).not_to be_nil
29
- expect(visa_checkout_card.expiration_date).not_to be_nil
30
- expect(visa_checkout_card.expiration_month).not_to be_nil
31
- expect(visa_checkout_card.expiration_year).not_to be_nil
32
- expect(visa_checkout_card.expired?).not_to be_nil
33
- expect(visa_checkout_card.healthcare).not_to be_nil
34
- expect(visa_checkout_card.image_url).not_to be_nil
35
- expect(visa_checkout_card.issuing_bank).not_to be_nil
36
- expect(visa_checkout_card.last_4).not_to be_nil
37
- expect(visa_checkout_card.payroll).not_to be_nil
38
- expect(visa_checkout_card.prepaid).not_to be_nil
39
- expect(visa_checkout_card.product_id).not_to be_nil
40
- expect(visa_checkout_card.subscriptions).not_to be_nil
41
- expect(visa_checkout_card.token).not_to be_nil
42
- expect(visa_checkout_card.unique_number_identifier).not_to be_nil
43
- expect(visa_checkout_card.updated_at).not_to be_nil
44
-
45
- customer = Braintree::Customer.find(customer.id)
46
- expect(customer.visa_checkout_cards.size).to eq(1)
47
- expect(customer.visa_checkout_cards.first).to eq(visa_checkout_card)
48
- end
49
-
50
- it "can create with verification" do
51
- customer = Braintree::Customer.create!
52
-
53
- result = Braintree::PaymentMethod.create(
54
- :payment_method_nonce => Braintree::Test::Nonce::VisaCheckoutDiscover,
55
- :customer_id => customer.id,
56
- :options => {:verify_card => true},
57
- )
58
- expect(result).to be_success
59
- expect(result.payment_method.verification.status).to eq(Braintree::CreditCardVerification::Status::Verified)
60
- end
61
-
62
- it "can search for transactions" do
63
- transaction_create_result = Braintree::Transaction.sale(
64
- :payment_method_nonce => Braintree::Test::Nonce::VisaCheckoutDiscover,
65
- :amount => "47.00",
66
- )
67
- expect(transaction_create_result).to be_success
68
- transaction_id = transaction_create_result.transaction.id
69
-
7
+ it "can search by payment instrument type" do
70
8
  search_results = Braintree::Transaction.search do |search|
71
- search.id.is transaction_id
72
9
  search.payment_instrument_type.is Braintree::PaymentInstrumentType::VisaCheckoutCard
73
10
  end
74
- expect(search_results.first.id).to eq(transaction_id)
75
- end
76
-
77
- it "can create transaction from nonce and vault" do
78
- customer = Braintree::Customer.create!
79
-
80
- result = Braintree::Transaction.sale(
81
- :payment_method_nonce => Braintree::Test::Nonce::VisaCheckoutDiscover,
82
- :customer_id => customer.id,
83
- :amount => "47.00",
84
- :options => {:store_in_vault => true},
85
- )
86
- expect(result).to be_success
87
11
 
88
- visa_checkout_card_details = result.transaction.visa_checkout_card_details
89
- expect(visa_checkout_card_details.call_id).to eq("abc123")
90
- expect(visa_checkout_card_details.bin).not_to be_nil
91
- expect(visa_checkout_card_details.card_type).not_to be_nil
92
- expect(visa_checkout_card_details.cardholder_name).not_to be_nil
93
- expect(visa_checkout_card_details.commercial).not_to be_nil
94
- expect(visa_checkout_card_details.country_of_issuance).not_to be_nil
95
- expect(visa_checkout_card_details.customer_location).not_to be_nil
96
- expect(visa_checkout_card_details.debit).not_to be_nil
97
- expect(visa_checkout_card_details.durbin_regulated).not_to be_nil
98
- expect(visa_checkout_card_details.expiration_date).not_to be_nil
99
- expect(visa_checkout_card_details.expiration_month).not_to be_nil
100
- expect(visa_checkout_card_details.expiration_year).not_to be_nil
101
- expect(visa_checkout_card_details.healthcare).not_to be_nil
102
- expect(visa_checkout_card_details.image_url).not_to be_nil
103
- expect(visa_checkout_card_details.issuing_bank).not_to be_nil
104
- expect(visa_checkout_card_details.last_4).not_to be_nil
105
- expect(visa_checkout_card_details.payroll).not_to be_nil
106
- expect(visa_checkout_card_details.prepaid).not_to be_nil
107
- expect(visa_checkout_card_details.product_id).not_to be_nil
108
- expect(visa_checkout_card_details.token).not_to be_nil
12
+ expect(search_results).not_to be_nil
109
13
  end
110
14
  end
data/spec/spec_helper.rb CHANGED
@@ -4,6 +4,7 @@ unless defined?(SPEC_HELPER_LOADED)
4
4
  require "rubygems"
5
5
  require "bundler/setup"
6
6
  require "rspec"
7
+ require "rspec/retry"
7
8
  require "pry"
8
9
 
9
10
  braintree_lib = "#{project_root}/lib"
@@ -119,18 +120,40 @@ unless defined?(SPEC_HELPER_LOADED)
119
120
  response[:three_d_secure_verification][:three_d_secure_authentication_id]
120
121
  end
121
122
 
122
- def self.create_merchant(params={})
123
+ def self.get_merchant(params={})
123
124
  gateway = Braintree::Gateway.new(
124
125
  :client_id => "client_id$#{Braintree::Configuration.environment}$integration_client_id",
125
126
  :client_secret => "client_secret$#{Braintree::Configuration.environment}$integration_client_secret",
126
127
  :logger => Logger.new("/dev/null"),
127
128
  )
128
129
 
129
- gateway.merchant.create({
130
- :email => "name@email.com",
131
- :country_code_alpha3 => "GBR",
132
- :payment_methods => ["credit_card", "paypal"],
133
- }.merge!(params))
130
+ code = Braintree::OAuthTestHelper.create_grant(gateway, {
131
+ :merchant_public_id => "partner_merchant_id",
132
+ :scope => "read_write"
133
+ })
134
+
135
+ result = gateway.oauth.create_token_from_code(
136
+ :code => code,
137
+ :scope => "read_write",
138
+ )
139
+
140
+ merchant_gateway = Braintree::Gateway.new(
141
+ :access_token => result.credentials.access_token,
142
+ :logger => Logger.new("/dev/null"),
143
+ )
144
+
145
+ ma_result = merchant_gateway.merchant_account.all
146
+
147
+ merchant_obj = OpenStruct.new(
148
+ :id => "partner_merchant_id",
149
+ :merchant_accounts => ma_result.merchant_accounts,
150
+ )
151
+
152
+ OpenStruct.new(
153
+ :success? => true,
154
+ :credentials => result.credentials,
155
+ :merchant => merchant_obj,
156
+ )
134
157
  end
135
158
 
136
159
  def self.stub_time_dot_now(desired_time)
@@ -234,4 +257,9 @@ RSpec.configure do |config|
234
257
  config.mock_with :rspec do |mock|
235
258
  mock.syntax = [:should, :expect]
236
259
  end
260
+
261
+ config.verbose_retry = true
262
+ config.display_try_failure_messages = true
263
+ config.default_retry_count = 3
264
+ config.default_sleep_interval = 1
237
265
  end
@@ -33,5 +33,16 @@ module Braintree
33
33
  end
34
34
  end
35
35
  end
36
+
37
+ describe "error response handling" do
38
+ it "correctly parses error response with nested structure" do
39
+ error_xml = "<api-error-response><message>Invalid request</message><errors><errors type=\"array\"></errors></errors></api-error-response>"
40
+ result = Braintree::Xml::Parser.hash_from_xml(error_xml)
41
+
42
+ expect(result[:api_error_response]).to be_a(Hash)
43
+ expect(result[:api_error_response][:message]).to eq("Invalid request")
44
+ expect(result[:api_error_response][:errors]).to be_a(Hash)
45
+ end
46
+ end
36
47
  end
37
48
  end
@@ -14,6 +14,34 @@ describe Braintree::ErrorResult do
14
14
  )
15
15
  end.to_not raise_error
16
16
  end
17
+
18
+ it "handles parsed XML error response structure correctly" do
19
+ data = {
20
+ :message => "Validation failed",
21
+ :errors => {
22
+ :errors => [{:code => "81234", :message => "Field is required"}]
23
+ }
24
+ }
25
+
26
+ expect do
27
+ result = Braintree::ErrorResult.new(:gateway, data)
28
+ expect(result.message).to eq("Validation failed")
29
+ expect(result.errors.inspect).to eq("#<Braintree::Errors :[(81234) Field is required]>")
30
+ end.to_not raise_error
31
+ end
32
+
33
+ it "handles empty error array in parsed XML response" do
34
+ data = {
35
+ :message => "Invalid request",
36
+ :errors => {:errors => []}
37
+ }
38
+
39
+ expect do
40
+ result = Braintree::ErrorResult.new(:gateway, data)
41
+ expect(result.message).to eq("Invalid request")
42
+ expect(result.errors).to be_a(Braintree::Errors)
43
+ end.to_not raise_error
44
+ end
17
45
  end
18
46
 
19
47
  describe "inspect" do
@@ -33,7 +33,7 @@ describe Braintree::TransactionGateway do
33
33
  # three_d_secure_token has been deprecated in favor of three_d_secure_authentication_id
34
34
  it "creates a transaction gateway signature" do
35
35
  expect(Braintree::TransactionGateway._create_signature).to match([
36
- :amount, :billing_address_id, :channel, :currency_iso_code, :customer_id, :device_data,
36
+ :accept_partial_authorization, :amount, :billing_address_id, :channel, :currency_iso_code, :customer_id, :device_data,
37
37
  :discount_amount, :exchange_rate_quote_id, :foreign_retailer,
38
38
  :merchant_account_id, :order_id, :payment_method_nonce, :payment_method_token, :processing_merchant_category_code,
39
39
  :product_sku, :purchase_order_number, :service_fee_amount, :shared_billing_address_id,
@@ -89,6 +89,7 @@ describe Braintree::TransactionGateway do
89
89
  :store_shipping_address_in_vault,
90
90
  :submit_for_settlement,
91
91
  {:three_d_secure => [:required]},
92
+ {:us_bank_account => [:ach_type]},
92
93
  {:venmo => [:profile_id]},
93
94
  :venmo_sdk_session, # Deprecated
94
95
  ]
@@ -133,16 +134,19 @@ describe Braintree::TransactionGateway do
133
134
  :transfer => [
134
135
  :type,
135
136
  {:sender => [
137
+ :account_reference_number,
138
+ :date_of_birth,
136
139
  :first_name,
137
140
  :last_name,
138
- :account_reference_number,
141
+ :middle_name,
139
142
  :tax_id,
140
143
  :address => Braintree::AddressGateway._address_attributes
141
144
  ]},
142
145
  {:receiver => [
146
+ :account_reference_number,
143
147
  :first_name,
144
148
  :last_name,
145
- :account_reference_number,
149
+ :middle_name,
146
150
  :tax_id,
147
151
  :address => Braintree::AddressGateway._address_attributes
148
152
  ]},
@@ -347,6 +347,15 @@ describe Braintree::Transaction do
347
347
  expect(transaction.network_transaction_id).to eq("123456789012345")
348
348
  end
349
349
 
350
+ it "sets partially_authorized to true if processor_response_code is 1004" do
351
+ transaction = Braintree::Transaction._new(
352
+ :gateway,
353
+ :processor_response_code => "1004",
354
+ )
355
+ expect(transaction.processor_response_code).to eq("1004")
356
+ expect(transaction.partially_authorized).to eq(true)
357
+ end
358
+
350
359
  it "accepts ach_return_code" do
351
360
  transaction = Braintree::Transaction._new(
352
361
  :gateway,
@@ -365,6 +374,16 @@ describe Braintree::Transaction do
365
374
  expect(transaction.ach_reject_reason).to eq("some reject reason")
366
375
  end
367
376
 
377
+ it "accepts ach_type" do
378
+ transaction = Braintree::Transaction._new(
379
+ :gateway,
380
+ :ach_type => "standard",
381
+ :requested_ach_type => "standard",
382
+ )
383
+ expect(transaction.ach_type).to eq("standard")
384
+ expect(transaction.requested_ach_type).to eq("standard")
385
+ end
386
+
368
387
  it "accepts network_response code and network_response_text" do
369
388
  transaction = Braintree::Transaction._new(
370
389
  :gateway,
@@ -1,5 +1,6 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
2
 
3
+ # DEPRECATED: Visa Checkout Transactions are no longer supported
3
4
  describe Braintree::VisaCheckoutCard do
4
5
  it "initializes prepaid reloadable correctly" do
5
6
  card = Braintree::VisaCheckoutCard._new(:gateway, {:prepaid_reloadable => "No"})
@@ -81,5 +81,62 @@ describe Braintree::Xml::Parser do
81
81
  END
82
82
  expect(xml).to parse_to(:root => {:paypal_details => {:deets => [{:secret_code => "1234"}], :payer_email => "abc@test.com", :payment_id => "1234567890"}})
83
83
  end
84
+
85
+ it "does not collapse nested structures with single-child elements" do
86
+ xml = "<api-error-response><message>Test</message><errors><errors type=\"array\"></errors></errors></api-error-response>"
87
+ expect(xml).to parse_to({:api_error_response=>{:message=>"Test", :errors=>{:errors=>[]}}})
88
+ end
89
+
90
+ it "preserves hash structure when one key has array value" do
91
+ xml = <<-END
92
+ <root>
93
+ <message>Error message</message>
94
+ <items type="array">
95
+ <item>Value1</item>
96
+ </items>
97
+ </root>
98
+ END
99
+ expect(xml).to parse_to({:root => {:message => "Error message", :items => ["Value1"]}})
100
+ end
101
+
102
+ it "handles error response with nested errors correctly" do
103
+ xml = <<-END
104
+ <api-error-response>
105
+ <message>Validation failed</message>
106
+ <errors>
107
+ <errors type="array">
108
+ <error>
109
+ <code>81234</code>
110
+ <message>Field is required</message>
111
+ </error>
112
+ </errors>
113
+ </errors>
114
+ </api-error-response>
115
+ END
116
+ expect(xml).to parse_to({
117
+ :api_error_response => {
118
+ :message => "Validation failed",
119
+ :errors => {
120
+ :errors => [{:code => "81234", :message => "Field is required"}]
121
+ }
122
+ }
123
+ })
124
+ end
125
+
126
+ it "handles client token error response structure" do
127
+ xml = <<-END
128
+ <api-error-response>
129
+ <message>Invalid request</message>
130
+ <errors>
131
+ <errors type="array"></errors>
132
+ </errors>
133
+ </api-error-response>
134
+ END
135
+ result = Braintree::Xml::Parser.hash_from_xml(xml)
136
+ expect(result[:api_error_response]).to be_a(Hash)
137
+ expect(result[:api_error_response][:message]).to eq("Invalid request")
138
+ expect(result[:api_error_response][:errors]).to be_a(Hash)
139
+ expect(result[:api_error_response][:errors][:errors]).to eq([])
140
+ end
84
141
  end
85
142
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: braintree
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.33.0
4
+ version: 4.35.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Braintree
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-10-24 00:00:00.000000000 Z
11
+ date: 2026-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: builder
@@ -405,7 +405,7 @@ metadata:
405
405
  changelog_uri: https://github.com/braintree/braintree_ruby/blob/master/CHANGELOG.md
406
406
  source_code_uri: https://github.com/braintree/braintree_ruby
407
407
  documentation_uri: https://developer.paypal.com/braintree/docs
408
- post_install_message:
408
+ post_install_message:
409
409
  rdoc_options: []
410
410
  require_paths:
411
411
  - lib
@@ -420,8 +420,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
420
420
  - !ruby/object:Gem::Version
421
421
  version: '0'
422
422
  requirements: []
423
- rubygems_version: 3.2.5
424
- signing_key:
423
+ rubygems_version: 3.3.15
424
+ signing_key:
425
425
  specification_version: 4
426
426
  summary: Braintree Ruby Server SDK
427
427
  test_files: []