braintree 2.31.0 → 2.32.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/README.rdoc +2 -2
  2. data/lib/braintree.rb +12 -0
  3. data/lib/braintree/client_token.rb +5 -0
  4. data/lib/braintree/client_token_gateway.rb +2 -1
  5. data/lib/braintree/configuration.rb +1 -1
  6. data/lib/braintree/credit_card.rb +1 -1
  7. data/lib/braintree/credit_card_gateway.rb +3 -3
  8. data/lib/braintree/customer.rb +18 -4
  9. data/lib/braintree/customer_gateway.rb +2 -2
  10. data/lib/braintree/customer_search.rb +1 -0
  11. data/lib/braintree/error_codes.rb +81 -14
  12. data/lib/braintree/exceptions.rb +2 -0
  13. data/lib/braintree/gateway.rb +16 -0
  14. data/lib/braintree/payment_instrument_type.rb +7 -0
  15. data/lib/braintree/payment_method.rb +17 -0
  16. data/lib/braintree/payment_method_gateway.rb +58 -0
  17. data/lib/braintree/paypal_account.rb +47 -0
  18. data/lib/braintree/paypal_account_gateway.rb +41 -0
  19. data/lib/braintree/sepa_bank_account.rb +34 -0
  20. data/lib/braintree/sepa_bank_account_gateway.rb +16 -0
  21. data/lib/braintree/successful_result.rb +1 -1
  22. data/lib/braintree/test/nonce.rb +10 -0
  23. data/lib/braintree/test_transaction.rb +15 -0
  24. data/lib/braintree/testing_gateway.rb +35 -0
  25. data/lib/braintree/transaction.rb +6 -0
  26. data/lib/braintree/transaction/paypal_details.rb +14 -0
  27. data/lib/braintree/transaction_gateway.rb +3 -1
  28. data/lib/braintree/transaction_search.rb +4 -0
  29. data/lib/braintree/unknown_payment_method.rb +20 -0
  30. data/lib/braintree/version.rb +2 -2
  31. data/lib/braintree/webhook_testing_gateway.rb +1 -1
  32. data/spec/integration/braintree/client_api/client_token_spec.rb +80 -17
  33. data/spec/integration/braintree/client_api/spec_helper.rb +93 -10
  34. data/spec/integration/braintree/credit_card_spec.rb +28 -27
  35. data/spec/integration/braintree/customer_search_spec.rb +23 -0
  36. data/spec/integration/braintree/customer_spec.rb +83 -1
  37. data/spec/integration/braintree/payment_method_spec.rb +315 -0
  38. data/spec/integration/braintree/paypal_account_spec.rb +188 -0
  39. data/spec/integration/braintree/subscription_spec.rb +50 -20
  40. data/spec/integration/braintree/test_transaction_spec.rb +104 -0
  41. data/spec/integration/braintree/transaction_search_spec.rb +60 -0
  42. data/spec/integration/braintree/transaction_spec.rb +583 -8
  43. data/spec/integration/spec_helper.rb +22 -0
  44. data/spec/spec_helper.rb +8 -2
  45. data/spec/unit/braintree/customer_spec.rb +24 -4
  46. data/spec/unit/braintree/payment_method_spec.rb +25 -0
  47. data/spec/unit/braintree/paypal_account_spec.rb +31 -0
  48. data/spec/unit/braintree/unknown_payment_method_spec.rb +29 -0
  49. metadata +141 -120
  50. checksums.yaml +0 -7
  51. data/spec/httpsd.pid +0 -1
