braintree 4.30.0 → 4.31.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 (31) hide show
  1. checksums.yaml +4 -4
  2. data/lib/braintree/address_gateway.rb +5 -0
  3. data/lib/braintree/apple_pay_card.rb +1 -0
  4. data/lib/braintree/bank_account_instant_verification_gateway.rb +38 -0
  5. data/lib/braintree/bank_account_instant_verification_jwt.rb +23 -0
  6. data/lib/braintree/bank_account_instant_verification_jwt_request.rb +21 -0
  7. data/lib/braintree/error_codes.rb +2 -0
  8. data/lib/braintree/gateway.rb +4 -0
  9. data/lib/braintree/payment_method_gateway.rb +6 -0
  10. data/lib/braintree/successful_result.rb +1 -0
  11. data/lib/braintree/transaction/apple_pay_details.rb +1 -0
  12. data/lib/braintree/transaction.rb +1 -0
  13. data/lib/braintree/transaction_gateway.rb +24 -0
  14. data/lib/braintree/us_bank_account_verification.rb +3 -1
  15. data/lib/braintree/version.rb +1 -1
  16. data/lib/braintree.rb +3 -0
  17. data/spec/integration/braintree/bank_account_instant_verification_spec.rb +191 -0
  18. data/spec/integration/braintree/client_api/spec_helper.rb +81 -0
  19. data/spec/integration/braintree/payment_method_spec.rb +3 -0
  20. data/spec/integration/braintree/transaction_search_spec.rb +26 -24
  21. data/spec/integration/braintree/transaction_spec.rb +34 -3
  22. data/spec/integration/braintree/transaction_transfer_type_spec.rb +255 -0
  23. data/spec/spec_helper.rb +7 -0
  24. data/spec/unit/braintree/apple_pay_card_spec.rb +2 -0
  25. data/spec/unit/braintree/bank_account_instant_verification_gateway_spec.rb +98 -0
  26. data/spec/unit/braintree/bank_account_instant_verification_jwt_request_spec.rb +71 -0
  27. data/spec/unit/braintree/transaction_ach_mandate_spec.rb +82 -0
  28. data/spec/unit/braintree/transaction_gateway_spec.rb +20 -0
  29. data/spec/unit/braintree/transaction_spec.rb +10 -0
  30. metadata +13 -7
  31. data/lib/ssl/securetrust_ca.crt +0 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2e98c0f65f8fc26db02c0f16cbe7b86e28aa7fbf6829ec4acf23c44db5159cff
4
- data.tar.gz: e954ce7e083b2e1ea24c7cdd06acdcec52fc90238426bfca8ca7756200514677
3
+ metadata.gz: 0a1505b44cec85c55cc5237d0fa3d57165dfa809589893774fdecfc972147940
4
+ data.tar.gz: e92b0f87a02744e0df5db4173aa6a2e237dd5b7817932232e380a160d7df1450
5
5
  SHA512:
6
- metadata.gz: acc8c82a96904ca3dd89d3719d020756540af5f7bfdc1d56340a4b382ba1b6640732bb7f4eefd0073378fa4ed1c5dbb16a44fce9fcf4ed67146bffc0acd47314
7
- data.tar.gz: 755c3a07a8469e6ee09f189b8d0ab60bdbb11c324fea726cd0af2bc86307b7213300c64a6d94ae9eff91d5fdf628295e4f42aec1bd2845ba4e5634c46c9d61ad
6
+ metadata.gz: 2d5c303f50bd453a719fc0586593fcf9307fc8a1be02c5307487178bbf368d7e1467bf08ceda4e0b96c421a46f1d43d1f9c17af35206efcb22b5c3d0f0da9094
7
+ data.tar.gz: 287dadfccf55558b99069ffd42458b67085a68aabeb2d6575765e8f96c281c97158228bf99254a802d84b50e41fc90dc28b06d4c5984fb06e2563e28c108c286
@@ -84,6 +84,11 @@ module Braintree
84
84
  def self._update_signature
85
85
  _create_signature
86
86
  end
