braintree 2.99.0 → 2.104.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/lib/braintree/address_gateway.rb +2 -2
  3. data/lib/braintree/amex_express_checkout_card.rb +2 -0
  4. data/lib/braintree/android_pay_card.rb +5 -0
  5. data/lib/braintree/base_module.rb +4 -0
  6. data/lib/braintree/credit_card.rb +5 -1
  7. data/lib/braintree/credit_card_gateway.rb +14 -0
  8. data/lib/braintree/credit_card_verification.rb +2 -0
  9. data/lib/braintree/customer.rb +5 -2
  10. data/lib/braintree/dispute.rb +1 -0
  11. data/lib/braintree/dispute/transaction.rb +2 -0
  12. data/lib/braintree/error_codes.rb +76 -33
  13. data/lib/braintree/graphql_client.rb +7 -1
  14. data/lib/braintree/masterpass_card.rb +2 -0
  15. data/lib/braintree/payment_instrument_type.rb +2 -1
  16. data/lib/braintree/payment_method_gateway.rb +14 -0
  17. data/lib/braintree/payment_method_nonce.rb +2 -0
  18. data/lib/braintree/payment_method_nonce_gateway.rb +13 -2
  19. data/lib/braintree/payment_method_parser.rb +1 -0
  20. data/lib/braintree/risk_data.rb +4 -1
  21. data/lib/braintree/test/authentication_id.rb +21 -0
  22. data/lib/braintree/test/credit_card.rb +1 -0
  23. data/lib/braintree/test/nonce.rb +18 -0
  24. data/lib/braintree/three_d_secure_info.rb +2 -0
  25. data/lib/braintree/transaction.rb +15 -1
  26. data/lib/braintree/transaction/address_details.rb +11 -0
  27. data/lib/braintree/transaction/android_pay_details.rb +5 -0
  28. data/lib/braintree/transaction/apple_pay_details.rb +1 -0
  29. data/lib/braintree/transaction/masterpass_card_details.rb +2 -0
  30. data/lib/braintree/transaction/paypal_details.rb +2 -0
  31. data/lib/braintree/transaction_gateway.rb +12 -3
  32. data/lib/braintree/version.rb +1 -1
  33. data/lib/braintree/webhook_notification.rb +3 -0
  34. data/lib/braintree/webhook_testing_gateway.rb +243 -0
  35. data/spec/integration/braintree/client_api/spec_helper.rb +98 -46
  36. data/spec/integration/braintree/credit_card_spec.rb +135 -2
  37. data/spec/integration/braintree/credit_card_verification_spec.rb +2 -0
  38. data/spec/integration/braintree/customer_spec.rb +116 -0
  39. data/spec/integration/braintree/dispute_search_spec.rb +1 -1
  40. data/spec/integration/braintree/dispute_spec.rb +1 -0
  41. data/spec/integration/braintree/document_upload_spec.rb +12 -0
  42. data/spec/integration/braintree/merchant_spec.rb +2 -2
  43. data/spec/integration/braintree/payment_method_nonce_spec.rb +83 -2
  44. data/spec/integration/braintree/payment_method_spec.rb +113 -18
  45. data/spec/integration/braintree/paypal_account_spec.rb +1 -1
  46. data/spec/integration/braintree/transaction_spec.rb +437 -45
  47. data/spec/spec_helper.rb +1 -1
  48. data/spec/unit/braintree/credit_card_spec.rb +51 -3
  49. data/spec/unit/braintree/credit_card_verification_spec.rb +7 -0
  50. data/spec/unit/braintree/customer_spec.rb +28 -2
  51. data/spec/unit/braintree/dispute_spec.rb +3 -0
  52. data/spec/unit/braintree/three_d_secure_info_spec.rb +3 -1
  53. data/spec/unit/braintree/transaction/paypal_details_spec.rb +57 -0
  54. data/spec/unit/braintree/transaction_spec.rb +16 -2
  55. data/spec/unit/braintree/webhook_notification_spec.rb +48 -0
  56. metadata +5 -3
@@ -56,59 +56,84 @@ def nonce_for_paypal_account(paypal_account_details)
56
56
  end
57
57
 
58
58
  def generate_non_plaid_us_bank_account_nonce(account_number="1000000000")
59
- raw_client_token = Braintree::ClientToken.generate
60
- client_token = decode_client_token(raw_client_token)
59
+ query = %{
60
+ mutation TokenizeUsBankAccount($input: TokenizeUsBankAccountInput!) {
61
+ tokenizeUsBankAccount(input: $input) {
62
+ paymentMethod {
63
+ id
64
+ }
65
+ }
66
+ }
67
+ }
61
68
 