@@ -0,0 +1,188 @@
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::PayPalAccount do
5
+ describe "self.find" do
6
+ it "returns a PayPalAccount" do
7
+ customer = Braintree::Customer.create!
8
+ payment_method_token = "paypal-account-#{Time.now.to_i}"
9
+
10
+ nonce = nonce_for_paypal_account(
11
+ :consent_code => "consent-code",
12
+ :token => payment_method_token
13
+ )
14
+ result = Braintree::PaymentMethod.create(
15
+ :payment_method_nonce => nonce,
16
+ :customer_id => customer.id
17
+ )
18
+ result.should be_success
19
+
20
+ paypal_account = Braintree::PayPalAccount.find(payment_method_token)
21
+ paypal_account.should be_a(Braintree::PayPalAccount)
22
+ paypal_account.token.should == payment_method_token
23
+ paypal_account.email.should == "jane.doe@example.com"
24
+ paypal_account.image_url.should_not be_nil
25
+ paypal_account.created_at.should_not be_nil
26
+ paypal_account.updated_at.should_not be_nil
27
+ end
28
+
29
+ it "raises if the payment method token is not found" do
30
+ expect do
31
+ Braintree::PayPalAccount.find("nonexistant-paypal-account")
32
+ end.to raise_error(Braintree::NotFoundError)
33
+ end
34
+
35
+ it "does not return a different payment method type" do
36
+ customer = Braintree::Customer.create!
37
+ result = Braintree::CreditCard.create(
38
+ :customer_id => customer.id,
39
+ :number => Braintree::Test::CreditCardNumbers::Visa,
40
+ :expiration_date => "05/2009",
41
+ :cvv => "100",
42
+ :token => "CREDIT_CARD_TOKEN"
43
+ )
44
+
45
+ expect do
46
+ Braintree::PayPalAccount.find("CREDIT_CARD_TOKEN")
47
+ end.to raise_error(Braintree::NotFoundError)
48
+ end
49
+ end
50
+
51
+ describe "self.update" do
52
+ it "updates a paypal account's token" do
53
+ customer = Braintree::Customer.create!
54
+ original_token = "paypal-account-#{Time.now.to_i}"
55
+ nonce = nonce_for_paypal_account(
56
+ :consent_code => "consent-code",
57
+ :token => original_token
58
+ )
59
+ original_result = Braintree::PaymentMethod.create(
60
+ :payment_method_nonce => nonce,
61
+ :customer_id => customer.id
62
+ )
63
+
64
+ updated_token = "UPDATED_TOKEN-" + rand(36**3).to_s(36)
65
+ updated_result = Braintree::PayPalAccount.update(
66
+ original_token,
67
+ :token => updated_token
68
+ )
69
+
70
+ updated_paypal_account = Braintree::PayPalAccount.find(updated_token)
71
+ updated_paypal_account.email.should == original_result.payment_method.email
72
+
73
+ expect do
74
+ Braintree::PayPalAccount.find(original_token)
75
+ end.to raise_error(Braintree::NotFoundError, "payment method with token \"#{original_token}\" not found")
76
+ end
77
+
78
+ it "can make a paypal account the default payment method" do
79
+ customer = Braintree::Customer.create!
80
+ result = Braintree::CreditCard.create(
81
+ :customer_id => customer.id,
82
+ :number => Braintree::Test::CreditCardNumbers::Visa,
83
+ :expiration_date => "05/2009",
84
+ :options => {:make_default => true}
85
+ )
86
+ result.should be_success
87
+
88
+ nonce = nonce_for_paypal_account(:consent_code => "consent-code")
89
+ original_token = Braintree::PaymentMethod.create(
90
+ :payment_method_nonce => nonce,
91
+ :customer_id => customer.id
92
+ ).payment_method.token
93
+
94
+ updated_result = Braintree::PayPalAccount.update(
95
+ original_token,
96
+ :options => {:make_default => true}
97
+ )
98
+
99
+ updated_paypal_account = Braintree::PayPalAccount.find(original_token)
100
+ updated_paypal_account.should be_default
101
+ end
102
+
103
+ it "returns an error if a token for account is used to attempt an update" do
104
+ customer = Braintree::Customer.create!
105
+ first_token = "paypal-account-#{rand(36**3).to_s(36)}"
106
+ second_token = "paypal-account-#{rand(36**3).to_s(36)}"
107
+
108
+ first_nonce = nonce_for_paypal_account(
109
+ :consent_code => "consent-code",
110
+ :token => first_token
111
+ )
112
+ first_result = Braintree::PaymentMethod.create(
113
+ :payment_method_nonce => first_nonce,
114
+ :customer_id => customer.id
115
+ )
116
+
117
+ second_nonce = nonce_for_paypal_account(
118
+ :consent_code => "consent-code",
119
+ :token => second_token
120
+ )
121
+ second_result = Braintree::PaymentMethod.create(
122
+ :payment_method_nonce => second_nonce,
123
+ :customer_id => customer.id
124
+ )
125
+
126
+ updated_result = Braintree::PayPalAccount.update(
127
+ first_token,
128
+ :token => second_token
129
+ )
130
+
131
+ updated_result.should_not be_success
132
+ updated_result.errors.first.code.should == "92906"
133
+ end
134
+ end
135
+
136
+ context "self.delete" do
137
+ it "deletes a PayPal account" do
138
+ customer = Braintree::Customer.create!
139
+ token = "paypal-account-#{Time.now.to_i}"
140
+
141
+ nonce = nonce_for_paypal_account(
142
+ :consent_code => "consent-code",
143
+ :token => token
144
+ )
145
+ Braintree::PaymentMethod.create(
146
+ :payment_method_nonce => nonce,
147
+ :customer_id => customer.id
148
+ )
149
+
150
+ result = Braintree::PayPalAccount.delete(token)
151
+
152
+ expect do
153
+ Braintree::PayPalAccount.find(token)
154
+ end.to raise_error(Braintree::NotFoundError, "payment method with token \"#{token}\" not found")
155
+ end
156
+ end
157
+
158
+ context "self.sale" do
159
+ it "creates a transaction using a paypal account and returns a result object" do
160
+ customer = Braintree::Customer.create!(
161
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalFuturePayment
162
+ )
163
+
164
+ result = Braintree::PayPalAccount.sale(customer.paypal_accounts[0].token, :amount => "100.00")
165
+
166
+ result.success?.should == true
167
+ result.transaction.amount.should == BigDecimal.new("100.00")
168
+ result.transaction.type.should == "sale"
169
+ result.transaction.customer_details.id.should == customer.id
170
+ result.transaction.paypal_details.token.should == customer.paypal_accounts[0].token
171
+ end
172
+ end
173
+
174
+ context "self.sale!" do
175
+ it "creates a transaction using a paypal account and returns a transaction" do
176
+ customer = Braintree::Customer.create!(
177
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalFuturePayment
178
+ )
179
+
180
+ transaction = Braintree::PayPalAccount.sale!(customer.paypal_accounts[0].token, :amount => "100.00")
181
+
182
+ transaction.amount.should == BigDecimal.new("100.00")
183
+ transaction.type.should == "sale"
184
+ transaction.customer_details.id.should == customer.id
185
+ transaction.paypal_details.token.should == customer.paypal_accounts[0].token
186
+ end
187
+ end
188
+ end
@@ -64,26 +64,56 @@ describe Braintree::Subscription do
64
64
  result.subscription.id.should == new_id
65
65
  end
66
66
 
67
- it "creates a subscription when given a payment_method_nonce" do
68
- nonce = nonce_for_new_credit_card(
69
- :credit_card => {
70
- :number => Braintree::Test::CreditCardNumbers::Visa,
71
- :expiration_month => "11",
72
- :expiration_year => "2099",
73
- },
74
- :client_token_options => {
75
- :customer_id => @credit_card.customer_id
76
- }
77
- )
78
- result = Braintree::Subscription.create(
79
- :payment_method_nonce => nonce,
80
- :plan_id => SpecHelper::TriallessPlan[:id]
81
- )
67
+ context "with payment_method_nonces" do
68
+ it "creates a subscription when given a credit card payment_method_nonce" do
69
+ nonce = nonce_for_new_payment_method(
70
+ :credit_card => {
71
+ :number => Braintree::Test::CreditCardNumbers::Visa,
72
+ :expiration_month => "11",
73
+ :expiration_year => "2099",
74
+ },
75
+ :client_token_options => {
76
+ :customer_id => @credit_card.customer_id
77
+ }
78
+ )
79
+ result = Braintree::Subscription.create(
80
+ :payment_method_nonce => nonce,
81
+ :plan_id => SpecHelper::TriallessPlan[:id]
82
+ )
82
83
 
