lib/active_merchant/billing/gateways/modern_payments_cim.rb
module ActiveMerchant #:nodoc:
module Billing #:nodoc:
class ModernPaymentsCimGateway < Gateway #:nodoc:
self.test_url = 'https://secure.modpay.com/netservices/test/ModpayTest.asmx'
self.live_url = 'https://secure.modpay.com/ws/modpay.asmx'
LIVE_XMLNS = 'https://secure.modpay.com/ws/'
TEST_XMLNS = 'https://secure.modpay.com/netservices/test/'
self.supported_countries = ['US']
self.supported_cardtypes = %i[visa master american_express discover]
self.homepage_url = 'http://www.modpay.com'
self.display_name = 'Modern Payments'
SUCCESS_MESSAGE = 'Transaction accepted'
FAILURE_MESSAGE = 'Transaction failed'
ERROR_MESSAGE = 'Transaction error'
PAYMENT_METHOD = {
check: 1,
credit_card: 2
}
def initialize(options = {})
requires!(options, :login, :password)
super
end
def create_customer(options = {})
post = {}
add_customer_data(post, options)
add_address(post, options)
commit('CreateCustomer', post)
end
def modify_customer_credit_card(customer_id, credit_card)
raise ArgumentError, 'The customer_id cannot be blank' if customer_id.blank?
post = {}
add_customer_id(post, customer_id)
add_credit_card(post, credit_card)
commit('ModifyCustomerCreditCard', post)
end
def authorize_credit_card_payment(customer_id, amount)
raise ArgumentError, 'The customer_id cannot be blank' if customer_id.blank?
post = {}
add_customer_id(post, customer_id)
add_amount(post, amount)
commit('AuthorizeCreditCardPayment', post)
end
def create_payment(customer_id, amount, options = {})
raise ArgumentError, 'The customer_id cannot be blank' if customer_id.blank?
post = {}
add_customer_id(post, customer_id)
add_amount(post, amount)
add_payment_details(post, options)
commit('CreatePayment', post)
end
private
def add_payment_details(post, options)
post[:pmtDate] = (options[:payment_date] || Time.now.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
post[:pmtType] = PAYMENT_METHOD[options[:payment_method] || :credit_card]
end
def add_amount(post, money)
post[:pmtAmount] = amount(money)
end
def add_customer_id(post, customer_id)
post[:custId] = customer_id
end
def add_customer_data(post, options)
post[:acctNum] = options[:customer]
end
def add_address(post, options)
address = options[:billing_address] || options[:address] || {}
if name = address[:name]
post[:firstName], post[:lastName] = split_names(name)
else
post[:firstName] = address[:first_name]
post[:lastName] = address[:last_name]
end
post[:address] = address[:address1]
post[:city] = address[:city]
post[:state] = address[:state]
post[:zip] = address[:zip]
post[:phone] = address[:phone]
post[:fax] = address[:fax]
post[:email] = options[:email]
end
def add_credit_card(post, credit_card)
post[:ccName] = credit_card.name
post[:ccNum] = credit_card.number
post[:expMonth] = credit_card.month
post[:expYear] = credit_card.year
end
def build_request(action, params)
envelope_obj = { 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/',
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance' }
xml = Builder::XmlMarkup.new indent: 2
xml.instruct!
xml.tag! 'env:Envelope', envelope_obj do
xml.tag! 'env:Body' do
xml.tag! action, { 'xmlns' => xmlns(action) } do
xml.tag! 'clientId', @options[:login]
xml.tag! 'clientCode', @options[:password]
params.each { |key, value| xml.tag! key, value }
end
end
end
xml.target!
end
def xmlns(action)
if test? && action == 'AuthorizeCreditCardPayment'
TEST_XMLNS
else
LIVE_XMLNS
end
end
def url(action)
if test? && action == 'AuthorizeCreditCardPayment'
self.test_url
else
self.live_url
end
end
def commit(action, params)
data = ssl_post(
url(action),
build_request(action, params),
{
'Content-Type' => 'text/xml; charset=utf-8',
'SOAPAction' => "#{xmlns(action)}#{action}"
}
)
response = parse(action, data)
Response.new(
successful?(action, response),
message_from(action, response),
response,
test: test?,
authorization: authorization_from(action, response),
avs_result: { code: response[:avs_code] }
)
end
def authorization_from(action, response)
response[authorization_key(action)]
end
def authorization_key(action)
action == 'AuthorizeCreditCardPayment' ? :trans_id : "#{action.underscore}_result".to_sym
end
def successful?(action, response)
key = authorization_key(action)
if key == :trans_id
response[:approved] == 'true'
else
response[key].to_i > 0
end
end
def message_from(action, response)
if response[:faultcode]
ERROR_MESSAGE
elsif successful?(action, response)
SUCCESS_MESSAGE
else
FAILURE_MESSAGE
end
end
def parse(action, xml)
response = {}
response[:action] = action
xml = REXML::Document.new(xml)
if root = REXML::XPath.first(xml, "//#{action}Response")
root.elements.to_a.each do |node|
parse_element(response, node)
end
elsif root = REXML::XPath.first(xml, '//soap:Fault')
root.elements.to_a.each do |node|
response[node.name.underscore.to_sym] = node.text
end
end
response
end
def parse_element(response, node)
if node.has_elements?
node.elements.each { |e| parse_element(response, e) }
else
response[node.name.underscore.to_sym] = node.text.to_s.strip
end
end
end
end
end