braintree 2.10.1 → 2.10.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -41,6 +41,8 @@ require File.dirname(__FILE__) + "/braintree/error_result"
41
41
  require File.dirname(__FILE__) + "/braintree/errors"
42
42
  require File.dirname(__FILE__) + "/braintree/gateway"
43
43
  require File.dirname(__FILE__) + "/braintree/http"
44
+ require File.dirname(__FILE__) + "/braintree/payer_authentication"
45
+ require File.dirname(__FILE__) + "/braintree/payer_authentication_gateway"
44
46
  require File.dirname(__FILE__) + "/braintree/resource_collection"
45
47
  require File.dirname(__FILE__) + "/braintree/subscription"
46
48
  require File.dirname(__FILE__) + "/braintree/subscription_gateway"
@@ -184,6 +184,8 @@ module Braintree
184
184
  TaxAmountIsTooLarge = "81536"
185
185
  TypeIsInvalid = "91523"
186
186
  TypeIsRequired = "91524"
187
+ UnsupportedVoiceAuthorization = "91539"
188
+
187
189
  module Options
188
190
  VaultIsDisabled = "91525"
189
191
  end
@@ -3,12 +3,14 @@ module Braintree
3
3
  class ErrorResult
4
4
 
5
5
  attr_reader :credit_card_verification, :transaction, :subscription, :errors, :params, :message
6
+ attr_reader :payer_authentication
6
7
 
7
8
  def initialize(gateway, data) # :nodoc:
8
9
  @gateway = gateway
9
10
  @params = data[:params]
10
11
  @credit_card_verification = CreditCardVerification._new(data[:verification]) if data[:verification]
11
12
  @message = data[:message]
13
+ @payer_authentication = PayerAuthentication._new(gateway, data[:payer_authentication]) if data[:payer_authentication]
12
14
  @transaction = Transaction._new(gateway, data[:transaction]) if data[:transaction]
13
15
  @subscription = Subscription._new(gateway, data[:subscription]) if data[:subscription]
14
16
  @errors = Errors.new(data[:errors])
@@ -24,6 +26,10 @@ module Braintree
24
26
  "#<#{self.class} params:{...} errors:<#{@errors._inner_inspect}>#{verification_inspect}#{transaction_inspect}>"
25
27
  end
26
28
 
29
+ def payer_authentication_required?
30
+ !!@payer_authentication
31
+ end
32
+
27
33
  # Always returns false.
28
34
  def success?
29
35
  false
@@ -24,6 +24,10 @@ module Braintree
24
24
  CustomerGateway.new(self)
25
25
  end
26
26
 
27
+ def payer_authentication
28
+ PayerAuthenticationGateway.new(self)
29
+ end
30
+
27
31
  def subscription
28
32
  SubscriptionGateway.new(self)
29
33
  end
@@ -0,0 +1,31 @@
1
+ module Braintree
2
+ class PayerAuthentication
3
+ include BaseModule # :nodoc:
4
+
5
+ attr_reader :id, :post_params, :post_url
6
+
7
+ def self.authenticate(payer_authentication_id, response_payload)
8
+ Configuration.gateway.payer_authentication.authenticate(
9
+ payer_authentication_id,
10
+ response_payload
11
+ )
12
+ end
13
+
14
+ def initialize(gateway, attributes) # :nodoc:
15
+ @gateway = gateway
16
+ set_instance_variables_from_hash(attributes)
17
+
18
+ @post_params = (@post_params || []).map do |params|
19
+ OpenStruct.new(:name => params[:name], :value => params[:value])
20
+ end
21
+ end
22
+
23
+ class << self
24
+ protected :new
25
+ end
26
+
27
+ def self._new(*args) # :nodoc:
28
+ self.new *args
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ module Braintree
2
+ class PayerAuthenticationGateway # :nodoc:
3
+ def initialize(gateway)
4
+ @gateway = gateway
5
+ @config = gateway.config
6
+ end
7
+
8
+ def authenticate(payer_authentication_id, response_payload)
9
+ response = @config.http.post(
10
+ "/payer_authentications/#{payer_authentication_id}/authenticate",
11
+ :payer_authentication => {
12
+ :response_payload => response_payload
13
+ }
14
+ )
15
+
16
+ if response[:transaction]
17
+ SuccessfulResult.new(:transaction => Transaction._new(@gateway, response[:transaction]))
18
+ elsif response[:api_error_response]
19
+ ErrorResult.new(@gateway, response[:api_error_response])
20
+ else
21
+ raise UnexpectedError, "expected :transaction or :api_error_response"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -19,7 +19,10 @@ module Braintree
19
19
  "#<#{self.class} #{inspected_attributes.join(" ")}>"
20
20
  end
21
21
 
