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
@@ -483,41 +483,6 @@ describe Braintree::PaymentMethod do
483
483
  found_credit_card.billing_address.street_address.should == "456 Xyz Way"
484
484
  end
485
485
 
486
- context "us bank account" do
487
- it "creates a payment method from a us bank account nonce" do
488
- customer = Braintree::Customer.create.customer
489
- result = Braintree::PaymentMethod.create(
490
- :payment_method_nonce => generate_valid_us_bank_account_nonce,
491
- :customer_id => customer.id
492
- )
493
-
494
- result.should be_success
495
- us_bank_account = result.payment_method
496
- us_bank_account.should be_a(Braintree::UsBankAccount)
497
- us_bank_account.routing_number.should == "021000021"
498
- us_bank_account.last_4.should == "1234"
499
- us_bank_account.account_type.should == "checking"
500
- us_bank_account.account_holder_name.should == "Dan Schulman"
501
- us_bank_account.bank_name.should =~ /CHASE/
502
- us_bank_account.default.should == true
503
- us_bank_account.ach_mandate.text.should == "cl mandate text"
504
- us_bank_account.ach_mandate.accepted_at.should be_a Time
505
-
506
- Braintree::PaymentMethod.find(us_bank_account.token).should be_a(Braintree::UsBankAccount)
507
- end
508
-
509
- it "does not creates a payment method from an invalid us bank account nonce" do
510
- customer = Braintree::Customer.create.customer
511
- result = Braintree::PaymentMethod.create(
512
- :payment_method_nonce => generate_invalid_us_bank_account_nonce,
513
- :customer_id => customer.id
514
- )
515
-
516
- result.should_not be_success
517
- result.errors.for(:payment_method).on(:payment_method_nonce)[0].code.should == Braintree::ErrorCodes::PaymentMethod::PaymentMethodNonceUnknown
518
- end
519
- end
520
-
521
486
  context "paypal" do
522
487
  it "creates a payment method from an unvalidated future paypal account nonce" do
523
488
  nonce = nonce_for_paypal_account(:consent_code => "PAYPAL_CONSENT_CODE")
