forked from activemerchant/active_merchant
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added new gateway for Merchant eSolutions gateway (ActiveMerchant::Bi…
…lling::MerchantESolutionsGateway) initial implementation of purchase(), authorize(), capture(), and store() operations
- Loading branch information
Zac Williams
committed
Sep 29, 2008
1 parent
9e7407d
commit 9313363
Showing
3 changed files
with
256 additions
and
0 deletions.
There are no files selected for viewing
150 changes: 150 additions & 0 deletions
150
lib/active_merchant/billing/gateways/merchant_e_solutions.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
module ActiveMerchant #:nodoc: | ||
module Billing #:nodoc: | ||
class MerchantESolutionsGateway < Gateway | ||
|
||
TEST_URL = 'https://test.merchante-solutions.com/mes-api/tridentApi' | ||
LIVE_URL = 'https://api.merchante-solutions.com/mes-api/tridentApi' | ||
|
||
# The countries the gateway supports merchants from as 2 digit ISO country codes | ||
self.supported_countries = ['US'] | ||
|
||
# The card types supported by the payment gateway | ||
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :jcb] | ||
|
||
# The homepage URL of the gateway | ||
self.homepage_url = 'http://www.merchante-solutions.com/' | ||
|
||
# The name of the gateway | ||
self.display_name = 'Merchant e-Solutions' | ||
|
||
def initialize(options = {}) | ||
#requires!(options, :login, :password) | ||
@options = options | ||
super | ||
end | ||
|
||
def authorize(money, creditcard_or_card_id, options = {}) | ||
post = {} | ||
add_invoice(post, options) | ||
add_payment_source(post, creditcard_or_card_id, options) | ||
add_address(post, options) | ||
commit('P', money, post) | ||
end | ||
|
||
def purchase(money, creditcard_or_card_id, options = {}) | ||
post = {} | ||
add_invoice(post, options) | ||
add_payment_source(post, creditcard_or_card_id, options) | ||
add_address(post, options) | ||
commit('D', money, post) | ||
end | ||
|
||
def capture(money, authorization, options = {}) | ||
post ={} | ||
post[:transaction_id] = authorization | ||
commit('S', money, post) | ||
end | ||
|
||
def store(creditcard, options = {}) | ||
post = {} | ||
add_creditcard(post, creditcard, options) | ||
commit('T', nil, post) | ||
end | ||
|
||
# def unstore(card_id) | ||
# post = {} | ||
# post[:card_id] = card_id | ||
# commit('X', nil, post) | ||
# end | ||
|
||
# def credit(money, creditcard_or_card_id, options = {}) | ||
# post ={} | ||
# add_payment_source(post, creditcard_or_card_id, options) | ||
# commit('C', money, post) | ||
# end | ||
|
||
# def void | ||
# end | ||
|
||
private | ||
|
||
def add_address(post, options) | ||
if address = options[:billing_address] || options[:address] | ||
post[:cardholder_street_address] = address[:address1].to_s.gsub(/[^\w.]/, '+') | ||
post[:cardholder_zip] = address[:zip].to_s | ||
end | ||
end | ||
|
||
def add_invoice(post, options) | ||
if options.has_key? :order_id | ||
post[:invoice_number] = options[:order_id].to_s.gsub(/[^\w.]/, '') | ||
end | ||
end | ||
|
||
def add_payment_source(post, creditcard_or_card_id, options) | ||
if creditcard_or_card_id.is_a?(String) | ||
# using stored card | ||
post[:card_id] = creditcard_or_card_id | ||
else | ||
# card info is provided | ||
add_creditcard(post, creditcard_or_card_id, options) | ||
end | ||
end | ||
|
||
def add_creditcard(post, creditcard, options) | ||
post[:card_number] = creditcard.number | ||
post[:cvv2] = creditcard.verification_value if creditcard.verification_value? | ||
post[:card_exp_date] = expdate(creditcard) | ||
end | ||
|
||
def parse(body) | ||
results = {} | ||
body.split(/&/).each do |pair| | ||
key,val = pair.split(/=/) | ||
results[key] = val | ||
end | ||
results | ||
end | ||
|
||
def commit(action, money, parameters) | ||
|
||
url = test? ? TEST_URL : LIVE_URL | ||
parameters[:transaction_amount] = amount(money) if money unless action == 'V' | ||
|
||
response = parse( ssl_post(url, post_data(action,parameters)) ) | ||
|
||
Response.new(response["error_code"] == "000", message_from(response), response, | ||
:authorization => response["auth_code"], | ||
:test => test?, | ||
:cvv_result => response["cvv2_result"], | ||
:avs_result => { :code => response["avs_result"] } | ||
) | ||
end | ||
|
||
def expdate(creditcard) | ||
year = sprintf("%.4i", creditcard.year) | ||
month = sprintf("%.2i", creditcard.month) | ||
"#{month}#{year[-2..-1]}" | ||
end | ||
|
||
def message_from(response) | ||
if response["error_code"] == "000" | ||
"This transaction has been approved" | ||
else | ||
response["auth_response_text"] | ||
end | ||
end | ||
|
||
def post_data(action, parameters = {}) | ||
post = {} | ||
post[:profile_id] = @options[:login] | ||
post[:profile_key] = @options[:password] | ||
post[:transaction_type] = action if action | ||
|
||
request = post.merge(parameters).map {|key,value| "#{key}=#{CGI.escape(value.to_s)}"}.join("&") | ||
request | ||
end | ||
end | ||
end | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
require File.dirname(__FILE__) + '/../test_helper' | ||
|
||
class RemoteMerchantESolutionTest < Test::Unit::TestCase | ||
|
||
|
||
def setup | ||
@gateway = MerchantESolutionsGateway.new(fixtures(:merchant_esolution)) | ||
|
||
@amount = 100 | ||
@credit_card = credit_card('4000100011112224') | ||
@declined_card = credit_card('4000300011112220') | ||
|
||
@options = { | ||
:order_id => '1', | ||
:billing_address => address, | ||
:description => 'Store Purchase' | ||
} | ||
end | ||
|
||
def test_successful_purchase | ||
assert response = @gateway.purchase(@amount, @credit_card, @options) | ||
assert_success response | ||
assert_equal 'REPLACE WITH SUCCESS MESSAGE', response.message | ||
end | ||
|
||
def test_unsuccessful_purchase | ||
assert response = @gateway.purchase(@amount, @declined_card, @options) | ||
assert_failure response | ||
assert_equal 'REPLACE WITH FAILED PURCHASE MESSAGE', response.message | ||
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 | ||
assert capture = @gateway.capture(amount, auth.authorization) | ||
assert_success capture | ||
end | ||
|
||
def test_failed_capture | ||
assert response = @gateway.capture(@amount, '') | ||
assert_failure response | ||
assert_equal 'REPLACE WITH GATEWAY FAILURE MESSAGE', response.message | ||
end | ||
|
||
def test_invalid_login | ||
gateway = MerchantESolutionsGateway.new( | ||
:login => '', | ||
:password => '' | ||
) | ||
assert response = gateway.purchase(@amount, @credit_card, @options) | ||
assert_failure response | ||
assert_equal 'REPLACE WITH FAILURE MESSAGE', response.message | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
require File.dirname(__FILE__) + '/../../test_helper' | ||
|
||
class MerchantESolutionTest < Test::Unit::TestCase | ||
def setup | ||
@gateway = MerchantESolutionsGateway.new( | ||
:login => 'login', | ||
:password => 'password' | ||
) | ||
|
||
@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_instance_of | ||
assert_success response | ||
|
||
# Replace with authorization number from the successful response | ||
assert_equal '', response.authorization | ||
assert response.test? | ||
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? | ||
end | ||
|
||
private | ||
|
||
# Place raw successful response from gateway here | ||
def successful_purchase_response | ||
end | ||
|
||
# Place raw failed response from gateway here | ||
def failed_purcahse_response | ||
end | ||
end |