braintree 2.84.0 → 2.85.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/lib/braintree.rb +3 -0
  3. data/lib/braintree/advanced_search.rb +8 -0
  4. data/lib/braintree/credit_card_verification_gateway.rb +1 -1
  5. data/lib/braintree/error_codes.rb +6 -0
  6. data/lib/braintree/gateway.rb +4 -0
  7. data/lib/braintree/payment_method_gateway.rb +3 -1
  8. data/lib/braintree/us_bank_account.rb +8 -0
  9. data/lib/braintree/us_bank_account_verification.rb +75 -0
  10. data/lib/braintree/us_bank_account_verification_gateway.rb +32 -0
  11. data/lib/braintree/us_bank_account_verification_search.rb +19 -0
  12. data/lib/braintree/version.rb +1 -1
  13. data/lib/braintree/webhook_notification.rb +3 -0
  14. data/lib/braintree/webhook_testing_gateway.rb +10 -0
  15. data/spec/httpsd.pid +1 -1
  16. data/spec/integration/braintree/client_api/spec_helper.rb +33 -5
  17. data/spec/integration/braintree/credit_card_spec.rb +2 -2
  18. data/spec/integration/braintree/customer_spec.rb +9 -4
  19. data/spec/integration/braintree/dispute_search_spec.rb +14 -3
  20. data/spec/integration/braintree/payment_method_spec.rb +0 -35
  21. data/spec/integration/braintree/payment_method_us_bank_account_spec.rb +412 -0
  22. data/spec/integration/braintree/transaction_search_spec.rb +49 -51
  23. data/spec/integration/braintree/transaction_spec.rb +3 -93
  24. data/spec/integration/braintree/transaction_us_bank_account_spec.rb +432 -0
  25. data/spec/integration/braintree/us_bank_account_spec.rb +36 -15
  26. data/spec/integration/braintree/us_bank_account_verification_search_spec.rb +178 -0
  27. data/spec/integration/braintree/us_bank_account_verification_spec.rb +79 -0
  28. data/spec/spec_helper.rb +2 -1
  29. data/spec/unit/braintree/us_bank_account_verification_search_spec.rb +60 -0
  30. data/spec/unit/braintree/us_bank_account_verification_spec.rb +67 -0
  31. data/spec/unit/braintree/webhook_notification_spec.rb +13 -0
  32. metadata +12 -3
@@ -776,62 +776,74 @@ describe Braintree::Transaction, "search" do
776
776
  end
777
777
 
778
778
  context "dispute_date" do
779
- it "searches on dispute_date in UTC" do
780
- disputed_time = Time.parse("2014-03-01 00:00:00 UTC")
781
- transaction_id = "2disputetransaction"
779
+ before(:all) do
780
+ @disputed_transaction = Braintree::Transaction.sale!(
781
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
782
+ :credit_card => {
783
+ :number => Braintree::Test::CreditCardNumbers::Disputes::Chargeback,
784
+ :expiration_date => "03/18"
785
+ }
786
+ )
787
+
788
+ @disputed_date = @disputed_transaction.disputes.first.received_date
789
+ @disputed_time = @disputed_date.to_time
782
790
 
791
+ Timeout::timeout(60) {
792
+ dispute_date_indexed = false
793
+ until dispute_date_indexed
794
+ sleep 1
795
+ collection = Braintree::Transaction.search do |search|
796
+ search.id.is @disputed_transaction.id
797
+ search.dispute_date.is @disputed_date
798
+ end
799
+
800
+ dispute_date_indexed = collection.maximum_size == 1
801
+ end
802
+ }
803
+ end
804
+
805
+ it "searches on dispute_date in UTC" do
783
806
  collection = Braintree::Transaction.search do |search|
784
- search.id.is transaction_id
807
+ search.id.is @disputed_transaction.id
785
808
  search.dispute_date.between(
786
- disputed_time - 60,
787
- disputed_time + 60
809
+ @disputed_time - 60,
810
+ @disputed_time + 60
788
811
  )
789
812
  end
790
813
 
791
814
  collection.maximum_size.should == 1
792
- collection.first.id.should == transaction_id
815
+ collection.first.id.should == @disputed_transaction.id
793
816
 
794
817
  collection = Braintree::Transaction.search do |search|
