braintree 4.38.0 → 4.40.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 (32) hide show
  1. checksums.yaml +4 -4
  2. data/lib/braintree/address_gateway.rb +13 -3
  3. data/lib/braintree/credit_card_gateway.rb +1 -0
  4. data/lib/braintree/credit_card_verification_gateway.rb +1 -0
  5. data/lib/braintree/dispute_gateway.rb +7 -7
  6. data/lib/braintree/error_codes.rb +14 -0
  7. data/lib/braintree/payment_method_gateway.rb +1 -0
  8. data/lib/braintree/three_d_secure_pass_thru.rb +11 -0
  9. data/lib/braintree/transaction/local_payment_details.rb +2 -0
  10. data/lib/braintree/transaction/paypal_details.rb +2 -0
  11. data/lib/braintree/transaction/sepa_direct_debit_account_details.rb +2 -0
  12. data/lib/braintree/transaction_gateway.rb +3 -0
  13. data/lib/braintree/util.rb +5 -0
  14. data/lib/braintree/version.rb +1 -1
  15. data/lib/braintree.rb +1 -0
  16. data/spec/integration/braintree/advanced_search_spec.rb +4 -7
  17. data/spec/integration/braintree/braintree_gateway_spec.rb +1 -2
  18. data/spec/integration/braintree/credit_card_spec.rb +94 -2
  19. data/spec/integration/braintree/credit_card_verification_spec.rb +33 -0
  20. data/spec/integration/braintree/customer_spec.rb +153 -5
  21. data/spec/integration/braintree/http_spec.rb +1 -1
  22. data/spec/integration/braintree/payment_method_spec.rb +77 -7
  23. data/spec/integration/braintree/samsung_pay_card_spec.rb +1 -1
  24. data/spec/integration/braintree/transaction_search_spec.rb +18 -13
  25. data/spec/integration/braintree/transaction_spec.rb +116 -16
  26. data/spec/integration/braintree/transaction_transfer_type_spec.rb +71 -1
  27. data/spec/unit/braintree/address_spec.rb +32 -0
  28. data/spec/unit/braintree/credit_card_spec.rb +2 -0
  29. data/spec/unit/braintree/customer_spec.rb +2 -0
  30. data/spec/unit/braintree/dispute_spec.rb +38 -0
  31. data/spec/unit/braintree/transaction_gateway_spec.rb +3 -0
  32. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9847c722f0454ca6210b66fd3c083214b2f81947e2b8e2aa3ffd31e7892ae5c1
4
- data.tar.gz: 0faf0a4519808b21007000b57e353fbf6fd89c02a64551f6fa5560fa00f9fbde
3
+ metadata.gz: a358a5cff7db74d5364a662ed1076dd786742d6d6f75b0f9c040fda06353a955
4
+ data.tar.gz: b78e2a6f20ab1207515ea76f3e7aaa6a367283b10821b026c9f89498e2e8f35c
5
5
  SHA512:
6
- metadata.gz: 91921d4cd7aabff1e758003dc4de8e715c5dd3ba704d5682b9adb74340012eb94eb7c328e40a6620985b1ad129006d62d2c15160f49b483f9b34d3ea8e441d6b
7
- data.tar.gz: 384b5dcaf3a750f916b1cfb49bc60b625d8cc8c2fc729f3999fe81e6b5c0fcdba32de94cdceb7fde1a1184a12fb3eeaf95eac2dfbfb46c58b38935d578e82b78
6
+ metadata.gz: 7fbb0b0ca10ec35cd3e8e6d34476eaada51e465caf4aa25a00e6d61fdbafea147a25579ed012717f2b2fec3da184d823dd0756add7738d8e4bcf1a8abea1dd2d
7
+ data.tar.gz: 7374cd696e006db551149f9363194c3a8ecafc7ec607b93b6a53f2eeb3eb2961e4b63bd68d20c2ea0f5262fab405597e924219b7e76fd514b0a398c367fa7403
@@ -13,7 +13,7 @@ module Braintree
13
13
  unless attributes[:customer_id]
14
14
  raise ArgumentError, "Expected hash to contain a :customer_id"
15
15
  end
16
- unless attributes[:customer_id] =~ /\A[0-9A-Za-z_-]+\z/
16
+ if Util.invalid_path_segment?(attributes[:customer_id])
17
17
  raise ArgumentError, ":customer_id contains invalid characters"
