Skip to content

Commit

Permalink
Add Merchant One Gateway
Browse files Browse the repository at this point in the history
  • Loading branch information
coteyr authored and Caleb Simpson committed Jun 24, 2013
1 parent b5b662e commit 0f4d9fc
Show file tree
Hide file tree
Showing 4 changed files with 245 additions and 0 deletions.
108 changes: 108 additions & 0 deletions lib/active_merchant/billing/gateways/merchant_one.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
module ActiveMerchant #:nodoc:
module Billing #:nodoc:
class MerchantOneGateway < Gateway

class MerchantOneSslConnection < ActiveMerchant::Connection
def configure_ssl(http)
super(http)
http.use_ssl = true
http.ssl_version = :SSLv3
end
end

BASE_URL = 'https://secure.merchantonegateway.com/api/transact.php'

self.supported_countries = ['US']
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
self.homepage_url = 'http://merchantone.com/'
self.display_name = 'Merchant One Gateway'
self.money_format = :dollars

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

def authorize(money, creditcard, options = {})
post = {}
add_customer_data(post, options)
add_creditcard(post, creditcard)
add_address(post, creditcard, options)
add_customer_data(post, options)
add_amount(post, money, options)
commit('auth', money, post)
end

def purchase(money, creditcard, options = {})
post = {}
add_customer_data(post, options)
add_creditcard(post, creditcard)
add_address(post, creditcard, options)
add_customer_data(post, options)
add_amount(post, money, options)
commit('sale', money, post)
end

def capture(money, authorization, options = {})
post = {}
post.merge!({transactionid: authorization})
add_amount(post, money, options)
commit('capture', money, post)
end

def new_connection(endpoint)
MerchantOneSslConnection.new(endpoint)
end

private

def add_customer_data(post, options)
post['firstname'] = options[:billing_address][:first_name]
post['lastname'] = options[:billing_address][:last_name]
end

def add_amount(post, money, options)
post['amount'] = amount(money)
end

def add_address(post, creditcard, options)
post['address1'] = options[:billing_address][:address1]
post['city'] = options[:billing_address][:city]
post['state'] = options[:billing_address][:state]
post['zip'] = options[:billing_address][:zip]
post['country'] = options[:billing_address][:country]
end

def add_creditcard(post, creditcard)
post['cvv'] = creditcard.verification_value
post['ccnumber'] = creditcard.number
post['ccexp'] = "#{sprintf("%02d", creditcard.month)}#{"#{creditcard.year}"[-2, 2]}"
end

def commit(action, money, parameters={})
parameters['username'] = @options[:username]
parameters['password'] = @options[:password]
parse(ssl_post(BASE_URL,post_data(action, parameters)))
end

def post_data(action, parameters = {})
parameters.merge!({type: action})
ret = ""
for key in parameters.keys
ret += "#{key}=#{CGI.escape(parameters[key].to_s)}"
if key != parameters.keys.last
ret += "&"
end
end
ret.to_s
end

def parse(data)
responses = Hash[URI::decode_www_form(data)]
response = Response.new(responses["response"].to_i == 1, responses["responsetext"], responses, test: test?, authorization: responses["transactionid"])
response
end
end
end
end

4 changes: 4 additions & 0 deletions test/fixtures.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,10 @@ merchant_esolutions:
login: "94100008043900000004"
password: "gvQzgKXOTEoDzpzJzROrQQzoKLaEqxjf"

merchant_one:
username: 'demo'
password: 'password'

merchant_ware:
login:
password:
Expand Down
64 changes: 64 additions & 0 deletions test/remote/gateways/remote_merchant_one_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
require 'test_helper'

class RemoteMerchantOneTest < Test::Unit::TestCase

def setup
@gateway = MerchantOneGateway.new(fixtures(:merchant_one))

@amount = 10000
@credit_card = credit_card('4111111111111111')
@declined_card = credit_card('1111111111111111')

@options = {
:order_id => '1',
:description => 'Store Purchase',
:billing_address => {
name: 'Jim Smith',
address1: '1234 My Street',
address2: 'Apt 1',
city: 'Tampa',
state: 'FL',
zip: '33603',
country: 'US',
phone: '(813)421-4331'
}
}
end

def test_successful_purchase
assert response = @gateway.purchase(@amount, @credit_card, @options)
assert_success response
assert_equal 'SUCCESS', response.message
end

def test_unsuccessful_purchase
assert response = @gateway.purchase(@amount, @declined_card, @options)
assert_failure response
assert response.message.include? 'Invalid Credit Card Number'
end

def test_authorize_and_capture
amount = @amount
assert auth = @gateway.authorize(amount, @credit_card, @options)
assert_success auth
assert_equal 'SUCCESS', auth.message
assert auth.authorization, auth.to_yaml
assert capture = @gateway.capture(amount, auth.authorization)
assert_success capture
end

def test_failed_capture
assert response = @gateway.capture(@amount, '')
assert_failure response
end

def test_invalid_login
gateway = MerchantOneGateway.new(
:username => 'nnn',
:password => 'nnn'
)
assert response = gateway.purchase(@amount, @credit_card, @options)
assert_failure response
assert_equal 'Authentication Failed', response.message
end
end
69 changes: 69 additions & 0 deletions test/unit/gateways/merchant_one_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
require 'test_helper'

class MerchantOneTest < Test::Unit::TestCase

def setup
@gateway = MerchantOneGateway.new(fixtures(:merchant_one))
@credit_card = credit_card
@amount = 1000
@options = {
:order_id => '1',
:description => 'Store Purchase',
:billing_address => {
name: 'Jim Smith',
address1: '1234 My Street',
address2: 'Apt 1',
city: 'Tampa',
state: 'FL',
zip: '33603',
country: 'US',
phone: '(813)421-4331'
}
}
end

def test_successful_purchase
@gateway.expects(:ssl_post).returns(successful_purchase_response)
assert response = @gateway.purchase(@amount, @credit_card, @options)
assert_instance_of Response, response
assert_success response
assert_equal "281719471", response.authorization
assert response.test?, response.test.to_s
end

def test_successful_authorize
@gateway.expects(:ssl_post).returns(successful_purchase_response)
assert response = @gateway.authorize(@amount, @credit_card, @options)
assert_instance_of Response, response
assert_success response
assert_equal '281719471', response.authorization
assert response.test?, response.test.to_s
end

def test_successful_capture
@gateway.expects(:ssl_post).returns(successful_purchase_response)
assert response = @gateway.capture(@amount, '281719471', @options)
assert_instance_of Response, response
assert_success response
assert_equal '281719471', response.authorization
assert response.test?, response.test.to_s
end

def test_unsuccessful_request
@gateway.expects(:ssl_post).returns(failed_purchase_response)

assert response = @gateway.purchase(@amount, @credit_card, @options)
assert_failure response
assert response.test?, response.test.to_s
end

private

def successful_purchase_response
"response=1&responsetext=SUCCESS&authcode=123456&transactionid=281719471&avsresponse=&cvvresponse=M&orderid=&type=sale&response_code=100"
end

def failed_purchase_response
"response=3&responsetext=DECLINE&authcode=123456&transactionid=281719471&avsresponse=&cvvresponse=M&orderid=&type=sale&response_code=300"
end
end

0 comments on commit 0f4d9fc

Please sign in to comment.