Skip to content

Commit

Permalink
2.11.0
Browse files Browse the repository at this point in the history
  • Loading branch information
braintreeps committed Aug 24, 2011
1 parent 86dad78 commit 96bb119
Show file tree
Hide file tree
Showing 19 changed files with 127 additions and 237 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rdoc
@@ -1,3 +1,7 @@
== 2.11.0

* Added SettlementBatchSummary

== 2.10.2

* Added support for international Maestro cards with payer authentication
Expand Down
4 changes: 2 additions & 2 deletions lib/braintree.rb
Expand Up @@ -41,8 +41,8 @@ module Braintree
require File.dirname(__FILE__) + "/braintree/errors"
require File.dirname(__FILE__) + "/braintree/gateway"
require File.dirname(__FILE__) + "/braintree/http"
require File.dirname(__FILE__) + "/braintree/payer_authentication"
require File.dirname(__FILE__) + "/braintree/payer_authentication_gateway"
require File.dirname(__FILE__) + "/braintree/settlement_batch_summary"
require File.dirname(__FILE__) + "/braintree/settlement_batch_summary_gateway"
require File.dirname(__FILE__) + "/braintree/resource_collection"
require File.dirname(__FILE__) + "/braintree/subscription"
require File.dirname(__FILE__) + "/braintree/subscription_gateway"
Expand Down
7 changes: 7 additions & 0 deletions lib/braintree/error_codes.rb
Expand Up @@ -84,6 +84,12 @@ module Descriptor
NameFormatIsInvalid = "92201"
end

module SettlementBatchSummary
CustomFieldIsInvalid = "82303"
SettlementDateIsInvalid = "82302"
SettlementDateIsRequired = "82301"
end

# See http://www.braintreepayments.com/docs/ruby/subscriptions/validations
module Subscription
BillingDayOfMonthCannotBeUpdated = "91918"
Expand All @@ -101,6 +107,7 @@ module Subscription
InconsistentStartDate = "91917"
InvalidRequestFormat = "91921"
MerchantAccountIdIsInvalid = "91901"
MismatchCurrencyISOCode = "91923"
NumberOfBillingCyclesCannotBeBlank = "91912"
NumberOfBillingCyclesIsTooSmall = "91909"
NumberOfBillingCyclesMustBeGreaterThanZero = "91907"
Expand Down
6 changes: 0 additions & 6 deletions lib/braintree/error_result.rb
Expand Up @@ -3,14 +3,12 @@ module Braintree
class ErrorResult

attr_reader :credit_card_verification, :transaction, :subscription, :errors, :params, :message
attr_reader :payer_authentication

def initialize(gateway, data) # :nodoc:
@gateway = gateway
@params = data[:params]
@credit_card_verification = CreditCardVerification._new(data[:verification]) if data[:verification]
@message = data[:message]
@payer_authentication = PayerAuthentication._new(gateway, data[:payer_authentication]) if data[:payer_authentication]
@transaction = Transaction._new(gateway, data[:transaction]) if data[:transaction]
@subscription = Subscription._new(gateway, data[:subscription]) if data[:subscription]
@errors = Errors.new(data[:errors])
Expand All @@ -26,10 +24,6 @@ def inspect # :nodoc:
"#<#{self.class} params:{...} errors:<#{@errors._inner_inspect}>#{verification_inspect}#{transaction_inspect}>"
end

def payer_authentication_required?
!!@payer_authentication
end

# Always returns false.
def success?
false
Expand Down
4 changes: 2 additions & 2 deletions lib/braintree/gateway.rb
Expand Up @@ -24,8 +24,8 @@ def customer
CustomerGateway.new(self)
end

def payer_authentication
PayerAuthenticationGateway.new(self)
def settlement_batch_summary
SettlementBatchSummaryGateway.new(self)
end

def subscription
Expand Down
2 changes: 1 addition & 1 deletion lib/braintree/http.rb
Expand Up @@ -16,7 +16,7 @@ def delete(path)

def get(path)
response = _http_do Net::HTTP::Get, path
if response.code.to_i == 200
if response.code.to_i == 200 || response.code.to_i == 422
Xml.hash_from_xml(_body(response))
else
Util.raise_exception_for_status_code(response.code)
Expand Down
31 changes: 0 additions & 31 deletions lib/braintree/payer_authentication.rb

This file was deleted.

25 changes: 0 additions & 25 deletions lib/braintree/payer_authentication_gateway.rb

This file was deleted.

Empty file.
24 changes: 24 additions & 0 deletions lib/braintree/settlement_batch_summary.rb
@@ -0,0 +1,24 @@
module Braintree
class SettlementBatchSummary
include BaseModule
attr_reader :records