18
18
  end
19
19
  response = @config.http.post("#{@config.base_merchant_path}/customers/#{attributes.delete(:customer_id)}/addresses", :address => attributes)
@@ -32,13 +32,14 @@ module Braintree
32
32
 
33
33
  def delete(customer_or_customer_id, address_id)
34
34
  customer_id = _determine_customer_id(customer_or_customer_id)
35
+ address_id = _determine_address_id(address_id)
35
36
  @config.http.delete("#{@config.base_merchant_path}/customers/#{customer_id}/addresses/#{address_id}")
36
37
  SuccessfulResult.new
37
38
  end
38
39
 
39
40
  def find(customer_or_customer_id, address_id)
40
41
  customer_id = _determine_customer_id(customer_or_customer_id)
41
- raise ArgumentError if address_id.nil? || address_id.to_s.strip == ""
42
+ address_id = _determine_address_id(address_id)
42
43
  response = @config.http.get("#{@config.base_merchant_path}/customers/#{customer_id}/addresses/#{address_id}")
43
44
  Address._new(@gateway, response[:address])
44
45
  rescue NotFoundError
@@ -48,6 +49,7 @@ module Braintree
48
49
  def update(customer_or_customer_id, address_id, attributes)
49
50
  Util.verify_keys(AddressGateway._update_signature, attributes)
50
51
  customer_id = _determine_customer_id(customer_or_customer_id)
52
+ address_id = _determine_address_id(address_id)
51
53
  response = @config.http.put("#{@config.base_merchant_path}/customers/#{customer_id}/addresses/#{address_id}", :address => attributes)
52
54
  if response[:address]
53
55
  SuccessfulResult.new(:address => Address._new(@gateway, response[:address]))
@@ -64,12 +66,20 @@ module Braintree
64
66
 
65
67
  def _determine_customer_id(customer_or_customer_id)
66
68
  customer_id = customer_or_customer_id.is_a?(Customer) ? customer_or_customer_id.id : customer_or_customer_id
67
- unless customer_id =~ /\A[\w_-]+\z/
69
+ if Util.invalid_path_segment?(customer_id)
68
70
  raise ArgumentError, "customer_id contains invalid characters"
69
71
  end
70
72
  customer_id
71
73
  end
72
74
 
75
+ def _determine_address_id(address_id)
76
+ address_id = address_id.to_s
77
+ if Util.invalid_path_segment?(address_id)
78
+ raise ArgumentError, "address_id contains invalid characters"
79
+ end
80
+ address_id
81
+ end
82
+
73
83
  def self._create_signature
74
84
  _shared_signature + [:customer_id]
75
85
  end
@@ -129,6 +129,7 @@ module Braintree
129
129
  :directory_response,
130
130
  :cavv_algorithm,
131
131
  :ds_transaction_id,
132
+ :network,
132
133
  ]
133
134
  }
134
135
 
@@ -81,6 +81,7 @@ module Braintree
81
81
  :directory_response,
82
82
  :ds_transaction_id,
83
83
  :eci_flag,
84
+ :network,
84
85
  :three_d_secure_version,
85
86
  :xid,
86
87
  ]},
@@ -7,7 +7,7 @@ module Braintree
7
7
  end
8
8
 
9
9
  def accept(dispute_id)
10
- raise ArgumentError, "dispute_id contains invalid characters" unless dispute_id.to_s =~ /\A[\w-]+\z/
10
+ raise ArgumentError, "dispute_id contains invalid characters" if Util.invalid_path_segment?(dispute_id)
11
11
  raise ArgumentError, "dispute_id cannot be blank" if dispute_id.nil? || dispute_id.to_s.strip == ""
12
12
 
13
13
  response = @config.http.put("#{@config.base_merchant_path}/disputes/#{dispute_id}/accept")
@@ -21,7 +21,7 @@ module Braintree
21
21
  end
22
22
 
23
23
  def add_file_evidence(dispute_id, document_id_or_request)
24
- raise ArgumentError, "dispute_id contains invalid characters" unless dispute_id.to_s =~ /\A[\w-]+\z/
24
+ raise ArgumentError, "dispute_id contains invalid characters" if Util.invalid_path_segment?(dispute_id)
25
25
  raise ArgumentError, "dispute_id cannot be blank" if dispute_id.nil? || dispute_id.to_s.strip == ""