795
- search.id.is transaction_id
796
- search.dispute_date >= disputed_time - 1
818
+ search.id.is @disputed_transaction.id
819
+ search.dispute_date >= @disputed_time - 1
797
820
  end
798
821
 
799
822
  collection.maximum_size.should == 1
800
- collection.first.id.should == transaction_id
823
+ collection.first.id.should == @disputed_transaction.id
801
824
 
802
825
  collection = Braintree::Transaction.search do |search|
803
- search.id.is transaction_id
804
- search.dispute_date <= disputed_time + 1
826
+ search.id.is @disputed_transaction.id
827
+ search.dispute_date <= @disputed_time + 1
805
828
  end
806
829
 
807
830
  collection.maximum_size.should == 1
808
- collection.first.id.should == transaction_id
831
+ collection.first.id.should == @disputed_transaction.id
809
832
 
810
833
  collection = Braintree::Transaction.search do |search|
811
- search.id.is transaction_id
812
- search.disbursement_date.between(
813
- disputed_time - 300,
814
- disputed_time - 100
815
- )
816
- end
817
-
818
- collection.maximum_size.should == 0
819
-
820
- collection = Braintree::Transaction.search do |search|
821
- search.id.is transaction_id
822
- search.dispute_date.is disputed_time
834
+ search.id.is @disputed_transaction.id
835
+ search.dispute_date.is @disputed_time
823
836
  end
824
837
 
825
838
  collection.maximum_size.should == 1
826
- collection.first.id.should == transaction_id
839
+ collection.first.id.should == @disputed_transaction.id
827
840
  end
828
841
 
829
842
  it "searches on dispute_date in local time" do
830
- now = Time.parse("2014-03-01 18:00:00 CST")
831
- transaction_id = "2disputetransaction"
843
+ now = @disputed_time.localtime("-06:00")
832
844
 
833
845
  collection = Braintree::Transaction.search do |search|
834
- search.id.is transaction_id
846
+ search.id.is @disputed_transaction.id
835
847
  search.dispute_date.between(
836
848
  now - 60,
837
849
  now + 60
@@ -839,49 +851,35 @@ describe Braintree::Transaction, "search" do
839
851
  end
840
852
 
841
853
  collection.maximum_size.should == 1
842
- collection.first.id.should == transaction_id
854
+ collection.first.id.should == @disputed_transaction.id
843
855
 
844
856
  collection = Braintree::Transaction.search do |search|
845
- search.id.is transaction_id
857
+ search.id.is @disputed_transaction.id
846
858
  search.dispute_date >= now - 60
847
859
  end
848
860
 
849
861
  collection.maximum_size.should == 1
850
- collection.first.id.should == transaction_id
862
+ collection.first.id.should == @disputed_transaction.id
851
863
 
852
864
  collection = Braintree::Transaction.search do |search|
853
- search.id.is transaction_id
865
+ search.id.is @disputed_transaction.id
854
866
  search.dispute_date <= now + 60
855
867
  end
856
868
 
857
869
  collection.maximum_size.should == 1
858
- collection.first.id.should == transaction_id
859
-
860
- collection = Braintree::Transaction.search do |search|
861
- search.id.is transaction_id
862
- search.dispute_date.between(
863
- now + 100,
864
- now + 300
865
- )
866
- end
867
-
868
- collection.maximum_size.should == 0
869
870
  end
870
871
 
871
872
  it "searches on dispute_date with date ranges" do
872
- disputed_date = Date.new(2014, 3, 1)
873
- transaction_id = "disputedtransaction"
874
-
875
873
  collection = Braintree::Transaction.search do |search|
876
- search.id.is transaction_id
874
+ search.id.is @disputed_transaction.id
877
875
  search.dispute_date.between(
878
- disputed_date - 1,
879
- disputed_date + 1
876
+ @disputed_date - 1,
877
+ @disputed_date + 1
880
878
  )
881
879
  end
882
880
 
883
881
  collection.maximum_size.should == 1
884
- collection.first.id.should == transaction_id
882
+ collection.first.id.should == @disputed_transaction.id
885
883
  end
886
884
  end
887
885
 
@@ -1281,7 +1281,7 @@ describe Braintree::Transaction do
1281
1281
  }