87
+
88
+ def self._address_attributes
89
+ [:street_address, :extended_address, :locality, :region, :postal_code, :country_code_alpha2,
90
+ {:international_phone => [:country_code, :national_number]}]
91
+ end
87
92
  end
88
93
  end
89
94
 
@@ -29,6 +29,7 @@ module Braintree
29
29
  attr_reader :expired
30
30
  attr_reader :healthcare
31
31
  attr_reader :image_url
32
+ attr_reader :is_device_token
32
33
  attr_reader :issuing_bank
33
34
  attr_reader :last_4
34
35
  attr_reader :merchant_token_identifier
@@ -0,0 +1,38 @@
1
+ module Braintree
2
+ class BankAccountInstantVerificationGateway
3
+
4
+ CREATE_JWT_MUTATION =
5
+ "mutation CreateBankAccountInstantVerificationJwt($input: CreateBankAccountInstantVerificationJwtInput!) { " +
6
+ " createBankAccountInstantVerificationJwt(input: $input) {" +
7
+ " jwt" +
8
+ " }" +
9
+ "}"
10
+
11
+ def initialize(gateway)
12
+ @gateway = gateway
13
+ @config = gateway.config
14
+ end
15
+
16
+ def create_jwt(request)
17
+ variables = request.to_graphql_variables
18
+ response = @gateway.graphql_client.query(CREATE_JWT_MUTATION, variables)
19
+ errors = Braintree::GraphQLClient.get_validation_errors(response)
20
+
21
+ if errors
22
+ ErrorResult.new(@gateway, {errors: errors})
23
+ else
24
+ data = response.dig(:data, :createBankAccountInstantVerificationJwt)
25
+
26
+ if data.nil?
27
+ raise UnexpectedError, "expected :createBankAccountInstantVerificationJwt"
28
+ end
29
+
30
+ jwt_attrs = {
31
+ :jwt => data[:jwt]
32
+ }
33
+
34
+ SuccessfulResult.new(:bank_account_instant_verification_jwt => BankAccountInstantVerificationJwt._new(jwt_attrs))
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,23 @@
1
+ module Braintree
2
+ class BankAccountInstantVerificationJwt
3
+ include BaseModule
4
+
5
+ attr_reader :jwt
6
+
7
+ def initialize(attributes)
8
+ set_instance_variables_from_hash(attributes)
9
+ end
10
+
11
+ def self._new(*args)
12
+ self.new(*args)
13
+ end
14
+
15
+ def inspect
16
+ attr_order = [:jwt]
17
+ formatted_attrs = attr_order.map do |attr|
18
+ "#{attr}: #{send(attr).inspect}"
19
+ end
20
+ "#<#{self.class} #{formatted_attrs.join(', ')}>"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ module Braintree
2
+ class BankAccountInstantVerificationJwtRequest
3
+ include BaseModule
4
+
5
+ attr_accessor :business_name, :return_url, :cancel_url
6
+
7
+ def initialize(attributes = {})
8
+ set_instance_variables_from_hash(attributes)
9
+ end
10
+
11
+ def to_graphql_variables
12
+ variables = {:input => {}}
13
+
14
+ variables[:input][:businessName] = business_name if business_name
15
+ variables[:input][:returnUrl] = return_url if return_url
16
+ variables[:input][:cancelUrl] = cancel_url if cancel_url
17
+
18
+ variables
19
+ end
20
+ end
21
+ end
@@ -459,6 +459,8 @@ module Braintree
459
459
  TransactionIsNotEligibleForAdjustment = "915219"
460
460
  TransactionMustBeInStateAuthorized = "915218"
461
461
  TransactionSourceIsInvalid = "915133"
462
+ TransactionTransferDetailsAreMandatory = "97510"
463
+ TransactionTransferTypeIsInvalid = "97501"
462
464
  TypeIsInvalid = "91523"
463
465
  TypeIsRequired = "91524"
464
466
  UnsupportedVoiceAuthorization = "91539"
@@ -26,6 +26,10 @@ module Braintree
26
26
  ApplePayGateway.new(self)
27
27
  end
28
28
 