26
26
  raise ArgumentError, "document_id_or_request cannot be blank" if document_id_or_request.nil?
27
27
 
@@ -51,7 +51,7 @@ module Braintree
51
51
  end
52
52
 
53
53
  def add_text_evidence(dispute_id, content_or_request)
54
- raise ArgumentError, "dispute_id contains invalid characters" unless dispute_id.to_s =~ /\A[\w-]+\z/
54
+ raise ArgumentError, "dispute_id contains invalid characters" if Util.invalid_path_segment?(dispute_id)
55
55
  raise ArgumentError, "dispute_id cannot be blank" if dispute_id.nil? || dispute_id.to_s.strip == ""
56
56
  raise ArgumentError, "content_or_request cannot be blank" if content_or_request.nil?
57
57
 
@@ -84,7 +84,7 @@ module Braintree
84
84
  end
85
85
 
86
86
  def finalize(dispute_id)
87
- raise ArgumentError, "dispute_id contains invalid characters" unless dispute_id.to_s =~ /\A[\w-]+\z/
87
+ raise ArgumentError, "dispute_id contains invalid characters" if Util.invalid_path_segment?(dispute_id)
88
88
  raise ArgumentError, "dispute_id cannot be blank" if dispute_id.nil? || dispute_id.to_s.strip == ""
89
89
 
90
90
  response = @config.http.put("#{@config.base_merchant_path}/disputes/#{dispute_id}/finalize")
@@ -98,7 +98,7 @@ module Braintree
98
98
  end
99
99
 
100
100
  def find(dispute_id)
101
- raise ArgumentError, "dispute_id contains invalid characters" unless dispute_id.to_s =~ /\A[\w-]+\z/
101
+ raise ArgumentError, "dispute_id contains invalid characters" if Util.invalid_path_segment?(dispute_id)
102
102
  raise ArgumentError, "dispute_id cannot be blank" if dispute_id.nil? || dispute_id.to_s.strip == ""
103
103
  response = @config.http.get("#{@config.base_merchant_path}/disputes/#{dispute_id}")
104
104
  Dispute._new(response[:dispute])
@@ -107,9 +107,9 @@ module Braintree
107
107
  end
108
108
 
109
109
  def remove_evidence(dispute_id, evidence_id)
110
- raise ArgumentError, "dispute_id contains invalid characters" unless dispute_id.to_s =~ /\A[\w-]+\z/
110
+ raise ArgumentError, "dispute_id contains invalid characters" if Util.invalid_path_segment?(dispute_id)
111
111
  raise ArgumentError, "dispute_id cannot be blank" if dispute_id.nil? || dispute_id.to_s.strip == ""
112
- raise ArgumentError, "evidence_id contains invalid characters" unless evidence_id.to_s =~ /\A[\w-]+\z/
112
+ raise ArgumentError, "evidence_id contains invalid characters" if Util.invalid_path_segment?(evidence_id)
113
113
  raise ArgumentError, "evidence_id cannot be blank" if evidence_id.nil? || evidence_id.to_s.strip == ""
114
114
 
115
115
  response = @config.http.delete("#{@config.base_merchant_path}/disputes/#{dispute_id}/evidence/#{evidence_id}")
@@ -216,6 +216,8 @@ module Braintree
216
216
  CannotVaultOneTimeUsePayPalAccount = "82902"
217
217
  ConsentCodeOrAccessTokenIsRequired = "82901"
218
218
  CustomerIdIsRequiredForVaulting = "82905"
219
+ EmailFormatIsInvalid = "92963"
220
+ EmailIsTooLong = "92964"
219
221
  IncompletePayPalAccount = "82901"
220
222
  InvalidFundingSourceSelection = "92913"
221
223
  InvalidParamsForPayPalAccountUpdate = "92915"
@@ -355,6 +357,7 @@ module Braintree
355
357
  BillingPhoneNumberIsInvalid = "915206"
356
358
  CannotBeVoided = "91504"
357
359
  CannotCloneCredit = "91543"
