braintree 4.39.0 → 4.41.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 +4 -4
- data/lib/braintree/address_gateway.rb +13 -3
- data/lib/braintree/client_token_gateway.rb +10 -1
- data/lib/braintree/credit_card_gateway.rb +9 -2
- data/lib/braintree/credit_card_verification_gateway.rb +3 -0
- data/lib/braintree/customer_gateway.rb +11 -3
- data/lib/braintree/dispute_gateway.rb +7 -7
- data/lib/braintree/error_codes.rb +11 -0
- data/lib/braintree/http.rb +4 -2
- data/lib/braintree/merchant_account_gateway.rb +2 -0
- data/lib/braintree/payment_method_gateway.rb +7 -1
- data/lib/braintree/payment_method_nonce_gateway.rb +4 -0
- data/lib/braintree/paypal_account_gateway.rb +6 -1
- data/lib/braintree/plan_gateway.rb +4 -0
- data/lib/braintree/sepa_direct_debit_account_gateway.rb +4 -0
- data/lib/braintree/subscription_gateway.rb +6 -0
- data/lib/braintree/testing_gateway.rb +4 -0
- data/lib/braintree/three_d_secure_pass_thru.rb +11 -0
- data/lib/braintree/transaction.rb +6 -0
- data/lib/braintree/transaction_gateway.rb +17 -7
- data/lib/braintree/transaction_line_item_gateway.rb +3 -1
- data/lib/braintree/transaction_search.rb +1 -0
- data/lib/braintree/us_bank_account_gateway.rb +2 -0
- data/lib/braintree/us_bank_account_verification_gateway.rb +4 -0
- data/lib/braintree/util.rb +5 -0
- data/lib/braintree/version.rb +1 -1
- data/lib/braintree.rb +1 -0
- data/spec/integration/braintree/advanced_search_spec.rb +4 -7
- data/spec/integration/braintree/braintree_gateway_spec.rb +1 -2
- data/spec/integration/braintree/client_api/client_token_spec.rb +14 -0
- data/spec/integration/braintree/credit_card_spec.rb +94 -2
- data/spec/integration/braintree/credit_card_verification_spec.rb +33 -0
- data/spec/integration/braintree/customer_spec.rb +196 -5
- data/spec/integration/braintree/http_spec.rb +1 -1
- data/spec/integration/braintree/payment_method_spec.rb +77 -7
- data/spec/integration/braintree/samsung_pay_card_spec.rb +1 -1
- data/spec/integration/braintree/transaction_search_spec.rb +113 -13
- data/spec/integration/braintree/transaction_spec.rb +197 -17
- data/spec/unit/braintree/address_spec.rb +32 -0
- data/spec/unit/braintree/client_token_spec.rb +72 -0
- data/spec/unit/braintree/credit_card_spec.rb +28 -0
- data/spec/unit/braintree/credit_card_verification_spec.rb +8 -0
- data/spec/unit/braintree/customer_spec.rb +28 -0
- data/spec/unit/braintree/dispute_spec.rb +38 -0
- data/spec/unit/braintree/http_spec.rb +44 -0
- data/spec/unit/braintree/merchant_account_spec.rb +11 -0
- data/spec/unit/braintree/package_tracking_spec.rb +2 -2
- data/spec/unit/braintree/payment_method_nonce_spec.rb +14 -0
- data/spec/unit/braintree/payment_method_spec.rb +20 -0
- data/spec/unit/braintree/paypal_account_spec.rb +20 -0
- data/spec/unit/braintree/plan_gateway_spec.rb +30 -0
- data/spec/unit/braintree/sepa_debit_account_spec.rb +14 -0
- data/spec/unit/braintree/subscription_spec.rb +20 -0
- data/spec/unit/braintree/test_transaction_spec.rb +18 -0
- data/spec/unit/braintree/transaction_gateway_spec.rb +11 -0
- data/spec/unit/braintree/transaction_line_item_spec.rb +11 -0
- data/spec/unit/braintree/transaction_search_spec.rb +25 -0
- data/spec/unit/braintree/transaction_spec.rb +68 -6
- data/spec/unit/braintree/us_bank_account_spec.rb +8 -0
- data/spec/unit/braintree/us_bank_account_verification_spec.rb +14 -0
- data/spec/unit/braintree/util_spec.rb +37 -0
- metadata +8 -3
|
@@ -46,6 +46,7 @@ module Braintree
|
|
|
46
46
|
equality_fields :credit_card_expiration_date
|
|
47
47
|
partial_match_fields :credit_card_number
|
|
48
48
|
|
|
49
|
+
multiple_value_field :ach_type, :allows => Transaction::AchType::All
|
|
49
50
|
multiple_value_field :created_using, :allows => [
|
|
50
51
|
Transaction::CreatedUsing::FullInformation,
|
|
51
52
|
Transaction::CreatedUsing::Token
|
|
@@ -8,6 +8,8 @@ module Braintree
|
|
|
8
8
|
|
|
9
9
|
def find(token)
|
|
10
10
|
raise ArgumentError if token.nil? || token.to_s.strip == ""
|
|
11
|
+
raise ArgumentError, "token contains invalid characters" if Util.invalid_path_segment?(token)
|
|
12
|
+
|
|
11
13
|
response = @config.http.get("#{@config.base_merchant_path}/payment_methods/us_bank_account/#{token}")
|
|
12
14
|
UsBankAccount._new(@gateway, response[:us_bank_account])
|
|
13
15
|
rescue NotFoundError
|
|
@@ -8,6 +8,8 @@ module Braintree
|
|
|
8
8
|
|
|
9
9
|
def confirm_micro_transfer_amounts(id, deposit_amounts)
|
|
10
10
|
raise ArgumentError if id.nil? || id.to_s.strip == "" || !deposit_amounts.kind_of?(Array)
|
|
11
|
+
raise ArgumentError, "id contains invalid characters" if Util.invalid_path_segment?(id)
|
|
12
|
+
|
|
11
13
|
response = @config.http.put(
|
|
12
14
|
"#{@config.base_merchant_path}/us_bank_account_verifications/#{id}/confirm_micro_transfer_amounts",
|
|
13
15
|
:us_bank_account_verification => {
|
|
@@ -27,6 +29,8 @@ module Braintree
|
|
|
27
29
|
|
|
28
30
|
def find(id)
|
|
29
31
|
raise ArgumentError if id.nil? || id.to_s.strip == ""
|
|
32
|
+
raise ArgumentError, "id contains invalid characters" if Util.invalid_path_segment?(id)
|
|
33
|
+
|
|
30
34
|
response = @config.http.get("#{@config.base_merchant_path}/us_bank_account_verifications/#{id}")
|
|
31
35
|
UsBankAccountVerification._new(response[:us_bank_account_verification])
|
|
32
36
|
rescue NotFoundError
|
data/lib/braintree/util.rb
CHANGED
|
@@ -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) : []
|
data/lib/braintree/version.rb
CHANGED
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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) {
|
|
@@ -378,6 +378,20 @@ describe Braintree::ClientToken do
|
|
|
378
378
|
end
|
|
379
379
|
end
|
|
380
380
|
|
|
381
|
+
it "can pass preferred_payment_method_token" do
|
|
382
|
+
result = Braintree::Customer.create
|
|
383
|
+
raw_client_token = Braintree::ClientToken.generate(
|
|
384
|
+
:customer_id => result.customer.id,
|
|
385
|
+
:preferred_payment_method_token => "a-pmt",
|
|
386
|
+
)
|
|
387
|
+
client_token = decode_client_token(raw_client_token)
|
|
388
|
+
|
|
389
|
+
expect(client_token["paymentMethodIdJwt"]).not_to be_nil
|
|
390
|
+
jwt_segment = client_token["paymentMethodIdJwt"].split(".")[1]
|
|
391
|
+
jwt_payload = JSON.parse(Base64.urlsafe_decode64(jwt_segment + "=" * ((4 - jwt_segment.length % 4) % 4)))
|
|
392
|
+
expect(jwt_payload["pmid"]).to eq("a-pmt")
|
|
393
|
+
end
|
|
394
|
+
|
|
381
395
|
it "can pass merchant_account_id" do
|
|
382
396
|
merchant_account_id = SpecHelper::NonDefaultMerchantAccountId
|
|
383
397
|
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
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,
|
|
@@ -2529,4 +2677,47 @@ describe Braintree::Customer do
|
|
|
2529
2677
|
end
|
|
2530
2678
|
end
|
|
2531
2679
|
|
|
2680
|
+
describe "path traversal" do
|
|
2681
|
+
it "self.update rejects a traversal customer_id and does not void the victim transaction" do
|
|
2682
|
+
transaction = Braintree::Transaction.sale!(
|
|
2683
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
|
2684
|
+
:credit_card => {
|
|
2685
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
|
2686
|
+
:expiration_date => "05/2009"
|
|
2687
|
+
},
|
|
2688
|
+
:options => {:submit_for_settlement => false},
|
|
2689
|
+
)
|
|
2690
|
+
traversal_id = "../transactions/#{transaction.id}/void"
|
|
2691
|
+
|
|
2692
|
+
expect do
|
|
2693
|
+
Braintree::Customer.update(traversal_id, :first_name => "HackerOne")
|
|
2694
|
+
end.to raise_error(ArgumentError, "customer_id contains invalid characters")
|
|
2695
|
+
|
|
2696
|
+
unaffected_transaction = Braintree::Transaction.find(transaction.id)
|
|
2697
|
+
expect(unaffected_transaction.status).to eq(Braintree::Transaction::Status::Authorized)
|
|
2698
|
+
end
|
|
2699
|
+
|
|
2700
|
+
it "self.delete rejects a traversal customer_id and does not delete the victim payment method" do
|
|
2701
|
+
create_result = Braintree::Customer.create(:first_name => "Victim")
|
|
2702
|
+
expect(create_result.success?).to eq(true)
|
|
2703
|
+
customer = create_result.customer
|
|
2704
|
+
|
|
2705
|
+
credit_card_result = Braintree::CreditCard.create(
|
|
2706
|
+
:customer_id => customer.id,
|
|
2707
|
+
:number => Braintree::Test::CreditCardNumbers::Visa,
|
|
2708
|
+
:expiration_date => "05/2009",
|
|
2709
|
+
)
|
|
2710
|
+
expect(credit_card_result.success?).to eq(true)
|
|
2711
|
+
token = credit_card_result.credit_card.token
|
|
2712
|
+
traversal_id = "../payment_methods/any/#{token}"
|
|
2713
|
+
|
|
2714
|
+
expect do
|
|
2715
|
+
Braintree::Customer.delete(traversal_id)
|
|
2716
|
+
end.to raise_error(ArgumentError, "customer_id contains invalid characters")
|
|
2717
|
+
|
|
2718
|
+
unaffected_credit_card = Braintree::CreditCard.find(token)
|
|
2719
|
+
expect(unaffected_credit_card.token).to eq(token)
|
|
2720
|
+
end
|
|
2721
|
+
end
|
|
2722
|
+
|
|
2532
2723
|
end
|
|
@@ -97,7 +97,7 @@ describe Braintree::Http do
|
|
|
97
97
|
end
|
|
98
98
|
|
|
99
99
|
describe "ssl_version" do
|
|
100
|
-
|
|
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
|
|
@@ -92,8 +92,8 @@ describe Braintree::PaymentMethod do
|
|
|
92
92
|
expect(apple_pay_card.bin).not_to be_nil
|
|
93
93
|
expect(apple_pay_card.token).to eq(token)
|
|
94
94
|
expect(apple_pay_card.card_type).to eq(Braintree::ApplePayCard::CardType::AmEx)
|
|
95
|
-
expect(apple_pay_card.payment_instrument_name).to
|
|
96
|
-
expect(apple_pay_card.source_description).to
|
|
95
|
+
expect(apple_pay_card.payment_instrument_name).to match(/\AAmEx \d{4,5}\z/)
|
|
96
|
+
expect(apple_pay_card.source_description).to match(/\AAmEx \d{4,5}\z/)
|
|
97
97
|
expect(apple_pay_card.default).to eq(true)
|
|
98
98
|
expect(apple_pay_card.image_url).to match(/apple_pay/)
|
|
99
99
|
expect(apple_pay_card.expiration_month.to_i).to be > 0
|
|
@@ -127,8 +127,8 @@ describe Braintree::PaymentMethod do
|
|
|
127
127
|
expect(apple_pay_card.bin).not_to be_nil
|
|
128
128
|
expect(apple_pay_card.token).to eq(token)
|
|
129
129
|
expect(apple_pay_card.card_type).to eq(Braintree::ApplePayCard::CardType::Visa)
|
|
130
|
-
expect(apple_pay_card.payment_instrument_name).to
|
|
131
|
-
expect(apple_pay_card.source_description).to
|
|
130
|
+
expect(apple_pay_card.payment_instrument_name).to match(/\AVisa \d{4}\z/)
|
|
131
|
+
expect(apple_pay_card.source_description).to match(/\AVisa \d{4}\z/)
|
|
132
132
|
expect(apple_pay_card.default).to eq(true)
|
|
133
133
|
expect(apple_pay_card.image_url).to match(/apple_pay/)
|
|
134
134
|
expect(apple_pay_card.expiration_month.to_i).to be > 0
|
|
@@ -382,6 +382,76 @@ describe Braintree::PaymentMethod do
|
|
|
382
382
|
expect(result).to be_success
|
|
383
383
|
end
|
|
384
384
|
|
|
385
|
+
it "accepts a three_d_secure_pass_thru network specified in the request" do
|
|
386
|
+
customer = Braintree::Customer.create!
|
|
387
|
+
result = Braintree::PaymentMethod.create(
|
|
388
|
+
:customer_id => customer.id,
|
|
389
|
+
:payment_method_nonce => Braintree::Test::Nonce::TransactableVisa,
|
|
390
|
+
:three_d_secure_pass_thru => {
|
|
391
|
+
:eci_flag => "05",
|
|
392
|
+
:cavv => "some_cavv",
|
|
393
|
+
:xid => "some_xid",
|
|
394
|
+
:three_d_secure_version => "2.2.0",
|
|
395
|
+
:authentication_response => "Y",
|
|
396
|
+
:directory_response => "Y",
|
|
397
|
+
:cavv_algorithm => "2",
|
|
398
|
+
:ds_transaction_id => "some_ds_transaction_id",
|
|
399
|
+
:network => Braintree::ThreeDSecurePassThru::Network::Visa,
|
|
400
|
+
},
|
|
401
|
+
:options => {:verify_card => true},
|
|
402
|
+
)
|
|
403
|
+
|
|
404
|
+
expect(result).to be_success
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
it "rejects invalid network value in 3ds pass thru params" do
|
|
408
|
+
customer = Braintree::Customer.create!
|
|
409
|
+
result = Braintree::PaymentMethod.create(
|
|
410
|
+
:customer_id => customer.id,
|
|
411
|
+
:payment_method_nonce => Braintree::Test::Nonce::Transactable,
|
|
412
|
+
:three_d_secure_pass_thru => {
|
|
413
|
+
:eci_flag => "05",
|
|
414
|
+
:cavv => "some_cavv",
|
|
415
|
+
:xid => "some_xid",
|
|
416
|
+
:three_d_secure_version => "2.2.0",
|
|
417
|
+
:authentication_response => "Y",
|
|
418
|
+
:directory_response => "Y",
|
|
419
|
+
:cavv_algorithm => "2",
|
|
420
|
+
:ds_transaction_id => "some_ds_transaction_id",
|
|
421
|
+
:network => "DISCOVER",
|
|
422
|
+
},
|
|
423
|
+
:options => {:verify_card => true},
|
|
424
|
+
)
|
|
425
|
+
expect(result).not_to be_success
|
|
426
|
+
error = result.errors.for(:verification).first
|
|
427
|
+
expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::NetworkIsInvalid)
|
|
428
|
+
expect(error.message).to eq("Network is invalid. Supported networks are eftpos, Visa, and Mastercard.")
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
it "rejects request where 3ds pass thru network does not match the payment instrument (VISA nonce, Mastercard network)" do
|
|
432
|
+
customer = Braintree::Customer.create!
|
|
433
|
+
result = Braintree::PaymentMethod.create(
|
|
434
|
+
:customer_id => customer.id,
|
|
435
|
+
:payment_method_nonce => Braintree::Test::Nonce::TransactableVisa,
|
|
436
|
+
:three_d_secure_pass_thru => {
|
|
437
|
+
:eci_flag => "05",
|
|
438
|
+
:cavv => "some_cavv",
|
|
439
|
+
:xid => "some_xid",
|
|
440
|
+
:three_d_secure_version => "2.2.0",
|
|
441
|
+
:authentication_response => "Y",
|
|
442
|
+
:directory_response => "Y",
|
|
443
|
+
:cavv_algorithm => "2",
|
|
444
|
+
:ds_transaction_id => "some_ds_transaction_id",
|
|
445
|
+
:network => Braintree::ThreeDSecurePassThru::Network::MasterCard,
|
|
446
|
+
},
|
|
447
|
+
:options => {:verify_card => true},
|
|
448
|
+
)
|
|
449
|
+
expect(result).not_to be_success
|
|
450
|
+
error = result.errors.for(:verification).first
|
|
451
|
+
expect(error.code).to eq(Braintree::ErrorCodes::Verification::ThreeDSecurePassThru::NetworkDoesNotMatchPaymentInstrument)
|
|
452
|
+
expect(error.message).to eq("Network does not match the payment instrument.")
|
|
453
|
+
end
|
|
454
|
+
|
|
385
455
|
it "returns 3DS info on cc verification" do
|
|
386
456
|
customer = Braintree::Customer.create.customer
|
|
387
457
|
result = Braintree::PaymentMethod.create(
|
|
@@ -813,7 +883,7 @@ describe Braintree::PaymentMethod do
|
|
|
813
883
|
expect(update_result.payment_method.verification.credit_card[:account_type]).to eq("credit")
|
|
814
884
|
end
|
|
815
885
|
|
|
816
|
-
|
|
886
|
+
it "updates the credit card with account_type debit" do
|
|
817
887
|
customer = Braintree::Customer.create!
|
|
818
888
|
credit_card = Braintree::CreditCard.create!(
|
|
819
889
|
:cardholder_name => "Original Holder",
|
|
@@ -1404,7 +1474,7 @@ describe Braintree::PaymentMethod do
|
|
|
1404
1474
|
expect(apple_pay_card.image_url).to match(/apple_pay/)
|
|
1405
1475
|
expect(apple_pay_card.expiration_month.to_i).to be > 0
|
|
1406
1476
|
expect(apple_pay_card.expiration_year.to_i).to be > 0
|
|
1407
|
-
expect(apple_pay_card.source_description).to
|
|
1477
|
+
expect(apple_pay_card.source_description).to match(/\AAmEx \d{4,5}\z/)
|
|
1408
1478
|
expect(apple_pay_card.customer_id).to eq(customer.id)
|
|
1409
1479
|
end
|
|
1410
1480
|
|
|
@@ -1427,7 +1497,7 @@ describe Braintree::PaymentMethod do
|
|
|
1427
1497
|
expect(apple_pay_card.image_url).to match(/apple_pay/)
|
|
1428
1498
|
expect(apple_pay_card.expiration_month.to_i).to be > 0
|
|
1429
1499
|
expect(apple_pay_card.expiration_year.to_i).to be > 0
|
|
1430
|
-
expect(apple_pay_card.source_description).to
|
|
1500
|
+
expect(apple_pay_card.source_description).to match(/\AVisa \d{4}\z/)
|
|
1431
1501
|
expect(apple_pay_card.customer_id).to eq(customer.id)
|
|
1432
1502
|
expect(apple_pay_card.is_device_token).to eq(false)
|
|
1433
1503
|
apple_pay_card.merchant_token_identifier == "DNITHE302308980427388297"
|