22
- # Always returns true.
22
+ def payer_authentication_required?
23
+ false
24
+ end
25
+
23
26
  def success?
24
27
  true
25
28
  end
@@ -6,20 +6,14 @@ module Braintree
6
6
  #
7
7
  # See http://www.braintreepayments.com/docs/ruby/reference/sandbox
8
8
  module CreditCardNumbers
9
- AmExes = %w[
10
- 378282246310005
11
- 371449635398431
12
- 378734493671000
13
- ]
9
+ AmExes = %w[378282246310005 371449635398431 378734493671000]
14
10
  CarteBlanches = %w[30569309025904] # :nodoc:
15
11
  DinersClubs = %w[38520000023237] # :nodoc:
16
12
 
17
- Discovers = %w[
18
- 6011111111111117
19
- 6011000990139424
20
- ]
13
+ Discovers = %w[6011111111111117 6011000990139424]
21
14
  JCBs = %w[3530111333300000 3566002020360505] # :nodoc:
22
15
 
16
+ Maestro = "6304000000000000" # :nodoc:
23
17
  MasterCard = "5555555555554444"
24
18
  MasterCardInternational = "5105105105105100" # :nodoc:
25
19
 
@@ -28,15 +22,15 @@ module Braintree
28
22
  Visa = "4012888888881881"
29
23
  VisaInternational = "4009348888881881" # :nodoc:
30
24
 
31
- Visas = %w[
32
- 4009348888881881
33
- 4012888888881881
34
- 4111111111111111
35
- 4000111111111115
36
- ]
37
- Unknowns = %w[
38
- 1000000000000008
39
- ]
25
+ Visas = %w[4009348888881881 4012888888881881 4111111111111111 4000111111111115]
26
+ Unknowns = %w[1000000000000008]
27
+
28
+ module PayerAuthentication
29
+ ValidMaestro = "6304000000000000"
30
+ InvalidMaestro = "6773900000000000007"
31
+ AuthenticationSuccessfulPayload = "authentication_successful_payload"
32
+ AuthenticationFailedPayload = "authentication_failed_payload"
33
+ end
40
34
 
41
35
  module FailsSandboxVerification
42
36
  AmEx = "378734493671000"
@@ -2,7 +2,7 @@ module Braintree
2
2
  module Version
3
3
  Major = 2
4
4
  Minor = 10
5
- Tiny = 1
5
+ Tiny = 2
6
6
 
7
7
  String = "#{Major}.#{Minor}.#{Tiny}"
8
8
  end
@@ -40,7 +40,7 @@ describe Braintree::CreditCard do
40
40
  end
41
41
 
42
42
  it "can specify the desired token" do
43
- token = "token_#{rand(1_000_000)}"
43
+ token = "token_#{rand(10**10)}"
44
44
  customer = Braintree::Customer.create!