360
+ CannotCloneThirdPartyCofNetworkTokenTransaction = "915274"
358
361
  CannotCloneTransactionWithPayPalAccount = "91573"
359
362
  CannotCloneTransactionWithVaultCreditCard = "91540"
360
363
  CannotCloneUnsuccessfulTransaction = "91542"
@@ -471,6 +474,10 @@ module Braintree
471
474
  ThreeDSecureEciFlagIsInvalid = "915114"
472
475
  ThreeDSecureEciFlagIsRequired = "915113"
473
476
  ThreeDSecureMerchantAccountDoesNotSupportCardType = "915131"
477
+ ThreeDSecureNetworkDoesNotMatchPaymentInstrument = "915139"
478
+ ThreeDSecureNetworkDoesNotSupportCurrency = "915239"
479
+ ThreeDSecureNetworkDoesNotSupportMerchantAccountCurrency = "915243"
480
+ ThreeDSecureNetworkIsInvalid = "915128"
474
481
  ThreeDSecureThreeDSecureVersionIsInvalid = "915119"
475
482
  ThreeDSecureTokenIsInvalid = "91568"
476
483
  ThreeDSecureTransactionDataDoesntMatchVerify = "91570"
@@ -483,10 +490,12 @@ module Braintree
483
490
  TransactionTransferDetailsAreMandatory = "97510"
484
491
  TransactionTransferDetailsAreNotApplicable = "97511"
485
492
  TransactionTransferReceiverAccountReferenceNumberIsNotValid = "97509"
493
+ TransactionTransferReceiverAccountReferenceNumberTypeIsInvalid = "97514"
486
494
  TransactionTransferReceiverFirstNameIsNotValid = "97507"
487
495
  TransactionTransferReceiverLastNameIsNotValid = "97508"
488
496
  TransactionTransferReceiverTaxIdIsNotValid = "97506"
489
497
  TransactionTransferSenderAccountReferenceNumberIsNotValid = "97505"
498
+ TransactionTransferSenderAccountReferenceNumberTypeIsInvalid = "97513"
490
499
  TransactionTransferSenderFirstNameIsNotValid = "97503"
491
500
  TransactionTransferSenderLastNameIsNotValid = "97504"
492
501
  TransactionTransferSenderTaxIdIsNotValid = "97502"
@@ -499,6 +508,7 @@ module Braintree
499
508
 
500
509
 
501
510
  module Options
511
+ SubmitForSettlementIsNotSupportedForNetwork = "915261"
502
512
  SubmitForSettlementIsRequiredForCloning = "91544"
503
513
  SubmitForSettlementIsRequiredForPayPalUnilateral = "91582"
504
514
  VaultIsDisabled = "91525"
@@ -765,6 +775,10 @@ module Braintree
765
775
  DirectoryResponseIsInvalid = "942121"
766
776
  EciFlagIsInvalid = "942114"
767
777
  EciFlagIsRequired = "942113"
778
+ NetworkDoesNotMatchPaymentInstrument = "942139"
779
+ NetworkDoesNotSupportCurrency = "942129"
780
+ NetworkDoesNotSupportMerchantAccountCurrency = "942130"
781
+ NetworkIsInvalid = "942128"
768
782
  ThreeDSecureVersionIsInvalid = "942119"
769
783
  ThreeDSecureVersionIsRequired = "942117"
770
784
  end
@@ -199,6 +199,7 @@ module Braintree
199
199
  :directory_response,
200
200
  :cavv_algorithm,
201
201
  :ds_transaction_id,
202
+ :network,
202
203
  ]
203
204
  }