def self.generate(settlement_date, group_by_custom_field = nil)
criteria = { :settlement_date => settlement_date }
criteria.merge!({:group_by_custom_field => group_by_custom_field}) if group_by_custom_field
Configuration.gateway.settlement_batch_summary.generate(criteria)
end

def initialize(gateway, attributes)
@gateway = gateway
set_instance_variables_from_hash(attributes)
end

class << self
protected :new
def _new(*args)
self.new(*args)
end
end
end
end
24 changes: 24 additions & 0 deletions lib/braintree/settlement_batch_summary_gateway.rb
@@ -0,0 +1,24 @@
module Braintree
class SettlementBatchSummaryGateway # :nodoc
def initialize(gateway)
@gateway = gateway
@config = gateway.config
end

def generate(criteria)
Util.verify_keys(_signature, criteria)
response = @config.http.post "/settlement_batch_summary", :settlement_batch_summary => criteria
if response[:settlement_batch_summary]
SuccessfulResult.new(:settlement_batch_summary => SettlementBatchSummary._new(@gateway, response[:settlement_batch_summary]))
elsif response[:api_error_response]
ErrorResult.new(@gateway, response[:api_error_response])
else
raise UnexpectedError, "expected :settlement_batch_summary or :api_error_response"
end
end

def _signature
[:settlement_date, :group_by_custom_field]
end
end
end
4 changes: 0 additions & 4 deletions lib/braintree/successful_result.rb
Expand Up @@ -19,10 +19,6 @@ def inspect # :nodoc:
"#<#{self.class} #{inspected_attributes.join(" ")}>"
end

def payer_authentication_required?
false
end

def success?
true
end
Expand Down
7 changes: 0 additions & 7 deletions lib/braintree/test/credit_card_numbers.rb
Expand Up @@ -25,13 +25,6 @@ module CreditCardNumbers
Visas = %w[4009348888881881 4012888888881881 4111111111111111 4000111111111115]
Unknowns = %w[1000000000000008]

module PayerAuthentication
ValidMaestro = "6304000000000000"
InvalidMaestro = "6773900000000000007"
AuthenticationSuccessfulPayload = "authentication_successful_payload"
AuthenticationFailedPayload = "authentication_failed_payload"
end

module FailsSandboxVerification
AmEx = "378734493671000"
Discover = "6011000990139424"
Expand Down
4 changes: 2 additions & 2 deletions lib/braintree/version.rb
@@ -1,8 +1,8 @@
module Braintree
module Version
Major = 2
Minor = 10
Tiny = 2
Minor = 11
Tiny = 0

String = "#{Major}.#{Minor}.#{Tiny}"
end
Expand Down
61 changes: 61 additions & 0 deletions spec/integration/braintree/settlement_batch_summary_spec.rb
@@ -0,0 +1,61 @@
# encoding: utf-8
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")

describe Braintree::SettlementBatchSummary do
describe "self.generate" do
it "returns an empty collection if there is not data" do
result = Braintree::SettlementBatchSummary.generate("1979-01-01")
result.should be_success
result.settlement_batch_summary.records.size.should be_zero
end

it "returns an error response if the date cannot be parsed" do
result = Braintree::SettlementBatchSummary.generate("NOT A DATE :(")
result.should_not be_success
result.errors.for(:settlement_batch_summary).on(:settlement_date).map {|e| e.code}.should include(Braintree::ErrorCodes::SettlementBatchSummary::SettlementDateIsInvalid)
end

it "returns transactions settled on a given day" do
transaction = Braintree::Transaction.sale!(
:amount => Braintree::Test::TransactionAmounts::Authorize,
:credit_card => {
:number => Braintree::Test::CreditCardNumbers::AmExes.first,
:expiration_date => "05/2012",
:cardholder_name => "Sergio Ramos"
},
:options => { :submit_for_settlement => true }
)
SpecHelper.settle_transaction transaction.id

result = Braintree::SettlementBatchSummary.generate(Time.now.strftime("%Y-%m-%d"))
result.should be_success
amex_records = result.settlement_batch_summary.records.select {|row| row[:card_type] == Braintree::CreditCard::CardType::AmEx }
amex_records.first[:count].to_i.should >= 1
amex_records.first[:amount_settled].to_i.should >= Braintree::Test::TransactionAmounts::Authorize.to_i
end

it "can be grouped by a custom field" do
transaction = Braintree::Transaction.sale!(
:amount => Braintree::Test::TransactionAmounts::Authorize,
:credit_card => {
:number => Braintree::Test::CreditCardNumbers::AmExes.first,
:expiration_date => "05/2012",
:cardholder_name => "Sergio Ramos"
},
:custom_fields => {
:store_me => "1"
},
:options => { :submit_for_settlement => true }
)
SpecHelper.settle_transaction transaction.id

result = Braintree::SettlementBatchSummary.generate(Time.now.strftime("%Y-%m-%d"), 'store_me')
result.should be_success

