From a1babb99f15d2050c5cea010a680df61f953c983 Mon Sep 17 00:00:00 2001 From: Braintree Date: Wed, 4 Dec 2013 20:32:40 +0000 Subject: [PATCH] 2.27.0 --- CHANGELOG.rdoc | 4 + lib/braintree.rb | 4 + lib/braintree/error_codes.rb | 76 ++++- lib/braintree/merchant_account.rb | 18 +- .../merchant_account/address_details.rb | 13 + .../merchant_account/business_details.rb | 14 + .../merchant_account/funding_details.rb | 13 + .../merchant_account/individual_details.rb | 15 + lib/braintree/merchant_account_gateway.rb | 50 ++- lib/braintree/version.rb | 2 +- .../braintree/merchant_account_spec.rb | 320 +++++++++++++++++- .../braintree/transparent_redirect_spec.rb | 24 ++ spec/unit/braintree/merchant_account_spec.rb | 1 + .../braintree/webhook_notification_spec.rb | 2 +- 14 files changed, 531 insertions(+), 25 deletions(-) create mode 100644 lib/braintree/merchant_account/address_details.rb create mode 100644 lib/braintree/merchant_account/business_details.rb create mode 100644 lib/braintree/merchant_account/funding_details.rb create mode 100644 lib/braintree/merchant_account/individual_details.rb diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc index f7d26f71..780d5cc7 100644 --- a/CHANGELOG.rdoc +++ b/CHANGELOG.rdoc @@ -1,3 +1,7 @@ +== 2.27.0 +* Merchant account update API +* Merchant account create API v2 + == 2.26.0 * Official support for Partnerships * Changed visibility of methods used in multi-tenancy diff --git a/lib/braintree.rb b/lib/braintree.rb index b8747c68..966b10d9 100644 --- a/lib/braintree.rb +++ b/lib/braintree.rb @@ -46,6 +46,10 @@ require "braintree/http" require "braintree/merchant_account" require "braintree/merchant_account_gateway" +require "braintree/merchant_account/individual_details" +require "braintree/merchant_account/business_details" +require "braintree/merchant_account/funding_details" +require "braintree/merchant_account/address_details" require "braintree/plan" require "braintree/plan_gateway" require "braintree/settlement_batch_summary" diff --git a/lib/braintree/error_codes.rb b/lib/braintree/error_codes.rb index 88945738..2c3340e0 100644 --- a/lib/braintree/error_codes.rb +++ b/lib/braintree/error_codes.rb @@ -243,6 +243,15 @@ module MerchantAccount MasterMerchantAccountIdIsInvalid = "82607" MasterMerchantAccountMustBeActive = "82608" TosAcceptedIsRequired = "82610" + IdCannotBeUpdated = "82675" + MasterMerchantAccountIdCannotBeUpdated = "82676" + CannotBeUpdated = "82674" + DeclinedOFAC = "82621" + DeclinedMasterCardMatch = "82622" + DeclinedFailedKYC = "82623" + DeclinedSsnInvalid = "82624" + DeclinedSsnMatchesDeceased = "82625" + Declined = "82626" module ApplicantDetails FirstNameIsRequired = "82609" @@ -259,13 +268,17 @@ module ApplicantDetails CompanyNameIsRequiredWithTaxId = "82633" TaxIdIsRequiredWithCompanyName = "82634" RoutingNumberIsInvalid = "82635" - DeclinedOFAC = "82621" - DeclinedMasterCardMatch = "82622" - DeclinedFailedKYC = "82623" - DeclinedSsnInvalid = "82624" - DeclinedSsnMatchesDeceased = "82625" - Declined = "82626" + DeclinedOFAC = "82621" # Keep for backwards compatibility + DeclinedMasterCardMatch = "82622" # Keep for backwards compatibility + DeclinedFailedKYC = "82623" # Keep for backwards compatibility + DeclinedSsnInvalid = "82624" # Keep for backwards compatibility + DeclinedSsnMatchesDeceased = "82625" # Keep for backwards compatibility + Declined = "82626" # Keep for backwards compatibility PhoneIsInvalid = "82636" + DateOfBirthIsInvalid = "82663" + AccountNumberIsInvalid = "82670" + EmailAddressIsRequired = "82665" + TaxIdMustBeBlank = "82673" module Address StreetAddressIsRequired = "82617" @@ -274,8 +287,59 @@ module Address RegionIsRequired = "82620" StreetAddressIsInvalid = "82629" PostalCodeIsInvalid = "82630" + RegionIsInvalid = "82664" end end + + module Individual + FirstNameIsRequired = "82637" + LastNameIsRequired = "82638" + DateOfBirthIsRequired = "82639" + SsnIsInvalid = "82642" + EmailIsInvalid = "82643" + FirstNameIsInvalid = "82644" + LastNameIsInvalid = "82645" + PhoneIsInvalid = "82656" + DateOfBirthIsInvalid = "82666" + EmailIsRequired = "82667" + + module Address + StreetAddressIsRequired = "82657" + LocalityIsRequired = "82658" + PostalCodeIsRequired = "82659" + RegionIsRequired = "82660" + StreetAddressIsInvalid = "82661" + PostalCodeIsInvalid = "82662" + RegionIsInvalid = "82668" + end + end + + module Business + DbaNameIsInvalid = "82646" + LegalNameIsInvalid = "82677" + LegalNameIsRequiredWithTaxId = "82669" + TaxIdIsInvalid = "82647" + TaxIdIsRequiredWithLegalName = "82648" + TaxIdMustBeBlank = "82672" + module Address + StreetAddressIsInvalid = "82685" + PostalCodeIsInvalid = "82686" + RegionIsInvalid = "82684" + end + end + + module Funding + AccountNumberIsInvalid = "82671" + AccountNumberIsRequired = "82641" + DestinationIsInvalid = "82679" + DestinationIsRequired = "82678" + EmailIsInvalid = "82681" + EmailIsRequired = "82680" + MobilePhoneIsInvalid = "82683" + MobilePhoneIsRequired = "82682" + RoutingNumberIsInvalid = "82649" + RoutingNumberIsRequired = "82640" + end end module SettlementBatchSummary diff --git a/lib/braintree/merchant_account.rb b/lib/braintree/merchant_account.rb index db9faddb..88c786b6 100644 --- a/lib/braintree/merchant_account.rb +++ b/lib/braintree/merchant_account.rb @@ -8,16 +8,30 @@ module Status Suspended = "suspended" end - attr_reader :status, :id, :master_merchant_account + module FundingDestinations + Bank = "bank" + MobilePhone = "mobile_phone" + Email = "email" + end + + attr_reader :status, :id, :master_merchant_account, + :individual_details, :business_details, :funding_details def self.create(attributes) Configuration.gateway.merchant_account.create(attributes) end + def self.update(id, attributes) + Configuration.gateway.merchant_account.update(id, attributes) + end + def initialize(gateway, attributes) # :nodoc @gateway = gateway - @master_merchant_account = MerchantAccount._new(@gateway, attributes.delete(:master_merchant_account)) if attributes[:master_merchant_account] set_instance_variables_from_hash(attributes) + @individual_details = IndividualDetails.new(@individual) + @business_details = BusinessDetails.new(@business) + @funding_details = FundingDetails.new(@funding) + @master_merchant_account = MerchantAccount._new(@gateway, attributes.delete(:master_merchant_account)) if attributes[:master_merchant_account] end class << self diff --git a/lib/braintree/merchant_account/address_details.rb b/lib/braintree/merchant_account/address_details.rb new file mode 100644 index 00000000..34f2c177 --- /dev/null +++ b/lib/braintree/merchant_account/address_details.rb @@ -0,0 +1,13 @@ +module Braintree + class MerchantAccount + class AddressDetails + include BaseModule + + attr_reader :street_address, :locality, :region, :postal_code + + def initialize(attributes) + set_instance_variables_from_hash attributes unless attributes.nil? + end + end + end +end diff --git a/lib/braintree/merchant_account/business_details.rb b/lib/braintree/merchant_account/business_details.rb new file mode 100644 index 00000000..1430a05a --- /dev/null +++ b/lib/braintree/merchant_account/business_details.rb @@ -0,0 +1,14 @@ +module Braintree + class MerchantAccount + class BusinessDetails + include BaseModule + + attr_reader :dba_name, :legal_name, :tax_id, :address_details + + def initialize(attributes) + set_instance_variables_from_hash attributes unless attributes.nil? + @address_details = MerchantAccount::AddressDetails.new(@address) + end + end + end +end diff --git a/lib/braintree/merchant_account/funding_details.rb b/lib/braintree/merchant_account/funding_details.rb new file mode 100644 index 00000000..1647ed6a --- /dev/null +++ b/lib/braintree/merchant_account/funding_details.rb @@ -0,0 +1,13 @@ +module Braintree + class MerchantAccount + class FundingDetails + include BaseModule + + attr_reader :account_number_last_4, :destination, :email, :mobile_phone, :routing_number + + def initialize(attributes) + set_instance_variables_from_hash attributes unless attributes.nil? + end + end + end +end diff --git a/lib/braintree/merchant_account/individual_details.rb b/lib/braintree/merchant_account/individual_details.rb new file mode 100644 index 00000000..6875f31d --- /dev/null +++ b/lib/braintree/merchant_account/individual_details.rb @@ -0,0 +1,15 @@ +module Braintree + class MerchantAccount + class IndividualDetails + include BaseModule + + attr_reader :first_name, :last_name, :email, :phone, :date_of_birth, :ssn_last_4, + :address_details + + def initialize(attributes) + set_instance_variables_from_hash attributes unless attributes.nil? + @address_details = MerchantAccount::AddressDetails.new(@address) + end + end + end +end diff --git a/lib/braintree/merchant_account_gateway.rb b/lib/braintree/merchant_account_gateway.rb index fe99c36d..502def13 100644 --- a/lib/braintree/merchant_account_gateway.rb +++ b/lib/braintree/merchant_account_gateway.rb @@ -6,10 +6,16 @@ def initialize(gateway) end def create(attributes) - Util.verify_keys(MerchantAccountGateway._create_signature, attributes) + signature = MerchantAccountGateway._detect_signature(attributes) + Util.verify_keys(signature, attributes) _do_create "/merchant_accounts/create_via_api", :merchant_account => attributes end + def update(merchant_account_id, attributes) + Util.verify_keys(MerchantAccountGateway._update_signature, attributes) + _do_update "/merchant_accounts/#{merchant_account_id}/update_via_api", :merchant_account => attributes + end + def _do_create(url, params=nil) # :nodoc: response = @config.http.post url, params if response[:api_error_response] @@ -19,7 +25,25 @@ def _do_create(url, params=nil) # :nodoc: end end - def self._create_signature # :nodoc: + def _do_update(url, params=nil) # :nodoc: + response = @config.http.put(url, params) + if response[:api_error_response] + ErrorResult.new(@gateway, response[:api_error_response]) + else + SuccessfulResult.new(:merchant_account => MerchantAccount._new(@gateway, response[:merchant_account])) + end + end + + def self._detect_signature(attributes) + if attributes.has_key?(:applicant_details) + warn "[DEPRECATED] Passing :applicant_details to create is deprecated. Please use :individual, :business, and :funding." + MerchantAccountGateway._deprecated_create_signature + else + MerchantAccountGateway._create_signature + end + end + + def self._deprecated_create_signature # :nodoc: [ {:applicant_details => [ :first_name, :last_name, :email, :date_of_birth, :ssn, :routing_number, @@ -29,5 +53,27 @@ def self._create_signature # :nodoc: :tos_accepted, :master_merchant_account_id, :id ] end + + def self._signature # :nodoc: + [ + {:individual => [ + :first_name, :last_name, :email, :date_of_birth, :ssn, :phone, + {:address => [:street_address, :locality, :region, :postal_code]}] + }, + {:business => [ + :dba_name, :legal_name, :tax_id, + {:address => [:street_address, :locality, :region, :postal_code]}] + }, + {:funding => [:destination, :email, :mobile_phone, :routing_number, :account_number]} + ] + end + + def self._create_signature # :nodoc: + _signature + [:tos_accepted, :master_merchant_account_id, :id] + end + + def self._update_signature # :nodoc: + _signature + end end end diff --git a/lib/braintree/version.rb b/lib/braintree/version.rb index d63647c7..ee7b2fc1 100644 --- a/lib/braintree/version.rb +++ b/lib/braintree/version.rb @@ -1,7 +1,7 @@ module Braintree module Version Major = 2 - Minor = 26 + Minor = 27 Tiny = 0 String = "#{Major}.#{Minor}.#{Tiny}" diff --git a/spec/integration/braintree/merchant_account_spec.rb b/spec/integration/braintree/merchant_account_spec.rb index 360f89a6..31fc5534 100644 --- a/spec/integration/braintree/merchant_account_spec.rb +++ b/spec/integration/braintree/merchant_account_spec.rb @@ -1,11 +1,11 @@ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") -VALID_APPLICATION_PARAMS = { +DEPRECATED_APPLICATION_PARAMS = { :applicant_details => { :first_name => "Joe", :last_name => "Bloggs", :email => "joe@bloggs.com", - :phone => "312-555-1234", + :phone => "3125551234", :address => { :street_address => "123 Credibility St.", :postal_code => "60606", @@ -14,7 +14,44 @@ }, :date_of_birth => "10/9/1980", :ssn => "123-00-1234", - :routing_number => "121000248", + :routing_number => "011103093", + :account_number => "43759348798", + :tax_id => "111223333", + :company_name => "Joe's Junkyard" + }, + :tos_accepted => true, + :master_merchant_account_id => "sandbox_master_merchant_account" +} + +VALID_APPLICATION_PARAMS = { + :individual => { + :first_name => "Joe", + :last_name => "Bloggs", + :email => "joe@bloggs.com", + :phone => "3125551234", + :address => { + :street_address => "123 Credibility St.", + :postal_code => "60606", + :locality => "Chicago", + :region => "IL", + }, + :date_of_birth => "10/9/1980", + :ssn => "123-00-1234", + }, + :business => { + :legal_name => "Joe's Bloggs", + :dba_name => "Joe's Junkyard", + :tax_id => "123456789", + :address => { + :street_address => "456 Fake St", + :postal_code => "48104", + :locality => "Ann Arbor", + :region => "MI", + } + }, + :funding => { + :destination => Braintree::MerchantAccount::FundingDestinations::Bank, + :routing_number => "011103093", :account_number => "43759348798" }, :tos_accepted => true, @@ -23,7 +60,15 @@ describe Braintree::MerchantAccount do describe "create" do - it "doesn't require an id" do + it "accepts the deprecated parameters" do + result = Braintree::MerchantAccount.create(DEPRECATED_APPLICATION_PARAMS) + + result.should be_success + result.merchant_account.status.should == Braintree::MerchantAccount::Status::Pending + result.merchant_account.master_merchant_account.id.should == "sandbox_master_merchant_account" + end + + it "creates a merchant account with the new parameters and doesn't require an id" do result = Braintree::MerchantAccount.create(VALID_APPLICATION_PARAMS) result.should be_success @@ -54,21 +99,270 @@ it "requires all fields" do result = Braintree::MerchantAccount.create( - :master_merchant_account_id => "sandbox_master_merchant_account", - :tos_accepted => true, - :applicant_details => {} + :master_merchant_account_id => "sandbox_master_merchant_account" ) result.should_not be_success - result.errors.for(:merchant_account).for(:applicant_details).on(:first_name).first.code.should == Braintree::ErrorCodes::MerchantAccount::ApplicantDetails::FirstNameIsRequired + result.errors.for(:merchant_account).on(:tos_accepted).first.code.should == Braintree::ErrorCodes::MerchantAccount::TosAcceptedIsRequired end - it "accepts tax_id and business_name fields" do + context "funding destination" do + it "accepts a bank" do + params = VALID_APPLICATION_PARAMS.dup + params[:funding][:destination] = ::Braintree::MerchantAccount::FundingDestinations::Bank + result = Braintree::MerchantAccount.create(params) + + result.should be_success + end + + it "accepts an email" do + params = VALID_APPLICATION_PARAMS.dup + params[:funding][:destination] = ::Braintree::MerchantAccount::FundingDestinations::Email + params[:funding][:email] = "joebloggs@compuserve.com" + result = Braintree::MerchantAccount.create(params) + + result.should be_success + end + + it "accepts a mobile_phone" do + params = VALID_APPLICATION_PARAMS.dup + params[:funding][:destination] = ::Braintree::MerchantAccount::FundingDestinations::MobilePhone + params[:funding][:mobile_phone] = "3125882300" + result = Braintree::MerchantAccount.create(params) + + result.should be_success + end + end + end + + describe "update" do + it "updates the Merchant Account info" do params = VALID_APPLICATION_PARAMS.clone - params[:applicant_details][:company_name] = "Test Company" - params[:applicant_details][:tax_id] = "123456789" - result = Braintree::MerchantAccount.create(params) + params.delete(:tos_accepted) + params.delete(:master_merchant_account_id) + params[:individual][:first_name] = "John" + params[:individual][:last_name] = "Doe" + params[:individual][:email] = "john.doe@example.com" + params[:individual][:date_of_birth] = "1970-01-01" + params[:individual][:phone] = "3125551234" + params[:individual][:address][:street_address] = "123 Fake St" + params[:individual][:address][:locality] = "Chicago" + params[:individual][:address][:region] = "IL" + params[:individual][:address][:postal_code] = "60622" + params[:business][:dba_name] = "James's Bloggs" + params[:business][:legal_name] = "James's Bloggs Inc" + params[:business][:tax_id] = "123456789" + params[:business][:address][:street_address] = "999 Fake St" + params[:business][:address][:locality] = "Miami" + params[:business][:address][:region] = "FL" + params[:business][:address][:postal_code] = "99999" + params[:funding][:account_number] = "43759348798" + params[:funding][:routing_number] = "071000013" + params[:funding][:email] = "check@this.com" + params[:funding][:mobile_phone] = "1234567890" + params[:funding][:destination] = Braintree::MerchantAccount::FundingDestinations::MobilePhone + result = Braintree::MerchantAccount.update("sandbox_sub_merchant_account", params) result.should be_success - result.merchant_account.status.should == Braintree::MerchantAccount::Status::Pending + result.merchant_account.status.should == "active" + result.merchant_account.id.should == "sandbox_sub_merchant_account" + result.merchant_account.master_merchant_account.id.should == "sandbox_master_merchant_account" + result.merchant_account.individual_details.first_name.should == "John" + result.merchant_account.individual_details.last_name.should == "Doe" + result.merchant_account.individual_details.email.should == "john.doe@example.com" + result.merchant_account.individual_details.date_of_birth.should == "1970-01-01" + result.merchant_account.individual_details.phone.should == "3125551234" + result.merchant_account.individual_details.address_details.street_address.should == "123 Fake St" + result.merchant_account.individual_details.address_details.locality.should == "Chicago" + result.merchant_account.individual_details.address_details.region.should == "IL" + result.merchant_account.individual_details.address_details.postal_code.should == "60622" + result.merchant_account.business_details.dba_name.should == "James's Bloggs" + result.merchant_account.business_details.legal_name.should == "James's Bloggs Inc" + result.merchant_account.business_details.tax_id.should == "123456789" + result.merchant_account.business_details.address_details.street_address.should == "999 Fake St" + result.merchant_account.business_details.address_details.locality.should == "Miami" + result.merchant_account.business_details.address_details.region.should == "FL" + result.merchant_account.business_details.address_details.postal_code.should == "99999" + result.merchant_account.funding_details.account_number_last_4.should == "8798" + result.merchant_account.funding_details.routing_number.should == "071000013" + result.merchant_account.funding_details.email.should == "check@this.com" + result.merchant_account.funding_details.mobile_phone.should == "1234567890" + result.merchant_account.funding_details.destination.should == Braintree::MerchantAccount::FundingDestinations::MobilePhone + end + + it "does not require all fields" do + result = Braintree::MerchantAccount.update("sandbox_sub_merchant_account", { :individual => { :first_name => "Jose" } }) + result.should be_success + end + + it "handles validation errors for blank fields" do + result = Braintree::MerchantAccount.update( + "sandbox_sub_merchant_account", { + :individual => { + :first_name => "", + :last_name => "", + :email => "", + :phone => "", + :address => { + :street_address => "", + :postal_code => "", + :locality => "", + :region => "", + }, + :date_of_birth => "", + :ssn => "", + }, + :business => { + :legal_name => "", + :dba_name => "", + :tax_id => "" + }, + :funding => { + :destination => "", + :routing_number => "", + :account_number => "" + }, + } + ) + + result.should_not be_success + result.errors.for(:merchant_account).for(:individual).on(:first_name).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::FirstNameIsRequired] + result.errors.for(:merchant_account).for(:individual).on(:last_name).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::LastNameIsRequired] + result.errors.for(:merchant_account).for(:individual).on(:date_of_birth).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::DateOfBirthIsRequired] + result.errors.for(:merchant_account).for(:individual).on(:email).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::EmailIsRequired] + result.errors.for(:merchant_account).for(:individual).for(:address).on(:street_address).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::Address::StreetAddressIsRequired] + result.errors.for(:merchant_account).for(:individual).for(:address).on(:postal_code).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::Address::PostalCodeIsRequired] + result.errors.for(:merchant_account).for(:individual).for(:address).on(:locality).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::Address::LocalityIsRequired] + result.errors.for(:merchant_account).for(:individual).for(:address).on(:region).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::Address::RegionIsRequired] + result.errors.for(:merchant_account).for(:funding).on(:destination).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Funding::DestinationIsRequired] + result.errors.for(:merchant_account).on(:base).should be_empty + end + + it "handles validation errors for invalid fields" do + result = Braintree::MerchantAccount.update( + "sandbox_sub_merchant_account", { + :individual => { + :first_name => "<>", + :last_name => "<>", + :email => "bad", + :phone => "999", + :address => { + :street_address => "nope", + :postal_code => "1", + :region => "QQ", + }, + :date_of_birth => "hah", + :ssn => "12345", + }, + :business => { + :legal_name => "``{}", + :dba_name => "{}``", + :tax_id => "bad", + :address => { + :street_address => "nope", + :postal_code => "1", + :region => "QQ", + }, + }, + :funding => { + :destination => "MY WALLET", + :routing_number => "LEATHER", + :account_number => "BACK POCKET", + :email => "BILLFOLD", + :mobile_phone => "TRIFOLD" + }, + } + ) + + result.should_not be_success + result.errors.for(:merchant_account).for(:individual).on(:first_name).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::FirstNameIsInvalid] + result.errors.for(:merchant_account).for(:individual).on(:last_name).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::LastNameIsInvalid] + result.errors.for(:merchant_account).for(:individual).on(:email).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::EmailIsInvalid] + result.errors.for(:merchant_account).for(:individual).on(:phone).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::PhoneIsInvalid] + result.errors.for(:merchant_account).for(:individual).for(:address).on(:street_address).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::Address::StreetAddressIsInvalid] + result.errors.for(:merchant_account).for(:individual).for(:address).on(:postal_code).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::Address::PostalCodeIsInvalid] + result.errors.for(:merchant_account).for(:individual).for(:address).on(:region).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::Address::RegionIsInvalid] + result.errors.for(:merchant_account).for(:individual).on(:ssn).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Individual::SsnIsInvalid] + + result.errors.for(:merchant_account).for(:business).on(:legal_name).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Business::LegalNameIsInvalid] + result.errors.for(:merchant_account).for(:business).on(:dba_name).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Business::DbaNameIsInvalid] + result.errors.for(:merchant_account).for(:business).on(:tax_id).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Business::TaxIdIsInvalid] + result.errors.for(:merchant_account).for(:business).for(:address).on(:street_address).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Business::Address::StreetAddressIsInvalid] + result.errors.for(:merchant_account).for(:business).for(:address).on(:postal_code).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Business::Address::PostalCodeIsInvalid] + result.errors.for(:merchant_account).for(:business).for(:address).on(:region).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Business::Address::RegionIsInvalid] + + result.errors.for(:merchant_account).for(:funding).on(:destination).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Funding::DestinationIsInvalid] + result.errors.for(:merchant_account).for(:funding).on(:routing_number).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Funding::RoutingNumberIsInvalid] + result.errors.for(:merchant_account).for(:funding).on(:account_number).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Funding::AccountNumberIsInvalid] + result.errors.for(:merchant_account).for(:funding).on(:email).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Funding::EmailIsInvalid] + result.errors.for(:merchant_account).for(:funding).on(:mobile_phone).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Funding::MobilePhoneIsInvalid] + + result.errors.for(:merchant_account).on(:base).should be_empty + end + + it "handles validation errors for business fields" do + result = Braintree::MerchantAccount.update( + "sandbox_sub_merchant_account", { + :business => { + :legal_name => "", + :tax_id => "111223333", + }, + } + ) + + result.should_not be_success + result.errors.for(:merchant_account).for(:business).on(:legal_name).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Business::LegalNameIsRequiredWithTaxId] + result.errors.for(:merchant_account).for(:business).on(:tax_id).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Business::TaxIdMustBeBlank] + + result = Braintree::MerchantAccount.update( + "sandbox_sub_merchant_account", { + :business => { + :legal_name => "legal_name", + :tax_id => "", + }, + } + ) + + result.should_not be_success + result.errors.for(:merchant_account).for(:business).on(:tax_id).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Business::TaxIdIsRequiredWithLegalName] + end + + it "handles validation errors for funding fields" do + result = Braintree::MerchantAccount.update( + "sandbox_sub_merchant_account", { + :funding => { + :destination => Braintree::MerchantAccount::FundingDestinations::Bank, + :routing_number => "", + :account_number => "" + }, + } + ) + + result.should_not be_success + result.errors.for(:merchant_account).for(:funding).on(:routing_number).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Funding::RoutingNumberIsRequired] + result.errors.for(:merchant_account).for(:funding).on(:account_number).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Funding::AccountNumberIsRequired] + + result = Braintree::MerchantAccount.update( + "sandbox_sub_merchant_account", { + :funding => { + :destination => Braintree::MerchantAccount::FundingDestinations::Email, + :email => "" + }, + } + ) + + result.should_not be_success + result.errors.for(:merchant_account).for(:funding).on(:email).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Funding::EmailIsRequired] + + result = Braintree::MerchantAccount.update( + "sandbox_sub_merchant_account", { + :funding => { + :destination => Braintree::MerchantAccount::FundingDestinations::MobilePhone, + :mobile_phone => "" + }, + } + ) + + result.should_not be_success + result.errors.for(:merchant_account).for(:funding).on(:mobile_phone).map(&:code).should == [Braintree::ErrorCodes::MerchantAccount::Funding::MobilePhoneIsRequired] end end end diff --git a/spec/integration/braintree/transparent_redirect_spec.rb b/spec/integration/braintree/transparent_redirect_spec.rb index e08a6b18..dd3bf23f 100644 --- a/spec/integration/braintree/transparent_redirect_spec.rb +++ b/spec/integration/braintree/transparent_redirect_spec.rb @@ -49,6 +49,30 @@ transaction.credit_card_details.expiration_date.should == "05/2009" end + it "allows specifying a service fee" do + params = { + :transaction => { + :amount => Braintree::Test::TransactionAmounts::Authorize, + :merchant_account_id => SpecHelper::NonDefaultSubMerchantAccountId, + :credit_card => { + :number => Braintree::Test::CreditCardNumbers::Visa, + :expiration_date => "05/2009" + }, + :service_fee_amount => "1.00" + } + } + tr_data_params = { + :transaction => { + :type => "sale" + } + } + tr_data = Braintree::TransparentRedirect.transaction_data({:redirect_url => "http://example.com"}.merge(tr_data_params)) + query_string_response = SpecHelper.simulate_form_post_for_tr(tr_data, params) + result = Braintree::TransparentRedirect.confirm(query_string_response) + result.success?.should == true + result.transaction.service_fee_amount.should == BigDecimal.new("1.00") + end + it "returns an error when there's an error" do params = { :transaction => { diff --git a/spec/unit/braintree/merchant_account_spec.rb b/spec/unit/braintree/merchant_account_spec.rb index 0001da72..d3f9e8f0 100644 --- a/spec/unit/braintree/merchant_account_spec.rb +++ b/spec/unit/braintree/merchant_account_spec.rb @@ -21,3 +21,4 @@ end end end + diff --git a/spec/unit/braintree/webhook_notification_spec.rb b/spec/unit/braintree/webhook_notification_spec.rb index 3befda63..5bf50a3d 100644 --- a/spec/unit/braintree/webhook_notification_spec.rb +++ b/spec/unit/braintree/webhook_notification_spec.rb @@ -102,7 +102,7 @@ notification.merchant_account.master_merchant_account.id.should == "master_ma_for_my_id" notification.merchant_account.master_merchant_account.status.should == Braintree::MerchantAccount::Status::Suspended notification.message.should == "Credit score is too low" - notification.errors.for(:merchant_account).on(:base).first.code.should == Braintree::ErrorCodes::MerchantAccount::ApplicantDetails::DeclinedOFAC + notification.errors.for(:merchant_account).on(:base).first.code.should == Braintree::ErrorCodes::MerchantAccount::DeclinedOFAC end end