83
- result.success?.should == true
84
- transaction = result.subscription.transactions[0]
85
- transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Visa[0, 6]
86
- transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4, 4]
84
+ result.success?.should == true
85
+ transaction = result.subscription.transactions[0]
86
+ transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Visa[0, 6]
87
+ transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4, 4]
88
+ end
89
+
90
+ it "creates a subscription when given a paypal account payment_method_nonce" do
91
+ customer = Braintree::Customer.create!
92
+ payment_method_result = Braintree::PaymentMethod.create(
93
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalFuturePayment,
94
+ :customer_id => customer.id
95
+ )
96
+
97
+ result = Braintree::Subscription.create(
98
+ :payment_method_token => payment_method_result.payment_method.token,
99
+ :plan_id => SpecHelper::TriallessPlan[:id]
100
+ )
101
+
102
+ result.should be_success
103
+ transaction = result.subscription.transactions[0]
104
+ transaction.paypal_details.payer_email.should == "payer@example.com"
105
+ end
106
+
107
+ it "returns an error if the payment_method_nonce hasn't been vaulted" do
108
+ customer = Braintree::Customer.create!
109
+ result = Braintree::Subscription.create(
110
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalFuturePayment,
111
+ :plan_id => SpecHelper::TriallessPlan[:id]
112
+ )
113
+
114
+ result.should_not be_success
115
+ result.errors.for(:subscription).on(:payment_method_nonce).first.code.should == '91925'
116
+ end
87
117
  end
88
118
 
89
119
  context "billing_day_of_month" do
@@ -691,7 +721,7 @@ describe Braintree::Subscription do
691
721
  end
692
722
 
693
723
  it "allows changing the payment_method by payment_method_nonce" do