29
+ def bank_account_instant_verification
30
+ BankAccountInstantVerificationGateway.new(self)
31
+ end
32
+
29
33
  def client_token
30
34
  ClientTokenGateway.new(self)
31
35
  end
@@ -201,6 +201,12 @@ module Braintree
201
201
  :ds_transaction_id,
202
202
  ]
203
203
  }
204
+ signature << {
205
+ :us_bank_account => [
206
+ :ach_mandate_text,
207
+ :ach_mandate_accepted_at,
208
+ ]
209
+ }
204
210
 
205
211
  case type
206
212
  when :create
@@ -23,6 +23,7 @@ module Braintree
23
23
  attr_reader :subscription
24
24
  attr_reader :supported_networks
25
25
  attr_reader :transaction
26
+ attr_reader :bank_account_instant_verification_jwt
26
27
  attr_reader :us_bank_account_verification
27
28
  attr_reader :session_id
28
29
  attr_reader :customer_recommendations
@@ -18,6 +18,7 @@ module Braintree
18
18
  attr_reader :global_id
19
19
  attr_reader :healthcare
20
20
  attr_reader :image_url
21
+ attr_reader :is_device_token
21
22
  attr_reader :issuing_bank
22
23
  attr_reader :last_4
23
24
  attr_reader :merchant_token_identifier
@@ -83,6 +83,7 @@ module Braintree
83
83
  end
84
84
 
85
85
  attr_reader :account_funding_transaction
86
+ attr_reader :ach_reject_reason
86
87
  attr_reader :ach_return_code
87
88
  attr_reader :ach_return_responses
88
89
  attr_reader :acquirer_reference_number
@@ -283,6 +283,30 @@ module Braintree
283
283
  {
284
284
  :transfer => [
285
285
  :type,
286
+ {
287
+ :sender => [
288
+ :first_name,
289
+ :last_name,
290
+ :account_reference_number,
291
+ :tax_id,
292
+ {:address => AddressGateway._address_attributes}
293
+ ]
294
+ },
295
+ {
296
+ :receiver => [
297
+ :first_name,
298
+ :last_name,
299
+ :account_reference_number,
300
+ :tax_id,
301
+ {:address => AddressGateway._address_attributes}
302
+ ]
303
+ },
304
+ ]
305
+ },
306
+ {
307
+ :us_bank_account => [
308
+ :ach_mandate_text,
309
+ :ach_mandate_accepted_at,
286
310
  ]
287
311
  },
288
312
  ]
@@ -15,11 +15,12 @@ module Braintree
15
15
 
16
16
  module VerificationMethod
17
17
  IndependentCheck = "independent_check"
18
+ InstantVerificationAccountValidation = "instant_verification_account_validation"
18
19
  NetworkCheck = "network_check"
19
20
  TokenizedCheck = "tokenized_check"
20
21
  MicroTransfers = "micro_transfers"
21
22
 
22
- All = [IndependentCheck, NetworkCheck, TokenizedCheck, MicroTransfers]
23
+ All = [IndependentCheck, InstantVerificationAccountValidation, NetworkCheck, TokenizedCheck, MicroTransfers]
23
24
  end
24
25
 
25
26
  module VerificationAddOns
@@ -42,6 +43,7 @@ module Braintree
42
43
 
43
44
  def initialize(attributes)
44
45
  set_instance_variables_from_hash(attributes)
46
+ @us_bank_account = UsBankAccount._new(nil, attributes[:us_bank_account]) if attributes[:us_bank_account]
45
47
  end
46
48
 
47
49
  def inspect
@@ -1,7 +1,7 @@
1
1
  module Braintree
2
2
  module Version
3
3
  Major = 4
4
- Minor = 30
4
+ Minor = 31
5
5
  Tiny = 0
6
6
 
7
7
  String = "#{Major}.#{Minor}.#{Tiny}"
data/lib/braintree.rb CHANGED
@@ -35,6 +35,9 @@ require "braintree/apple_pay_card"
35
35
  require "braintree/apple_pay_gateway"
36
36
  require "braintree/apple_pay_options"
37
37
  require "braintree/authorization_adjustment"
