braintree 4.39.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a8a4986148f9b2ded5832261519f85d75e2932d7d7d15bc7d49207d2422431e
4
- data.tar.gz: 3431f5d87f5f15ffd7c2d29fe28674d7c49645f0447342360d0f41444def6c16
3
+ metadata.gz: a358a5cff7db74d5364a662ed1076dd786742d6d6f75b0f9c040fda06353a955
4
+ data.tar.gz: b78e2a6f20ab1207515ea76f3e7aaa6a367283b10821b026c9f89498e2e8f35c
5
5
  SHA512:
6
- metadata.gz: d523c2199f88f2eea71960c92659b7e8aabb02aa78c35ab51f0b513b575d408b6df9b881c5d895ed8a30b300c3ab4c43fa48ce3d88a331dcd9c96c9c6aac8ca8
7
- data.tar.gz: d6dc3e11eec83fcbd5c045ff92b04e83ff80686ecc19eedf17a50b19b68d0511f2ec1514fa0f13081ba889509ae161f8f1121380a6e51baa1daf66fa6115f509
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"
@@ -472,6 +474,10 @@ module Braintree
472
474
  ThreeDSecureEciFlagIsInvalid = "915114"
473
475
  ThreeDSecureEciFlagIsRequired = "915113"
474
476
  ThreeDSecureMerchantAccountDoesNotSupportCardType = "915131"
477
+ ThreeDSecureNetworkDoesNotMatchPaymentInstrument = "915139"
478
+ ThreeDSecureNetworkDoesNotSupportCurrency = "915239"
479
+ ThreeDSecureNetworkDoesNotSupportMerchantAccountCurrency = "915243"
480
+ ThreeDSecureNetworkIsInvalid = "915128"
475
481
  ThreeDSecureThreeDSecureVersionIsInvalid = "915119"
476
482
  ThreeDSecureTokenIsInvalid = "91568"
477
483
  ThreeDSecureTransactionDataDoesntMatchVerify = "91570"
@@ -502,6 +508,7 @@ module Braintree
502
508
 
503
509
 
504
510
  module Options
511
+ SubmitForSettlementIsNotSupportedForNetwork = "915261"
505
512
  SubmitForSettlementIsRequiredForCloning = "91544"
506
513
  SubmitForSettlementIsRequiredForPayPalUnilateral = "91582"
507
514
  VaultIsDisabled = "91525"
@@ -768,6 +775,10 @@ module Braintree
768
775
  DirectoryResponseIsInvalid = "942121"
769
776
  EciFlagIsInvalid = "942114"
770
777
  EciFlagIsRequired = "942113"
778
+ NetworkDoesNotMatchPaymentInstrument = "942139"
779
+ NetworkDoesNotSupportCurrency = "942129"
780
+ NetworkDoesNotSupportMerchantAccountCurrency = "942130"
781
+ NetworkIsInvalid = "942128"
771
782
  ThreeDSecureVersionIsInvalid = "942119"
772
783
  ThreeDSecureVersionIsRequired = "942117"