204
205
  signature << {
@@ -0,0 +1,11 @@
1
+ module Braintree
2
+ module ThreeDSecurePassThru
3
+ module Network
4
+ Eftpos = "eftpos"
5
+ MasterCard = "Mastercard"
6
+ Visa = "Visa"
7
+
8
+ All = constants.map { |c| const_get(c) }
9
+ end
10
+ end
11
+ end
@@ -6,6 +6,8 @@ module Braintree
6
6
  attr_reader :blik_aliases
7
7
  attr_reader :capture_id
8
8
  attr_reader :custom_field
9
+ # NEXT_MAJOR_VERSION Remove this attribute
10
+ # DEPRECATED debug_id is deprecated and will be removed in a future version
9
11
  attr_reader :debug_id
10
12
  attr_reader :description
11
13
  attr_reader :funding_source
@@ -7,6 +7,8 @@ module Braintree
7
7
  attr_reader :billing_agreement_id
8
8
  attr_reader :capture_id
9
9
  attr_reader :custom_field
10
+ # NEXT_MAJOR_VERSION Remove this attribute
11
+ # DEPRECATED debug_id is deprecated and will be removed in a future version
10
12
  attr_reader :debug_id
11
13
  attr_reader :description
12
14
  attr_reader :image_url
@@ -5,6 +5,8 @@ module Braintree
5
5
 
6
6
  attr_reader :bank_reference_token
7
7
  attr_reader :capture_id
8
+ # NEXT_MAJOR_VERSION Remove this attribute
9
+ # DEPRECATED debug_id is deprecated and will be removed in a future version
8
10
  attr_reader :debug_id
9
11
  attr_reader :global_id
10
12
  attr_reader :last_4
@@ -283,6 +283,7 @@ module Braintree
283
283
  :directory_response,
284
284
  :cavv_algorithm,
285
285
  :ds_transaction_id,
286
+ :network,
286
287
  ]
287
288
  },