38
+ require "braintree/bank_account_instant_verification_gateway"
39
+ require "braintree/bank_account_instant_verification_jwt"
40
+ require "braintree/bank_account_instant_verification_jwt_request"
38
41
  require "braintree/bin_data"
39
42
  require "braintree/client_token"
40
43
  require "braintree/client_token_gateway"
@@ -0,0 +1,191 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+ require File.expand_path(File.dirname(__FILE__) + "/client_api/spec_helper")
3
+
4
+ describe Braintree::BankAccountInstantVerificationGateway do
5
+ before do
6
+ @gateway = Braintree::Gateway.new(
7
+ :environment => :development,
8
+ :merchant_id => "integration2_merchant_id",
9
+ :public_key => "integration2_public_key",
10
+ :private_key => "integration2_private_key",
11
+ )
12
+
13
+ @us_bank_gateway = Braintree::Gateway.new(
14
+ :environment => :development,
15
+ :merchant_id => "integration_merchant_id",
16
+ :public_key => "integration_public_key",
17
+ :private_key => "integration_private_key",
18
+ )
19
+ end
20
+
21
+ describe "create_jwt" do
22
+ it "creates a jwt with valid request" do
23
+ request = Braintree::BankAccountInstantVerificationJwtRequest.new(
24
+ :business_name => "15Ladders",
25
+ :return_url => "https://example.com/success",
26
+ :cancel_url => "https://example.com/cancel",
27
+ )
28
+
29
+ result = @gateway.bank_account_instant_verification.create_jwt(request)
30
+
31
+ unless result.success?
32
+ puts "DEBUG: Result failed!"
33
+ puts "DEBUG: Errors: #{result.errors.inspect}" if result.respond_to?(:errors)
34
+ end
35
+
36
+ expect(result.success?).to eq(true)
37
+ expect(result.bank_account_instant_verification_jwt).to have_attributes(
38
+ jwt: a_string_matching(/.+/),
39
+ )
40
+ end
41
+
42
+ it "fails with invalid business name" do
43
+ request = Braintree::BankAccountInstantVerificationJwtRequest.new(
44
+ :business_name => "", # Empty business name should cause validation error
45
+ :return_url => "https://example.com/return",
46
+ :cancel_url => "https://example.com/cancel",
47
+ )
48
+
49
+ result = @gateway.bank_account_instant_verification.create_jwt(request)
50
+
51
+ expect(result.success?).to eq(false)
52
+ expect(result.errors).not_to be_nil
53
+ end
54
+
55
+ it "fails with invalid URLs" do
56
+ request = Braintree::BankAccountInstantVerificationJwtRequest.new(
57
+ :business_name => "15Ladders",
58
+ :return_url => "not-a-valid-url",
59
+ :cancel_url => "also-not-valid",
60
+ )
61
+
62
+ result = @us_bank_gateway.bank_account_instant_verification.create_jwt(request)
63
+
64
+ expect(result.success?).to eq(false)
65
+ expect(result.errors).not_to be_nil
66
+ end
67
+ end
68
+
69
+ describe "charge US bank with ACH mandate" do
70
+ it "creates transaction directly with nonce and provides ACH mandate at transaction time (instant verification)" do
71
+ nonce = generate_us_bank_account_nonce_via_open_banking
72
+
73
+ mandate_accepted_at = Time.now - 300 # 5 minutes ago
74
+
75
+ # Create transaction directly with nonce and provide ACH mandate at transaction time (instant verification)
76
+ transaction_request = {
77
+ :amount => "12.34",
78
+ :payment_method_nonce => nonce,
79
+ :merchant_account_id => SpecHelper::UsBankMerchantAccountId, # could it be?
80
+ :us_bank_account => {
81
+ :ach_mandate_text => "I authorize this transaction and future debits",
82
+ :ach_mandate_accepted_at => mandate_accepted_at
83
+ },
84
+ :options => {
85
+ :submit_for_settlement => true
86
+ }
87
+ }
88
+
89
+ transaction_result = @us_bank_gateway.transaction.sale(transaction_request)
90
+
91
+ expect(transaction_result.success?).to eq(true), "Expected transaction success but got failure with validation errors (see console output)"
92
+ transaction = transaction_result.transaction
93
+
94
+ expected_transaction = {
95
+ id: a_string_matching(/.+/),
96
+ amount: BigDecimal("12.34"),
97
+ us_bank_account_details: have_attributes(
98
+ ach_mandate: have_attributes(
99
+ text: "I authorize this transaction and future debits",
100
+ accepted_at: be_a(Time),
101
+ ),
102
+ account_holder_name: "Dan Schulman",
103
+ last_4: "1234",
104
+ routing_number: "021000021",
105
+ account_type: "checking",
106
+ )
107
+ }
108
+
109
+ expect(transaction).to have_attributes(expected_transaction)
110
+ end
111
+ end
112
+
113
+ describe "Open Finance flow with INSTANT_VERIFICATION_ACCOUNT_VALIDATION" do
114
+ it "tokenizes bank account via Open Finance API, vaults with and charges" do
115
+
116
+ nonce = generate_us_bank_account_nonce_via_open_banking
117
+
118
+ customer_result = @us_bank_gateway.customer.create({})
119
+ expect(customer_result.success?).to eq(true)
120
+ customer = customer_result.customer
121
+
122
+ mandate_accepted_at = Time.now - 300
123
+
124
+ payment_method_request = {
125
+ :customer_id => customer.id,
126
+ :payment_method_nonce => nonce,
127
+ :us_bank_account => {
128
+ :ach_mandate_text => "I authorize this transaction and future debits",
129
+ :ach_mandate_accepted_at => mandate_accepted_at
130
+ },
131
+ :options => {
132
+ :verification_merchant_account_id => SpecHelper::UsBankMerchantAccountId,
133
+ :us_bank_account_verification_method => Braintree::UsBankAccountVerification::VerificationMethod::InstantVerificationAccountValidation
134
+ }
135
+ }
136
+
137
+ payment_method_result = @us_bank_gateway.payment_method.create(payment_method_request)
138
+ expect(payment_method_result.success?).to eq(true), "Expected payment method creation success but got failure with validation errors"
139
+
140
+ us_bank_account = payment_method_result.payment_method
141
+
142
+ expected_us_bank_account = {
143
+ verifications: a_collection_containing_exactly(
144
+ have_attributes(
145
+ verification_method: Braintree::UsBankAccountVerification::VerificationMethod::InstantVerificationAccountValidation,
146
+ status: "verified",
147
+ ),
148
+ ),
149
+ ach_mandate: have_attributes(
150
+ text: "I authorize this transaction and future debits",
151
+ accepted_at: be_a(Time),
152
+ )
153
+ }
154
+
155
+ expect(us_bank_account).to have_attributes(expected_us_bank_account)
156
+
157
+ verification = us_bank_account.verifications.first
158
+ expect(verification.verification_method).to eq(Braintree::UsBankAccountVerification::VerificationMethod::InstantVerificationAccountValidation)
159
+
160
+ transaction_request = {
161
+ :amount => "12.34",
162
+ :payment_method_token => us_bank_account.token,
163
+ :merchant_account_id => SpecHelper::UsBankMerchantAccountId,
164
+ :options => {
165
+ :submit_for_settlement => true
166
+ }
167
+ }
168
+
169
+ transaction_result = @us_bank_gateway.transaction.sale(transaction_request)
170
+ expect(transaction_result.success?).to eq(true), "Expected transaction success but got failure"
171
+ transaction = transaction_result.transaction
172
+
173
+ expected_transaction = {
174
+ id: a_string_matching(/.+/),
175
+ amount: BigDecimal("12.34"),
176
+ us_bank_account_details: have_attributes(
177
+ token: us_bank_account.token,
178
+ ach_mandate: have_attributes(
179
+ text: "I authorize this transaction and future debits",
180
+ accepted_at: be_a(Time),
181
+ ),
182
+ last_4: "1234",
183
+ routing_number: "021000021",
184
+ account_type: "checking",
185
+ )
186
+ }
187
+
188
+ expect(transaction).to have_attributes(expected_transaction)
189
+ end
190
+ end
191
+ end
@@ -147,6 +147,87 @@ def generate_invalid_us_bank_account_nonce
147
147
  nonce + "_xxx"
