Skip to content

Commit

Permalink
Merge pull request activemerchant#183 from chargify/master
Browse files Browse the repository at this point in the history
Now passing through :email, :customer, and :description from options hash to EwayManagedGateway#store
  • Loading branch information
Tobias Lütke committed Sep 6, 2011
2 parents cf972e7 + 2b85332 commit 72c2c91
Show file tree
Hide file tree
Showing 3 changed files with 238 additions and 14 deletions.
57 changes: 45 additions & 12 deletions lib/active_merchant/billing/gateways/eway_managed.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def store(creditcard, options = {})

add_creditcard(post, creditcard)
add_address(post, billing_address)
add_misc_fields(post, billing_address)
add_misc_fields(post, options)

commit("CreateCustomer", post)
end
Expand All @@ -63,17 +63,30 @@ def update(billing_id, creditcard, options={})
post[:managedCustomerID]=billing_id
add_creditcard(post, creditcard)
add_address(post, billing_address)
add_misc_fields(post, billing_address)
add_misc_fields(post, options)

commit("UpdateCustomer", post)
end

#process payment for given amount from stored CC "ManagedCustomerID = billing_id"
# Process a payment in the given amount against the stored credit card given by billing_id
#
# ==== Parameters
#
# * <tt>money</tt> -- The amount to be purchased as an Integer value in cents.
# * <tt>billing_id</tt> -- The eWay provided card/customer token to charge (managedCustomerID)
# * <tt>options</tt> -- A hash of optional parameters.
#
# ==== Options
#
# * <tt>:order_id</tt> -- The order number, passed to eWay as the "Invoice Reference"
# * <tt>:invoice</tt> -- The invoice number, passed to eWay as the "Invoice Reference" unless :order_id is also given
# * <tt>:description</tt> -- A description of the payment, passed to eWay as the "Invoice Description"
def purchase(money, billing_id, options={})
post = {}
post[:managedCustomerID] = billing_id.to_s
post[:amount]=money

add_invoice(post, options)

commit("ProcessPayment", post)
end

Expand Down Expand Up @@ -102,14 +115,21 @@ def add_address(post, address)
end

def add_misc_fields(post, options)
post[:CustomerRef]=options[:customer_ref].to_s
post[:Title]=options[:title]
post[:Company]=options[:company]
post[:JobDesc]=options[:job_desc]
post[:Email]=options[:email]
post[:URL]=options[:url]
post[:CustomerRef]=options[:billing_address][:customer_ref] || options[:customer]
post[:Title]=options[:billing_address][:title]
post[:Company]=options[:billing_address][:company]
post[:JobDesc]=options[:billing_address][:job_desc]
post[:Email]=options[:billing_address][:email] || options[:email]
post[:URL]=options[:billing_address][:url]
post[:Comments]=options[:description]
end

def add_invoice(post, options)
post[:invoiceReference] = options[:order_id] || options[:invoice]
post[:invoiceDescription] = options[:description]
end


# add credit card details to be stored by eway. NOTE eway requires "title" field
def add_creditcard(post, creditcard)
post[:CCNumber] = creditcard.number
Expand Down Expand Up @@ -188,7 +208,12 @@ def commit(action, post)
# Where we build the full SOAP 1.2 request using builder
def soap_request(arguments, action)
# eWay demands all fields be sent, but contain an empty string if blank
post=default_fields.merge(arguments)
post = case action
when 'ProcessPayment'
default_payment_fields.merge(arguments)
else
default_customer_fields.merge(arguments)
end

xml = Builder::XmlMarkup.new :indent => 2
xml.instruct!
Expand All @@ -211,14 +236,22 @@ def soap_request(arguments, action)
xml.target!
end

def default_fields
def default_customer_fields
hash={}
%w( CustomerRef Title FirstName LastName Company JobDesc Email Address Suburb State PostCode Country Phone Mobile Fax URL Comments CCNumber CCNameOnCard CCExpiryMonth CCExpiryYear ).each do |field|
hash[field.to_sym]=''
end
return hash
end

def default_payment_fields
hash={}
%w( managedCustomerID amount invoiceReference invoiceDescription ).each do |field|
hash[field.to_sym]=''
end
return hash
end