288
289
  {
@@ -291,6 +292,7 @@ module Braintree
291
292
  {
292
293
  :sender => [
293
294
  :account_reference_number,
295
+ :account_reference_number_type,
294
296
  :date_of_birth,
295
297
  :first_name,
296
298
  :last_name,
@@ -302,6 +304,7 @@ module Braintree
302
304
  {
303
305
  :receiver => [
304
306
  :account_reference_number,
307
+ :account_reference_number_type,
305
308
  :first_name,
306
309
  :last_name,
307
310
  :middle_name,
@@ -1,5 +1,10 @@
1
1
  module Braintree
2
2
  module Util
3
+ # Allowlist of the characters that make up a Braintree id/token.
4
+ def self.invalid_path_segment?(value)
5
+ !value.to_s.match?(/\A[A-Za-z0-9_-]+\z/)
6
+ end
7
+
3
8
  def self.extract_attribute_as_array(hash, attribute)
4
9
  raise UnexpectedError.new("Unprocessable entity due to an invalid request") if hash.nil?
5
10
  value = hash.has_key?(attribute) ? hash.delete(attribute) : []
@@ -1,7 +1,7 @@
1
1
  module Braintree
2
2
  module Version
3
3
  Major = 4
4
- Minor = 38
4
+ Minor = 40
5
5
  Tiny = 0
6
6
 
7
7
  String = "#{Major}.#{Minor}.#{Tiny}"
data/lib/braintree.rb CHANGED
@@ -138,6 +138,7 @@ require "braintree/risk_data/liability_shift"
138
138
  require "braintree/facilitated_details"
139
139
  require "braintree/facilitator_details"
140
140
  require "braintree/three_d_secure_info"
141
+ require "braintree/three_d_secure_pass_thru"
141
142
  require "braintree/settlement_batch_summary"
142
143
  require "braintree/settlement_batch_summary_gateway"
143
144
  require "braintree/resource_collection"
@@ -33,8 +33,7 @@ describe Braintree::AdvancedSearch do
33
33
  expect(collection).not_to include(subscription2)
34
34
  end
35
35
 
36
- # we are temporarily skipping this test until we have a more stable CI env
37
- xit "is_not" do
36
+ it "is_not" do
38
37
  id = rand(36**8).to_s(36)
39
38
  subscription1 = Braintree::Subscription.create(
40
39
  :payment_method_token => @credit_card.token,
@@ -81,8 +80,7 @@ describe Braintree::AdvancedSearch do
81
80
  expect(collection).not_to include(subscription2)
82
81
  end
83
82
 
84
- # we are temporarily skipping this test until we have a more stable CI env
85
- xit "ends_with" do
83
+ it "ends_with" do
86
84
  id = rand(36**8).to_s(36)
87
85
  subscription1 = Braintree::Subscription.create(
88
86
  :payment_method_token => @credit_card.token,
@@ -177,8 +175,7 @@ describe Braintree::AdvancedSearch do
177
175
  expect(collection).not_to include(subscription2)
178
176
  end
179
177
 
180
- # ignore until more stable CI
181
- xit "returns only matching results given an argument list" do
178
+ it "returns only matching results given an argument list" do
182
179
  subscription1 = Braintree::Subscription.create(
183
180
  :payment_method_token => @credit_card.token,
184
181
  :plan_id => SpecHelper::TriallessPlan[:id],
@@ -265,7 +262,7 @@ describe Braintree::AdvancedSearch do
265
262
 
266
263
  context "multiple_value_or_text_field" do
267
264
  describe "in" do
268
- xit "works for the in operator(temporarily disabling until more stable CI)" do
265
+ it "works for the in operator(temporarily disabling until more stable CI)" do
269
266
  Braintree::Subscription.create(
270
267
  :payment_method_token => @credit_card.token,
271
268
  :plan_id => SpecHelper::TriallessPlan[:id],
@@ -12,8 +12,7 @@ describe Braintree::Gateway do
12
12
  end
13
13
 
14
14
  describe "query" do
15
- # we are temporarily skipping this test until we have a more stable CI env
16
- xit "makes valid GraphQL queries when given a definition" do
15
+ it "makes valid GraphQL mutation queries for tokenizeCreditCard" do
17
16
  definition = <<-GRAPHQL
18
17
  mutation ExampleServerSideSingleUseToken($input: TokenizeCreditCardInput!) {
19
18
  tokenizeCreditCard(input: $input) {
@@ -312,6 +312,99 @@ describe Braintree::CreditCard do
312
312
  expect(result.success?).to eq(true)
313
313
  end
314
314
 
315
+ it "accepts a three_d_secure_pass_thru network specified in the request" do
316
+ customer = Braintree::Customer.create!
317
+ result = Braintree::CreditCard.create(
318
+ :customer_id => customer.id,
319
+ :payment_method_nonce => Braintree::Test::Nonce::TransactableVisa,
320
+ :three_d_secure_pass_thru => {
321
+ :eci_flag => "05",
322
+ :cavv => "some_cavv",
323
+ :xid => "some_xid",
324
+ :three_d_secure_version => "2.2.0",
325
+ :authentication_response => "Y",
326
+ :directory_response => "Y",
327
+ :cavv_algorithm => "2",
328
+ :ds_transaction_id => "some_ds_transaction_id",
329
+ :network => Braintree::ThreeDSecurePassThru::Network::Visa,
330
+ },
331
+ :options => {:verify_card => true},
332
+ )
333
+ expect(result.success?).to eq(true)
334
+ end
335
+
336
+ it "rejects invalid network value in 3ds pass thru params" do
337
+ customer = Braintree::Customer.create!
338
+ result = Braintree::CreditCard.create(
339
+ :customer_id => customer.id,
340
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
341
+ :three_d_secure_pass_thru => {
342
+ :eci_flag => "05",
343
+ :cavv => "some_cavv",
344
+ :xid => "some_xid",
345
+ :three_d_secure_version => "2.2.0",
346
+ :authentication_response => "Y",
347
+ :directory_response => "Y",
348
+ :cavv_algorithm => "2",
349
+ :ds_transaction_id => "some_ds_transaction_id",
350
+ :network => "DISCOVER",
351
+ },
352
+ :options => {:verify_card => true},
353
+ )
354
+ expect(result).not_to be_success
355
+ error = result.errors.for(:verification).first
356
+ expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::NetworkIsInvalid)
357
+ expect(error.message).to eq("Network is invalid. Supported networks are eftpos, Visa, and Mastercard.")
358
+ end
359
+
360
+ it "rejects request where 3ds pass thru network does not match the payment instrument (VISA nonce, Mastercard network)" do
361
+ customer = Braintree::Customer.create!
362
+ result = Braintree::CreditCard.create(
363
+ :customer_id => customer.id,
364
+ :payment_method_nonce => Braintree::Test::Nonce::TransactableVisa,
365
+ :three_d_secure_pass_thru => {
366
+ :eci_flag => "05",
367
+ :cavv => "some_cavv",
368
+ :xid => "some_xid",
369
+ :three_d_secure_version => "2.2.0",
370
+ :authentication_response => "Y",
371
+ :directory_response => "Y",
372
+ :cavv_algorithm => "2",
373
+ :ds_transaction_id => "some_ds_transaction_id",
374
+ :network => Braintree::ThreeDSecurePassThru::Network::MasterCard,
375
+ },
376
+ :options => {:verify_card => true},
377
+ )
378
+ expect(result).not_to be_success
379
+ error = result.errors.for(:verification).first
380
+ expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::NetworkDoesNotMatchPaymentInstrument)
381
+ expect(error.message).to eq("Network does not match the payment instrument.")
382
+ end
383
+
384
+ it "rejects request where 3ds pass thru network does not support the merchant account currency" do
385
+ customer = Braintree::Customer.create!
386
+ result = Braintree::CreditCard.create(
387
+ :customer_id => customer.id,
388
+ :payment_method_nonce => Braintree::Test::Nonce::TransactableVisa,
389
+ :three_d_secure_pass_thru => {
390
+ :eci_flag => "05",
391
+ :cavv => "some_cavv",
392
+ :xid => "some_xid",
393
+ :three_d_secure_version => "2.2.0",
394
+ :authentication_response => "Y",
395
+ :directory_response => "Y",
396
+ :cavv_algorithm => "2",
397
+ :ds_transaction_id => "some_ds_transaction_id",
398
+ :network => Braintree::ThreeDSecurePassThru::Network::Eftpos,
399
+ },
400
+ :options => {:verify_card => true},
401
+ )
402
+ expect(result).not_to be_success
403
+ error = result.errors.for(:verification).first
404
+ expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::NetworkDoesNotSupportMerchantAccountCurrency)
405
+ expect(error.message).to eq("Network does not support the currency of the merchant account.")
406
+ end
407
+
315
408
  it "returns 3DS info on cc verification" do
316
409
  customer = Braintree::Customer.create!
317
410
  result = Braintree::CreditCard.create(
@@ -1263,8 +1356,7 @@ describe Braintree::CreditCard do
1263
1356
  end
1264
1357
 
1265
1358
  describe "self.expiring_between" do
1266
- #Disabling this test until we have a more stable CI
1267
- xit "finds payment methods expiring between the given dates" do
1359
+ it "finds payment methods expiring between the given dates" do
1268
1360
  next_year = Time.now.year + 1
1269
1361
  collection = Braintree::CreditCard.expiring_between(Time.mktime(next_year, 1), Time.mktime(next_year, 12))
1270
1362
  expect(collection.maximum_size).to be > 0
@@ -630,5 +630,38 @@ describe Braintree::CreditCardVerification, "search" do
630
630
  expect(result.credit_card_verification.processor_response_type).to eq(Braintree::ProcessorResponseTypes::Approved)
631
631
  expect(result.credit_card_verification.network_transaction_id).not_to be_nil
632
632
  end
633
+
634
+ it "can create a verification with a three_d_secure_pass_thru network specified" do
635
+ verification_params = {
636
+ :credit_card => {
637
+ :number => Braintree::Test::CreditCardNumbers::Visa,
638
+ :expiration_date => "12/12",
639
+ },
640
+ :options => {
641
+ :amount => "10.00",
642
+ },
643
+ :three_d_secure_pass_thru => {
644
+ :eci_flag => "05",
645
+ :cavv => "some_cavv",
646
+ :xid => "some_xid",
647
+ :three_d_secure_version => "2.2.0",
648
+ :authentication_response => "Y",
649
+ :directory_response => "Y",
650
+ :cavv_algorithm => "2",
651
+ :ds_transaction_id => "some_ds_id",
652
+ :network => Braintree::ThreeDSecurePassThru::Network::Visa,
653
+ },
654
+ }
655
+
656
+ result = Braintree::CreditCardVerification.create(verification_params)
657
+
658
+ expect(result).to be_success
659
+ expect(result.credit_card_verification.id).to match(/^\w{6,}$/)
660
+ expect(result.credit_card_verification.status).to eq(Braintree::CreditCardVerification::Status::Verified)
661
+ expect(result.credit_card_verification.processor_response_code).to eq("1000")
662
+ expect(result.credit_card_verification.processor_response_text).to eq("Approved")
663
+ expect(result.credit_card_verification.processor_response_type).to eq(Braintree::ProcessorResponseTypes::Approved)
664
+ expect(result.credit_card_verification.network_transaction_id).not_to be_nil
665
+ end
633
666
  end
634
667
  end