braintree 2.10.1 → 2.10.2

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.
@@ -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