braintree 2.31.0 → 2.32.1
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.
- data/README.rdoc +2 -2
- data/lib/braintree.rb +12 -0
- data/lib/braintree/client_token.rb +5 -0
- data/lib/braintree/client_token_gateway.rb +2 -1
- data/lib/braintree/configuration.rb +1 -1
- data/lib/braintree/credit_card.rb +1 -1
- data/lib/braintree/credit_card_gateway.rb +3 -3
- data/lib/braintree/customer.rb +18 -4
- data/lib/braintree/customer_gateway.rb +2 -2
- data/lib/braintree/customer_search.rb +1 -0
- data/lib/braintree/error_codes.rb +81 -14
- data/lib/braintree/exceptions.rb +2 -0
- data/lib/braintree/gateway.rb +16 -0
- data/lib/braintree/payment_instrument_type.rb +7 -0
- data/lib/braintree/payment_method.rb +17 -0
- data/lib/braintree/payment_method_gateway.rb +58 -0
- data/lib/braintree/paypal_account.rb +47 -0
- data/lib/braintree/paypal_account_gateway.rb +41 -0
- data/lib/braintree/sepa_bank_account.rb +34 -0
- data/lib/braintree/sepa_bank_account_gateway.rb +16 -0
- data/lib/braintree/successful_result.rb +1 -1
- data/lib/braintree/test/nonce.rb +10 -0
- data/lib/braintree/test_transaction.rb +15 -0
- data/lib/braintree/testing_gateway.rb +35 -0
- data/lib/braintree/transaction.rb +6 -0
- data/lib/braintree/transaction/paypal_details.rb +14 -0
- data/lib/braintree/transaction_gateway.rb +3 -1
- data/lib/braintree/transaction_search.rb +4 -0
- data/lib/braintree/unknown_payment_method.rb +20 -0
- data/lib/braintree/version.rb +2 -2
- data/lib/braintree/webhook_testing_gateway.rb +1 -1
- data/spec/integration/braintree/client_api/client_token_spec.rb +80 -17
- data/spec/integration/braintree/client_api/spec_helper.rb +93 -10
- data/spec/integration/braintree/credit_card_spec.rb +28 -27
- data/spec/integration/braintree/customer_search_spec.rb +23 -0
- data/spec/integration/braintree/customer_spec.rb +83 -1
- data/spec/integration/braintree/payment_method_spec.rb +315 -0
- data/spec/integration/braintree/paypal_account_spec.rb +188 -0
- data/spec/integration/braintree/subscription_spec.rb +50 -20
- data/spec/integration/braintree/test_transaction_spec.rb +104 -0
- data/spec/integration/braintree/transaction_search_spec.rb +60 -0
- data/spec/integration/braintree/transaction_spec.rb +583 -8
- data/spec/integration/spec_helper.rb +22 -0
- data/spec/spec_helper.rb +8 -2
- data/spec/unit/braintree/customer_spec.rb +24 -4
- data/spec/unit/braintree/payment_method_spec.rb +25 -0
- data/spec/unit/braintree/paypal_account_spec.rb +31 -0
- data/spec/unit/braintree/unknown_payment_method_spec.rb +29 -0
- metadata +141 -120
- checksums.yaml +0 -7
- 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
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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 =>
|
|
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 ==
|
|
1534
|
-
transaction.vault_credit_card.token.should ==
|
|
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
|
-
|
|
2600
|
-
|
|
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
|