62
- url = client_token["braintree_api"]["url"] + "/tokens"
63
- token = client_token["braintree_api"]["access_token"]
64
- payload = {
65
- :type => "us_bank_account",
66
- :billing_address => {
67
- :street_address => "123 Ave",
68
- :region => "CA",
69
- :locality => "San Francisco",
70
- :postal_code => "94112"
71
- },
72
- :account_type => "checking",
73
- :routing_number => "021000021",
74
- :account_number => account_number,
75
- :first_name => "John",
76
- :last_name => "Doe",
77
- :ownership_type => "personal",
78
- :ach_mandate => {
79
- :text => "cl mandate text"
69
+ variables = {
70
+ :input => {
71
+ :usBankAccount => {
72
+ :accountNumber => account_number,
73
+ :routingNumber => "021000021",
74
+ :accountType => "CHECKING",
75
+ :individualOwner => {
76
+ :firstName => "John",
77
+ :lastName => "Doe",
78
+ },
79
+ :billingAddress => {
80
+ :streetAddress => "123 Ave",
81
+ :state => "CA",
82
+ :city => "San Francisco",
83
+ :zipCode => "94112"
84
+ },
85
+ :achMandate => "cl mandate text"
86
+ }
80
87
  }
81
88
  }
82
89
 
83
- json = _cosmos_post(token, url, payload)
84
- json["data"]["id"]
90
+ graphql_request = {
91
+ :query => query,
92
+ :variables => variables
93
+ }
94
+
95
+ json = _send_graphql_request(graphql_request)
96
+ json["data"]["tokenizeUsBankAccount"]["paymentMethod"]["id"]
85
97
  end
86
98
 
87
99
  def generate_valid_plaid_us_bank_account_nonce
88
- raw_client_token = Braintree::ClientToken.generate
89
- client_token = decode_client_token(raw_client_token)
100
+ query = %{
101
+ mutation TokenizeUsBankLogin($input: TokenizeUsBankLoginInput!) {
102
+ tokenizeUsBankLogin(input: $input) {
103
+ paymentMethod {
104
+ id
105
+ }
106
+ }
107
+ }
108
+ }
90
109
 
91
- url = client_token["braintree_api"]["url"] + "/tokens"
92
- token = client_token["braintree_api"]["access_token"]
93
- payload = {
94
- :type => "plaid_public_token",
95
- :public_token => "good",
96
- :account_id => "plaid_account_id",
97
- :ownership_type => "business",
98
- :business_name => "PayPal, Inc.",
99
- :billing_address => {
100
- :street_address => "123 Ave",
101
- :region => "CA",
102
- :locality => "San Francisco",
103
- :postal_code => "94112"
104
- },
105
- :ach_mandate => {
106
- :text => "cl mandate text"
110
+ variables = {
111
+ :input => {
112
+ :usBankLogin => {
113
+ :publicToken => "good",
114
+ :accountId => "plaid_account_id",
115
+ :accountType => "CHECKING",
116
+ :businessOwner => {
117
+ :businessName => "PayPal, Inc.",
118
+ },
119
+ :billingAddress => {
120
+ :streetAddress => "123 Ave",
121
+ :state => "CA",
122
+ :city => "San Francisco",
123
+ :zipCode => "94112"
124
+ },
125
+ :achMandate => "cl mandate text"
126
+ }
107
127
  }
108
128
  }
109
129
 
110
- json = _cosmos_post(token, url, payload)
111
- json["data"]["id"]
130
+ graphql_request = {
131
+ :query => query,
132
+ :variables => variables
133
+ }
134
+
135
+ json = _send_graphql_request(graphql_request)
136
+ json["data"]["tokenizeUsBankLogin"]["paymentMethod"]["id"]
112
137
  end
113
138
 
114
139
  def generate_valid_ideal_payment_nonce(amount = Braintree::Test::TransactionAmounts::Authorize)
@@ -120,8 +145,10 @@ def generate_valid_ideal_payment_nonce(amount = Braintree::Test::TransactionAmou
120
145
  )
121
146
  config = JSON.parse(client.get_configuration.body)
122
147
 
123
- token = client_token["braintree_api"]["access_token"]
124
- url = client_token["braintree_api"]["url"] + "/ideal-payments"
148
+ braintree_api = client_token["braintree_api"]
149
+ url = braintree_api["url"] + "/ideal-payments"
150
+
151
+ token = braintree_api["access_token"]
125
152
  payload = {
126
153
  :issuer => "RABONL2U",
127
154
  :order_id => SpecHelper::DefaultOrderId,
@@ -149,8 +176,10 @@ end
149
176
  def _cosmos_post(token, url, payload)
150
177
  uri = URI::parse(url)
151
178
  connection = Net::HTTP.new(uri.host, uri.port)
152
- connection.use_ssl = true
153
- connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
179
+ if uri.scheme == "https"
180
+ connection.use_ssl = true
181
+ connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
182
+ end
154
183
  resp = connection.start do |http|
155
184
  request = Net::HTTP::Post.new(uri.path)
156
185
  request["Content-Type"] = "application/json"
@@ -163,6 +192,29 @@ def _cosmos_post(token, url, payload)
163
192
  JSON.parse(resp.body)
164
193
  end
165
194
 
195
+ def _send_graphql_request(graphql_request)
196
+ raw_client_token = Braintree::ClientToken.generate
197
+ client_token = decode_client_token(raw_client_token)
198
+ uri = URI::parse("#{client_token["braintree_api"]["url"]}/graphql")
199
+ connection = Net::HTTP.new(uri.host, uri.port)
200
+
201
+ if uri.scheme == "https"
202
+ connection.use_ssl = true
203
+ connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
204
+ end
205
+
206
+ resp = connection.start do |http|
207
+ request = Net::HTTP::Post.new(uri.path)
208
+ request["Content-Type"] = "application/json"
209
+ request["Braintree-Version"] = "2016-10-07"
210
+ request["Authorization"] = "Bearer #{client_token["braintree_api"]["access_token"]}"
211
+ request.body = graphql_request.to_json
212
+ http.request(request)
213
+ end
214
+
215
+ JSON.parse(resp.body)
216
+ end
217
+
166
218
  class ClientApiHttp
167
219
  attr_reader :config, :options
168
220
 
@@ -15,7 +15,7 @@ describe Braintree::CreditCard do
15
15
  :customer_id => customer.id,
16
16
  :number => Braintree::Test::CreditCardNumbers::Visa,
17
17
  :expiration_date => "05/2009",
18
- :cvv => "100"
18
+ :cvv => "100",
19
19
  )
20
20
  result.success?.should == true
21
21
  credit_card = result.credit_card
@@ -227,6 +227,49 @@ describe Braintree::CreditCard do
227
227
  result.success?.should == true
228
228
  end
229
229
 
230
+ it "validates presence of three_d_secure_version in 3ds pass thru params" do
231
+ customer = Braintree::Customer.create!
232
+ result = Braintree::CreditCard.create(
233
+ :customer_id => customer.id,
234
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
235
+ :three_d_secure_pass_thru => {
236
+ :eci_flag => '02',
237
+ :cavv => 'some_cavv',
238
+ :xid => 'some_xid',
239
+ :authentication_response => 'Y',
240
+ :directory_response => 'Y',
241
+ :cavv_algorithm => '2',
242
+ :ds_transaction_id => 'some_ds_transaction_id',
243
+ },
244
+ :options => {:verify_card => true}
245
+ )
246
+ expect(result).not_to be_success
247
+ error = result.errors.for(:verification).first
248
+ expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::ThreeDSecureVersionIsRequired)
249
+ expect(error.message).to eq("ThreeDSecureVersion is required.")
250
+ end
251
+
252
+ it "accepts three_d_secure pass thru params in the request" do
253
+ customer = Braintree::Customer.create!
254
+ result = Braintree::CreditCard.create(
255
+ :customer_id => customer.id,
256
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
257
+ :three_d_secure_pass_thru => {
258
+ :eci_flag => '02',
259
+ :cavv => 'some_cavv',
260
+ :xid => 'some_xid',
261
+ :three_d_secure_version => '1.0.2',
262
+ :authentication_response => 'Y',
263
+ :directory_response => 'Y',
264
+ :cavv_algorithm => '2',
265
+ :ds_transaction_id => 'some_ds_transaction_id',
266
+ },
267
+ :options => {:verify_card => true}
268
+ )
269
+ result.success?.should == true
270
+
271
+ end
272
+
230
273
  it "returns 3DS info on cc verification" do
231
274
  customer = Braintree::Customer.create!
232
275
  result = Braintree::CreditCard.create(
@@ -246,6 +289,7 @@ describe Braintree::CreditCard do
246
289
  three_d_secure_info.eci_flag.should == "05"
247
290
  three_d_secure_info.three_d_secure_version.should == "1.0.2"
248
291
  three_d_secure_info.ds_transaction_id.should == nil
292
+ three_d_secure_info.three_d_secure_authentication_id.should_not be_nil
249
293
  end
250
294
 
251
295
  it "adds credit card with billing address to customer" do
@@ -336,6 +380,21 @@ describe Braintree::CreditCard do
336
380
  Braintree::CreditCard.find(card1.token).should_not be_default
337
381
  end
338
382
 
383
+ it "can set the network transaction identifier when creating a credit card" do
384
+ customer = Braintree::Customer.create!
385
+
386
+ result = Braintree::CreditCard.create(
387
+ :customer_id => customer.id,
388
+ :number => Braintree::Test::CreditCardNumbers::Visa,
389
+ :expiration_date => "05/2009",
390
+ :external_vault => {
391
+ :network_transaction_id => "MCC123456789",
392
+ },
393
+ )
394
+
395
+ expect(result.success?).to eq(true)
396
+ end
397
+
339
398
  context "card type indicators" do
340
399
  it "sets the prepaid field if the card is prepaid" do
341
400
  customer = Braintree::Customer.create!
@@ -828,6 +887,62 @@ describe Braintree::CreditCard do
828
887
  updated_credit_card.cardholder_name.should == "New Holder"
829
888
  end
830
889
 
890
+ it "validates presence of three_d_secure_version in 3ds pass thru params" do
891
+ customer = Braintree::Customer.create!
892
+ credit_card = Braintree::CreditCard.create!(
893
+ :cardholder_name => "Original Holder",
894
+ :customer_id => customer.id,
895
+ :cvv => "123",
896
+ :number => Braintree::Test::CreditCardNumbers::Visa,
897
+ :expiration_date => "05/2012"
898
+ )
899
+ result = Braintree::CreditCard.update(credit_card.token,
900
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
901
+ :three_d_secure_pass_thru => {
902
+ :eci_flag => '02',
903
+ :cavv => 'some_cavv',
904
+ :xid => 'some_xid',
905
+ :authentication_response => 'Y',
906
+ :directory_response => 'Y',
907
+ :cavv_algorithm => '2',
908
+ :ds_transaction_id => 'some_ds_transaction_id',
909
+ },
910
+ :options => {:verify_card => true}
911
+ )
912
+ expect(result).not_to be_success
913
+ error = result.errors.for(:verification).first
914
+ expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::ThreeDSecureVersionIsRequired)
915
+ expect(error.message).to eq("ThreeDSecureVersion is required.")
916
+ end
917
+
918
+ it "accepts three_d_secure pass thru params in the request" do
919
+ customer = Braintree::Customer.create!
920
+ credit_card = Braintree::CreditCard.create!(
921
+ :cardholder_name => "Original Holder",
922
+ :customer_id => customer.id,
923
+ :cvv => "123",
924
+ :number => Braintree::Test::CreditCardNumbers::Visa,
925
+ :expiration_date => "05/2012"
926
+ )
927
+ result = Braintree::CreditCard.update(credit_card.token,
928
+ :payment_method_nonce => Braintree::Test::Nonce::Transactable,
929
+ :three_d_secure_pass_thru => {
930
+ :eci_flag => '02',
931
+ :cavv => 'some_cavv',
932
+ :three_d_secure_version=> "2.1.0",
933
+ :xid => 'some_xid',
934
+ :authentication_response => 'Y',
935
+ :directory_response => 'Y',
936
+ :cavv_algorithm => '2',
937
+ :ds_transaction_id => 'some_ds_transaction_id',
938
+ },
939
+ :options => {:verify_card => true}
940
+ )
941
+
942
+ result.success?.should == true
943
+
944
+ end
945
+
831
946
  context "billing address" do
832
947
  it "creates a new billing address by default" do
833
948
  customer = Braintree::Customer.create!
@@ -1259,7 +1374,7 @@ describe Braintree::CreditCard do
1259
1374
  Braintree::CreditCard.create!(
1260
1375
  :customer_id => customer.id,
1261
1376
  :number => Braintree::Test::CreditCardNumbers::Visa,
1262
- :expiration_date => "01/2015"
1377
+ :expiration_date => "01/#{Time.now.year - 3}"
1263
1378
  )
1264
1379
  end
1265
1380
 
@@ -1736,4 +1851,22 @@ describe Braintree::CreditCard do
1736
1851
  credit_card.nonce.should_not be_nil
1737
1852
  end
1738
1853
  end
1854
+
1855
+ describe "card on file network tokenization" do
1856
+ it "should find a network tokenized credit card" do
1857
+ credit_card = Braintree::CreditCard.find("network_tokenized_credit_card")
1858
+ credit_card.is_network_tokenized?.should == true
1859
+ end
1860
+
1861
+ it "should find a non-network tokenized credit card" do
1862
+ customer = Braintree::Customer.create!
1863
+ credit_card = Braintree::CreditCard.create(
1864
+ :customer_id => customer.id,
1865
+ :number => Braintree::Test::CreditCardNumbers::Visa,
1866
+ :expiration_date => "05/2009"
1867
+ ).credit_card
1868
+ credit_card_vaulted = Braintree::CreditCard.find(credit_card.token)
1869
+ credit_card_vaulted.is_network_tokenized?.should == false
1870
+ end
1871
+ end
1739
1872
  end
@@ -22,6 +22,7 @@ describe Braintree::CreditCardVerification, "search" do
22
22
  result.credit_card_verification.processor_response_code.should == "1000"
23
23
  result.credit_card_verification.processor_response_text.should == "Approved"
24
24
  result.credit_card_verification.processor_response_type.should == Braintree::ProcessorResponseTypes::Approved
25
+ expect(result.credit_card_verification.network_transaction_id).not_to be_nil
25
26
  end
26
27
 
27
28
  it "creates a new verification with network response code/text" do
@@ -161,6 +162,7 @@ describe Braintree::CreditCardVerification, "search" do
161
162
  found_verification = Braintree::CreditCardVerification.find(credit_card_verification.id)
162
163
 
163
164
  found_verification.should == credit_card_verification
165
+ found_verification.graphql_id.should_not be_nil
164
166
  end
165
167
 
166
168
  it "raises a NotFoundError exception if verification cannot be found" do
@@ -889,6 +889,7 @@ describe Braintree::Customer do
889
889
 
890
890
  customer = Braintree::Customer.find(result.customer.id)
891
891
  customer.id.should == result.customer.id
892
+ customer.graphql_id.should_not be_nil
892
893
  customer.first_name.should == "Joe"
893
894
  customer.last_name.should == "Cool"
894
895
  end
@@ -1015,6 +1016,7 @@ describe Braintree::Customer do
1015
1016
  android_pay_card.should be_a Braintree::AndroidPayCard
1016
1017
  android_pay_card.token.should_not be_nil
1017
1018
  android_pay_card.expiration_year.should_not be_nil
1019
+ android_pay_card.is_network_tokenized?.should == false
1018
1020
  end
1019
1021
 
1020
1022
  it "returns associated android pay network tokens" do
@@ -1030,6 +1032,7 @@ describe Braintree::Customer do
1030
1032
  android_pay_card.should be_a Braintree::AndroidPayCard
1031
1033
  android_pay_card.token.should_not be_nil
1032
1034
  android_pay_card.expiration_year.should_not be_nil
1035
+ android_pay_card.is_network_tokenized?.should == true
1033
1036
  end
1034
1037
 
1035
1038
  it "returns associated amex express checkout cards" do
@@ -1112,6 +1115,74 @@ describe Braintree::Customer do
1112
1115
  end
1113
1116
 
1114
1117
  describe "self.update" do
1118
+ it "updates the credit card with three_d_secure pass thru params" do
1119
+ customer = Braintree::Customer.create!(
1120
+ :first_name => "Joe",
1121
+ :last_name => "Cool"
1122
+ )
1123
+ result = Braintree::Customer.update(
1124
+ customer.id,
1125
+ :first_name => "Mr. Joe",
1126
+ :last_name => "Super Cool",
1127
+ :custom_fields => {
1128
+ :store_me => "a value"
1129
+ },
1130
+ :credit_card => {
1131
+ :number => 4111111111111111,
1132
+ :expiration_date => "05/2060",
1133
+ :three_d_secure_pass_thru => {
1134
+ :eci_flag => '02',
1135
+ :cavv => 'some_cavv',
1136
+ :xid => 'some_xid',
1137
+ :three_d_secure_version => '1.0.2',
1138
+ :authentication_response => 'Y',
1139
+ :directory_response => 'Y',
1140
+ :cavv_algorithm => '2',
1141
+ :ds_transaction_id => 'some_ds_transaction_id',
1142
+ },
1143
+ :options => {:verify_card => true},
1144
+ }
1145
+ )
1146
+ result.success?.should == true
1147
+ result.customer.id.should == customer.id
1148
+ result.customer.first_name.should == "Mr. Joe"
1149
+ result.customer.last_name.should == "Super Cool"
1150
+ result.customer.custom_fields[:store_me].should == "a value"
1151
+ end
1152
+
1153
+ it "validates the presence of three_d_secure_version while passing three_d_secure_pass_thru in update" do
1154
+ customer = Braintree::Customer.create!(
1155
+ :first_name => "Joe",
1156
+ :last_name => "Cool"
1157
+ )
1158
+ result = Braintree::Customer.update(
1159
+ customer.id,
1160
+ :first_name => "Mr. Joe",
1161
+ :last_name => "Super Cool",
1162
+ :custom_fields => {
1163
+ :store_me => "a value"
1164
+ },
1165
+ :credit_card => {
1166
+ :number => 4111111111111111,
1167
+ :expiration_date => "05/2060",
1168
+ :three_d_secure_pass_thru => {
1169
+ :eci_flag => '02',
1170
+ :cavv => 'some_cavv',
1171
+ :xid => 'some_xid',
1172
+ :authentication_response => 'Y',
1173
+ :directory_response => 'Y',
1174
+ :cavv_algorithm => '2',
1175
+ :ds_transaction_id => 'some_ds_transaction_id',
1176
+ },
1177
+ options: {:verify_card => true}
1178
+ }
1179
+ )
1180
+ expect(result).to_not be_success
1181
+ error = result.errors.for(:verification).first
1182
+ expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::ThreeDSecureVersionIsRequired)
1183
+ expect(error.message).to eq("ThreeDSecureVersion is required.")
1184
+ end
1185
+
1115
1186
  it "updates the customer with the given id if successful" do
1116
1187
  customer = Braintree::Customer.create!(
1117
1188
  :first_name => "Joe",
@@ -1309,6 +1380,51 @@ describe Braintree::Customer do
1309
1380
  result.success?.should == true
1310
1381
  end
1311
1382
 
1383
+ it "validates presence of three_d_secure_version in 3ds pass thru params" do
1384
+ result = Braintree::Customer.create(
1385
+ :payment_method_nonce => Braintree::Test::Nonce::ThreeDSecureVisaFullAuthentication,
1386
+ :credit_card => {
1387
+ :three_d_secure_pass_thru => {
1388
+ :eci_flag => '02',
1389
+ :cavv => 'some_cavv',
1390
+ :xid => 'some_xid',
1391
+ :three_d_secure_version => 'xx',
1392
+ :authentication_response => 'Y',
1393
+ :directory_response => 'Y',
1394
+ :cavv_algorithm => '2',
1395
+ :ds_transaction_id => 'some_ds_transaction_id',
1396
+ },
1397
+ :options => {:verify_card => true}
1398
+ }
1399
+ )
1400
+
1401
+ expect(result).not_to be_success
1402
+ error = result.errors.for(:verification).first
1403
+ expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::ThreeDSecureVersionIsInvalid)
1404
+ expect(error.message).to eq("The version of 3D Secure authentication must be composed only of digits and separated by periods (e.g. `1.0.2`).")
1405
+ end
1406
+
1407
+ it "accepts three_d_secure pass thru params in the request" do
1408
+ result = Braintree::Customer.create(
1409
+ :payment_method_nonce => Braintree::Test::Nonce::ThreeDSecureVisaFullAuthentication,
1410
+ :credit_card => {
1411
+ :three_d_secure_pass_thru => {
1412
+ :eci_flag => '02',
1413
+ :cavv => 'some_cavv',
1414
+ :xid => 'some_xid',
1415
+ :three_d_secure_version => '2.2.1',
1416
+ :authentication_response => 'Y',
1417
+ :directory_response => 'Y',
1418
+ :cavv_algorithm => '2',
1419
+ :ds_transaction_id => 'some_ds_transaction_id',
1420
+ },
1421
+ :options => {:verify_card => true}
1422
+ }
1423
+ )
1424
+
1425
+ expect(result).to be_success
1426
+ end
1427
+
1312
1428
  it "returns 3DS info on cc verification" do
1313
1429
  result = Braintree::Customer.create(
1314
1430
  :payment_method_nonce => Braintree::Test::Nonce::ThreeDSecureVisaFullAuthentication,