773
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
@@ -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
  {
@@ -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 = 39
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
@@ -4,8 +4,7 @@ require File.expand_path(File.dirname(__FILE__) + "/client_api/spec_helper")
4
4
 
5
5
  describe Braintree::Customer do
6
6
  describe "self.all" do
7
- #Disabling test until we have a more stable CI
8
- xit "gets more than a page of customers" do
7
+ it "gets more than a page of customers" do
9
8
  customers = Braintree::Customer.all
10
9
  expect(customers.maximum_size).to be > 100
11
10
 
@@ -1242,7 +1241,7 @@ describe Braintree::Customer do
1242
1241
  expect(apple_pay_card.expiration_year).not_to be_nil
1243
1242
  expect(apple_pay_card.healthcare).not_to be_nil
1244
1243
  expect(apple_pay_card.issuing_bank).not_to be_nil
1245
- expect(apple_pay_card.payment_instrument_name).to eq("AmEx 41002")
1244
+ expect(apple_pay_card.payment_instrument_name).to match(/\AAmEx \d{4,5}\z/)
1246
1245
  expect(apple_pay_card.payroll).not_to be_nil
1247
1246
  expect(apple_pay_card.prepaid).not_to be_nil
1248
1247
  expect(apple_pay_card.prepaid_reloadable).not_to be_nil
@@ -1326,7 +1325,7 @@ describe Braintree::Customer do
1326
1325
  expect(venmo_account.username).not_to be_nil
1327
1326
  end
1328
1327
 
1329
- xit "returns associated us bank accounts" do
1328
+ it "returns associated us bank accounts" do
1330
1329
  result = Braintree::Customer.create(
1331
1330
  :payment_method_nonce => generate_non_plaid_us_bank_account_nonce,
1332
1331
  :credit_card => {
@@ -1693,7 +1692,8 @@ describe Braintree::Customer do
1693
1692
 
1694
1693
  apple_pay_card = result.customer.payment_methods.find { |pm| pm.is_a?(Braintree::ApplePayCard) }
1695
1694
  expect(apple_pay_card).not_to be_nil
1696
- expect(apple_pay_card.last_4).to eq(Braintree::Test::CreditCardNumbers::Visa[-4..-1])
1695
+ expect(apple_pay_card.card_type).to eq(Braintree::ApplePayCard::CardType::Visa)
1696
+ expect(apple_pay_card.last_4).to match(/\A\d{4}\z/)
1697
1697
  expect(apple_pay_card.cardholder_name).to eq("Updated Joe Cardholder")
1698
1698
 
1699
1699
  verification = apple_pay_card.verification
@@ -2084,6 +2084,154 @@ describe Braintree::Customer do
2084
2084
  expect(result).to be_success
2085
2085
  end
2086
2086
 
2087
+ it "accepts a three_d_secure_pass_thru network specified on customer create" do
2088
+ result = Braintree::Customer.create(
2089
+ :payment_method_nonce => Braintree::Test::Nonce::TransactableVisa,
2090
+ :credit_card => {
2091
+ :three_d_secure_pass_thru => {
2092
+ :eci_flag => "05",
2093
+ :cavv => "some_cavv",
2094
+ :xid => "some_xid",
2095
+ :three_d_secure_version => "2.2.0",
2096
+ :authentication_response => "Y",
2097
+ :directory_response => "Y",
2098
+ :cavv_algorithm => "2",
2099
+ :ds_transaction_id => "some_ds_transaction_id",
2100
+ :network => Braintree::ThreeDSecurePassThru::Network::Visa,
2101
+ },
2102
+ :options => {:verify_card => true},
2103
+ },
2104
+ )
2105
+ expect(result).to be_success
2106
+ end
2107
+
2108
+ it "rejects invalid network value in 3ds pass thru params on customer create" do
2109
+ result = Braintree::Customer.create(
2110
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
2111
+ :credit_card => {
2112
+ :three_d_secure_pass_thru => {
2113
+ :eci_flag => "05",
2114
+ :cavv => "some_cavv",
2115
+ :xid => "some_xid",
2116
+ :three_d_secure_version => "2.2.0",
2117
+ :authentication_response => "Y",
2118
+ :directory_response => "Y",
2119
+ :cavv_algorithm => "2",
2120
+ :ds_transaction_id => "some_ds_transaction_id",
2121
+ :network => "DISCOVER",
2122
+ },
2123
+ :options => {:verify_card => true},
2124
+ },
2125
+ )
2126
+ expect(result).not_to be_success
2127
+ error = result.errors.for(:verification).first
2128
+ expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::NetworkIsInvalid)
2129
+ expect(error.message).to eq("Network is invalid. Supported networks are eftpos, Visa, and Mastercard.")
2130
+ end
2131
+
2132
+ it "rejects request where 3ds pass thru network does not match the payment instrument on customer create (VISA nonce, Mastercard network)" do
2133
+ result = Braintree::Customer.create(
2134
+ :payment_method_nonce => Braintree::Test::Nonce::TransactableVisa,
2135
+ :credit_card => {
2136
+ :three_d_secure_pass_thru => {
2137
+ :eci_flag => "05",
2138
+ :cavv => "some_cavv",
2139
+ :xid => "some_xid",
2140
+ :three_d_secure_version => "2.2.0",
2141
+ :authentication_response => "Y",
2142
+ :directory_response => "Y",
2143
+ :cavv_algorithm => "2",
2144
+ :ds_transaction_id => "some_ds_transaction_id",
2145
+ :network => Braintree::ThreeDSecurePassThru::Network::MasterCard,
2146
+ },
2147
+ :options => {:verify_card => true},
2148
+ },
2149
+ )
2150
+ expect(result).not_to be_success
2151
+ error = result.errors.for(:verification).first
2152
+ expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::NetworkDoesNotMatchPaymentInstrument)
2153
+ expect(error.message).to eq("Network does not match the payment instrument.")
2154
+ end
2155
+
2156
+ it "accepts a three_d_secure_pass_thru network specified on customer update" do
2157
+ customer = Braintree::Customer.create!
2158
+ result = Braintree::Customer.update(
2159
+ customer.id,
2160
+ :credit_card => {
2161
+ :number => Braintree::Test::CreditCardNumbers::Visa,
2162
+ :expiration_date => "05/2009",
2163
+ :three_d_secure_pass_thru => {
2164
+ :eci_flag => "05",
2165
+ :cavv => "some_cavv",
2166
+ :xid => "some_xid",
2167
+ :three_d_secure_version => "2.2.0",
2168
+ :authentication_response => "Y",
2169
+ :directory_response => "Y",
2170
+ :cavv_algorithm => "2",
2171
+ :ds_transaction_id => "some_ds_transaction_id",
2172
+ :network => Braintree::ThreeDSecurePassThru::Network::Visa,
2173
+ },
2174
+ :options => {:verify_card => true}
2175
+ },
2176
+ )
2177
+
2178
+ expect(result).to be_success
2179
+ end
2180
+
2181
+ it "rejects invalid network value in 3ds pass thru params on customer update" do
2182
+ customer = Braintree::Customer.create!
2183
+ result = Braintree::Customer.update(
2184
+ customer.id,
2185
+ :credit_card => {
2186
+ :number => Braintree::Test::CreditCardNumbers::Visa,
2187
+ :expiration_date => "05/2009",
2188
+ :three_d_secure_pass_thru => {
2189
+ :eci_flag => "05",
2190
+ :cavv => "some_cavv",
2191
+ :xid => "some_xid",
2192
+ :three_d_secure_version => "2.2.0",
2193
+ :authentication_response => "Y",
2194
+ :directory_response => "Y",
2195
+ :cavv_algorithm => "2",
2196
+ :ds_transaction_id => "some_ds_transaction_id",
2197
+ :network => "DISCOVER",
2198
+ },
2199
+ :options => {:verify_card => true}
2200
+ },
2201
+ )
2202
+ expect(result).not_to be_success
2203
+ error = result.errors.for(:verification).first
2204
+ expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::NetworkIsInvalid)
2205
+ expect(error.message).to eq("Network is invalid. Supported networks are eftpos, Visa, and Mastercard.")
2206
+ end
2207
+
2208
+ it "rejects request where 3ds pass thru network does not match the payment instrument on customer update (VISA card, Mastercard network)" do
2209
+ customer = Braintree::Customer.create!
2210
+ result = Braintree::Customer.update(
2211
+ customer.id,
2212
+ :credit_card => {
2213
+ :number => Braintree::Test::CreditCardNumbers::Visa,
2214
+ :expiration_date => "05/2009",
2215
+ :three_d_secure_pass_thru => {
2216
+ :eci_flag => "05",
2217
+ :cavv => "some_cavv",
2218
+ :xid => "some_xid",
2219
+ :three_d_secure_version => "2.2.0",
2220
+ :authentication_response => "Y",
2221
+ :directory_response => "Y",
2222
+ :cavv_algorithm => "2",
2223
+ :ds_transaction_id => "some_ds_transaction_id",
2224
+ :network => Braintree::ThreeDSecurePassThru::Network::MasterCard,
2225
+ },
2226
+ :options => {:verify_card => true}
2227
+ },
2228
+ )
2229
+ expect(result).not_to be_success
2230
+ error = result.errors.for(:verification).first
2231
+ expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::NetworkDoesNotMatchPaymentInstrument)
2232
+ expect(error.message).to eq("Network does not match the payment instrument.")
2233
+ end
2234
+
2087
2235
  it "returns 3DS info on cc verification" do
2088
2236
  result = Braintree::Customer.create(
2089
2237
  :payment_method_nonce => Braintree::Test::Nonce::ThreeDSecureVisaFullAuthentication,
@@ -97,7 +97,7 @@ describe Braintree::Http do
97
97
  end
98
98
 
99
99
  describe "ssl_version" do
100
- xit "causes failed requests to sandbox with incompatible SSL version" do
100
+ it "causes failed requests to sandbox with incompatible SSL version" do
101
101
  begin
102
102
  original_env = Braintree::Configuration.environment
103
103
  Braintree::Configuration.environment = :sandbox