amex_records = result.settlement_batch_summary.records.select {|row| row[:store_me] == "1" }
amex_records.should_not be_empty
amex_records.first[:count].to_i.should >= 1
amex_records.first[:amount_settled].to_i.should >= Braintree::Test::TransactionAmounts::Authorize.to_i
end
end
end
100 changes: 0 additions & 100 deletions spec/integration/braintree/transaction_spec.rb
Expand Up @@ -152,106 +152,6 @@
codes.should include(Braintree::ErrorCodes::Address::CountryCodeNumericIsNotAccepted)
end

context "maestro authentication" do
it "returns an authentication response on successful lookup" do
result = Braintree::Transaction.create(
:type => "sale",
:amount => Braintree::Test::TransactionAmounts::Authorize,
:merchant_account_id => "secure_code_ma",
:credit_card => {
:number => Braintree::Test::CreditCardNumbers::PayerAuthentication::ValidMaestro,
:expiration_date => "01/2012"
}
)

result.success?.should == false
result.payer_authentication_required?.should == true

payer_authentication = result.payer_authentication
payer_authentication.id.should match(/\A[a-z0-9]+\z/)
payer_authentication.post_url.should match(%r{\Ahttps?://})
payer_authentication.post_params.size.should == 1
payer_authentication.post_params.first.name.should == "PaReq"
payer_authentication.post_params.first.value.should_not be_empty

result = Braintree::PayerAuthentication.authenticate(
payer_authentication.id,
Braintree::Test::CreditCardNumbers::PayerAuthentication::AuthenticationSuccessfulPayload
)

result.success?.should == true
result.transaction.id.should =~ /^\w{6}$/
result.transaction.type.should == "sale"
result.transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
result.transaction.processor_authorization_code.should_not be_nil
result.transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Maestro[0, 6]
result.transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Maestro[-4..-1]
result.transaction.credit_card_details.expiration_date.should == "01/2012"
result.transaction.credit_card_details.customer_location.should == "US"
end

it "attempts to create the transaction on an unsuccessful authentication" do
result = Braintree::Transaction.create(
:type => "sale",
:amount => Braintree::Test::TransactionAmounts::Authorize,
:merchant_account_id => "secure_code_ma",
:credit_card => {
:number => Braintree::Test::CreditCardNumbers::PayerAuthentication::ValidMaestro,
:expiration_date => "01/2012"
}
)

result.success?.should == false
result.payer_authentication_required?.should == true

payer_authentication = result.payer_authentication
payer_authentication.id.should match(/\A[a-z0-9]+\z/)
payer_authentication.post_url.should match(%r{\Ahttps?://})
payer_authentication.post_params.size.should == 1
payer_authentication.post_params.first.name.should == "PaReq"
payer_authentication.post_params.first.value.should_not be_empty

result = Braintree::PayerAuthentication.authenticate(
payer_authentication.id,
Braintree::Test::CreditCardNumbers::PayerAuthentication::AuthenticationFailedPayload
)

result.success?.should == true
result.transaction.id.should =~ /^\w{6}$/
result.transaction.type.should == "sale"
result.transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
result.transaction.processor_authorization_code.should_not be_nil
result.transaction.credit_card_details.bin.should == Braintree::Test::CreditCardNumbers::Maestro[0, 6]
result.transaction.credit_card_details.last_4.should == Braintree::Test::CreditCardNumbers::Maestro[-4..-1]
result.transaction.credit_card_details.expiration_date.should == "01/2012"
result.transaction.credit_card_details.customer_location.should == "US"
end

it "runs a regular transaction on unsuccessful lookup" do
cc_number = Braintree::Test::CreditCardNumbers::PayerAuthentication::InvalidMaestro
result = Braintree::Transaction.create(
:type => "sale",
:amount => Braintree::Test::TransactionAmounts::Authorize,
:merchant_account_id => "secure_code_ma",
:credit_card => {
:number => cc_number,
:expiration_date => "01/2012"
}
)

result.payer_authentication_required?.should == false
result.success?.should == true
result.transaction.id.should =~ /^\w{6}$/
result.transaction.type.should == "sale"
result.transaction.amount.should == BigDecimal.new(Braintree::Test::TransactionAmounts::Authorize)
result.transaction.processor_authorization_code.should_not be_nil
result.transaction.credit_card_details.bin.should == cc_number[0, 6]
result.transaction.credit_card_details.last_4.should == cc_number[-4..-1]
result.transaction.credit_card_details.expiration_date.should == "01/2012"
result.transaction.credit_card_details.customer_location.should == "US"
end
end

context "gateway rejection reason" do
it "exposes the cvv gateway rejection reason" do
old_merchant = Braintree::Configuration.merchant_id
Expand Down

0 comments on commit 96bb119

Please sign in to comment.