braintree 2.25.0 → 2.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/lib/braintree/configuration.rb +6 -9
- data/lib/braintree/credit_card_gateway.rb +1 -1
- data/lib/braintree/gateway.rb +2 -1
- data/lib/braintree/test/credit_card.rb +2 -0
- data/lib/braintree/transaction.rb +27 -20
- data/lib/braintree/transaction_gateway.rb +7 -2
- data/lib/braintree/version.rb +1 -1
- data/lib/braintree/webhook_notification.rb +7 -3
- data/lib/braintree/webhook_testing_gateway.rb +29 -6
- data/lib/ssl/api_braintreegateway_com.ca.crt +351 -0
- data/spec/httpsd.pid +1 -1
- data/spec/integration/braintree/credit_card_spec.rb +2 -1
- data/spec/integration/braintree/customer_spec.rb +3 -2
- data/spec/integration/braintree/http_spec.rb +14 -0
- data/spec/integration/braintree/merchant_account_spec.rb +4 -2
- data/spec/integration/braintree/transaction_search_spec.rb +10 -0
- data/spec/integration/braintree/transaction_spec.rb +17 -2
- data/spec/spec_helper.rb +158 -155
- data/spec/unit/braintree/configuration_spec.rb +35 -9
- data/spec/unit/braintree/credit_card_spec.rb +2 -0
- data/spec/unit/braintree/customer_spec.rb +2 -0
- data/spec/unit/braintree/webhook_notification_spec.rb +34 -7
- metadata +109 -112
data/spec/httpsd.pid
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
4588
|
@@ -34,7 +34,8 @@ describe Braintree::CreditCard do
|
|
34
34
|
:number => Braintree::Test::CreditCardNumbers::Visa,
|
35
35
|
:expiration_date => "05/2009",
|
36
36
|
:cvv => "100",
|
37
|
-
:device_session_id => "abc123"
|
37
|
+
:device_session_id => "abc123",
|
38
|
+
:fraud_merchant_id => "7"
|
38
39
|
)
|
39
40
|
result.success?.should == true
|
40
41
|
end
|
@@ -53,13 +53,14 @@ describe Braintree::Customer do
|
|
53
53
|
result.customer.updated_at.between?(Time.now - 10, Time.now).should == true
|
54
54
|
end
|
55
55
|
|
56
|
-
it "supports creation with a device session ID" do
|
56
|
+
it "supports creation with a device session ID and (optional) fraud_merchant_id" do
|
57
57
|
result = Braintree::Customer.create(
|
58
58
|
:credit_card => {
|
59
59
|
:number => Braintree::Test::CreditCardNumbers::MasterCard,
|
60
60
|
:expiration_date => "05/2010",
|
61
61
|
:cvv => "100",
|
62
|
-
:device_session_id => "abc123"
|
62
|
+
:device_session_id => "abc123",
|
63
|
+
:fraud_merchant_id => "7"
|
63
64
|
}
|
64
65
|
)
|
65
66
|
|
@@ -113,6 +113,20 @@ describe Braintree::Http do
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
+
it "accepts the certificate on the qa server" do
|
117
|
+
begin
|
118
|
+
original_env = Braintree::Configuration.environment
|
119
|
+
Braintree::Configuration.environment = :qa
|
120
|
+
Braintree::Configuration.stub(:base_merchant_path).and_return("/")
|
121
|
+
|
122
|
+
expect do
|
123
|
+
Braintree::Configuration.instantiate.http._http_do(Net::HTTP::Get, "/login")
|
124
|
+
end.to_not raise_error
|
125
|
+
ensure
|
126
|
+
Braintree::Configuration.environment = original_env
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
116
130
|
it "accepts the certificate on the sandbox server" do
|
117
131
|
begin
|
118
132
|
original_env = Braintree::Configuration.environment
|
@@ -14,7 +14,7 @@ VALID_APPLICATION_PARAMS = {
|
|
14
14
|
},
|
15
15
|
:date_of_birth => "10/9/1980",
|
16
16
|
:ssn => "123-00-1234",
|
17
|
-
:routing_number => "
|
17
|
+
:routing_number => "121000248",
|
18
18
|
:account_number => "43759348798"
|
19
19
|
},
|
20
20
|
:tos_accepted => true,
|
@@ -54,7 +54,9 @@ describe Braintree::MerchantAccount do
|
|
54
54
|
|
55
55
|
it "requires all fields" do
|
56
56
|
result = Braintree::MerchantAccount.create(
|
57
|
-
:master_merchant_account_id => "sandbox_master_merchant_account"
|
57
|
+
:master_merchant_account_id => "sandbox_master_merchant_account",
|
58
|
+
:tos_accepted => true,
|
59
|
+
:applicant_details => {}
|
58
60
|
)
|
59
61
|
result.should_not be_success
|
60
62
|
result.errors.for(:merchant_account).for(:applicant_details).on(:first_name).first.code.should == Braintree::ErrorCodes::MerchantAccount::ApplicantDetails::FirstNameIsRequired
|
@@ -1090,5 +1090,15 @@ describe Braintree::Transaction, "search" do
|
|
1090
1090
|
collection.maximum_size.should == 0
|
1091
1091
|
end
|
1092
1092
|
end
|
1093
|
+
|
1094
|
+
context "when the search times out" do
|
1095
|
+
it "raises a Down for Maintenance Error" do
|
1096
|
+
expect {
|
1097
|
+
collection = Braintree::Transaction.search do |search|
|
1098
|
+
search.amount.is -10
|
1099
|
+
end
|
1100
|
+
}.to raise_error(Braintree::DownForMaintenanceError)
|
1101
|
+
end
|
1102
|
+
end
|
1093
1103
|
end
|
1094
1104
|
end
|
@@ -149,13 +149,14 @@ describe Braintree::Transaction do
|
|
149
149
|
result.transaction.type.should == "sale"
|
150
150
|
result.transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
|
151
151
|
result.transaction.processor_authorization_code.should_not be_nil
|
152
|
+
result.transaction.voice_referral_number.should be_nil
|
152
153
|
result.transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Visa[0, 6]
|
153
154
|
result.transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Visa[-4..-1]
|
154
155
|
result.transaction.credit_card_details.expiration_date.should == "05/2009"
|
155
156
|
result.transaction.credit_card_details.customer_location.should == "US"
|
156
157
|
end
|
157
158
|
|
158
|
-
it "accepts additional security parameters
|
159
|
+
it "accepts additional security parameters: device_session_id and fraud_merchant_id" do
|
159
160
|
result = Braintree::Transaction.create(
|
160
161
|
:type => "sale",
|
161
162
|
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
@@ -163,7 +164,8 @@ describe Braintree::Transaction do
|
|
163
164
|
:number => Braintree::Test::CreditCardNumbers::Visa,
|
164
165
|
:expiration_date => "05/2009"
|
165
166
|
},
|
166
|
-
:device_session_id => "abc123"
|
167
|
+
:device_session_id => "abc123",
|
168
|
+
:fraud_merchant_id => "7"
|
167
169
|
)
|
168
170
|
|
169
171
|
result.success?.should == true
|
@@ -385,6 +387,19 @@ describe Braintree::Transaction do
|
|
385
387
|
Braintree::Configuration.private_key = old_private_key
|
386
388
|
end
|
387
389
|
end
|
390
|
+
|
391
|
+
it "exposes the fraud gateway rejection reason" do
|
392
|
+
result = Braintree::Transaction.sale(
|
393
|
+
:amount => Braintree::Test::TransactionAmounts::Authorize,
|
394
|
+
:credit_card => {
|
395
|
+
:number => Braintree::Test::CreditCardNumbers::Fraud,
|
396
|
+
:expiration_date => "05/2017",
|
397
|
+
:cvv => "333"
|
398
|
+
}
|
399
|
+
)
|
400
|
+
result.success?.should == false
|
401
|
+
result.transaction.gateway_rejection_reason.should == Braintree::Transaction::GatewayRejectionReason::Fraud
|
402
|
+
end
|
388
403
|
end
|
389
404
|
|
390
405
|
it "accepts credit card expiration month and expiration year" do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,182 +1,185 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
Braintree::Configuration.
|
12
|
-
Braintree::Configuration.
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
1
|
+
unless defined?(SPEC_HELPER_LOADED)
|
2
|
+
SPEC_HELPER_LOADED = true
|
3
|
+
project_root = File.expand_path(File.dirname(__FILE__) + "/..")
|
4
|
+
require "rubygems"
|
5
|
+
require "libxml"
|
6
|
+
|
7
|
+
braintree_lib = "#{project_root}/lib"
|
8
|
+
$LOAD_PATH << braintree_lib
|
9
|
+
require "braintree"
|
10
|
+
|
11
|
+
Braintree::Configuration.environment = :development
|
12
|
+
Braintree::Configuration.merchant_id = "integration_merchant_id"
|
13
|
+
Braintree::Configuration.public_key = "integration_public_key"
|
14
|
+
Braintree::Configuration.private_key = "integration_private_key"
|
15
|
+
logger = Logger.new("/dev/null")
|
16
|
+
logger.level = Logger::INFO
|
17
|
+
Braintree::Configuration.logger = logger
|
18
|
+
|
19
|
+
module Kernel
|
20
|
+
alias_method :original_warn, :warn
|
21
|
+
def warn(message)
|
22
|
+
return if message =~ /^\[DEPRECATED\]/
|
23
|
+
original_warn(message)
|
24
|
+
end
|
22
25
|
end
|
23
|
-
end
|
24
26
|
|
25
|
-
def now_in_eastern
|
26
|
-
|
27
|
-
end
|
27
|
+
def now_in_eastern
|
28
|
+
(Time.now.utc - 5*60*60).strftime("%Y-%m-%d")
|
29
|
+
end
|
28
30
|
|
29
|
-
module SpecHelper
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
31
|
+
module SpecHelper
|
32
|
+
|
33
|
+
DefaultMerchantAccountId = "sandbox_credit_card"
|
34
|
+
NonDefaultMerchantAccountId = "sandbox_credit_card_non_default"
|
35
|
+
NonDefaultSubMerchantAccountId = "sandbox_sub_merchant_account"
|
36
|
+
|
37
|
+
TrialPlan = {
|
38
|
+
:description => "Plan for integration tests -- with trial",
|
39
|
+
:id => "integration_trial_plan",
|
40
|
+
:price => BigDecimal.new("43.21"),
|
41
|
+
:trial_period => true,
|
42
|
+
:trial_duration => 2,
|
43
|
+
:trial_duration_unit => Braintree::Subscription::TrialDurationUnit::Day
|
44
|
+
}
|
45
|
+
|
46
|
+
TriallessPlan = {
|
47
|
+
:description => "Plan for integration tests -- without a trial",
|
48
|
+
:id => "integration_trialless_plan",
|
49
|
+
:price => BigDecimal.new("12.34"),
|
50
|
+
:trial_period => false
|
51
|
+
}
|
52
|
+
|
53
|
+
AddOnDiscountPlan = {
|
54
|
+
:description => "Plan for integration tests -- with add-ons and discounts",
|
55
|
+
:id => "integration_plan_with_add_ons_and_discounts",
|
56
|
+
:price => BigDecimal.new("9.99"),
|
57
|
+
:trial_period => true,
|
58
|
+
:trial_duration => 2,
|
59
|
+
:trial_duration_unit => Braintree::Subscription::TrialDurationUnit::Day
|
60
|
+
}
|
61
|
+
|
62
|
+
BillingDayOfMonthPlan = {
|
63
|
+
:description => "Plan for integration tests -- with billing day of month",
|
64
|
+
:id => "integration_plan_with_billing_day_of_month",
|
65
|
+
:price => BigDecimal.new("8.88"),
|
66
|
+
:billing_day_of_month => 5
|
67
|
+
}
|
68
|
+
|
69
|
+
AddOnIncrease10 = "increase_10"
|
70
|
+
AddOnIncrease20 = "increase_20"
|
71
|
+
AddOnIncrease30 = "increase_30"
|
72
|
+
|
73
|
+
Discount7 = "discount_7"
|
74
|
+
Discount11 = "discount_11"
|
75
|
+
Discount15 = "discount_15"
|
76
|
+
|
77
|
+
TestMerchantConfig = Braintree::Configuration.new(
|
78
|
+
:logger => Logger.new("/dev/null"),
|
79
|
+
:environment => :development,
|
80
|
+
:merchant_id => "test_merchant_id",
|
81
|
+
:public_key => "test_public_key",
|
82
|
+
:private_key => "test_private_key"
|
83
|
+
)
|
84
|
+
|
85
|
+
def self.make_past_due(subscription, number_of_days_past_due = 1)
|
86
|
+
Braintree::Configuration.instantiate.http.put(
|
87
|
+
"/subscriptions/#{subscription.id}/make_past_due?days_past_due=#{number_of_days_past_due}"
|
81
88
|
)
|
89
|
+
end
|
82
90
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
)
|
87
|
-
end
|
88
|
-
|
89
|
-
def self.settle_transaction(transaction_id)
|
90
|
-
Braintree::Configuration.instantiate.http.put("/transactions/#{transaction_id}/settle")
|
91
|
-
end
|
91
|
+
def self.settle_transaction(transaction_id)
|
92
|
+
Braintree::Configuration.instantiate.http.put("/transactions/#{transaction_id}/settle")
|
93
|
+
end
|
92
94
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
95
|
+
def self.stub_time_dot_now(desired_time)
|
96
|
+
Time.class_eval do
|
97
|
+
class << self
|
98
|
+
alias original_now now
|
99
|
+
end
|
97
100
|
end
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
101
|
+
(class << Time; self; end).class_eval do
|
102
|
+
define_method(:now) { desired_time }
|
103
|
+
end
|
104
|
+
yield
|
105
|
+
ensure
|
106
|
+
Time.class_eval do
|
107
|
+
class << self
|
108
|
+
alias now original_now
|
109
|
+
end
|
107
110
|
end
|
108
111
|
end
|
109
|
-
end
|
110
112
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
113
|
+
def self.simulate_form_post_for_tr(tr_data_string, form_data_hash, url = Braintree::TransparentRedirect.url)
|
114
|
+
response = nil
|
115
|
+
Net::HTTP.start("localhost", Braintree::Configuration.instantiate.port) do |http|
|
116
|
+
request = Net::HTTP::Post.new("/" + url.split("/", 4)[3])
|
117
|
+
request.add_field "Content-Type", "application/x-www-form-urlencoded"
|
118
|
+
request.body = Braintree::Util.hash_to_query_string({:tr_data => tr_data_string}.merge(form_data_hash))
|
119
|
+
response = http.request(request)
|
120
|
+
end
|
121
|
+
if response.code.to_i == 303
|
122
|
+
response["Location"].split("?", 2).last
|
123
|
+
else
|
124
|
+
raise "did not receive a valid tr response: #{response.body[0,1000].inspect}"
|
125
|
+
end
|
123
126
|
end
|
124
|
-
end
|
125
127
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
128
|
+
def self.using_configuration(config = {}, &block)
|
129
|
+
original_values = {}
|
130
|
+
[:merchant_id, :public_key, :private_key].each do |key|
|
131
|
+
if config[key]
|
132
|
+
original_values[key] = Braintree::Configuration.send(key)
|
133
|
+
Braintree::Configuration.send("#{key}=", config[key])
|
134
|
+
end
|
132
135
|
end
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
136
|
+
begin
|
137
|
+
yield
|
138
|
+
ensure
|
139
|
+
original_values.each do |key, value|
|
140
|
+
Braintree::Configuration.send("#{key}=", value)
|
141
|
+
end
|
139
142
|
end
|
140
143
|
end
|
141
144
|
end
|
142
|
-
end
|
143
145
|
|
144
|
-
module CustomMatchers
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
146
|
+
module CustomMatchers
|
147
|
+
class ParseTo
|
148
|
+
def initialize(hash)
|
149
|
+
@expected_hash = hash
|
150
|
+
end
|
149
151
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
152
|
+
def matches?(xml_string)
|
153
|
+
@libxml_parse = Braintree::Xml::Parser.hash_from_xml(xml_string, Braintree::Xml::Libxml)
|
154
|
+
@rexml_parse = Braintree::Xml::Parser.hash_from_xml(xml_string, Braintree::Xml::Rexml)
|
155
|
+
if @libxml_parse != @expected_hash
|
156
|
+
@results = @libxml_parse
|
157
|
+
@failed_parser = "libxml"
|
158
|
+
false
|
159
|
+
elsif @rexml_parse != @expected_hash
|
160
|
+
@results = @rexml_parse
|
161
|
+
@failed_parser = "rexml"
|
162
|
+
false
|
163
|
+
else
|
164
|
+
true
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def failure_message
|
169
|
+
"xml parsing failed for #{@failed_parser}, expected #{@expected_hash.inspect} but was #{@results.inspect}"
|
163
170
|
end
|
164
|
-
end
|
165
171
|
|
166
|
-
|
167
|
-
|
172
|
+
def negative_failure_message
|
173
|
+
raise NotImplementedError
|
174
|
+
end
|
168
175
|
end
|
169
176
|
|
170
|
-
def
|
171
|
-
|
177
|
+
def parse_to(hash)
|
178
|
+
ParseTo.new(hash)
|
172
179
|
end
|
173
180
|
end
|
174
181
|
|
175
|
-
|
176
|
-
|
182
|
+
Spec::Runner.configure do |config|
|
183
|
+
config.include CustomMatchers
|
177
184
|
end
|
178
185
|
end
|
179
|
-
|
180
|
-
Spec::Runner.configure do |config|
|
181
|
-
config.include CustomMatchers
|
182
|
-
end
|