694
- nonce = nonce_for_new_credit_card(
724
+ nonce = nonce_for_new_payment_method(
695
725
  :credit_card => {
696
726
  :number => Braintree::Test::CreditCardNumbers::MasterCard,
697
727
  :expiration_date => "05/2010"
@@ -0,0 +1,104 @@
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::TestTransaction do
5
+ context "testing" do
6
+ it "changes transaction status to settled" do
7
+ sale_result = Braintree::Transaction.sale(
8
+ :amount => "100",
9
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalOneTimePayment,
10
+ :options => {
11
+ :submit_for_settlement => true
12
+ }
13
+ )
14
+ sale_result.success?.should == true
15
+ sale_result.transaction.status.should == Braintree::Transaction::Status::SubmittedForSettlement
16
+
17
+ settle_result = Braintree::TestTransaction.settle(sale_result.transaction.id)
18
+ settle_result.transaction.status.should == Braintree::Transaction::Status::Settled
19
+ settle_result.success?.should == true
20
+ end
21
+
22
+ it "changes transaction status to settlement_confirmed" do
23
+ sale_result = Braintree::Transaction.sale(
24
+ :amount => "100",
25
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalOneTimePayment,
26
+ :options => {
27
+ :submit_for_settlement => true
28
+ }
29
+ )
30
+ sale_result.success?.should == true
31
+ sale_result.transaction.status.should == Braintree::Transaction::Status::SubmittedForSettlement
32
+
33
+ settle_result = Braintree::TestTransaction.settlement_confirm(sale_result.transaction.id)
34
+ settle_result.transaction.status.should == Braintree::Transaction::Status::SettlementConfirmed
35
+ settle_result.success?.should == true
36
+ end
37
+
38
+ it "changes transaction status to settlement_declined" do
39
+ sale_result = Braintree::Transaction.sale(
40
+ :amount => "100",
41
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalOneTimePayment,
42
+ :options => {
43
+ :submit_for_settlement => true
44
+ }
45
+ )
46
+ sale_result.success?.should == true
47
+ sale_result.transaction.status.should == Braintree::Transaction::Status::SubmittedForSettlement
48
+
49
+ settle_result = Braintree::TestTransaction.settlement_decline(sale_result.transaction.id)
50
+ settle_result.transaction.status.should == Braintree::Transaction::Status::SettlementDeclined
51
+ settle_result.success?.should == true
52
+ end
53
+
54
+ it "returns a validation error when invalid transition is specified" do
55
+ sale_result = Braintree::Transaction.sale(
56
+ :amount => "100",
57
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalOneTimePayment
58
+ )
59
+ sale_result.success?.should == true
60
+
61
+ settle_result = Braintree::TestTransaction.settlement_decline(sale_result.transaction.id)
62
+ settle_result.success?.should be_false
63
+ settle_result.errors.for(:transaction).on(:base).first.code.should == Braintree::ErrorCodes::Transaction::CannotSimulateTransactionSettlement
64
+ end
65
+ end
66
+
67
+ context "mistakenly testing in production" do
68
+ def in_prod
69
+ old_environment = Braintree::Configuration.environment
70
+ Braintree::Configuration.environment = :production
71
+ begin
72
+ yield
73
+ ensure
74
+ Braintree::Configuration.environment = old_environment
75
+ end
76
+ end
77
+
78
+
79
+ it "raises an exception if settle is called in a production environment" do
80
+ expect do
81
+ in_prod do
82
+ Braintree::TestTransaction.settle(nil)
83
+ end
84
+ end.to raise_error(Braintree::TestOperationPerformedInProduction)
85
+ end
86
+
87
+ it "raises an exception if settlement_decline is called in a production environment" do
88
+ expect do
89
+ in_prod do
90
+ Braintree::TestTransaction.settlement_decline(nil)
91
+ end
92
+ end.to raise_error(Braintree::TestOperationPerformedInProduction)
93
+ end
94
+
95
+ it "raises an exception if settlement_confirm is called in a production environment" do
96
+ expect do
97
+ in_prod do
98
+ Braintree::TestTransaction.settlement_confirm(nil)
99
+ end
100
+ end.to raise_error(Braintree::TestOperationPerformedInProduction)
101
+ end
102
+ end
103
+
104
+ end
@@ -1,4 +1,5 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+ require File.expand_path(File.dirname(__FILE__) + "/client_api/spec_helper")
2
3
 
3
4
  describe Braintree::Transaction, "search" do
4
5
  context "advanced" do
@@ -127,6 +128,65 @@ describe Braintree::Transaction, "search" do
127
128
  collection.first.id.should == transaction.id
128
129
  end
129
130
 
131
+ it "searches on paypal transactions" do
132
+ transaction = Braintree::Transaction.sale!(
133
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
134
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalFuturePayment
135
+ )
136
+
137
+ paypal_details = transaction.paypal_details
138
+
139
+ collection = Braintree::Transaction.search do |search|
140
+ search.paypal_payment_id.is paypal_details.payment_id
141
+ search.paypal_authorization_id.is paypal_details.authorization_id
142
+ search.paypal_payer_email.is paypal_details.payer_email
143
+ end
144
+
145
+ collection.maximum_size.should == 1
146
+ collection.first.id.should == transaction.id
147
+ end
148
+
149
+ context "SEPA bank account transactions" do
150
+ it "does" do
151
+ with_altpay_merchant do
152
+ config = Braintree::Configuration.instantiate
153
+ customer = Braintree::Customer.create.customer
154
+ raw_client_token = Braintree::ClientToken.generate(:customer_id => customer.id, :sepa_mandate_type => Braintree::SEPABankAccount::MandateType::Business)
155
+ client_token = decode_client_token(raw_client_token)
156
+ authorization_fingerprint = client_token["authorizationFingerprint"]
157
+ http = ClientApiHttp.new(
158
+ config,
159
+ :authorization_fingerprint => authorization_fingerprint
160
+ )
161
+
162
+ nonce = http.create_sepa_bank_account_nonce(
163
+ :accountHolderName => "Bob Holder",
164
+ :iban => "DE89370400440532013000",
165
+ :bic => "DEUTDEFF",
166
+ :locale => "en-US",
167
+ :billingAddress => {
168
+ :region => "Hesse",
169
+ :country_name => "Germany"
170
+ }
171
+ )
172
+ nonce.should_not == nil
173
+
174
+ transaction = Braintree::Transaction.sale!(
175
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
176
+ :payment_method_nonce => nonce,
177
+ :merchant_account_id => "fake_sepa_ma"
178
+ )
179
+
180
+ collection = Braintree::Transaction.search do |search|
181
+ search.sepa_bank_account_iban.is "DE89370400440532013000"
182
+ end
183
+
184
+ collection.maximum_size.should >= 1
185
+ collection.map(&:id).should include(transaction.id)
186
+ end
187
+ end
188
+ end
189
+
130
190
  context "multiple value fields" do
131
191
  it "searches on created_using" do
132
192
  transaction = Braintree::Transaction.sale!(
@@ -133,6 +133,136 @@ describe Braintree::Transaction do
133
133
  }
134
134
  )
135
135
  result.transaction.credit_card_details.prepaid.should == Braintree::CreditCard::Prepaid::Yes
136
+ result.transaction.payment_instrument_type.should == Braintree::PaymentInstrumentType::CreditCard
137
+ end
138
+ end
139
+
140
+ describe "industry data" do
141
+ it "accepts valid industry data" do
142
+ result = Braintree::Transaction.create(
143
+ :type => "sale",
144
+ :amount => 1_00,
145
+ :credit_card => {
146
+ :number => Braintree::Test::CreditCardNumbers::CardTypeIndicators::Prepaid,
147
+ :expiration_date => "05/2009"
148
+ },
149
+ :industry => {
150
+ :industry_type => Braintree::Transaction::IndustryType::Lodging,
151
+ :data => {
152
+ :folio_number => "ABCDEFG",
153
+ :check_in_date => "2014-06-01",
154
+ :check_out_date => "2014-06-30"
155
+ }
156
+ }
157
+ )
158
+ result.success?.should be_true
159
+ end
160
+
161
+ it "returns errors if validations on industry data fails" do
162
+ result = Braintree::Transaction.create(
163
+ :type => "sale",
164
+ :amount => 1_00,
165
+ :credit_card => {
166
+ :number => Braintree::Test::CreditCardNumbers::CardTypeIndicators::Prepaid,
167
+ :expiration_date => "05/2009"
168
+ },
169
+ :industry => {
170
+ :industry_type => Braintree::Transaction::IndustryType::Lodging,
171
+ :data => {
172
+ :folio_number => "foo bar",
173
+ :check_in_date => "2014-06-30",
174
+ :check_out_date => "2014-06-01"
175
+ }
176
+ }
177
+ )
178
+ result.success?.should be_false
179
+ result.errors.for(:transaction).for(:industry).map { |e| e.code }.sort.should == ["93403", "93406"]
180
+ end
181
+ end
182
+
183
+ describe "industry data" do
184
+ it "accepts valid industry data" do
185
+ result = Braintree::Transaction.create(
186
+ :type => "sale",
187
+ :amount => 1_00,
188
+ :credit_card => {
189
+ :number => Braintree::Test::CreditCardNumbers::CardTypeIndicators::Prepaid,
190
+ :expiration_date => "05/2009"
191
+ },
192
+ :industry => {
193
+ :industry_type => Braintree::Transaction::IndustryType::Lodging,
194
+ :data => {
195
+ :folio_number => "ABCDEFG",
196
+ :check_in_date => "2014-06-01",
197
+ :check_out_date => "2014-06-30"
198
+ }
199
+ }
200
+ )
201
+ result.success?.should be_true
202
+ end
203
+
204
+ it "returns errors if validations on industry data fails" do
205
+ result = Braintree::Transaction.create(
206
+ :type => "sale",
207
+ :amount => 1_00,
208
+ :credit_card => {
209
+ :number => Braintree::Test::CreditCardNumbers::CardTypeIndicators::Prepaid,
210
+ :expiration_date => "05/2009"
211
+ },
212
+ :industry => {
213
+ :industry_type => Braintree::Transaction::IndustryType::Lodging,
214
+ :data => {
215
+ :folio_number => "foo bar",
216
+ :check_in_date => "2014-06-30",
217
+ :check_out_date => "2014-06-01"
218
+ }
219
+ }
220
+ )
221
+ result.success?.should be_false
222
+ result.errors.for(:transaction).for(:industry).map { |e| e.code }.sort.should == ["93403", "93406"]
223
+ end
224
+ end
225
+
226
+ describe "industry data" do
227
+ it "accepts valid industry data" do
228
+ result = Braintree::Transaction.create(
229
+ :type => "sale",
230
+ :amount => 1_00,
231
+ :credit_card => {
232
+ :number => Braintree::Test::CreditCardNumbers::CardTypeIndicators::Prepaid,
233
+ :expiration_date => "05/2009"
234
+ },
235
+ :industry => {
236
+ :industry_type => Braintree::Transaction::IndustryType::Lodging,
237
+ :data => {
238
+ :folio_number => "ABCDEFG",
239
+ :check_in_date => "2014-06-01",
240
+ :check_out_date => "2014-06-30"
241
+ }
242
+ }
243
+ )
244
+ result.success?.should be_true
245
+ end
246
+
247
+ it "returns errors if validations on industry data fails" do
248
+ result = Braintree::Transaction.create(
249
+ :type => "sale",
250
+ :amount => 1_00,
251
+ :credit_card => {
252
+ :number => Braintree::Test::CreditCardNumbers::CardTypeIndicators::Prepaid,
253
+ :expiration_date => "05/2009"
254
+ },
255
+ :industry => {
256
+ :industry_type => Braintree::Transaction::IndustryType::Lodging,
257
+ :data => {
258
+ :folio_number => "foo bar",
259
+ :check_in_date => "2014-06-30",
260
+ :check_out_date => "2014-06-01"
261
+ }
262
+ }
263
+ )
264
+ result.success?.should be_false
265
+ result.errors.for(:transaction).for(:industry).map { |e| e.code }.sort.should == ["93403", "93406"]
136
266
  end
137
267
  end
138
268
 
@@ -1099,8 +1229,8 @@ describe Braintree::Transaction do
1099
1229
  end
1100
1230
 
1101
1231
  context "client API" do
1102
- it "can create a transaction with a nonce" do
1103
- nonce = nonce_for_new_credit_card(
1232
+ it "can create a transaction with a shared card nonce" do
1233
+ nonce = nonce_for_new_payment_method(
1104
1234
  :credit_card => {
1105
1235
  :number => "4111111111111111",
1106
1236
  :expiration_month => "11",
@@ -1108,16 +1238,383 @@ describe Braintree::Transaction do
1108
1238
  },
1109
1239
  :share => true
1110
1240
  )
1241
+ nonce.should_not be_nil
1111
1242
 
1112
1243
  result = Braintree::Transaction.create(
1113
1244
  :type => "sale",
1114
1245
  :amount => Braintree::Test::TransactionAmounts::Authorize,
1115
1246
  :payment_method_nonce => nonce
1116
1247
  )
1248
+ result.success?.should == true
1249
+ end
1117
1250
 
1251
+ it "can create a transaction with a vaulted card nonce" do
1252
+ customer = Braintree::Customer.create!
1253
+ nonce = nonce_for_new_payment_method(
1254
+ :credit_card => {
1255
+ :number => "4111111111111111",
1256
+ :expiration_month => "11",
1257
+ :expiration_year => "2099",
1258
+ },
1259
+ :client_token_options => {
1260
+ :customer_id => customer.id,
1261
+ }
1262
+ )
1263
+ nonce.should_not be_nil
1264
+
1265
+ result = Braintree::Transaction.create(
1266
+ :type => "sale",
1267
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1268
+ :payment_method_nonce => nonce
1269
+ )
1270
+ result.success?.should == true
1271
+ end
1272
+
1273
+ it "can create a transaction with a vaulted PayPal account" do
1274
+ customer = Braintree::Customer.create!
1275
+ nonce = nonce_for_new_payment_method(
1276
+ :paypal_account => {
1277
+ :consent_code => "PAYPAL_CONSENT_CODE",
1278
+ },
1279
+ :client_token_options => {
1280
+ :customer_id => customer.id,
1281
+ }
1282
+ )
1283
+ nonce.should_not be_nil
1284
+
1285
+ result = Braintree::Transaction.create(
1286
+ :type => "sale",
1287
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1288
+ :payment_method_nonce => nonce
1289
+ )
1290
+ result.success?.should == true
1291
+ end
1292
+
1293
+ it "can create a transaction with a params nonce with PayPal account params" do
1294
+ customer = Braintree::Customer.create!
1295
+ nonce = nonce_for_new_payment_method(
1296
+ :paypal_account => {
1297
+ :consent_code => "PAYPAL_CONSENT_CODE",
1298
+ }
1299
+ )
1300
+ nonce.should_not be_nil
1301
+
1302
+ result = Braintree::Transaction.create(
1303
+ :type => "sale",
1304
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1305
+ :payment_method_nonce => nonce
1306
+ )
1118
1307
  result.success?.should == true
1119
1308
  end
1120
1309
  end
1310
+
1311
+ context "three_d_secure" do
1312
+ it "can create a transaction with a three_d_secure token" do
1313
+ three_d_secure_token = SpecHelper.create_3ds_verification(
1314
+ SpecHelper::ThreeDSecureMerchantAccountId,
1315
+ :number => Braintree::Test::CreditCardNumbers::Visa,
1316
+ :expiration_month => "12",
1317
+ :expiration_year => "2012"
1318
+ )
1319
+
1320
+ result = Braintree::Transaction.create(
1321
+ :type => "sale",
1322
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1323
+ :credit_card => {
1324
+ :number => Braintree::Test::CreditCardNumbers::Visa,
1325
+ :expiration_date => "12/12",
1326
+ },
1327
+ :three_d_secure_token => three_d_secure_token
1328
+ )
1329
+
1330
+ result.success?.should == true
1331
+ end
1332
+
1333
+ it "can create a transaction without a three_d_secure token" do
1334
+ result = Braintree::Transaction.create(
1335
+ :merchant_account_id => SpecHelper::ThreeDSecureMerchantAccountId,
1336
+ :type => "sale",
1337
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1338
+ :credit_card => {
1339
+ :number => Braintree::Test::CreditCardNumbers::Visa,
1340
+ :expiration_date => "12/12",
1341
+ }
1342
+ )
1343
+ result.success?.should == true
1344
+ end
1345
+
1346
+ it "returns an error if sent a nil three_d_secure token" do
1347
+ result = Braintree::Transaction.create(
1348
+ :merchant_account_id => SpecHelper::ThreeDSecureMerchantAccountId,
1349
+ :type => "sale",
1350
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1351
+ :credit_card => {
1352
+ :number => Braintree::Test::CreditCardNumbers::Visa,
1353
+ :expiration_date => "12/12",
1354
+ },
1355
+ :three_d_secure_token => nil
1356
+ )
1357
+ result.success?.should == false
1358
+ result.errors.for(:transaction).on(:three_d_secure_token)[0].code.should == Braintree::ErrorCodes::Transaction::ThreeDSecureTokenIsInvalid
1359
+ end
1360
+
1361
+ it "returns an error if 3ds lookup data does not match txn data" do
1362
+ three_d_secure_token = SpecHelper.create_3ds_verification(
1363
+ SpecHelper::ThreeDSecureMerchantAccountId,
1364
+ :number => Braintree::Test::CreditCardNumbers::Visa,
1365
+ :expiration_month => "12",
1366
+ :expiration_year => "2012"
1367
+ )
1368
+
1369
+ result = Braintree::Transaction.create(
1370
+ :merchant_account_id => SpecHelper::ThreeDSecureMerchantAccountId,
1371
+ :type => "sale",
1372
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1373
+ :credit_card => {
1374
+ :number => Braintree::Test::CreditCardNumbers::MasterCard,
1375
+ :expiration_date => "12/12",
1376
+ },
1377
+ :three_d_secure_token => three_d_secure_token
1378
+ )
1379
+ result.success?.should == false
1380
+ result.errors.for(:transaction).on(:three_d_secure_token)[0].code.should == Braintree::ErrorCodes::Transaction::ThreeDSecureTransactionDataDoesntMatchVerify
1381
+ end
1382
+ end
1383
+
1384
+ context "paypal" do
1385
+ context "using a vaulted paypal account payment_method_token" do
1386
+ it "can create a transaction" do
1387
+ payment_method_result = Braintree::PaymentMethod.create(
1388
+ :customer_id => Braintree::Customer.create.customer.id,
1389
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalFuturePayment
1390
+ )
1391
+ result = Braintree::Transaction.create(
1392
+ :type => "sale",
1393
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1394
+ :payment_method_token => payment_method_result.payment_method.token
1395
+ )
1396
+
1397
+ result.should be_success
1398
+ result.transaction.payment_instrument_type.should == Braintree::PaymentInstrumentType::PayPalAccount
1399
+ end
1400
+ end
1401
+
1402
+ context "future" do
1403
+ it "can create a paypal transaction with a nonce without vaulting" do
1404
+ payment_method_token = rand(36**3).to_s(36)
1405
+ nonce = nonce_for_paypal_account(
1406
+ :consent_code => "PAYPAL_CONSENT_CODE",
1407
+ :token => payment_method_token
1408
+ )
1409
+
1410
+ result = Braintree::Transaction.create(
1411
+ :type => "sale",
1412
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1413
+ :payment_method_nonce => nonce
1414
+ )
1415
+
1416
+ result.should be_success
1417
+
1418
+ expect do
1419
+ Braintree::PaymentMethod.find(payment_method_token)
1420
+ end.to raise_error(Braintree::NotFoundError, "payment method with token \"#{payment_method_token}\" not found")
1421
+ end
1422
+
1423
+ it "can create a paypal transaction and vault a paypal account" do
1424
+ payment_method_token = rand(36**3).to_s(36)
1425
+ nonce = nonce_for_paypal_account(
1426
+ :consent_code => "PAYPAL_CONSENT_CODE",
1427
+ :token => payment_method_token
1428
+ )
1429
+
1430
+ result = Braintree::Transaction.create(
1431
+ :type => "sale",
1432
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1433
+ :payment_method_nonce => nonce,
1434
+ :options => {:store_in_vault => true}
1435
+ )
1436
+
1437
+ result.success?.should == true
1438
+
1439
+ found_paypal_account = Braintree::PaymentMethod.find(payment_method_token)
1440
+ found_paypal_account.should be_a(Braintree::PayPalAccount)
1441
+ found_paypal_account.token.should == payment_method_token
1442
+ end
1443
+ end
1444
+
1445
+ context "onetime" do
1446
+ it "can create a paypal transaction with a nonce" do
1447
+ result = Braintree::Transaction.create(
1448
+ :type => "sale",
1449
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1450
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalOneTimePayment
1451
+ )
1452
+
1453
+ result.should be_success
1454
+ end
1455
+
1456
+ it "can create a paypal transaction and does not vault even if asked to" do
1457
+ payment_method_token = rand(36**3).to_s(36)
1458
+ nonce = nonce_for_paypal_account(
1459
+ :access_token => "PAYPAL_ACCESS_TOKEN",
1460
+ :token => payment_method_token
1461
+ )
1462
+
1463
+ result = Braintree::Transaction.create(
1464
+ :type => "sale",
1465
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1466
+ :payment_method_nonce => nonce,
1467
+ :options => {:store_in_vault => true}
1468
+ )
1469
+
1470
+ result.success?.should == true
1471
+
1472
+ expect do
1473
+ Braintree::PaymentMethod.find(payment_method_token)
1474
+ end.to raise_error(Braintree::NotFoundError, "payment method with token \"#{payment_method_token}\" not found")
1475
+ end
1476
+ end
1477
+
1478
+ context "submit" do
1479
+ it "submits for settlement if instructed to do so" do
1480
+ result = Braintree::Transaction.sale(
1481
+ :amount => "100",
1482
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalOneTimePayment,
1483
+ :options => {
1484
+ :submit_for_settlement => true
1485
+ }
1486
+ )
1487
+ result.success?.should == true
1488
+ result.transaction.status.should == Braintree::Transaction::Status::SubmittedForSettlement
1489
+ end
1490
+ end
1491
+
1492
+ context "void" do
1493
+ it "successfully voids a paypal transaction that's been authorized" do
1494
+ sale_transaction = Braintree::Transaction.sale!(
1495
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1496
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalOneTimePayment,
1497
+ :options => {
1498
+ :submit_for_settlement => true
1499
+ }
1500
+ )
1501
+
1502
+ void_transaction = Braintree::Transaction.void!(sale_transaction.id)
1503
+ void_transaction.should == sale_transaction
1504
+ void_transaction.status.should == Braintree::Transaction::Status::Voided
1505
+ end
1506
+
1507
+ it "fails to void a paypal transaction that's been declined" do
1508
+ sale_transaction = Braintree::Transaction.sale(
1509
+ :amount => Braintree::Test::TransactionAmounts::Decline,
1510
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalOneTimePayment,
1511
+ :options => {
1512
+ :submit_for_settlement => true
1513
+ }
1514
+ ).transaction
1515
+
1516
+ expect do
1517
+ Braintree::Transaction.void!(sale_transaction.id)
1518
+ end.to raise_error(Braintree::ValidationsFailed)
1519
+ end
1520
+ end
1521
+
1522
+ describe "refund" do
1523
+ context "partial refunds" do
1524
+ it "allows partial refunds" do
1525
+ transaction = create_paypal_transaction_for_refund
1526
+
1527
+ result = Braintree::Transaction.refund(transaction.id, transaction.amount / 2)
1528
+ result.should be_success
1529
+ result.transaction.type.should == "credit"
1530
+ end
1531
+
1532
+ it "allows multiple partial refunds" do
1533
+ transaction = create_paypal_transaction_for_refund
1534
+
1535
+ transaction_1 = Braintree::Transaction.refund(transaction.id, transaction.amount / 2).transaction
1536
+ transaction_2 = Braintree::Transaction.refund(transaction.id, transaction.amount / 2).transaction
1537
+
1538
+ transaction = Braintree::Transaction.find(transaction.id)
1539
+ transaction.refund_ids.sort.should == [transaction_1.id, transaction_2.id].sort
1540
+ end
1541
+ end
1542
+
1543
+ it "returns a successful result if successful" do
1544
+ transaction = create_paypal_transaction_for_refund
1545
+
1546
+ result = Braintree::Transaction.refund(transaction.id)
1547
+ result.success?.should == true
1548
+ result.transaction.type.should == "credit"
1549
+ end
1550
+
1551
+ it "assigns the refund_id on the original transaction" do
1552
+ transaction = create_paypal_transaction_for_refund
1553
+ refund_transaction = Braintree::Transaction.refund(transaction.id).transaction
1554
+ transaction = Braintree::Transaction.find(transaction.id)
1555
+
1556
+ transaction.refund_id.should == refund_transaction.id
1557
+ end
1558
+
1559
+ it "assigns the refunded_transaction_id to the original transaction" do
1560
+ transaction = create_paypal_transaction_for_refund
1561
+ refund_transaction = Braintree::Transaction.refund(transaction.id).transaction
1562
+
1563
+ refund_transaction.refunded_transaction_id.should == transaction.id
1564
+ end
1565
+
1566
+ it "returns an error if already refunded" do
1567
+ transaction = create_paypal_transaction_for_refund
1568
+ result = Braintree::Transaction.refund(transaction.id)
1569
+ result.success?.should == true
1570
+ result = Braintree::Transaction.refund(transaction.id)
1571
+ result.success?.should == false
1572
+ result.errors.for(:transaction).on(:base)[0].code.should == Braintree::ErrorCodes::Transaction::HasAlreadyBeenRefunded
1573
+ end
1574
+
1575
+ it "returns an error result if unsettled" do
1576
+ transaction = Braintree::Transaction.sale!(
1577
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1578
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalOneTimePayment,
1579
+ :options => {
1580
+ :submit_for_settlement => true
1581
+ }
1582
+ )
1583
+ result = Braintree::Transaction.refund(transaction.id)
1584
+ result.success?.should == false
1585
+ result.errors.for(:transaction).on(:base)[0].code.should == Braintree::ErrorCodes::Transaction::CannotRefundUnlessSettled
1586
+ end
1587
+ end
1588
+
1589
+ context "handling errors" do
1590
+ it "handles bad unvalidated nonces" do
1591
+ nonce = nonce_for_paypal_account(
1592
+ :access_token => "PAYPAL_ACCESS_TOKEN",
1593
+ :consent_code => "PAYPAL_CONSENT_CODE"
1594
+ )
1595
+
1596
+ result = Braintree::Transaction.create(
1597
+ :type => "sale",
1598
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1599
+ :payment_method_nonce => nonce
1600
+ )
1601
+
1602
+ result.should_not be_success
1603
+ result.errors.for(:transaction).for(:paypal_account).first.code.should == "82903"
1604
+ end
1605
+
1606
+ it "handles non-existent nonces" do
1607
+ result = Braintree::Transaction.create(
1608
+ :type => "sale",
1609
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
1610
+ :payment_method_nonce => "NON_EXISTENT_NONCE"
1611
+ )
1612
+
1613
+ result.should_not be_success
1614
+ result.errors.for(:transaction).first.code.should == "91565"
1615
+ end
1616
+ end
1617
+ end
1121
1618
  end
1122
1619
 
1123
1620
  describe "self.create!" do
@@ -1509,7 +2006,7 @@ describe Braintree::Transaction do
1509
2006
 
1510
2007
  it "can specify the customer id and payment method token" do
1511
2008
  customer_id = "customer_#{rand(10**10)}"
1512
- payment_mehtod_token = "credit_card_#{rand(10**10)}"
2009
+ payment_method_token = "credit_card_#{rand(10**10)}"
1513
2010
  result = Braintree::Transaction.sale(
1514
2011
  :amount => "100",
1515
2012
  :customer => {
@@ -1518,7 +2015,7 @@ describe Braintree::Transaction do
1518
2015
  :last_name => "Williams"
1519
2016
  },
1520
2017
  :credit_card => {
1521
- :token => payment_mehtod_token,
2018
+ :token => payment_method_token,
1522
2019
  :number => "5105105105105100",
1523
2020
  :expiration_date => "05/2012"
1524
2021
  },
@@ -1530,8 +2027,8 @@ describe Braintree::Transaction do
1530
2027
  transaction = result.transaction
1531
2028
  transaction.customer_details.id.should == customer_id
1532
2029
  transaction.vault_customer.id.should == customer_id
1533
- transaction.credit_card_details.token.should == payment_mehtod_token
1534
- transaction.vault_credit_card.token.should == payment_mehtod_token
2030
+ transaction.credit_card_details.token.should == payment_method_token
2031
+ transaction.vault_credit_card.token.should == payment_method_token
1535
2032
  end
1536
2033
 
1537
2034
  it "can specify existing shipping address" do
@@ -2588,6 +3085,19 @@ describe Braintree::Transaction do
2588
3085
  Braintree::Transaction.find(transaction.id)
2589
3086
  end
2590
3087
 
3088
+ def create_paypal_transaction_for_refund
3089
+ transaction = Braintree::Transaction.sale!(
3090
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
3091
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalOneTimePayment,
3092
+ :options => {
3093
+ :submit_for_settlement => true
3094
+ }
3095
+ )
3096
+
3097
+ Braintree::Configuration.instantiate.http.put "/transactions/#{transaction.id}/settle"
3098
+ Braintree::Transaction.find(transaction.id)
3099
+ end
3100
+
2591
3101
  def create_escrowed_transcation
2592
3102
  transaction = Braintree::Transaction.sale!(
2593
3103
  :amount => Braintree::Test::TransactionAmounts::Authorize,
@@ -2596,8 +3106,8 @@ describe Braintree::Transaction do
2596
3106
  :number => Braintree::Test::CreditCardNumbers::Visa,
2597
3107
  :expiration_date => "05/2009"
2598
3108
  },
2599
- :service_fee_amount => '1.00',
2600
- :options => { :hold_in_escrow => true }
3109
+ :service_fee_amount => '1.00',
3110
+ :options => { :hold_in_escrow => true }
2601
3111
  )
2602
3112
 
2603
3113
  response = Braintree::Configuration.instantiate.http.put "/transactions/#{transaction.id}/settle"
@@ -2659,4 +3169,69 @@ describe Braintree::Transaction do
2659
3169
  end
2660
3170
  end
2661
3171
  end
3172
+
3173
+ context "paypal" do
3174
+ it "can create a transaction for a paypal account" do
3175
+ result = Braintree::Transaction.sale(
3176
+ :amount => "10.00",
3177
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalFuturePayment
3178
+ )
3179
+ result.success?.should == true
3180
+ result.transaction.paypal_details.payer_email.should == "payer@example.com"
3181
+ result.transaction.paypal_details.payment_id.should match(/PAY-\w+/)
3182
+ result.transaction.paypal_details.authorization_id.should match(/SALE-\w+/)
3183
+ result.transaction.paypal_details.image_url.should_not be_nil
3184
+ end
3185
+
3186
+ it "can vault a paypal account on a transaction" do
3187
+ result = Braintree::Transaction.sale(
3188
+ :amount => "10.00",
3189
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalFuturePayment,
3190
+ :options => {
3191
+ :store_in_vault => true
3192
+ }
3193
+ )
3194
+ result.success?.should == true
3195
+ result.transaction.paypal_details.token.should_not be_nil
3196
+ result.transaction.paypal_details.payer_email.should == "payer@example.com"
3197
+ result.transaction.paypal_details.payment_id.should match(/PAY-\w+/)
3198
+ result.transaction.paypal_details.authorization_id.should match(/SALE-\w+/)
3199
+ end
3200
+
3201
+ it "can create a transaction from a vaulted paypal account" do
3202
+ customer = Braintree::Customer.create!
3203
+ result = Braintree::PaymentMethod.create(
3204
+ :payment_method_nonce => Braintree::Test::Nonce::PayPalFuturePayment,
3205
+ :customer_id => customer.id
3206
+ )
3207
+
3208
+ result.should be_success
3209
+ result.payment_method.should be_a(Braintree::PayPalAccount)
3210
+ payment_method_token = result.payment_method.token
3211
+
3212
+ result = Braintree::Transaction.sale(
3213
+ :amount => "100",
3214
+ :customer_id => customer.id,
3215
+ :payment_method_token => payment_method_token
3216
+ )
3217
+
3218
+ result.should be_success
3219
+ result.transaction.paypal_details.token.should == payment_method_token
3220
+ result.transaction.paypal_details.payer_email.should == "payer@example.com"
3221
+ result.transaction.paypal_details.payment_id.should match(/PAY-\w+/)
3222
+ result.transaction.paypal_details.authorization_id.should match(/SALE-\w+/)
3223
+ end
3224
+
3225
+ context "validation failure" do
3226
+ it "returns a validation error if consent code and access token are omitted" do
3227
+ nonce = nonce_for_paypal_account(:token => "TOKEN")
3228
+ result = Braintree::Transaction.sale(
3229
+ :amount => "10.00",
3230
+ :payment_method_nonce => nonce
3231
+ )
3232
+ result.should_not be_success
3233
+ result.errors.for(:transaction).for(:paypal_account).first.code.should == Braintree::ErrorCodes::PayPalAccount::IncompletePayPalAccount
3234
+ end
3235
+ end
3236
+ end
2662
3237
  end