Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add First Data e4 gateway support #473

Closed
wants to merge 4 commits into from

2 participants

Lazer Catt Nathaniel Talbott
Lazer Catt

This attempts to support the First Data e4 gateway ; they claim to have no plans to stop supporting the old one, but this is what new users typically get. Does not support the 'void' method, due to the void operation requiring the amount.

Chris Sheppard added some commits
Chris Sheppard itransact: make 'void' able to conform to the 2-argument form. Make '…
…credit' into

'refund' and make it work.

Make void able to accept 1 2 or 3 arguments, figuring out which are
options based on what is passed in.  Make 'credit' be 'refund', and have
it work right.  Add a test that exercises 'refund'.  Rename the old
'credit' tests to indicate that they exercise 'void'.
3cb4ac8
Chris Sheppard Fix whitespace. Improve the 'hash-like' test. 72ac201
Chris Sheppard Stop supporting itransact's old 'void' interface entirely. Remove a
useless test.
99b25b8
Chris Sheppard Add support for First Data's e4 gateway.
First Data is no longer offering people the old Global Gateway; new
customers are typically being signed up for the Global Gateway e4
product.  This attempts to support that.  'void' is not supported, as
the amount would have to appear in the authorization string, which just
smells weird.
bfef5c7
Lazer Catt

Unless I misread the travis logs, the errors were environmental (some sort of machine powerdown, not related to this change). Plz advise if otherwise.

Nathaniel Talbott
Collaborator

@frobcode why does this also include changes to the iTransact gateway? Is there a dependency?

Lazer Catt

No, no dependency; that itransact stuff was already merged in. I suspect some sort of fat-fingering on the git side of things with me. Will fix and push a clean branch.

Lazer Catt frobcode closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 19, 2012
  1. itransact: make 'void' able to conform to the 2-argument form. Make '…

    Chris Sheppard authored
    …credit' into
    
    'refund' and make it work.
    
    Make void able to accept 1 2 or 3 arguments, figuring out which are
    options based on what is passed in.  Make 'credit' be 'refund', and have
    it work right.  Add a test that exercises 'refund'.  Rename the old
    'credit' tests to indicate that they exercise 'void'.
Commits on Sep 20, 2012
  1. Fix whitespace. Improve the 'hash-like' test.

    Chris Sheppard authored
Commits on Sep 21, 2012
  1. Stop supporting itransact's old 'void' interface entirely. Remove a

    Chris Sheppard authored
    useless test.
Commits on Oct 2, 2012
  1. Add support for First Data's e4 gateway.

    Chris Sheppard authored
    First Data is no longer offering people the old Global Gateway; new
    customers are typically being signed up for the Global Gateway e4
    product.  This attempts to support that.  'void' is not supported, as
    the amount would have to appear in the authorization string, which just
    smells weird.