class EwayResponse < Response
# add a method to response so we can easily get the eway token "ManagedCustomerID"
def token
Expand Down
2 changes: 1 addition & 1 deletion test/remote/gateways/remote_eway_managed_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def test_invalid_login
:username => ''
)
assert response = gateway.purchase(@amount, @valid_customer_id, @options)
assert_equal 'Login failed', response.message
assert_equal 'Login failed. ', response.message
assert_failure response
end

Expand Down
193 changes: 192 additions & 1 deletion test/unit/gateways/eway_managed_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ def setup
:phone => '(555)555-5555'
},
:email => '[email protected]',
:order_id => '1000'
:order_id => '1000',
:customer => 'mycustomerref',
:description => 'My Description',
:invoice => 'invoice-4567'
}
end

Expand Down Expand Up @@ -78,6 +81,51 @@ def test_successful_purchase
assert_equal "123456", response.authorization
assert response.test?
end

def test_expected_request_on_purchase
@gateway.expects(:ssl_post).with { |endpoint, data, headers|
# Compare the actual and expected XML documents, by converting them to Hashes first
expected = Hash.from_xml(expected_purchase_request)
actual = Hash.from_xml(data)
expected == actual
}.returns(successful_purchase_response)
@gateway.purchase(@amount, @valid_customer_id, @options)
end

def test_purchase_invoice_reference_comes_from_order_id_or_invoice
options = @options.dup

# invoiceReference == options[:order_id]
options[:order_id] = 'order_id'
options.delete(:invoice)

@gateway.expects(:ssl_post).with { |endpoint, data, headers|
request_hash = Hash.from_xml(data)
request_hash['Envelope']['Body']['ProcessPayment']['invoiceReference'] == 'order_id'
}.returns(successful_purchase_response)
@gateway.purchase(@amount, @valid_customer_id, options)

# invoiceReference == options[:invoice]
options[:invoice] = 'invoice'
options.delete(:order_id)

@gateway.expects(:ssl_post).with { |endpoint, data, headers|
request_hash = Hash.from_xml(data)
request_hash['Envelope']['Body']['ProcessPayment']['invoiceReference'] == 'invoice'
}.returns(successful_purchase_response)
@gateway.purchase(@amount, @valid_customer_id, options)

# invoiceReference == options[:order_id] || options[:invoice]
options[:order_id] = 'order_id'
options[:invoice] = 'invoice'

@gateway.expects(:ssl_post).with { |endpoint, data, headers|
request_hash = Hash.from_xml(data)
request_hash['Envelope']['Body']['ProcessPayment']['invoiceReference'] == 'order_id'
}.returns(successful_purchase_response)
@gateway.purchase(@amount, @valid_customer_id, options)

end

def test_invalid_customer_id
@gateway.expects(:ssl_post).returns(unsuccessful_authorization_response)
Expand All @@ -97,6 +145,84 @@ def test_successful_store
assert_equal "1234567", response.token
assert response.test?
end

def test_expected_request_on_store
@gateway.expects(:ssl_post).with { |endpoint, data, headers|
# Compare the actual and expected XML documents, by converting them to Hashes first
expected = Hash.from_xml(expected_store_request)
actual = Hash.from_xml(data)
expected == actual
}.returns(successful_store_response)
@gateway.store(@credit_card, @options)
end

def test_email_on_store_may_come_from_options_root_or_billing_address
options = @options.dup

# Legacy Behavior
options.delete(:email)
options[:billing_address][:email] = '[email protected]'

@gateway.expects(:ssl_post).with { |endpoint, data, headers|
request_hash = Hash.from_xml(data)
request_hash['Envelope']['Body']['CreateCustomer']['Email'] == '[email protected]'
}.returns(successful_store_response)
@gateway.store(@credit_card, options)

# Desired Behavior
options[:billing_address].delete(:email)
options[:email] = '[email protected]'

@gateway.expects(:ssl_post).with { |endpoint, data, headers|
request_hash = Hash.from_xml(data)
request_hash['Envelope']['Body']['CreateCustomer']['Email'] == '[email protected]'
}.returns(successful_store_response)
@gateway.store(@credit_card, options)

# Precedence given to billing address when email is in both hashes (to support legacy behavior)
options[:billing_address][:email] = '[email protected]'
options[:email] = '[email protected]'

@gateway.expects(:ssl_post).with { |endpoint, data, headers|
request_hash = Hash.from_xml(data)
request_hash['Envelope']['Body']['CreateCustomer']['Email'] == '[email protected]'
}.returns(successful_store_response)
@gateway.store(@credit_card, options)
end