148
148
  end
149
149
 
150
+ def generate_us_bank_account_nonce_via_open_banking
151
+
152
+ config = Braintree::Configuration.new(
153
+ :environment => :development,
154
+ :merchant_id => "integration_merchant_id",
155
+ :public_key => "integration_public_key",
156
+ :private_key => "integration_private_key",
157
+ )
158
+
159
+ request_body = {
160
+ :account_details => {
161
+ :account_number => "567891234",
162
+ :account_type => "CHECKING",
163
+ :classification => "PERSONAL",
164
+ :tokenized_account => true,
165
+ :last_4 => "1234"
166
+ },
167
+ :institution_details => {
168
+ :bank_id => {
169
+ :bank_code => "021000021",
170
+ :country_code => "US"
171
+ }
172
+ },
173
+ :account_holders => [
174
+ {
175
+ :ownership => "PRIMARY",
176
+ :full_name => {
177
+ :name => "Dan Schulman"
178
+ },
179
+ :name => {
180
+ :given_name => "Dan",
181
+ :surname => "Schulman",
182
+ :full_name => "Dan Schulman"
183
+ }
184
+ }
185
+ ]
186
+ }
187
+
188
+ graphql_base_url = config.graphql_base_url
189
+ atmosphere_base_url = graphql_base_url.gsub("/graphql", "")
190
+ url = "#{atmosphere_base_url}/v1/open-finance/tokenize-bank-account-details"
191
+
192
+ uri = URI.parse(url)
193
+ connection = Net::HTTP.new(uri.host, uri.port)
194
+
195
+ if uri.scheme == "https"
196
+ connection.use_ssl = true
197
+ connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
198
+ connection.ca_file = config.ca_file if config.ca_file
199
+ end
200
+
201
+ response = connection.start do |http|
202
+ request = Net::HTTP::Post.new(uri.path)
203
+ request["Content-Type"] = "application/json"
204
+ request["Accept"] = "application/json"
205
+ request["Braintree-Version"] = "2019-01-01"
206
+ request["User-Agent"] = "Braintree Ruby Library #{Braintree::Version::String}"
207
+ request["X-ApiVersion"] = config.api_version
208
+
209
+ # Basic auth like Node.js
210
+ auth_string = "#{config.public_key}:#{config.private_key}"
211
+ request["Authorization"] = "Basic #{Base64.strict_encode64(auth_string)}"
212
+
213
+ request.body = request_body.to_json
214
+
215
+ http.request(request)
216
+ end
217
+
218
+ if response.code.to_i != 200
219
+ raise "HTTP #{response.code}: #{response.body}"
220
+ end
221
+
222
+ result = JSON.parse(response.body)
223
+
224
+ unless result["tenant_token"]
225
+ raise "Open Banking tokenization failed: #{result.inspect}"
226
+ end
227
+
228
+ result["tenant_token"]
229
+ end
230
+
150
231
  def _cosmos_post(token, url, payload)