45
45
  result = Braintree::CreditCard.create(
46
46
  :customer_id => customer.id,
@@ -673,8 +673,8 @@ describe Braintree::CreditCard do
673
673
 
674
674
  describe "self.update_from_transparent_redirect" do
675
675
  it "updates the credit card" do
676
- old_token = "token#{rand(1_000_000)}"
677
- new_token = "token#{rand(1_000_000)}"
676
+ old_token = "token_#{rand(10**10)}"
677
+ new_token = "token_#{rand(10**10)}"
678
678
  customer = Braintree::Customer.create!(
679
679
  :credit_card => {
680
680
  :cardholder_name => "Old Cardholder Name",
@@ -11,7 +11,7 @@ describe Braintree::Transaction, "search" do
11
11
  end
12
12
 
13
13
  it "can search on text fields" do
14
- cctoken = "cctoken#{rand(1_000_000)}"
14
+ cctoken = "cctoken_#{rand(10**10)}"
15
15
  customer = Braintree::Customer.create!(
16
16
  :first_name => "Timmy",
17
17
  :last_name => "O'Toole",
@@ -11,9 +11,9 @@ describe Braintree::Transaction, "search" do
11
11
  end
12
12
 
13
13
  it "can search on text fields" do
14
- first_name = "Tim#{rand(10000)}"
15
- token = "creditcard#{rand(10000)}"
16
- customer_id = "customer#{rand(10000)}"
14
+ first_name = "Tim_#{rand(10**10)}"
15
+ token = "creditcard_#{rand(10**10)}"
16
+ customer_id = "customer_#{rand(10**10)}"
17
17
 
18
18
  transaction = Braintree::Transaction.sale!(
19
19
  :amount => Braintree::Test::TransactionAmounts::Authorize,
@@ -152,6 +152,106 @@ describe Braintree::Transaction do
152
152
  codes.should include(Braintree::ErrorCodes::Address::CountryCodeNumericIsNotAccepted)
153
153
  end
154
154
 
155
+ context "maestro authentication" do
156
+ it "returns an authentication response on successful lookup" do
157
+ result = Braintree::Transaction.create(
158
+ :type => "sale",
159
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
160
+ :merchant_account_id => "secure_code_ma",
161
+ :credit_card => {
162
+ :number => Braintree::Test::CreditCardNumbers::PayerAuthentication::ValidMaestro,
163
+ :expiration_date => "01/2012"
164
+ }
165
+ )
166
+
167
+ result.success?.should == false
168
+ result.payer_authentication_required?.should == true
169
+
170
+ payer_authentication = result.payer_authentication
171
+ payer_authentication.id.should match(/\A[a-z0-9]+\z/)
172
+ payer_authentication.post_url.should match(%r{\Ahttps?://})
173
+ payer_authentication.post_params.size.should == 1
174
+ payer_authentication.post_params.first.name.should == "PaReq"
175
+ payer_authentication.post_params.first.value.should_not be_empty
176
+
177
+ result = Braintree::PayerAuthentication.authenticate(
178
+ payer_authentication.id,
179
+ Braintree::Test::CreditCardNumbers::PayerAuthentication::AuthenticationSuccessfulPayload
180
+ )
181
+
182
+ result.success?.should == true
183
+ result.transaction.id.should =~ /^\w{6}$/
184
+ result.transaction.type.should == "sale"
185
+ result.transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
186
+ result.transaction.processor_authorization_code.should_not be_nil
187
+ result.transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Maestro[0, 6]
188
+ result.transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Maestro[-4..-1]
189
+ result.transaction.credit_card_details.expiration_date.should == "01/2012"
190
+ result.transaction.credit_card_details.customer_location.should == "US"
191
+ end
192
+
193
+ it "attempts to create the transaction on an unsuccessful authentication" do
194
+ result = Braintree::Transaction.create(
195
+ :type => "sale",
196
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
197
+ :merchant_account_id => "secure_code_ma",
198
+ :credit_card => {
199
+ :number => Braintree::Test::CreditCardNumbers::PayerAuthentication::ValidMaestro,
200
+ :expiration_date => "01/2012"
201
+ }
202
+ )
203
+
204
+ result.success?.should == false
205
+ result.payer_authentication_required?.should == true
206
+
207
+ payer_authentication = result.payer_authentication
208
+ payer_authentication.id.should match(/\A[a-z0-9]+\z/)
209
+ payer_authentication.post_url.should match(%r{\Ahttps?://})
210
+ payer_authentication.post_params.size.should == 1
211
+ payer_authentication.post_params.first.name.should == "PaReq"
212
+ payer_authentication.post_params.first.value.should_not be_empty
213
+
214
+ result = Braintree::PayerAuthentication.authenticate(
215
+ payer_authentication.id,
216
+ Braintree::Test::CreditCardNumbers::PayerAuthentication::AuthenticationFailedPayload
217
+ )
218
+
219
+ result.success?.should == true
220
+ result.transaction.id.should =~ /^\w{6}$/
221
+ result.transaction.type.should == "sale"
222
+ result.transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
223
+ result.transaction.processor_authorization_code.should_not be_nil
224
+ result.transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Maestro[0, 6]
225
+ result.transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Maestro[-4..-1]
226
+ result.transaction.credit_card_details.expiration_date.should == "01/2012"
227
+ result.transaction.credit_card_details.customer_location.should == "US"
228
+ end
229
+
230
+ it "runs a regular transaction on unsuccessful lookup" do
231
+ cc_number = Braintree::Test::CreditCardNumbers::PayerAuthentication::InvalidMaestro
232
+ result = Braintree::Transaction.create(
233
+ :type => "sale",
234
+ :amount => Braintree::Test::TransactionAmounts::Authorize,
235
+ :merchant_account_id => "secure_code_ma",
236
+ :credit_card => {
237
+ :number => cc_number,
238
+ :expiration_date => "01/2012"
239
+ }
240
+ )
241
+
242
+ result.payer_authentication_required?.should == false
243
+ result.success?.should == true
244
+ result.transaction.id.should =~ /^\w{6}$/
245
+ result.transaction.type.should == "sale"
246
+ result.transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
247
+ result.transaction.processor_authorization_code.should_not be_nil
248
+ result.transaction.credit_card_details.bin.should == cc_number[0, 6]
249
+ result.transaction.credit_card_details.last_4.should == cc_number[-4..-1]
250
+ result.transaction.credit_card_details.expiration_date.should == "01/2012"
251
+ result.transaction.credit_card_details.customer_location.should == "US"
252
+ end
253
+ end
254
+
155
255
  context "gateway rejection reason" do
156
256
  it "exposes the cvv gateway rejection reason" do
157
257
  old_merchant = Braintree::Configuration.merchant_id
@@ -1042,8 +1142,8 @@ describe Braintree::Transaction do
1042
1142
  end
1043
1143
 
1044
1144
  it "can specify the customer id and payment method token" do
1045
- customer_id = "customer_#{rand(1000000)}"
1046
- payment_mehtod_token = "credit_card_#{rand(1000000)}"
1145
+ customer_id = "customer_#{rand(10**10)}"
1146
+ payment_mehtod_token = "credit_card_#{rand(10**10)}"
1047
1147
  result = Braintree::Transaction.sale(
1048
1148
  :amount => "100",
1049
1149
  :customer => {
@@ -74,4 +74,17 @@ describe Braintree::ErrorResult do
74
74
  result.inspect.should_not include("transaction")
75
75
  end
76
76
  end
77
+
78
+ describe "payer_authentication_required?" do
79
+ it "is true if payer_authentication is in the response" do
80
+ result = Braintree::ErrorResult.new(
81
+ :gateway,
82
+ :payer_authentication => {:id => "public_id", :post_url => "post_url", :post_params => []},
83
+ :errors => {},
84
+ :verification => nil,
85
+ :transaction => nil
86
+ )
87
+ result.payer_authentication_required?.should be_true
88
+ end
89
+ end
77
90
  end
@@ -0,0 +1,38 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
2
+
3
+ describe Braintree::PayerAuthentication do
4
+ describe "id" do
5
+ it "returns the given id" do
6
+ payer_authentication = Braintree::PayerAuthentication._new(
7
+ :gateway,
8
+ :id => :test_id
9
+ )
10
+
11
+ payer_authentication.id.should == :test_id
12
+ end
13
+ end
14
+
15
+ describe "post_params" do
16
+ it "returns the given post params" do
17
+ payer_authentication = Braintree::PayerAuthentication._new(
18
+ :gateway,
19
+ :post_params => [{:name => 'imaname', :value => 'andimavalue'}]
20
+ )
21
+
22
+ post_param = payer_authentication.post_params.first
23
+ post_param.name.should == 'imaname'
24
+ post_param.value.should == 'andimavalue'
25
+ end
26
+ end
27
+
28
+ describe "post_url" do
29
+ it "returns the given post url" do
30
+ payer_authentication = Braintree::PayerAuthentication._new(
31
+ :gateway,
32
+ :post_url => "http://example.com"
33
+ )
34
+
35
+ payer_authentication.post_url.should == "http://example.com"
36
+ end
37
+ end
38
+ end
@@ -24,4 +24,10 @@ describe Braintree::SuccessfulResult do
24
24
  result.inspect.should == "#<Braintree::SuccessfulResult foo:\"foo_value\">"
25
25
  end
26
26
  end
27
+
28
+ describe "payer_authentication_required?" do
29
+ it "is always false" do
30
+ Braintree::SuccessfulResult.new.payer_authentication_required?.should be_false
31
+ end
32
+ end
27
33
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: braintree
3
3
  version: !ruby/object:Gem::Version
4
- hash: 37
4
+ hash: 35
5
5
  prerelease:
6
6
  segments:
7
7
  - 2
8
8
  - 10
9
- - 1
10
- version: 2.10.1
9
+ - 2
10
+ version: 2.10.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Braintree
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-06-07 00:00:00 -05:00
18
+ date: 2011-08-02 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -68,6 +68,8 @@ files:
68
68
  - lib/braintree/gateway.rb
69
69
  - lib/braintree/http.rb
70
70
  - lib/braintree/modification.rb
71
+ - lib/braintree/payer_authentication.rb
72
+ - lib/braintree/payer_authentication_gateway.rb
71
73
  - lib/braintree/resource_collection.rb
72
74
  - lib/braintree/subscription.rb
73
75
  - lib/braintree/subscription_gateway.rb
@@ -121,6 +123,7 @@ files:
121
123
  - spec/unit/braintree/error_result_spec.rb
122
124
  - spec/unit/braintree/errors_spec.rb
123
125
  - spec/unit/braintree/http_spec.rb
126
+ - spec/unit/braintree/payer_authentication_spec.rb
124
127
  - spec/unit/braintree/resource_collection_spec.rb
125
128
  - spec/unit/braintree/subscription_search_spec.rb
126
129
  - spec/unit/braintree/subscription_spec.rb
@@ -172,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
172
175
  requirements: []
173
176
 
174
177
  rubyforge_project: braintree
175
- rubygems_version: 1.4.0
178
+ rubygems_version: 1.6.2
176
179
  signing_key:
177
180
  specification_version: 3
178
181
  summary: Braintree Gateway Ruby Client Library