This page is out of date. Refresh to see the latest.
223 lib/active_merchant/billing/gateways/firstdata_e4.rb
View
@@ -0,0 +1,223 @@
+module ActiveMerchant #:nodoc:
+ module Billing #:nodoc:
+ class FirstdataE4Gateway < Gateway
+ self.test_url = "https://api.demo.globalgatewaye4.firstdata.com/transaction"
+ self.live_url = "https://api.globalgatewaye4.firstdata.com/transaction"
+
+ TRANSACTIONS = { :sale => "00",
+ :authorization => "01",
+ :capture => "32",
+ :void => "33",
+ :credit => "34" }
+
+
+ POST_HEADERS = { 'Accepts' => 'application/xml',
+ 'Content-Type' => 'application/xml'
+ }
+
+ SUCCESS = "true"
+
+ SENSITIVE_FIELDS = [ :verification_str2, :expiry_date, :card_number ]
+
+ self.supported_cardtypes = [:visa, :master, :american_express, :jcb, :discover]
+ self.supported_countries = ['CA', 'US']
+ self.default_currency = 'USD'
+ self.homepage_url = 'http://www.firstdata.com'
+ self.display_name = 'FirstData E4'
+
+ def initialize(options = {})
+ requires!(options, :login, :password)
+ @options = options
+
+ super
+ end
+
+ def test?
+ @test_mode || Base.gateway_mode == :test
+ end
+
+ def authorize(money, credit_card, options = {})
+ commit(:authorization, build_sale_or_authorization_request(money, credit_card, options))
+ end
+
+ def purchase(money, credit_card, options = {})
+ commit(:sale, build_sale_or_authorization_request(money, credit_card, options))
+ end
+
+ def capture(money, authorization, options = {})
+ commit(:capture, build_capture_or_credit_request(money, authorization, options))
+ end
+
+ # Void is not supported, because we would have to put the amount in the authorization string.
+ #def void(authorization, options = {})
+ # commit(:void, build_capture_or_credit_request(money_from_authorization(authorization), authorization, options))
+ #end
+
+ def credit(money, authorization, options = {})
+ deprecated CREDIT_DEPRECATION_MESSAGE
+ refund(money, authorization, options)
+ end
+
+ def refund(money, authorization, options = {})
+ commit(:credit, build_capture_or_credit_request(money, authorization, options))
+ end
+
+ private
+ def build_request(action, body)
+ xml = Builder::XmlMarkup.new
+
+ xml.instruct!
+ xml.tag! 'Transaction' do
+ add_credentials(xml)
+ add_transaction_type(xml, action)
+ xml << body
+ end
+
+ xml.target!
+ end
+
+ def build_sale_or_authorization_request(money, credit_card, options)
+ xml = Builder::XmlMarkup.new
+
+ add_amount(xml, money)
+ add_credit_card(xml, credit_card)
+ add_customer_data(xml, options)
+ add_invoice(xml, options)
+
+ xml.target!
+ end
+
+ def build_capture_or_credit_request(money, identification, options)
+ xml = Builder::XmlMarkup.new
+
+ add_identification(xml, identification)
+ add_amount(xml, money)
+ add_customer_data(xml, options)
+
+ xml.target!
+ end
+
+ def add_credentials(xml)
+ xml.tag! 'ExactID', @options[:login]
+ xml.tag! 'Password', @options[:password]
+ end
+
+ def add_transaction_type(xml, action)
+ xml.tag! 'Transaction_Type', TRANSACTIONS[action]
+ end
+
+ def add_identification(xml, identification)
+ authorization_num, transaction_tag, amount = identification.split(';')
+
+ xml.tag! 'Authorization_Num', authorization_num
+ xml.tag! 'Transaction_Tag', transaction_tag
+ end
+
+ def add_amount(xml, money)
+ xml.tag! 'DollarAmount', amount(money)
+ end
+
+ def add_credit_card(xml, credit_card)
+ xml.tag! 'Card_Number', credit_card.number
+ xml.tag! 'Expiry_Date', expdate(credit_card)
+ xml.tag! 'CardHoldersName', credit_card.name
+ xml.tag! 'CardType', credit_card.brand
+
+ if credit_card.verification_value?
+ xml.tag! 'CVD_Presence_Ind', '1'
+ xml.tag! 'VerificationStr2', credit_card.verification_value
+ end
+ end
+
+ def add_customer_data(xml, options)
+ xml.tag! 'Customer_Ref', options[:customer] if options[:customer]
+ xml.tag! 'Client_IP', options[:ip] if options[:ip]
+ xml.tag! 'Client_Email', options[:email] if options[:email]
+ end
+
+ def add_address(xml, options)
+ if address = options[:billing_address] || options[:address]
+ xml.tag! 'ZipCode', address[:zip]
+ end
+ end
+
+ def add_invoice(xml, options)
+ xml.tag! 'Reference_No', options[:order_id]
+ xml.tag! 'Reference_3', options[:description] if options[:description]
+ end
+
+ def expdate(credit_card)
+ "#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
+ end
+
+ def commit(action, request)
+ url = test? ? self.test_url : self.live_url
+ begin
+ req = build_request(action, request)
+ #response = parse(ssl_post(url, build_request(action, request), POST_HEADERS))
+ raw_response = ssl_post(url, req, POST_HEADERS)
+ response = parse(raw_response)
+ rescue ResponseError => e
+ response = parse_error(e.response)
+ end
+
+ Response.new(successful?(response), message_from(response), response,
+ :test => test?,
+ :authorization => authorization_from(response),
+ :avs_result => { :code => response[:avs] },
+ :cvv_result => response[:cvv2]
+ )
+ end
+
+ def successful?(response)
+ response[:transaction_approved] == SUCCESS
+ end
+
+ def authorization_from(response)
+ if response[:authorization_num] && response[:transaction_tag]
+ "#{response[:authorization_num]};#{response[:transaction_tag]}"
+ else
+ ''
+ end
+ end
+
+ def message_from(response)
+ if response[:faultcode] && response[:faultstring]
+ response[:faultstring]
+ elsif response[:error_number] != '0'
+ response[:error_description]
+ else
+ result = response[:exact_message] || ''
+ result << " - #{response[:bank_message]}" unless response[:bank_message].blank?
+ result
+ end
+ end
+
+ def parse_error(error)
+ response = {}
+ response[:transaction_approved] = 'false'
+ response[:error_number] = error.code
+ response[:error_description] = error.body
+ response
+ end
+
+ def parse(xml)
+ response = {}
+ xml = REXML::Document.new(xml)
+
+ if root = REXML::XPath.first(xml, "//TransactionResult")
+ parse_elements(response, root)
+ end
+
+ response.delete_if{ |k,v| SENSITIVE_FIELDS.include?(k) }
+ end
+
+ def parse_elements(response, root)
+ root.elements.to_a.each do |node|
+ response[node.name.gsub(/EXact/, 'Exact').underscore.to_sym] = (node.text || '').strip
+ end
+ end
+ end
+ end
+end
+
13 lib/active_merchant/billing/gateways/itransact.rb
View
@@ -196,7 +196,6 @@ def capture(money, authorization, options = {})
# This will reverse a previously run transaction which *has* *not* settled.
#
# ==== Parameters
- # * <tt>money</tt> - This parameter is ignored -- the PaymentClearing gateway does not allow partial voids.
# * <tt>authorization</tt> - The authorization returned from the previous capture or purchase request
# * <tt>options</tt> - A Hash of options, all are optional
#
@@ -209,7 +208,7 @@ def capture(money, authorization, options = {})
# * <tt>:test_mode</tt> - <tt>true</tt> or <tt>false</tt>. Runs the transaction with the 'TestMode' element set to 'TRUE' or 'FALSE'.
#
# ==== Examples
- # response = gateway.void(nil, '9999999999',
+ # response = gateway.void('9999999999',
# :vendor_data => [{'repId' => '1234567'}, {'customerId' => '9886'}],
# :send_customer_email => true,
# :send_merchant_email => true,
@@ -217,7 +216,7 @@ def capture(money, authorization, options = {})
# :test_mode => true
# )
#
- def void(money, authorization, options = {})
+ def void(authorization, options = {})
payload = Nokogiri::XML::Builder.new do |xml|
xml.VoidTransaction {
xml.OperationXID(authorization)
@@ -232,7 +231,7 @@ def void(money, authorization, options = {})
# This will reverse a previously run transaction which *has* settled.
#
# ==== Parameters
- # * <tt>money</tt> - The amount to be credited. Should be <tt>nil</tt> or an Integer amount in cents
+ # * <tt>money</tt> - The amount to be credited. Should be an Integer amount in cents
# * <tt>authorization</tt> - The authorization returned from the previous capture or purchase request
# * <tt>options</tt> - A Hash of options, all are optional
#
@@ -245,7 +244,7 @@ def void(money, authorization, options = {})
# * <tt>:test_mode</tt> - <tt>true</tt> or <tt>false</tt>. Runs the transaction with the 'TestMode' element set to 'TRUE' or 'FALSE'.
#
# ==== Examples
- # response = gateway.credit(nil, '9999999999',
+ # response = gateway.refund(555, '9999999999',
# :vendor_data => [{'repId' => '1234567'}, {'customerId' => '9886'}],
# :send_customer_email => true,
# :send_merchant_email => true,
@@ -253,9 +252,9 @@ def void(money, authorization, options = {})
# :test_mode => true
# )
#
- def credit(money, authorization, options = {})
+ def refund(money, authorization, options = {})
payload = Nokogiri::XML::Builder.new do |xml|
- xml.TranCreditTransaction {
+ xml.TranCredTransaction {
xml.OperationXID(authorization)
add_invoice(xml, money, options)
add_transaction_control(xml, options)
76 test/remote/gateways/remote_firstdata_e4_test.rb
View
@@ -0,0 +1,76 @@
+require 'test_helper'
+
+class RemoteFirstdataE4Test < Test::Unit::TestCase
+
+ def setup
+
+ @gateway = FirstdataE4Gateway.new(fixtures(:firstdata_e4))
+ @credit_card = credit_card
+ @bad_credit_card = credit_card('4111111111111113')
+ @amount = 100
+ @options = {
+ :order_id => '1',
+ :billing_address => address,
+ :description => 'Store Purchase'
+ }
+ end
+
+ def test_successful_purchase
+ assert response = @gateway.purchase(@amount, @credit_card, @options)
+ assert_match /Transaction Normal/, response.message
+ assert_success response
+ end
+
+ def test_unsuccessful_purchase
+ # ask for error 13 response (Amount Error) via dollar amount 5,000 + error
+ @amount = 501300
+ assert response = @gateway.purchase(@amount, @credit_card, @options )
+ assert_match /Transaction Normal/, response.message
+ assert_failure response
+ end
+
+ def test_bad_creditcard_number
+ assert response = @gateway.purchase(@amount, @bad_credit_card, @options)
+ assert_match /Invalid Credit Card/, response.message
+ assert_failure response
+ end
+
+
+ def test_trans_error
+ # ask for error 42 (unable to send trans) as the cents bit...
+ @amount = 500042
+ assert response = @gateway.purchase(@amount, @credit_card, @options )
+ assert_match /Unable to Send Transaction/, response.message # 42 is 'unable to send trans'
+ assert_failure response
+ end
+
+ def test_purchase_and_credit
+ assert purchase = @gateway.purchase(@amount, @credit_card, @options)
+ assert_success purchase
+ assert purchase.authorization
+ assert credit = @gateway.refund(@amount, purchase.authorization)
+ assert_success credit
+ end
+
+ def test_authorize_and_capture
+ assert auth = @gateway.authorize(@amount, @credit_card, @options)
+ assert_success auth
+ assert auth.authorization
+ assert capture = @gateway.capture(@amount, auth.authorization)
+ assert_success capture
+ end
+
+ def test_failed_capture
+ assert response = @gateway.capture(@amount, 'ET838747474;frob')
+ assert_failure response
+ assert_match /Invalid Authorization Number/i, response.message
+ end
+
+ def test_invalid_login
+ gateway = FirstdataE4Gateway.new( :login => "NotARealUser",
+ :password => "NotARealPassword" )
+ assert response = gateway.purchase(@amount, @credit_card, @options)
+ assert_equal "Unauthorized Request (bad or missing credentials).", response.message
+ assert_failure response
+ end
+end
20 test/remote/gateways/remote_itransact_test.rb
View
@@ -56,18 +56,24 @@ def test_authorize_and_void
assert_success response
assert_nil response.message
assert response.authorization
- assert capture = @gateway.void(nil, response.authorization)
+ assert capture = @gateway.void(response.authorization)
assert_success capture
end
- def test_credit
- assert credit = @gateway.void(nil, '9999999999')
- assert_success credit
+ def test_void
+ assert void = @gateway.void('9999999999')
+ assert_success void
end
- def test_credit_partial
- assert credit = @gateway.void(5.55, '9999999999')
- assert_success credit
+# As of Sep 19, 2012, iTransact REQUIRES the total amount for the refund.
+# def test_refund
+# assert refund = @gateway.refund(nil, '9999999999')
+# assert_success refund
+# end
+
+ def test_refund_partial
+ assert refund = @gateway.refund(555, '9999999999') # $5.55 in cents
+ assert_success refund
end
def test_invalid_login
384 test/unit/gateways/firstdata_e4_test.rb
View
@@ -0,0 +1,384 @@
+require 'test_helper'
+require 'yaml'
+
+class FirstdataE4Test < Test::Unit::TestCase
+ def setup
+ @gateway = FirstdataE4Gateway.new( :login => "A00427-01",
+ :password => "testus" )
+
+ @credit_card = credit_card
+ @amount = 100
+ @options = {
+ :order_id => '1',
+ :billing_address => address,
+ :description => 'Store Purchase'
+ }
+ end
+
+ def test_successful_purchase
+ @gateway.expects(:ssl_post).returns(successful_purchase_response)
+ assert response = @gateway.purchase(@amount, @credit_card, @options)
+ assert_success response
+ assert_equal 'ET1700;106625152', response.authorization
+ assert response.test?
+ assert_equal 'Transaction Normal - Approved', response.message
+
+ ExactGateway::SENSITIVE_FIELDS.each{ |f| assert !response.params.has_key?(f.to_s) }
+ end
+
+ def test_successful_refund
+ @gateway.expects(:ssl_post).returns(successful_refund_response)
+ assert response = @gateway.refund(@amount, "123")
+ assert_success response
+ end
+
+ def test_deprecated_credit
+ @gateway.expects(:ssl_post).returns(successful_refund_response)
+
+ assert_deprecation_warning(Gateway::CREDIT_DEPRECATION_MESSAGE, @gateway) do
+ assert response = @gateway.credit(@amount, "123")
+ assert_success response
+ end
+ end
+
+ def test_failed_purchase
+ @gateway.expects(:ssl_post).returns(failed_purchase_response)
+
+ assert response = @gateway.purchase(@amount, @credit_card, @options)
+ assert_instance_of Response, response
+ assert_failure response
+ end
+
+
+ def test_expdate
+ assert_equal( "%02d%s" % [ @credit_card.month,
+ @credit_card.year.to_s[-2..-1] ],
+ @gateway.send(:expdate, @credit_card) )
+ end
+
+ def test_no_transaction
+ @gateway.expects(:ssl_post).raises(no_transaction_response())
+ assert response = @gateway.purchase(100, @credit_card, {})
+ assert_failure response
+ assert response.test?
+ assert_equal 'Malformed request: Transaction Type is missing.', response.message
+ end
+
+ def test_supported_countries
+ assert_equal ['CA', 'US'], ExactGateway.supported_countries
+ end
+
+ def test_supported_card_types
+ assert_equal [:visa, :master, :american_express, :jcb, :discover], ExactGateway.supported_cardtypes
+ end
+
+ def test_avs_result
+ @gateway.expects(:ssl_post).returns(successful_purchase_response)
+
+ response = @gateway.purchase(@amount, @credit_card)
+ assert_equal 'U', response.avs_result['code']
+ end
+
+ def test_cvv_result
+ @gateway.expects(:ssl_post).returns(successful_purchase_response)
+
+ response = @gateway.purchase(@amount, @credit_card)
+ assert_equal 'M', response.cvv_result['code']
+ end
+
+
+ private
+ def successful_purchase_response
+ <<-RESPONSE
+ <?xml version="1.0" encoding="UTF-8"?>
+ <TransactionResult>
+ <ExactID>AD1234-56</ExactID>
+ <Password></Password>
+ <Transaction_Type>00</Transaction_Type>
+ <DollarAmount>47.38</DollarAmount>
+ <SurchargeAmount></SurchargeAmount>
+ <Card_Number>############1111</Card_Number>
+ <Transaction_Tag>106625152</Transaction_Tag>
+ <Track1></Track1>
+ <Track2></Track2>
+ <PAN></PAN>
+ <Authorization_Num>ET1700</Authorization_Num>
+ <Expiry_Date>0913</Expiry_Date>
+ <CardHoldersName>Fred Burfle</CardHoldersName>
+ <VerificationStr1></VerificationStr1>
+ <VerificationStr2>773</VerificationStr2>
+ <CVD_Presence_Ind>0</CVD_Presence_Ind>
+ <ZipCode></ZipCode>
+ <Tax1Amount></Tax1Amount>
+ <Tax1Number></Tax1Number>
+ <Tax2Amount></Tax2Amount>
+ <Tax2Number></Tax2Number>
+ <Secure_AuthRequired></Secure_AuthRequired>
+ <Secure_AuthResult></Secure_AuthResult>
+ <Ecommerce_Flag></Ecommerce_Flag>
+ <XID></XID>
+ <CAVV></CAVV>
+ <CAVV_Algorithm></CAVV_Algorithm>
+ <Reference_No>77</Reference_No>
+ <Customer_Ref></Customer_Ref>
+ <Reference_3></Reference_3>
+ <Language></Language>
+ <Client_IP>1.1.1.10</Client_IP>
+ <Client_Email></Client_Email>
+ <LogonMessage></LogonMessage>
+ <Error_Number>0</Error_Number>
+ <Error_Description> </Error_Description>
+ <Transaction_Error>false</Transaction_Error>
+ <Transaction_Approved>true</Transaction_Approved>
+ <EXact_Resp_Code>00</EXact_Resp_Code>
+ <EXact_Message>Transaction Normal</EXact_Message>
+ <Bank_Resp_Code>100</Bank_Resp_Code>
+ <Bank_Message>Approved</Bank_Message>
+ <Bank_Resp_Code_2></Bank_Resp_Code_2>
+ <SequenceNo>000040</SequenceNo>
+ <AVS>U</AVS>
+ <CVV2>M</CVV2>
+ <Retrieval_Ref_No>3146117</Retrieval_Ref_No>
+ <CAVV_Response></CAVV_Response>
+ <Currency>USD</Currency>
+ <AmountRequested></AmountRequested>
+ <PartialRedemption>false</PartialRedemption>
+ <MerchantName>Friendly Inc DEMO0983</MerchantName>
+ <MerchantAddress>123 King St</MerchantAddress>
+ <MerchantCity>Toronto</MerchantCity>
+ <MerchantProvince>Ontario</MerchantProvince>
+ <MerchantCountry>Canada</MerchantCountry>
+ <MerchantPostal>L7Z 3K8</MerchantPostal>
+ <MerchantURL></MerchantURL>
+ <CTR>=========== TRANSACTION RECORD ==========
+Friendly Inc DEMO0983
+123 King St
+Toronto, ON L7Z 3K8
+Canada
+
+
+TYPE: Purchase
+
+ACCT: Visa $ 47.38 USD
+
+CARD NUMBER : ############1111
+DATE/TIME : 28 Sep 12 07:54:48
+REFERENCE # : 000040 M
+AUTHOR. # : ET120454
+TRANS. REF. : 77
+
+ Approved - Thank You 100
+
+
+Please retain this copy for your records.
+
+Cardholder will pay above amount to card
+issuer pursuant to cardholder agreement.
+=========================================</CTR>
+ </TransactionResult>
+ RESPONSE
+ end
+ def successful_refund_response
+ <<-RESPONSE
+ <?xml version="1.0" encoding="UTF-8"?>
+ <TransactionResult>
+ <ExactID>AD1234-56</ExactID>
+ <Password></Password>
+ <Transaction_Type>34</Transaction_Type>
+ <DollarAmount>123</DollarAmount>
+ <SurchargeAmount></SurchargeAmount>
+ <Card_Number>############1111</Card_Number>
+ <Transaction_Tag>888</Transaction_Tag>
+ <Track1></Track1>
+ <Track2></Track2>
+ <PAN></PAN>
+ <Authorization_Num>ET112216</Authorization_Num>
+ <Expiry_Date>0913</Expiry_Date>
+ <CardHoldersName>Fred Burfle</CardHoldersName>
+ <VerificationStr1></VerificationStr1>
+ <VerificationStr2></VerificationStr2>
+ <CVD_Presence_Ind>0</CVD_Presence_Ind>
+ <ZipCode></ZipCode>
+ <Tax1Amount></Tax1Amount>
+ <Tax1Number></Tax1Number>
+ <Tax2Amount></Tax2Amount>
+ <Tax2Number></Tax2Number>
+ <Secure_AuthRequired></Secure_AuthRequired>
+ <Secure_AuthResult></Secure_AuthResult>
+ <Ecommerce_Flag></Ecommerce_Flag>
+ <XID></XID>
+ <CAVV></CAVV>
+ <CAVV_Algorithm></CAVV_Algorithm>
+ <Reference_No></Reference_No>
+ <Customer_Ref></Customer_Ref>
+ <Reference_3></Reference_3>
+ <Language></Language>
+ <Client_IP>1.1.1.10</Client_IP>
+ <Client_Email></Client_Email>
+ <LogonMessage></LogonMessage>
+ <Error_Number>0</Error_Number>
+ <Error_Description> </Error_Description>
+ <Transaction_Error>false</Transaction_Error>
+ <Transaction_Approved>true</Transaction_Approved>
+ <EXact_Resp_Code>00</EXact_Resp_Code>
+ <EXact_Message>Transaction Normal</EXact_Message>
+ <Bank_Resp_Code>100</Bank_Resp_Code>
+ <Bank_Message>Approved</Bank_Message>
+ <Bank_Resp_Code_2></Bank_Resp_Code_2>
+ <SequenceNo>000041</SequenceNo>
+ <AVS></AVS>
+ <CVV2>I</CVV2>
+ <Retrieval_Ref_No>9176784</Retrieval_Ref_No>
+ <CAVV_Response></CAVV_Response>
+ <Currency>USD</Currency>
+ <AmountRequested></AmountRequested>
+ <PartialRedemption>false</PartialRedemption>
+ <MerchantName>Friendly Inc DEMO0983</MerchantName>
+ <MerchantAddress>123 King St</MerchantAddress>
+ <MerchantCity>Toronto</MerchantCity>
+ <MerchantProvince>Ontario</MerchantProvince>
+ <MerchantCountry>Canada</MerchantCountry>
+ <MerchantPostal>L7Z 3K8</MerchantPostal>
+ <MerchantURL></MerchantURL>
+ <CTR>=========== TRANSACTION RECORD ==========
+Friendly Inc DEMO0983
+123 King St
+Toronto, ON L7Z 3K8
+Canada
+
+
+TYPE: Refund
+
+ACCT: Visa $ 23.69 USD
+
+CARD NUMBER : ############1111
+DATE/TIME : 28 Sep 12 08:31:23
+REFERENCE # : 000041 M
+AUTHOR. # : ET112216
+TRANS. REF. :
+
+ Approved - Thank You 100
+
+
+Please retain this copy for your records.
+
+=========================================</CTR>
+ </TransactionResult>
+ RESPONSE
+ end
+
+ def failed_purchase_response
+ <<-RESPONSE
+ <?xml version="1.0" encoding="UTF-8"?>
+ <TransactionResult>
+ <ExactID>AD1234-56</ExactID>
+ <Password></Password>
+ <Transaction_Type>00</Transaction_Type>
+ <DollarAmount>5013.0</DollarAmount>
+ <SurchargeAmount></SurchargeAmount>
+ <Card_Number>############1111</Card_Number>
+ <Transaction_Tag>555555</Transaction_Tag>
+ <Track1></Track1>
+ <Track2></Track2>
+ <PAN></PAN>
+ <Authorization_Num></Authorization_Num>
+ <Expiry_Date>0911</Expiry_Date>
+ <CardHoldersName>Fred Burfle</CardHoldersName>
+ <VerificationStr1></VerificationStr1>
+ <VerificationStr2>773</VerificationStr2>
+ <CVD_Presence_Ind>0</CVD_Presence_Ind>
+ <ZipCode></ZipCode>
+ <Tax1Amount></Tax1Amount>
+ <Tax1Number></Tax1Number>
+ <Tax2Amount></Tax2Amount>
+ <Tax2Number></Tax2Number>
+ <Secure_AuthRequired></Secure_AuthRequired>
+ <Secure_AuthResult></Secure_AuthResult>
+ <Ecommerce_Flag></Ecommerce_Flag>
+ <XID></XID>
+ <CAVV></CAVV>
+ <CAVV_Algorithm></CAVV_Algorithm>
+ <Reference_No>77</Reference_No>
+ <Customer_Ref></Customer_Ref>
+ <Reference_3></Reference_3>
+ <Language></Language>
+ <Client_IP>1.1.1.10</Client_IP>
+ <Client_Email></Client_Email>
+ <LogonMessage></LogonMessage>
+ <Error_Number>0</Error_Number>
+ <Error_Description> </Error_Description>
+ <Transaction_Error>false</Transaction_Error>
+ <Transaction_Approved>false</Transaction_Approved>
+ <EXact_Resp_Code>00</EXact_Resp_Code>
+ <EXact_Message>Transaction Normal</EXact_Message>
+ <Bank_Resp_Code>605</Bank_Resp_Code>
+ <Bank_Message>Invalid Expiration Date</Bank_Message>
+ <Bank_Resp_Code_2></Bank_Resp_Code_2>
+ <SequenceNo>000033</SequenceNo>
+ <AVS></AVS>
+ <CVV2></CVV2>
+ <Retrieval_Ref_No></Retrieval_Ref_No>
+ <CAVV_Response></CAVV_Response>
+ <Currency>USD</Currency>
+ <AmountRequested></AmountRequested>
+ <PartialRedemption>false</PartialRedemption>
+ <MerchantName>Friendly Inc DEMO0983</MerchantName>
+ <MerchantAddress>123 King St</MerchantAddress>
+ <MerchantCity>Toronto</MerchantCity>
+ <MerchantProvince>Ontario</MerchantProvince>
+ <MerchantCountry>Canada</MerchantCountry>
+ <MerchantPostal>L7Z 3K8</MerchantPostal>
+ <MerchantURL></MerchantURL>
+ <CTR>=========== TRANSACTION RECORD ==========
+Friendly Inc DEMO0983
+123 King St
+Toronto, ON L7Z 3K8
+Canada
+
+
+TYPE: Purchase
+ACCT: Visa $ 5,013.00 USD
+CARD NUMBER : ############1111
+DATE/TIME : 25 Sep 12 07:27:00
+REFERENCE # : 000033 M
+AUTHOR. # :
+TRANS. REF. : 77
+Transaction not approved 605
+Please retain this copy for your records.
+=========================================</CTR>
+ </TransactionResult>
+ RESPONSE
+ end
+
+ def no_transaction_response
+ yamlexcep = <<-RESPONSE
+--- !ruby/exception:ActiveMerchant::ResponseError
+message: Failed with 400 Bad Request
+message:
+response: !ruby/object:Net::HTTPBadRequest
+ body: "Malformed request: Transaction Type is missing."
+ body_exist: true
+ code: "400"
+ header:
+ connection:
+ - Close
+ content-type:
+ - text/html; charset=utf-8
+ server:
+ - Apache
+ date:
+ - Fri, 28 Sep 2012 18:21:37 GMT
+ content-length:
+ - "47"
+ status:
+ - "400"
+ cache-control:
+ - no-cache
+ http_version: "1.1"
+ message: Bad Request
+ read: true
+ socket:
+ RESPONSE
+ YAML.load(yamlexcep)
+ end
+end
Something went wrong with that request. Please try again.