1282
1282
  )
1283
1283
  result.success?.should == true
1284
- result.transaction.credit_card_details.venmo_sdk?.should == true
1284
+ result.transaction.credit_card_details.venmo_sdk?.should == false
1285
1285
  end
1286
1286
  end
1287
1287
 
@@ -2117,96 +2117,6 @@ describe Braintree::Transaction do
2117
2117
  end
2118
2118
  end
2119
2119
 
2120
- context "us bank account nonce" do
2121
- let!(:valid_nonce) { generate_valid_us_bank_account_nonce }
2122
- let!(:invalid_nonce) { generate_invalid_us_bank_account_nonce }
2123
- it "returns a successful result for tansacting on a us bank account nonce" do
2124
- result = Braintree::Transaction.create(
2125
- :type => "sale",
2126
- :amount => Braintree::Test::TransactionAmounts::Authorize,
2127
- :merchant_account_id => "us_bank_merchant_account",
2128
- :payment_method_nonce => valid_nonce,
2129
- :options => {
2130
- :submit_for_settlement => true,
2131
- }
2132
- )
2133
- result.success?.should == true
2134
- result.transaction.id.should =~ /^\w{6,}$/
2135
- result.transaction.type.should == "sale"
2136
- result.transaction.payment_instrument_type.should == Braintree::PaymentInstrumentType::UsBankAccount
2137
- result.transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
2138
- result.transaction.status.should == Braintree::Transaction::Status::SettlementPending
2139
- result.transaction.us_bank_account_details.routing_number.should == "021000021"
2140
- result.transaction.us_bank_account_details.last_4.should == "1234"
2141
- result.transaction.us_bank_account_details.account_type.should == "checking"
2142
- result.transaction.us_bank_account_details.account_holder_name.should == "Dan Schulman"
2143
- result.transaction.us_bank_account_details.bank_name.should =~ /CHASE/
2144
- result.transaction.us_bank_account_details.ach_mandate.text.should == "cl mandate text"
2145
- result.transaction.us_bank_account_details.ach_mandate.accepted_at.should be_a Time
2146
- end
2147
-
2148
- it "return successful result for vaulting and transacting on vaulted token" do
2149
- result = Braintree::Transaction.create(
2150
- :type => "sale",
2151
- :amount => Braintree::Test::TransactionAmounts::Authorize,
2152
- :merchant_account_id => "us_bank_merchant_account",
2153
- :payment_method_nonce => valid_nonce,
2154
- :options => {
2155
- :submit_for_settlement => true,
2156
- :store_in_vault => true,
2157
- }
2158
- )
2159
- result.success?.should == true
2160
- result.transaction.id.should =~ /^\w{6,}$/
2161
- result.transaction.type.should == "sale"
2162
- result.transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
2163
- result.transaction.status.should == Braintree::Transaction::Status::SettlementPending
2164
- result.transaction.us_bank_account_details.routing_number.should == "021000021"
2165
- result.transaction.us_bank_account_details.last_4.should == "1234"
2166
- result.transaction.us_bank_account_details.account_type.should == "checking"
2167
- result.transaction.us_bank_account_details.account_holder_name.should == "Dan Schulman"
2168
- result.transaction.us_bank_account_details.bank_name.should =~ /CHASE/
2169
- result.transaction.us_bank_account_details.ach_mandate.text.should == "cl mandate text"
2170
- result.transaction.us_bank_account_details.ach_mandate.accepted_at.should be_a Time
2171
-
2172
- result = Braintree::Transaction.create(
2173
- :type => "sale",
2174
- :amount => Braintree::Test::TransactionAmounts::Authorize,
2175
- :merchant_account_id => "us_bank_merchant_account",
2176
- :payment_method_token=> result.transaction.us_bank_account_details.token,
2177
- :options => {
2178
- :submit_for_settlement => true,
2179
- }
2180
- )
2181
- result.success?.should == true
2182
- result.transaction.id.should =~ /^\w{6,}$/
2183
- result.transaction.type.should == "sale"
2184
- result.transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
2185
- result.transaction.status.should == Braintree::Transaction::Status::SettlementPending
2186
- result.transaction.us_bank_account_details.routing_number.should == "021000021"
2187
- result.transaction.us_bank_account_details.last_4.should == "1234"
2188
- result.transaction.us_bank_account_details.account_type.should == "checking"
2189
- result.transaction.us_bank_account_details.account_holder_name.should == "Dan Schulman"
2190
- result.transaction.us_bank_account_details.bank_name.should =~ /CHASE/
2191
- result.transaction.us_bank_account_details.ach_mandate.text.should == "cl mandate text"
2192
- result.transaction.us_bank_account_details.ach_mandate.accepted_at.should be_a Time
2193
- end
2194
-
2195
- it "returns failure for token that doesn't exist" do
2196
- result = Braintree::Transaction.create(
2197
- :type => "sale",
2198
- :amount => Braintree::Test::TransactionAmounts::Authorize,
2199
- :merchant_account_id => "us_bank_merchant_account",
2200
- :payment_method_nonce => invalid_nonce,
2201
- :options => {
2202
- :submit_for_settlement => true,
2203
- }
2204
- )
2205
- result.success?.should == false
2206
- result.errors.for(:transaction).on(:payment_method_nonce)[0].code.should == Braintree::ErrorCodes::Transaction::PaymentMethodNonceUnknown
2207
- end
2208
- end
2209
-
2210
2120
  context "ideal payment nonce" do