151
232
  uri = URI::parse(url)
152
233
  connection = Net::HTTP.new(uri.host, uri.port)
@@ -108,6 +108,7 @@ describe Braintree::PaymentMethod do
108
108
  expect(apple_pay_card.payroll).not_to be_nil
109
109
  expect(apple_pay_card.prepaid).not_to be_nil
110
110
  expect(apple_pay_card.product_id).not_to be_nil
111
+ expect(apple_pay_card.is_device_token).to eq(true)
111
112
  end
112
113
 
113
114
  it "creates a payment method from a fake apple pay mpan nonce" do
@@ -143,6 +144,7 @@ describe Braintree::PaymentMethod do
143
144
  expect(apple_pay_card.prepaid).not_to be_nil
144
145
  expect(apple_pay_card.product_id).not_to be_nil
145
146
  expect(apple_pay_card.merchant_token_identifier).not_to be_nil
147
+ expect(apple_pay_card.is_device_token).not_to be_nil
146
148
  expect(apple_pay_card.source_card_last4).not_to be_nil
147
149
  end
148
150
 
@@ -1254,6 +1256,7 @@ describe Braintree::PaymentMethod do
1254
1256
  expect(apple_pay_card.expiration_year.to_i).to be > 0
1255
1257
  expect(apple_pay_card.source_description).to eq("Visa 2006")
