Skip to content

Commit

Permalink
Ezic: Add gateway
Browse files Browse the repository at this point in the history
  • Loading branch information
duff committed Apr 23, 2015
1 parent 456cf85 commit dbc710f
Show file tree
Hide file tree
Showing 7 changed files with 477 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Expand Up @@ -5,6 +5,7 @@
* Braintree: Add service_fee_amount option [duff]
* SecureNet: Allow shipping_address[:name] [duff]
* MonerisUS: Add verify [mrezentes]
* Ezic: Add gateway [duff]

== Version 1.48.0 (April 8, 2015)

Expand Down
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -115,6 +115,7 @@ The [ActiveMerchant Wiki](http://github.com/Shopify/active_merchant/wikis) conta
* [eWAY](http://www.eway.com.au/) - AU, NZ, GB
* [eWAY Rapid](http://www.eway.com.au/) - AU, NZ, GB, SG
* [E-xact](http://www.e-xact.com) - CA, US
* [Ezic](http://www.ezic.com/) - AU, CA, CN, FR, DE, GI, IL, MT, MU, MX, NL, NZ, PA, PH, RU, SG, KR, ES, KN, GB
* [Fat Zebra](https://www.fatzebra.com.au/) - AU
* [Federated Canada](http://www.federatedcanada.com/) - CA
* [Finansbank WebPOS](https://www.fbwebpos.com/) - US, TR
Expand Down
1 change: 1 addition & 0 deletions lib/active_merchant/billing/gateways/authorize_net.rb
Expand Up @@ -486,6 +486,7 @@ def fraud_review?(response)
(response[:response_code] == FRAUD_REVIEW)
end


def using_live_gateway_in_test_mode?(response)
!test? && response[:test_request] == "1"
end
Expand Down
193 changes: 193 additions & 0 deletions lib/active_merchant/billing/gateways/ezic.rb
@@ -0,0 +1,193 @@
module ActiveMerchant
module Billing
class EzicGateway < Gateway
self.live_url = 'https://secure-dm3.ezic.com/gw/sas/direct3.2'

self.supported_countries = %w(AU CA CN FR DE GI IL MT MU MX NL NZ PA PH RU SG KR ES KN GB)
self.default_currency = 'USD'
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb, :diners_club]

self.homepage_url = 'http://www.ezic.com/'
self.display_name = 'Ezic'

def initialize(options={})
requires!(options, :account_id)
super
end

def purchase(money, payment, options={})
post = {}

add_account_id(post)
add_invoice(post, money, options)
add_payment(post, payment)
add_customer_data(post, options)

commit("S", post)
end

def authorize(money, payment, options={})
post = {}

add_account_id(post)
add_invoice(post, money, options)
add_payment(post, payment)
add_customer_data(post, options)

commit("A", post)
end

def capture(money, authorization, options={})
post = {}

add_account_id(post)
add_invoice(post, money, options)
add_authorization(post, authorization)
add_pay_type(post)

commit("D", post)
end

def refund(money, authorization, options={})
post = {}

add_account_id(post)
add_invoice(post, money, options)
add_authorization(post, authorization)
add_pay_type(post)

commit("R", post)
end

def verify(credit_card, options={})
authorize(100, credit_card, options)
end

def supports_scrubbing?
true
end

def scrub(transcript)
transcript.
gsub(%r((card_number=)\w+), '\1[FILTERED]').
gsub(%r((card_cvv2=)\w+), '\1[FILTERED]')
end

private

def add_account_id(post)
post[:account_id] = @options[:account_id]
end

def add_addresses(post, options)
add_billing_address(post, options)
add_shipping_address(post, options)
end

def add_billing_address(post, options)
address = options[:billing_address] || {}

if address[:name]
names = address[:name].split
post[:bill_name2] = names.pop
post[:bill_name1] = names.join(" ")
end

post[:bill_street] = address[:address1] if address[:address1]
post[:bill_city] = address[:city] if address[:city]
post[:bill_state] = address[:state] if address[:state]
post[:bill_zip] = address[:zip] if address[:zip]
post[:bill_country] = address[:country] if address[:country]
post[:cust_phone] = address[:phone] if address[:phone]
end

def add_shipping_address(post, options)
address = options[:shipping_address] || {}

if address[:name]
names = address[:name].split
post[:ship_name2] = names.pop
post[:ship_name1] = names.join(" ")
end

post[:ship_street] = address[:address1] if address[:address1]
post[:ship_city] = address[:city] if address[:city]
post[:ship_state] = address[:state] if address[:state]
post[:ship_zip] = address[:zip] if address[:zip]
post[:ship_country] = address[:country] if address[:country]
end

def add_customer_data(post, options)
post[:cust_ip] = options[:ip] if options[:ip]
post[:cust_email] = options[:email] if options[:email]
add_addresses(post, options)
end

def add_invoice(post, money, options)
post[:amount] = amount(money)
post[:description] = options[:description] if options[:description]
end

def add_payment(post, payment)
add_pay_type(post)
post[:card_number] = payment.number
post[:card_cvv2] = payment.verification_value
post[:card_expire] = expdate(payment)
end

def add_authorization(post, authorization)
post[:orig_id] = authorization
end

def add_pay_type(post)
post[:pay_type] = "C"
end

def parse(body)
CGI::parse(body).inject({}) { |hash, (key, value)| hash[key] = value.first; hash }
end

def commit(transaction_type, parameters)
parameters[:tran_type] = transaction_type

begin
response = parse(ssl_post(live_url, post_data(parameters), headers))
Response.new(
success_from(response),
message_from(response),
response,
authorization: authorization_from(response),
avs_result: AVSResult.new(code: response["avs_code"]),
cvv_result: CVVResult.new(response["cvv2_code"]),
test: test?
)
rescue ResponseError => e
Response.new(false, e.response.message)
end
end

def success_from(response)
response["status_code"] == "1" || response["status_code"] == "T"
end

def message_from(response)
response["auth_msg"]
end

def authorization_from(response)
response["trans_id"]
end

def post_data(parameters = {})
parameters.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join("&")
end

def headers
{
"User-Agent" => "ActiveMerchantBindings/#{ActiveMerchant::VERSION}",
}
end
end

end
end
4 changes: 4 additions & 0 deletions test/fixtures.yml
Expand Up @@ -201,6 +201,10 @@ exact:
login: "A00427-01"
password: testus

# Working credentials, no need to replace
ezic:
account_id: "120536457270"

# Working credentials, no need to replace
fat_zebra:
username: TEST
Expand Down
110 changes: 110 additions & 0 deletions test/remote/gateways/remote_ezic_test.rb
@@ -0,0 +1,110 @@
require 'test_helper'

class RemoteEzicTest < Test::Unit::TestCase
def setup
@gateway = EzicGateway.new(fixtures(:ezic))

@amount = 100
@failed_amount = 19088
@credit_card = credit_card('4000100011112224')

@options = {
order_id: '1',
billing_address: address,
description: 'Store Purchase'
}
end

def test_successful_purchase
response = @gateway.purchase(@amount, @credit_card, @options)
assert_success response
assert_equal "TEST APPROVED", response.message
end

def test_failed_purchase
response = @gateway.purchase(@failed_amount, @credit_card, @options)
assert_failure response
assert_equal "TEST DECLINED", response.message
end

def test_successful_authorize_and_capture
auth = @gateway.authorize(@amount, @credit_card, @options)
assert_success auth

assert capture = @gateway.capture(@amount, auth.authorization)
assert_success capture
assert_equal "TEST CAPTURED", capture.message
end

def test_failed_authorize
response = @gateway.authorize(@failed_amount, @credit_card, @options)
assert_failure response
assert_equal "TEST DECLINED", response.message
end

def test_failed_capture
auth = @gateway.authorize(@amount, @credit_card, @options)
assert_success auth

assert capture = @gateway.capture(@amount+30, auth.authorization)
assert_failure capture
assert_match /Settlement amount cannot exceed authorized amount/, capture.message
end

def test_successful_refund
purchase = @gateway.purchase(@amount, @credit_card, @options)
assert_success purchase

assert refund = @gateway.refund(@amount, purchase.authorization)
assert_success refund
assert_equal "TEST RETURNED", refund.message
end

def test_partial_refund
purchase = @gateway.purchase(@amount, @credit_card, @options)
assert_success purchase

assert refund = @gateway.refund(@amount-1, purchase.authorization)
assert_success refund
assert_equal "TEST RETURNED", refund.message
assert_equal "-0.99", refund.params["settle_amount"]
end

def test_failed_refund
purchase = @gateway.purchase(@amount, @credit_card, @options)
assert_success purchase

assert refund = @gateway.refund(@amount + 49, purchase.authorization)
assert_failure refund
assert_match /Amount of refunds exceed original sale/, refund.message
end

def test_successful_verify
response = @gateway.verify(@credit_card, @options)
assert_success response
assert_equal "TEST APPROVED", response.message
end

def test_failed_verify
response = @gateway.verify(credit_card(""), @options)
assert_failure response
assert_match %r{Missing card or check number}, response.message
end

def test_transcript_scrubbing
transcript = capture_transcript(@gateway) do
@gateway.purchase(@amount, @credit_card, @options)
end
transcript = @gateway.scrub(transcript)

assert_scrubbed(@credit_card.number, transcript)
assert_scrubbed(@credit_card.verification_value, transcript)
end

def test_invalid_login
gateway = EzicGateway.new(account_id: '11231')
response = gateway.purchase(@amount, @credit_card, @options)
assert_failure response
assert_match /Invalid account number/, response.message
end
end

0 comments on commit dbc710f

Please sign in to comment.