braintree 2.100.0 → 2.104.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/braintree/address_gateway.rb +2 -2
- data/lib/braintree/amex_express_checkout_card.rb +2 -0
- data/lib/braintree/android_pay_card.rb +5 -0
- data/lib/braintree/base_module.rb +4 -0
- data/lib/braintree/credit_card.rb +5 -1
- data/lib/braintree/credit_card_gateway.rb +13 -0
- data/lib/braintree/credit_card_verification.rb +2 -0
- data/lib/braintree/customer.rb +5 -2
- data/lib/braintree/dispute.rb +1 -0
- data/lib/braintree/dispute/transaction.rb +2 -0
- data/lib/braintree/error_codes.rb +76 -34
- data/lib/braintree/graphql_client.rb +7 -1
- data/lib/braintree/local_payment_completed.rb +1 -1
- data/lib/braintree/masterpass_card.rb +2 -0
- data/lib/braintree/payment_instrument_type.rb +2 -1
- data/lib/braintree/payment_method_gateway.rb +14 -0
- data/lib/braintree/payment_method_nonce.rb +2 -0
- data/lib/braintree/payment_method_nonce_gateway.rb +13 -2
- data/lib/braintree/payment_method_parser.rb +1 -0
- data/lib/braintree/risk_data.rb +4 -1
- data/lib/braintree/test/authentication_id.rb +21 -0
- data/lib/braintree/test/credit_card.rb +1 -0
- data/lib/braintree/test/nonce.rb +18 -0
- data/lib/braintree/three_d_secure_info.rb +2 -0
- data/lib/braintree/transaction.rb +15 -1
- data/lib/braintree/transaction/address_details.rb +11 -0
- data/lib/braintree/transaction/android_pay_details.rb +4 -0
- data/lib/braintree/transaction/masterpass_card_details.rb +2 -0
- data/lib/braintree/transaction/paypal_details.rb +2 -0
- data/lib/braintree/transaction_gateway.rb +12 -3
- data/lib/braintree/version.rb +2 -2
- data/lib/braintree/webhook_notification.rb +3 -0
- data/lib/braintree/webhook_testing_gateway.rb +243 -0
- data/spec/integration/braintree/client_api/spec_helper.rb +98 -46
- data/spec/integration/braintree/credit_card_spec.rb +120 -2
- data/spec/integration/braintree/credit_card_verification_spec.rb +2 -0
- data/spec/integration/braintree/customer_spec.rb +116 -0
- data/spec/integration/braintree/dispute_search_spec.rb +1 -1
- data/spec/integration/braintree/dispute_spec.rb +1 -0
- data/spec/integration/braintree/document_upload_spec.rb +12 -0
- data/spec/integration/braintree/merchant_spec.rb +2 -2
- data/spec/integration/braintree/payment_method_nonce_spec.rb +83 -2
- data/spec/integration/braintree/payment_method_spec.rb +113 -18
- data/spec/integration/braintree/paypal_account_spec.rb +1 -1
- data/spec/integration/braintree/transaction_spec.rb +435 -45
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/braintree/credit_card_spec.rb +49 -3
- data/spec/unit/braintree/credit_card_verification_spec.rb +7 -0
- data/spec/unit/braintree/customer_spec.rb +26 -2
- data/spec/unit/braintree/dispute_spec.rb +3 -0
- data/spec/unit/braintree/local_payment_completed_spec.rb +14 -0
- data/spec/unit/braintree/three_d_secure_info_spec.rb +3 -1
- data/spec/unit/braintree/transaction/paypal_details_spec.rb +57 -0
- data/spec/unit/braintree/transaction_spec.rb +16 -2
- data/spec/unit/braintree/webhook_notification_spec.rb +48 -0
- 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
|
-
|
60
|
-
|
59
|
+
query = %{
|
60
|
+
mutation TokenizeUsBankAccount($input: TokenizeUsBankAccountInput!) {
|
61
|
+
tokenizeUsBankAccount(input: $input) {
|
62
|
+
paymentMethod {
|
63
|
+
id
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}
|
61
68
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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
|
-
|
84
|
-
|
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
|
-
|
89
|
-
|
100
|
+
query = %{
|
101
|
+
mutation TokenizeUsBankLogin($input: TokenizeUsBankLoginInput!) {
|
102
|
+
tokenizeUsBankLogin(input: $input) {
|
103
|
+
paymentMethod {
|
104
|
+
id
|
105
|
+
}
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}
|
90
109
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
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
|
-
|
111
|
-
|
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
|
-
|
124
|
-
url =
|
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
|
-
|
153
|
-
|
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
|
@@ -843,6 +887,62 @@ describe Braintree::CreditCard do
|
|
843
887
|
updated_credit_card.cardholder_name.should == "New Holder"
|
844
888
|
end
|
845
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
|
+
|
846
946
|
context "billing address" do
|
847
947
|
it "creates a new billing address by default" do
|
848
948
|
customer = Braintree::Customer.create!
|
@@ -1274,7 +1374,7 @@ describe Braintree::CreditCard do
|
|
1274
1374
|
Braintree::CreditCard.create!(
|
1275
1375
|
:customer_id => customer.id,
|
1276
1376
|
:number => Braintree::Test::CreditCardNumbers::Visa,
|
1277
|
-
:expiration_date => "01
|
1377
|
+
:expiration_date => "01/#{Time.now.year - 3}"
|
1278
1378
|
)
|
1279
1379
|
end
|
1280
1380
|
|
@@ -1751,4 +1851,22 @@ describe Braintree::CreditCard do
|
|
1751
1851
|
credit_card.nonce.should_not be_nil
|
1752
1852
|
end
|
1753
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
|
1754
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,
|