@@ -0,0 +1,412 @@
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::PaymentMethod do
5
+ describe "self.create" 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 nonce" do
14
+ let(:nonce) { generate_valid_plaid_us_bank_account_nonce }
15
+
16
+ it "succeeds" do
17
+ customer = Braintree::Customer.create.customer
18
+ result = Braintree::PaymentMethod.create(
19
+ :payment_method_nonce => nonce,
20
+ :customer_id => customer.id,
21
+ :options => {
22
+ :verification_merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
23
+ }
24
+ )
25
+
26
+ result.should be_success
27
+ us_bank_account = result.payment_method
28
+ us_bank_account.should be_a(Braintree::UsBankAccount)
29
+ us_bank_account.routing_number.should == "011000015"
30
+ us_bank_account.last_4.should == "0000"
31
+ us_bank_account.account_type.should == "checking"
32
+ us_bank_account.account_holder_name.should == "PayPal, Inc."
33
+ us_bank_account.bank_name.should == "FEDERAL RESERVE BANK"
34
+ us_bank_account.default.should == true
35
+ us_bank_account.ach_mandate.text.should == "cl mandate text"
36
+ us_bank_account.ach_mandate.accepted_at.should be_a Time
37
+
38
+ us_bank_account.verifications.count.should == 1
39
+ us_bank_account.verifications.first.status.should == Braintree::UsBankAccountVerification::Status::Verified
40
+ us_bank_account.verifications.first.verification_method.should == Braintree::UsBankAccountVerification::VerificationMethod::TokenizedCheck
41
+ us_bank_account.verifications.first.id.should_not be_empty
42
+ us_bank_account.verifications.first.verification_determined_at.should be_a Time
43
+ us_bank_account.verified.should == true
44
+
45
+ Braintree::PaymentMethod.find(us_bank_account.token).should be_a(Braintree::UsBankAccount)
46
+ end
47
+
48
+ [
49
+ Braintree::UsBankAccountVerification::VerificationMethod::IndependentCheck,
50
+ Braintree::UsBankAccountVerification::VerificationMethod::NetworkCheck,
51
+ ].each do |method|
52
+ it "succeeds and verifies via #{method}" do
53
+ customer = Braintree::Customer.create.customer
54
+ result = Braintree::PaymentMethod.create(
55
+ :payment_method_nonce => nonce,
56
+ :customer_id => customer.id,
57
+ :options => {
58
+ :us_bank_account_verification_method => method,
59
+ :verification_merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
60
+ }
61
+ )
62
+
63
+ result.should be_success
64
+ us_bank_account = result.payment_method
65
+ us_bank_account.should be_a(Braintree::UsBankAccount)
66
+ us_bank_account.routing_number.should == "011000015"
67
+ us_bank_account.last_4.should == "0000"
68
+ us_bank_account.account_type.should == "checking"
69
+ us_bank_account.account_holder_name.should == "PayPal, Inc."
70
+ us_bank_account.bank_name.should == "FEDERAL RESERVE BANK"
71
+ us_bank_account.default.should == true
72
+ us_bank_account.ach_mandate.text.should == "cl mandate text"
73
+ us_bank_account.ach_mandate.accepted_at.should be_a Time
74
+ us_bank_account.verified.should == true
75
+
76
+ us_bank_account.verifications.count.should == 2
77
+
78
+ us_bank_account.verifications.map(&:verification_method).should contain_exactly(
79
+ Braintree::UsBankAccountVerification::VerificationMethod::TokenizedCheck,
80
+ method,
81
+ )
82
+
83
+ us_bank_account.verifications.each do |verification|
84
+ verification.status.should == Braintree::UsBankAccountVerification::Status::Verified
85
+ verification.id.should_not be_empty
86
+ verification.verification_determined_at.should be_a Time
87
+ end
88
+
89
+ Braintree::PaymentMethod.find(us_bank_account.token).should be_a(Braintree::UsBankAccount)
90
+ end
91
+ end
92
+ end
93
+
94
+ context "non plaid verified nonce" do
95
+ let(:nonce) { generate_non_plaid_us_bank_account_nonce }
96
+
97
+ it "succeeds and does not verify when no method provided" do
98
+ customer = Braintree::Customer.create.customer
99
+ result = Braintree::PaymentMethod.create(
100
+ :payment_method_nonce => nonce,
101
+ :customer_id => customer.id,
102
+ :options => {
103
+ :verification_merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
104
+ }
105
+ )
106
+
107
+ result.should be_success
108
+ us_bank_account = result.payment_method
109
+ us_bank_account.should be_a(Braintree::UsBankAccount)
110
+ us_bank_account.routing_number.should == "021000021"
111
+ us_bank_account.last_4.should == "0000"
112
+ us_bank_account.account_type.should == "checking"
113
+ us_bank_account.account_holder_name.should == "John Doe"
114
+ us_bank_account.bank_name.should =~ /CHASE/
115
+ us_bank_account.default.should == true
116
+ us_bank_account.ach_mandate.text.should == "cl mandate text"
117
+ us_bank_account.ach_mandate.accepted_at.should be_a Time
118
+
119
+ us_bank_account.verifications.count.should == 0
120
+ us_bank_account.verified.should == false
121
+
122
+ Braintree::PaymentMethod.find(us_bank_account.token).should be_a(Braintree::UsBankAccount)
123
+ end
124
+
125
+ [
126
+ Braintree::UsBankAccountVerification::VerificationMethod::IndependentCheck,
127
+ Braintree::UsBankAccountVerification::VerificationMethod::NetworkCheck,
128
+ ].each do |method|
129
+ it "succeeds and verifies via #{method}" do
130
+ customer = Braintree::Customer.create.customer
131
+ result = Braintree::PaymentMethod.create(
132
+ :payment_method_nonce => nonce,
133
+ :customer_id => customer.id,
134
+ :options => {
135
+ :us_bank_account_verification_method => method,
136
+ :verification_merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
137
+ }
138
+ )
139
+
140
+ result.should be_success
141
+ us_bank_account = result.payment_method
142
+ us_bank_account.should be_a(Braintree::UsBankAccount)
143
+ us_bank_account.routing_number.should == "021000021"
144
+ us_bank_account.last_4.should == "0000"
145
+ us_bank_account.account_type.should == "checking"
146
+ us_bank_account.account_holder_name.should == "John Doe"
147
+ us_bank_account.bank_name.should =~ /CHASE/
148
+ us_bank_account.default.should == true
149
+ us_bank_account.ach_mandate.text.should == "cl mandate text"
150
+ us_bank_account.ach_mandate.accepted_at.should be_a Time
151
+
152
+ us_bank_account.verifications.count.should == 1
153
+ us_bank_account.verifications.first.status.should == Braintree::UsBankAccountVerification::Status::Verified
154
+ us_bank_account.verifications.first.verification_method.should == method
155
+ us_bank_account.verifications.first.id.should_not be_empty
156
+ us_bank_account.verifications.first.verification_determined_at.should be_a Time
157
+ us_bank_account.verified.should == true
158
+
159
+ Braintree::PaymentMethod.find(us_bank_account.token).should be_a(Braintree::UsBankAccount)
160
+ end
161
+ end
162
+ end
163
+
164
+ it "fails with invalid nonce" do
165
+ customer = Braintree::Customer.create.customer
166
+ result = Braintree::PaymentMethod.create(
167
+ :payment_method_nonce => generate_invalid_us_bank_account_nonce,
168
+ :customer_id => customer.id
169
+ )
170
+
171
+ result.should_not be_success
172
+ result.errors.for(:payment_method).on(:payment_method_nonce)[0].code.should == Braintree::ErrorCodes::PaymentMethod::PaymentMethodNonceUnknown
173
+ end
174
+ end
175
+
176
+ context "exempt merchant" do
177
+ context "plaid verified nonce" do
178
+ before do
179
+ Braintree::Configuration.merchant_id = "integration_merchant_id"
180
+ Braintree::Configuration.public_key = "integration_public_key"
181
+ Braintree::Configuration.private_key = "integration_private_key"
182
+ end
183
+
184
+ let(:nonce) { generate_valid_plaid_us_bank_account_nonce }
185
+
186
+ it "succeeds and verifies via independent check" do
187
+ customer = Braintree::Customer.create.customer
188
+ result = Braintree::PaymentMethod.create(
189
+ :payment_method_nonce => nonce,
190
+ :customer_id => customer.id,
191
+ :options => {
192
+ :verification_merchant_account_id => SpecHelper::UsBankMerchantAccountId,
193
+ }
194
+ )
195
+
196
+ result.should be_success
197
+ us_bank_account = result.payment_method
198
+ us_bank_account.should be_a(Braintree::UsBankAccount)
199
+ us_bank_account.routing_number.should == "011000015"
200
+ us_bank_account.last_4.should == "0000"
201
+ us_bank_account.account_type.should == "checking"
202
+ us_bank_account.account_holder_name.should == "PayPal, Inc."
203
+ us_bank_account.bank_name.should == "FEDERAL RESERVE BANK"
204
+ us_bank_account.default.should == true
205
+ us_bank_account.ach_mandate.text.should == "cl mandate text"
206
+ us_bank_account.ach_mandate.accepted_at.should be_a Time
207
+
208
+ us_bank_account.verifications.count.should == 1
209
+ us_bank_account.verifications.first.status.should == Braintree::UsBankAccountVerification::Status::Verified
210
+ us_bank_account.verifications.first.verification_method.should == Braintree::UsBankAccountVerification::VerificationMethod::TokenizedCheck
211
+ us_bank_account.verifications.first.id.should_not be_empty
212
+ us_bank_account.verifications.first.verification_determined_at.should be_a Time
213
+ us_bank_account.verified.should == true
214
+
215
+ Braintree::PaymentMethod.find(us_bank_account.token).should be_a(Braintree::UsBankAccount)
216
+ end
217
+ end
218
+
219
+ context "non plaid verified nonce" do
220
+ let(:nonce) { generate_non_plaid_us_bank_account_nonce }
221
+
222
+ it "succeeds and verifies via independent check" do
223
+ customer = Braintree::Customer.create.customer
224
+ result = Braintree::PaymentMethod.create(
225
+ :payment_method_nonce => nonce,
226
+ :customer_id => customer.id,
227
+ :options => {
228
+ :verification_merchant_account_id => SpecHelper::UsBankMerchantAccountId,
229
+ }
230
+ )
231
+
232
+ result.should be_success
233
+ us_bank_account = result.payment_method
234
+ us_bank_account.should be_a(Braintree::UsBankAccount)
235
+ us_bank_account.routing_number.should == "021000021"
236
+ us_bank_account.last_4.should == "0000"
237
+ us_bank_account.account_type.should == "checking"
238
+ us_bank_account.account_holder_name.should == "John Doe"
239
+ us_bank_account.bank_name.should =~ /CHASE/
240
+ us_bank_account.default.should == true
241
+ us_bank_account.ach_mandate.text.should == "cl mandate text"
242
+ us_bank_account.ach_mandate.accepted_at.should be_a Time
243
+
244
+ us_bank_account.verifications.count.should == 1
245
+ us_bank_account.verifications.first.status.should == Braintree::UsBankAccountVerification::Status::Verified
246
+ us_bank_account.verifications.first.verification_method.should == Braintree::UsBankAccountVerification::VerificationMethod::IndependentCheck
247
+ us_bank_account.verifications.first.id.should_not be_empty
248
+ us_bank_account.verifications.first.verification_determined_at.should be_a Time
249
+ us_bank_account.verified.should == true
250
+
251
+ Braintree::PaymentMethod.find(us_bank_account.token).should be_a(Braintree::UsBankAccount)
252
+ end
253
+ end
254
+
255
+ it "fails with invalid nonce" do
256
+ customer = Braintree::Customer.create.customer
257
+ result = Braintree::PaymentMethod.create(
258
+ :payment_method_nonce => generate_invalid_us_bank_account_nonce,
259
+ :customer_id => customer.id
260
+ )
261
+
262
+ result.should_not be_success
263
+ result.errors.for(:payment_method).on(:payment_method_nonce)[0].code.should == Braintree::ErrorCodes::PaymentMethod::PaymentMethodNonceUnknown
264
+ end
265
+ end
266
+ end
267
+
268
+ context "self.update" do
269
+ context "compliant merchant" do
270
+ before do
271
+ Braintree::Configuration.merchant_id = "integration2_merchant_id"
272
+ Braintree::Configuration.public_key = "integration2_public_key"
273
+ Braintree::Configuration.private_key = "integration2_private_key"
274
+ end
275
+
276
+ context "unverified token" do
277
+ let(:payment_method) do
278
+ customer = Braintree::Customer.create.customer
279
+ result = Braintree::PaymentMethod.create(
280
+ :payment_method_nonce => generate_non_plaid_us_bank_account_nonce,
281
+ :customer_id => customer.id,
282
+ :options => {
283
+ :verification_merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
284
+ },
285
+ ).payment_method
286
+ end
287
+
288
+ [
289
+ Braintree::UsBankAccountVerification::VerificationMethod::IndependentCheck,
290
+ Braintree::UsBankAccountVerification::VerificationMethod::NetworkCheck,
291
+ ].each do |method|
292
+ it "succeeds and verifies via #{method}" do
293
+ result = Braintree::PaymentMethod.update(
294
+ payment_method.token,
295
+ :options => {
296
+ :verification_merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
297
+ :us_bank_account_verification_method => method,
298
+ },
299
+ )
300
+
301
+ result.should be_success
302
+
303
+ us_bank_account = result.payment_method
304
+ us_bank_account.should be_a(Braintree::UsBankAccount)
305
+ us_bank_account.routing_number.should == "021000021"
306
+ us_bank_account.last_4.should == "0000"
307
+ us_bank_account.account_type.should == "checking"
308
+ us_bank_account.account_holder_name.should == "John Doe"
309
+ us_bank_account.bank_name.should =~ /CHASE/
310
+ us_bank_account.default.should == true
311
+ us_bank_account.ach_mandate.text.should == "cl mandate text"
312
+ us_bank_account.ach_mandate.accepted_at.should be_a Time
313
+
314
+ us_bank_account.verifications.count.should == 1
315
+ us_bank_account.verifications.first.status.should == Braintree::UsBankAccountVerification::Status::Verified
316
+ us_bank_account.verifications.first.verification_method.should == method
317
+ us_bank_account.verifications.first.id.should_not be_empty
318
+ us_bank_account.verifications.first.verification_determined_at.should be_a Time
319
+ us_bank_account.verified.should == true
320
+
321
+ Braintree::PaymentMethod.find(us_bank_account.token).should be_a(Braintree::UsBankAccount)
322
+ end
323
+ end
324
+
325
+ it "fails with invalid verification method" do
326
+ result = Braintree::PaymentMethod.update(
327
+ payment_method.token,
328
+ :options => {
329
+ :verification_merchant_account_id => SpecHelper::AnotherUsBankMerchantAccountId,
330
+ :us_bank_account_verification_method => "blahblah",
331
+ },
332
+ )
333
+
334
+ result.should_not be_success
335
+ result.errors.for(:options).first.code.should == Braintree::ErrorCodes::PaymentMethod::Options::UsBankAccountVerificationMethodIsInvalid
336
+ end
337
+ end
338
+ end
339
+
340
+ context "exempt merchant" do
341
+ before do
342
+ Braintree::Configuration.merchant_id = "integration_merchant_id"
343
+ Braintree::Configuration.public_key = "integration_public_key"
344
+ Braintree::Configuration.private_key = "integration_private_key"
345
+ end
346
+
347
+ context "unverified token" do
348
+ let(:payment_method) do
349
+ customer = Braintree::Customer.create.customer
350
+ result = Braintree::PaymentMethod.create(
351
+ :payment_method_nonce => generate_non_plaid_us_bank_account_nonce,
352
+ :customer_id => customer.id,
353
+ :options => {
354
+ :verification_merchant_account_id => SpecHelper::UsBankMerchantAccountId,
355
+ }
356
+ ).payment_method
357
+ end
358
+
359
+ [
360
+ Braintree::UsBankAccountVerification::VerificationMethod::IndependentCheck,
361
+ Braintree::UsBankAccountVerification::VerificationMethod::NetworkCheck,
362
+ ].each do |method|
363
+ it "succeeds and verifies via #{method}" do
364
+ result = Braintree::PaymentMethod.update(
365
+ payment_method.token,
366
+ :options => {
367
+ :verification_merchant_account_id => SpecHelper::UsBankMerchantAccountId,
368
+ :us_bank_account_verification_method => method,
369
+ },
370
+ )
371
+
372
+ result.should be_success
373
+
374
+ us_bank_account = result.payment_method
375
+ us_bank_account.should be_a(Braintree::UsBankAccount)
376
+ us_bank_account.routing_number.should == "021000021"
377
+ us_bank_account.last_4.should == "0000"
378
+ us_bank_account.account_type.should == "checking"
379
+ us_bank_account.account_holder_name.should == "John Doe"
380
+ us_bank_account.bank_name.should =~ /CHASE/
381
+ us_bank_account.default.should == true
382
+ us_bank_account.ach_mandate.text.should == "cl mandate text"
383
+ us_bank_account.ach_mandate.accepted_at.should be_a Time
384
+
385
+ us_bank_account.verifications.count.should == 2
386
+ verification = us_bank_account.verifications.find do |verification|
387
+ verification.verification_method == method
388
+ end
389
+ verification.status.should == Braintree::UsBankAccountVerification::Status::Verified
390
+ verification.id.should_not be_empty
391
+ verification.verification_determined_at.should be_a Time
392
+ us_bank_account.verified.should == true
393
+
394
+ Braintree::PaymentMethod.find(us_bank_account.token).should be_a(Braintree::UsBankAccount)
395
+ end
396
+ end
397
+
398
+ it "fails with invalid verification method" do
399
+ result = Braintree::PaymentMethod.update(
400
+ payment_method.token,
401
+ :options => {
402
+ :us_bank_account_verification_method => "blahblah",
403
+ },
404
+ )
405
+
406
+ result.should_not be_success
407
+ result.errors.for(:options).first.code.should == Braintree::ErrorCodes::PaymentMethod::Options::UsBankAccountVerificationMethodIsInvalid
408
+ end
409
+ end
410
+ end
411
+ end
412
+ end