2211
2121
  it "returns a successful result for tansacting on an ideal payment nonce" do
2212
2122
  valid_ideal_payment_id = generate_valid_ideal_payment_nonce
@@ -5809,7 +5719,7 @@ describe Braintree::Transaction do
5809
5719
  :venmo_sdk_payment_method_code => Braintree::Test::VenmoSDK.generate_test_payment_method_code(Braintree::Test::CreditCardNumbers::Visa)
5810
5720
  )
5811
5721
  result.success?.should == true
5812
- result.transaction.credit_card_details.venmo_sdk?.should == true
5722
+ result.transaction.credit_card_details.venmo_sdk?.should == false
5813
5723
  end
5814
5724
 
5815
5725
  it "errors when an invalid payment method code is passed" do
@@ -5836,7 +5746,7 @@ describe Braintree::Transaction do
5836
5746
  }
5837
5747
  )
5838
5748
  result.success?.should == true
5839
- result.transaction.credit_card_details.venmo_sdk?.should == true
5749
+ result.transaction.credit_card_details.venmo_sdk?.should == false
5840
5750
  end
5841
5751
 
5842
5752
  it "venmo_sdk boolean is false when an invalid session is passed" do
@@ -0,0 +1,432 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+ require File.expand_path(File.dirname(__FILE__) + "/client_api/spec_helper")
3
+
4
+ describe Braintree::Transaction do
5
+ describe "self.create us bank account" do
6
+ context "compliant merchant" do
7
+ before do
8
+ Braintree::Configuration.merchant_id = "integration2_merchant_id"
9
+ Braintree::Configuration.public_key = "integration2_public_key"
10
+ Braintree::Configuration.private_key = "integration2_private_key"
11
+ end
12
+
13
+ context "plaid-verified" do
14
+ let(:plaid_nonce) { generate_valid_plaid_us_bank_account_nonce }
15
+
16
+ context "nonce" do
17
+ it "sale succeeds" do
18
+ result = Braintree::Transaction.create(
19
+ :type => "sale",
20
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
21
+ :merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
22
+ :payment_method_nonce => plaid_nonce,
23
+ :options => {
24
+ :submit_for_settlement => true,
25
+ }
26
+ )
27
+ result.success?.should == true
28
+ result.transaction.id.should =~ /^\w{6,}$/
29
+ result.transaction.type.should == "sale"
30
+ result.transaction.payment_instrument_type.should == Braintree::PaymentInstrumentType::UsBankAccount
31
+ result.transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
32
+ result.transaction.status.should == Braintree::Transaction::Status::SettlementPending
33
+ result.transaction.us_bank_account_details.routing_number.should == "011000015"
34
+ result.transaction.us_bank_account_details.last_4.should == "0000"
35
+ result.transaction.us_bank_account_details.account_type.should == "checking"
36
+ result.transaction.us_bank_account_details.account_holder_name.should == "PayPal, Inc."
37
+ result.transaction.us_bank_account_details.bank_name.should == "FEDERAL RESERVE BANK"
38
+ result.transaction.us_bank_account_details.ach_mandate.text.should == "cl mandate text"
39
+ result.transaction.us_bank_account_details.ach_mandate.accepted_at.should be_a Time
40
+ end
41
+ end
42
+
43
+ context "token" do
44
+ it "payment_method#create then sale succeeds" do
45
+ payment_method = Braintree::PaymentMethod.create(
46
+ :payment_method_nonce => plaid_nonce,
47
+ :customer_id => Braintree::Customer.create.customer.id,
48
+ :options => {
49
+ :verification_merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
50
+ }
51
+ ).payment_method
52
+
53
+ payment_method.verifications.count.should == 1
54
+ payment_method.verifications.first.status.should == Braintree::UsBankAccountVerification::Status::Verified
55
+ payment_method.verifications.first.verification_method.should == Braintree::UsBankAccountVerification::VerificationMethod::TokenizedCheck
56
+ payment_method.verifications.first.id.should_not be_empty
57
+ payment_method.verifications.first.verification_determined_at.should be_a Time
58
+ payment_method.verified.should == true
59
+
60
+ result = Braintree::Transaction.create(
61
+ :type => "sale",
62
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
63
+ :merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
64
+ :payment_method_token => payment_method.token,
65
+ :options => {
66
+ :submit_for_settlement => true,
67
+ }
68
+ )
69
+
70
+ result.success?.should == true
71
+
72
+ transaction = result.transaction
73
+
74
+ transaction.id.should =~ /^\w{6,}$/
75
+ transaction.type.should == "sale"
76
+ transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
77
+ transaction.status.should == Braintree::Transaction::Status::SettlementPending
78
+ transaction.us_bank_account_details.routing_number.should == "011000015"
79
+ transaction.us_bank_account_details.last_4.should == "0000"
80
+ transaction.us_bank_account_details.account_type.should == "checking"
81
+ transaction.us_bank_account_details.account_holder_name.should == "PayPal, Inc."
82
+ transaction.us_bank_account_details.bank_name.should == "FEDERAL RESERVE BANK"
83
+ transaction.us_bank_account_details.ach_mandate.text.should == "cl mandate text"
84
+ transaction.us_bank_account_details.ach_mandate.accepted_at.should be_a Time
85
+ end
86
+
87
+ it "transaction#create store_in_vault then sale succeeds" do
88
+ result = Braintree::Transaction.create(
89
+ :type => "sale",
90
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
91
+ :merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
92
+ :payment_method_nonce => plaid_nonce,
93
+ :options => {
94
+ :submit_for_settlement => true,
95
+ :store_in_vault => true,
96
+ }
97
+ )
98
+
99
+ result.success?.should == true
100
+
101
+ result = Braintree::Transaction.create(
102
+ :type => "sale",
103
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
104
+ :merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
105
+ :payment_method_token => result.transaction.us_bank_account_details.token,
106
+ :options => {
107
+ :submit_for_settlement => true,
108
+ }
109
+ )
110
+
111
+ result.success?.should == true
112
+
113
+ transaction = result.transaction
114
+
115
+ transaction.id.should =~ /^\w{6,}$/
116
+ transaction.type.should == "sale"
117
+ transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
118
+ transaction.status.should == Braintree::Transaction::Status::SettlementPending
119
+ transaction.us_bank_account_details.routing_number.should == "011000015"
120
+ transaction.us_bank_account_details.last_4.should == "0000"
121
+ transaction.us_bank_account_details.account_type.should == "checking"
122
+ transaction.us_bank_account_details.account_holder_name.should == "PayPal, Inc."
123
+ transaction.us_bank_account_details.bank_name.should == "FEDERAL RESERVE BANK"
124
+ transaction.us_bank_account_details.ach_mandate.text.should == "cl mandate text"
125
+ transaction.us_bank_account_details.ach_mandate.accepted_at.should be_a Time
126
+ end
127
+ end
128
+ end
129
+
130
+ context "not plaid-verified" do
131
+ let(:non_plaid_nonce) { generate_non_plaid_us_bank_account_nonce }
132
+ let(:invalid_nonce) { generate_invalid_us_bank_account_nonce }
133
+
134
+ context "nonce" do
135
+ it "sale fails for valid nonce" do
136
+ result = Braintree::Transaction.create(
137
+ :type => "sale",
138
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
139
+ :merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
140
+ :payment_method_nonce => non_plaid_nonce,
141
+ :options => {
142
+ :submit_for_settlement => true,
143
+ }
144
+ )
145
+ result.success?.should == false
146
+ result.errors.for(:transaction).on(:payment_method_nonce)[0].code.should == Braintree::ErrorCodes::Transaction::UsBankAccountNonceMustBePlaidVerified
147
+ end
148
+
149
+ it "sale fails for invalid nonce" do
150
+ result = Braintree::Transaction.create(
151
+ :type => "sale",
152
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
153
+ :merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
154
+ :payment_method_nonce => invalid_nonce,
155
+ :options => {
156
+ :submit_for_settlement => true,
157
+ }
158
+ )
159
+ result.success?.should == false
160
+ result.errors.for(:transaction).on(:payment_method_nonce)[0].code.should == Braintree::ErrorCodes::Transaction::PaymentMethodNonceUnknown
161
+ end
162
+ end
163
+
164
+ context "token" do
165
+ it "sale succeeds for verified token" do
166
+ result = Braintree::PaymentMethod.create(
167
+ :payment_method_nonce => non_plaid_nonce,
168
+ :customer_id => Braintree::Customer.create.customer.id,
169
+ :options => {
170
+ :us_bank_account_verification_method => "independent_check",
171
+ :verification_merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
172
+ }
173
+ )
174
+ payment_method = result.payment_method
175
+
176
+ payment_method.verifications.count.should == 1
177
+ payment_method.verifications.first.status == Braintree::UsBankAccountVerification::Status::Verified
178
+ payment_method.verifications.first.verification_method == Braintree::UsBankAccountVerification::VerificationMethod::IndependentCheck
179
+ payment_method.verifications.first.id.should_not be_empty
180
+ payment_method.verifications.first.verification_determined_at.should be_a Time
181
+ payment_method.verified.should == true
182
+
183
+ result = Braintree::Transaction.create(
184
+ :type => "sale",
185
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
186
+ :merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
187
+ :payment_method_token => payment_method.token,
188
+ :options => {
189
+ :submit_for_settlement => true,
190
+ }
191
+ )
192
+
193
+ result.success?.should == true
194
+ end
195
+
196
+ it "sale fails for unverified token" do
197
+ payment_method = Braintree::PaymentMethod.create(
198
+ :payment_method_nonce => non_plaid_nonce,
199
+ :customer_id => Braintree::Customer.create.customer.id,
200
+ :options => {
201
+ :verification_merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
202
+ }
203
+ ).payment_method
204
+
205
+ payment_method.verifications.count.should == 0
206
+ payment_method.verified.should == false
207
+
208
+ result = Braintree::Transaction.create(
209
+ :type => "sale",
210
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
211
+ :merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
212
+ :payment_method_token => payment_method.token,
213
+ :options => {
214
+ :submit_for_settlement => true,
215
+ }
216
+ )
217
+
218
+ result.success?.should == false
219
+ result.errors.for(:transaction)[0].code.should == Braintree::ErrorCodes::Transaction::UsBankAccountNotVerified
220
+ end
221
+ end
222
+ end
223
+ end
224
+
225
+ context "exempt merchant" do
226
+ before do
227
+ Braintree::Configuration.merchant_id = "integration_merchant_id"
228
+ Braintree::Configuration.public_key = "integration_public_key"
229
+ Braintree::Configuration.private_key = "integration_private_key"
230
+ end
231
+
232
+ context "plaid-verified" do
233
+ let(:plaid_nonce) { generate_valid_plaid_us_bank_account_nonce }
234
+
235
+ context "nonce" do
236
+ it "sale succeeds" do
237
+ result = Braintree::Transaction.create(
238
+ :type => "sale",
239
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
240
+ :merchant_account_id => SpecHelper::UsBankMerchantAccountId,
241
+ :payment_method_nonce => plaid_nonce,
242
+ :options => {
243
+ :submit_for_settlement => true,
244
+ }
245
+ )
246
+ result.success?.should == true
247
+ result.transaction.id.should =~ /^\w{6,}$/
248
+ result.transaction.type.should == "sale"
249
+ result.transaction.payment_instrument_type.should == Braintree::PaymentInstrumentType::UsBankAccount
250
+ result.transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
251
+ result.transaction.status.should == Braintree::Transaction::Status::SettlementPending
252
+ result.transaction.us_bank_account_details.routing_number.should == "011000015"
253
+ result.transaction.us_bank_account_details.last_4.should == "0000"
254
+ result.transaction.us_bank_account_details.account_type.should == "checking"
255
+ result.transaction.us_bank_account_details.account_holder_name.should == "PayPal, Inc."
256
+ result.transaction.us_bank_account_details.bank_name.should == "FEDERAL RESERVE BANK"
257
+ result.transaction.us_bank_account_details.ach_mandate.text.should == "cl mandate text"
258
+ result.transaction.us_bank_account_details.ach_mandate.accepted_at.should be_a Time
259
+ end
260
+ end
261
+
262
+ context "token" do
263
+ it "payment_method#create then sale succeeds" do
264
+ result = Braintree::PaymentMethod.create(
265
+ :payment_method_nonce => plaid_nonce,
266
+ :customer_id => Braintree::Customer.create.customer.id,
267
+ :options => {
268
+ :verification_merchant_account_id => SpecHelper::UsBankMerchantAccountId,
269
+ }
270
+ )
271
+
272
+ payment_method = result.payment_method
273
+
274
+ payment_method.verifications.count.should == 1
275
+ payment_method.verifications.first.status.should == Braintree::UsBankAccountVerification::Status::Verified
276
+ payment_method.verifications.first.verification_method.should == Braintree::UsBankAccountVerification::VerificationMethod::TokenizedCheck
277
+ payment_method.verifications.first.id.should_not be_empty
278
+ payment_method.verifications.first.verification_determined_at.should be_a Time
279
+ payment_method.verified.should == true
280
+
281
+ result = Braintree::Transaction.create(
282
+ :type => "sale",
283
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
284
+ :merchant_account_id => SpecHelper::UsBankMerchantAccountId,
285
+ :payment_method_token => payment_method.token,
286
+ :options => {
287
+ :submit_for_settlement => true,
288
+ }
289
+ )
290
+
291
+ result.success?.should == true
292
+
293
+ transaction = result.transaction
294
+
295
+ transaction.id.should =~ /^\w{6,}$/
296
+ transaction.type.should == "sale"
297
+ transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
298
+ transaction.status.should == Braintree::Transaction::Status::SettlementPending
299
+ transaction.us_bank_account_details.routing_number.should == "011000015"
300
+ transaction.us_bank_account_details.last_4.should == "0000"
301
+ transaction.us_bank_account_details.account_type.should == "checking"
302
+ transaction.us_bank_account_details.account_holder_name.should == "PayPal, Inc."
303
+ transaction.us_bank_account_details.bank_name.should == "FEDERAL RESERVE BANK"
304
+ transaction.us_bank_account_details.ach_mandate.text.should == "cl mandate text"
305
+ transaction.us_bank_account_details.ach_mandate.accepted_at.should be_a Time
306
+ end
307
+
308
+ it "transaction#create store_in_vault then sale succeeds" do
309
+ result = Braintree::Transaction.create(
310
+ :type => "sale",
311
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
312
+ :merchant_account_id => SpecHelper::UsBankMerchantAccountId,
313
+ :payment_method_nonce => plaid_nonce,
314
+ :options => {
315
+ :submit_for_settlement => true,
316
+ :store_in_vault => true,
317
+ }
318
+ )
319
+
320
+ result.success?.should == true
321
+
322
+ result = Braintree::Transaction.create(
323
+ :type => "sale",
324
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
325
+ :merchant_account_id => SpecHelper::UsBankMerchantAccountId,
326
+ :payment_method_token => result.transaction.us_bank_account_details.token,
327
+ :options => {
328
+ :submit_for_settlement => true,
329
+ }
330
+ )
331
+
332
+ result.success?.should == true
333
+
334
+ transaction = result.transaction
335
+
336
+ transaction.id.should =~ /^\w{6,}$/
337
+ transaction.type.should == "sale"
338
+ transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
339
+ transaction.status.should == Braintree::Transaction::Status::SettlementPending
340
+ transaction.us_bank_account_details.routing_number.should == "011000015"
341
+ transaction.us_bank_account_details.last_4.should == "0000"
342
+ transaction.us_bank_account_details.account_type.should == "checking"
343
+ transaction.us_bank_account_details.account_holder_name.should == "PayPal, Inc."
344
+ transaction.us_bank_account_details.bank_name.should == "FEDERAL RESERVE BANK"
345
+ transaction.us_bank_account_details.ach_mandate.text.should == "cl mandate text"
346
+ transaction.us_bank_account_details.ach_mandate.accepted_at.should be_a Time
347
+ end
348
+ end
349
+ end
350
+
351
+ context "not plaid-verified" do
352
+ let(:non_plaid_nonce) { generate_non_plaid_us_bank_account_nonce }
353
+ let(:invalid_nonce) { generate_invalid_us_bank_account_nonce }
354
+
355
+ context "nonce" do
356
+ it "sale succeeds for valid nonce" do
357
+ result = Braintree::Transaction.create(
358
+ :type => "sale",
359
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
360
+ :merchant_account_id => SpecHelper::UsBankMerchantAccountId,
361
+ :payment_method_nonce => non_plaid_nonce,
362
+ :options => {
363
+ :submit_for_settlement => true,
364
+ }
365
+ )
366
+ result.success?.should == true
367
+
368
+ transaction = result.transaction
369
+
370
+ transaction.id.should =~ /^\w{6,}$/
371
+ transaction.type.should == "sale"
372
+ transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
373
+ transaction.status.should == Braintree::Transaction::Status::SettlementPending
374
+ transaction.us_bank_account_details.routing_number.should == "021000021"
375
+ transaction.us_bank_account_details.last_4.should == "0000"
376
+ transaction.us_bank_account_details.account_type.should == "checking"
377
+ transaction.us_bank_account_details.account_holder_name.should == "John Doe"
378
+ transaction.us_bank_account_details.bank_name.should =~ /CHASE/
379
+ transaction.us_bank_account_details.ach_mandate.text.should == "cl mandate text"
380
+ transaction.us_bank_account_details.ach_mandate.accepted_at.should be_a Time
381
+ end
382
+
383
+ it "sale fails for invalid nonce" do
384
+ result = Braintree::Transaction.create(
385
+ :type => "sale",
386
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
387
+ :merchant_account_id => SpecHelper::UsBankMerchantAccountId,
388
+ :payment_method_nonce => invalid_nonce,
389
+ :options => {
390
+ :submit_for_settlement => true,
391
+ }
392
+ )
393
+ result.success?.should == false
394
+ result.errors.for(:transaction).on(:payment_method_nonce)[0].code.should == Braintree::ErrorCodes::Transaction::PaymentMethodNonceUnknown
395
+ end
396
+ end
397
+
398
+ context "token" do
399
+ it "sale succeeds for unverified token" do
400
+ result = Braintree::PaymentMethod.create(
401
+ :payment_method_nonce => non_plaid_nonce,
402
+ :customer_id => Braintree::Customer.create.customer.id,
403
+ :options => {
404
+ :verification_merchant_account_id => SpecHelper::UsBankMerchantAccountId,
405
+ }
406
+ )
407
+ payment_method = result.payment_method
408
+
409
+ payment_method.verifications.count.should == 1
410
+ payment_method.verifications.first.status == Braintree::UsBankAccountVerification::Status::Verified
411
+ payment_method.verifications.first.verification_method == Braintree::UsBankAccountVerification::VerificationMethod::IndependentCheck
412
+ payment_method.verifications.first.id.should_not be_empty
413
+ payment_method.verifications.first.verification_determined_at.should be_a Time
414
+ payment_method.verified.should == true
415
+
416
+ result = Braintree::Transaction.create(
417
+ :type => "sale",
418
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
419
+ :merchant_account_id => SpecHelper::UsBankMerchantAccountId,
420
+ :payment_method_token => payment_method.token,
421
+ :options => {
422
+ :submit_for_settlement => true,
423
+ }
424
+ )
425
+
426
+ result.success?.should == true
427
+ end
428
+ end
429
+ end
430
+ end
431
+ end
432
+ end