1256
1258
  expect(apple_pay_card.customer_id).to eq(customer.id)
1259
+ expect(apple_pay_card.is_device_token).to eq(false)
1257
1260
  apple_pay_card.merchant_token_identifier == "DNITHE302308980427388297"
1258
1261
  apple_pay_card.source_card_last4 == "2006"
1259
1262
  end
@@ -176,6 +176,16 @@ describe Braintree::Transaction, "search" do
176
176
  expect(collection.first.id).to eq(transaction_id)
177
177
  end
178
178
 
179
+ it "searches on reason_codes for 3 items" do
180
+ reason_code = ["R01", "R02"]
181
+
182
+ collection = Braintree::Transaction.search do |search|
183
+ search.reason_code.in reason_code
184
+ end
185
+
186
+ expect(collection.maximum_size).to eq(3)
187
+ end
188
+
179
189
  it "searches on reason_code" do
180
190
  transaction_id = "ach_txn_ret1"
181
191
  reason_code = "R01"
@@ -184,9 +194,24 @@ describe Braintree::Transaction, "search" do
184
194
  search.reason_code.in reason_code
185
195
  end
186
196
  item = collection.find { |t| t.id == transaction_id }
197
+ expect(item.ach_return_code).to eq("R01")
187
198
  expect(item.ach_return_responses.first[:reason_code]).to eq("R01")
188
199
  end
189
200
 
201
+ it "searches on rejections reason_code" do
202
+ transaction_id = "ach_txn_ret3"
203
+ reason_code = "RJCT"
204
+
205
+ collection = Braintree::Transaction.search do |search|
206
+ search.reason_code.in reason_code
207
+ end
208
+ item = collection.find { |t| t.id == transaction_id }
209
+ expect(item.ach_return_code).to eq("RJCT")
210
+ expect(item.ach_reject_reason).to eq("Bank accounts located outside of the U.S. are not supported.")
211
+ expect(item.ach_return_responses.first[:reason_code]).to eq("RJCT")
212
+ expect(item.ach_return_responses.first[:reject_reason]).to eq("Bank accounts located outside of the U.S. are not supported.")
213
+ end
214
+
190
215
  it "searches on reason_codes" do
191
216
  reason_code = "any_reason_code"
192
217
 
@@ -194,7 +219,7 @@ describe Braintree::Transaction, "search" do
194
219
  search.reason_code.is reason_code
195
220
  end
196
221
 
197
- expect(collection.maximum_size).to eq(4)
222
+ expect(collection.maximum_size).to eq(6)
198
223
  end
199
224
 
200
225
  context "multiple value fields" do
@@ -588,29 +613,6 @@ describe Braintree::Transaction, "search" do
588
613
  expect(collection.first.id).to eq(transaction_id)
589
614
  end
590
615
 
591
- it "searches on reason_codes for 3 items" do
592
- reason_code = ["R01", "R02"]
593
-
594
- collection = Braintree::Transaction.search do |search|
595
- search.reason_code.in reason_code
596
- end
597
-
598
- expect(collection.maximum_size).to eq(3)
599
- end
600
-
601
- xit "searches on a reason_code" do
602
- # duplicate test
603
- reason_code = ["R01"]
604
- transaction_id = "ach_txn_ret1"
605
-
606
- collection = Braintree::Transaction.search do |search|
607
- search.reason_code.in reason_code
608
- end
609
-
610
- expect(collection.maximum_size).to eq(1)
611
- expect(collection.first.id).to eq(transaction_id)
612
- end
613
-
614
616
  xit "searches on debit_network" do
615
617
  transaction = Braintree::Transaction.sale!(
616
618
  :amount => Braintree::Test::TransactionAmounts::Authorize,