def test_customer_ref_on_store_may_come_from_options_root_or_billing_address
options = @options.dup

# Legacy Behavior
options.delete(:customer)
options[:billing_address][:customer_ref] = 'customer_ref+billing'

@gateway.expects(:ssl_post).with { |endpoint, data, headers|
request_hash = Hash.from_xml(data)
request_hash['Envelope']['Body']['CreateCustomer']['CustomerRef'] == 'customer_ref+billing'
}.returns(successful_store_response)
@gateway.store(@credit_card, options)

# Desired Behavior
options[:billing_address].delete(:customer_ref)
options[:customer] = 'customer_ref+root'

@gateway.expects(:ssl_post).with { |endpoint, data, headers|
request_hash = Hash.from_xml(data)
request_hash['Envelope']['Body']['CreateCustomer']['CustomerRef'] == 'customer_ref+root'
}.returns(successful_store_response)
@gateway.store(@credit_card, options)

# Precedence given to billing address when customer_ref is in both hashes (to support legacy behavior)
options[:billing_address][:customer_ref] = 'customer_ref+billing'
options[:customer] = 'customer_ref+root'

@gateway.expects(:ssl_post).with { |endpoint, data, headers|
request_hash = Hash.from_xml(data)
request_hash['Envelope']['Body']['CreateCustomer']['CustomerRef'] == 'customer_ref+billing'
}.returns(successful_store_response)
@gateway.store(@credit_card, options)
end

def test_sucessful_update
@gateway.expects(:ssl_post).returns(successful_update_response)
Expand Down Expand Up @@ -164,5 +290,70 @@ def successful_update_response
</soap12:Envelope>
XML
end

# Documented here: https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?op=CreateCustomer
def expected_store_request
<<-XML
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Header>
<eWAYHeader xmlns="https://www.eway.com.au/gateway/managedpayment">
<eWAYCustomerID>login</eWAYCustomerID>
<Username>username</Username>
<Password>password</Password>
</eWAYHeader>
</soap12:Header>
<soap12:Body>
<CreateCustomer xmlns="https://www.eway.com.au/gateway/managedpayment">
<Title>Mr.</Title>
<FirstName>#{@credit_card.first_name}</FirstName>
<LastName>#{@credit_card.last_name}</LastName>
<Address>#{@options[:billing_address][:address1]}</Address>
<Suburb>#{@options[:billing_address][:city]}</Suburb>
<State>#{@options[:billing_address][:state]}</State>
<Company>#{@options[:billing_address][:company]}</Company>
<PostCode>#{@options[:billing_address][:zip]}</PostCode>
<Country>#{@options[:billing_address][:country]}</Country>
<Email>#{@options[:email]}</Email>
<Fax></Fax>
<Phone>#{@options[:billing_address][:phone]}</Phone>
<Mobile></Mobile>
<CustomerRef>#{@options[:customer]}</CustomerRef>
<JobDesc></JobDesc>
<Comments>#{@options[:description]}</Comments>
<URL></URL>
<CCNumber>#{@credit_card.number}</CCNumber>
<CCNameOnCard>#{@credit_card.first_name} #{@credit_card.last_name}</CCNameOnCard>
<CCExpiryMonth>#{sprintf("%.2i", @credit_card.month)}</CCExpiryMonth>
<CCExpiryYear>#{sprintf("%.4i", @credit_card.year)[-2..-1]}</CCExpiryYear>
</CreateCustomer>
</soap12:Body>
</soap12:Envelope>
XML
end

# Documented here: https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?op=CreateCustomer
def expected_purchase_request
<<-XML
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Header>
<eWAYHeader xmlns="https://www.eway.com.au/gateway/managedpayment">
<eWAYCustomerID>login</eWAYCustomerID>
<Username>username</Username>
<Password>password</Password>
</eWAYHeader>
</soap12:Header>
<soap12:Body>
<ProcessPayment xmlns="https://www.eway.com.au/gateway/managedpayment">
<managedCustomerID>#{@valid_customer_id}</managedCustomerID>
<amount>#{@amount}</amount>
<invoiceReference>#{@options[:order_id] || @options[:invoice]}</invoiceReference>
<invoiceDescription>#{@options[:description]}</invoiceDescription>
</ProcessPayment>
</soap12:Body>
</soap12:Envelope>
XML
end

end

0 comments on commit 72c2c91

Please sign in to comment.