tlconnor-activemerchant 1.20.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +805 -0
- data/CONTRIBUTORS +274 -0
- data/MIT-LICENSE +20 -0
- data/gem-public_cert.pem +20 -0
- data/lib/active_merchant.rb +63 -0
- data/lib/active_merchant/billing.rb +9 -0
- data/lib/active_merchant/billing/avs_result.rb +98 -0
- data/lib/active_merchant/billing/base.rb +57 -0
- data/lib/active_merchant/billing/check.rb +68 -0
- data/lib/active_merchant/billing/credit_card.rb +264 -0
- data/lib/active_merchant/billing/credit_card_formatting.rb +21 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +129 -0
- data/lib/active_merchant/billing/cvv_result.rb +38 -0
- data/lib/active_merchant/billing/expiry_date.rb +34 -0
- data/lib/active_merchant/billing/gateway.rb +170 -0
- data/lib/active_merchant/billing/gateways.rb +18 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +694 -0
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +944 -0
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +308 -0
- data/lib/active_merchant/billing/gateways/beanstream.rb +167 -0
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +388 -0
- data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
- data/lib/active_merchant/billing/gateways/blue_pay.rb +11 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +142 -0
- data/lib/active_merchant/billing/gateways/braintree.rb +17 -0
- data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +308 -0
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +21 -0
- data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +230 -0
- data/lib/active_merchant/billing/gateways/certo_direct.rb +279 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +430 -0
- data/lib/active_merchant/billing/gateways/data_cash.rb +597 -0
- data/lib/active_merchant/billing/gateways/efsnet.rb +235 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +135 -0
- data/lib/active_merchant/billing/gateways/epay.rb +274 -0
- data/lib/active_merchant/billing/gateways/eway.rb +277 -0
- data/lib/active_merchant/billing/gateways/eway_managed.rb +265 -0
- data/lib/active_merchant/billing/gateways/exact.rb +227 -0
- data/lib/active_merchant/billing/gateways/federated_canada.rb +168 -0
- data/lib/active_merchant/billing/gateways/first_pay.rb +177 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +262 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +250 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_rabobank.pem +13 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_response.rb +29 -0
- data/lib/active_merchant/billing/gateways/ideal_rabobank.rb +55 -0
- data/lib/active_merchant/billing/gateways/inspire.rb +221 -0
- data/lib/active_merchant/billing/gateways/instapay.rb +164 -0
- data/lib/active_merchant/billing/gateways/iridium.rb +258 -0
- data/lib/active_merchant/billing/gateways/jetpay.rb +276 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +454 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +157 -0
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +289 -0
- data/lib/active_merchant/billing/gateways/modern_payments.rb +36 -0
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +220 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +239 -0
- data/lib/active_merchant/billing/gateways/nab_transact.rb +244 -0
- data/lib/active_merchant/billing/gateways/net_registry.rb +189 -0
- data/lib/active_merchant/billing/gateways/netaxept.rb +239 -0
- data/lib/active_merchant/billing/gateways/netbilling.rb +168 -0
- data/lib/active_merchant/billing/gateways/nmi.rb +13 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +330 -0
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +277 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +344 -0
- data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +46 -0
- data/lib/active_merchant/billing/gateways/pay_junction.rb +397 -0
- data/lib/active_merchant/billing/gateways/pay_secure.rb +120 -0
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +207 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +261 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +208 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +39 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
- data/lib/active_merchant/billing/gateways/payflow_express.rb +222 -0
- data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +15 -0
- data/lib/active_merchant/billing/gateways/payflow_uk.rb +21 -0
- data/lib/active_merchant/billing/gateways/payment_express.rb +235 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +121 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +354 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +49 -0
- data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +229 -0
- data/lib/active_merchant/billing/gateways/paypal_express_common.rb +25 -0
- data/lib/active_merchant/billing/gateways/paystation.rb +201 -0
- data/lib/active_merchant/billing/gateways/plugnpay.rb +298 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +219 -0
- data/lib/active_merchant/billing/gateways/psl_card.rb +304 -0
- data/lib/active_merchant/billing/gateways/qbms.rb +297 -0
- data/lib/active_merchant/billing/gateways/quantum.rb +282 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +298 -0
- data/lib/active_merchant/billing/gateways/realex.rb +315 -0
- data/lib/active_merchant/billing/gateways/sage.rb +146 -0
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +88 -0
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +116 -0
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +97 -0
- data/lib/active_merchant/billing/gateways/sage_pay.rb +320 -0
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +144 -0
- data/lib/active_merchant/billing/gateways/samurai.rb +121 -0
- data/lib/active_merchant/billing/gateways/secure_net.rb +330 -0
- data/lib/active_merchant/billing/gateways/secure_pay.rb +31 -0
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +280 -0
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +113 -0
- data/lib/active_merchant/billing/gateways/skip_jack.rb +458 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +271 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +244 -0
- data/lib/active_merchant/billing/gateways/trans_first.rb +127 -0
- data/lib/active_merchant/billing/gateways/transax.rb +25 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +423 -0
- data/lib/active_merchant/billing/gateways/usa_epay.rb +23 -0
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1496 -0
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +206 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +233 -0
- data/lib/active_merchant/billing/gateways/viaklix.rb +189 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +318 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +280 -0
- data/lib/active_merchant/billing/integrations.rb +17 -0
- data/lib/active_merchant/billing/integrations/action_view_helper.rb +72 -0
- data/lib/active_merchant/billing/integrations/authorize_net_sim.rb +38 -0
- data/lib/active_merchant/billing/integrations/authorize_net_sim/helper.rb +228 -0
- data/lib/active_merchant/billing/integrations/authorize_net_sim/notification.rb +340 -0
- data/lib/active_merchant/billing/integrations/bogus.rb +23 -0
- data/lib/active_merchant/billing/integrations/bogus/helper.rb +17 -0
- data/lib/active_merchant/billing/integrations/bogus/notification.rb +11 -0
- data/lib/active_merchant/billing/integrations/bogus/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/chronopay.rb +23 -0
- data/lib/active_merchant/billing/integrations/chronopay/helper.rb +120 -0
- data/lib/active_merchant/billing/integrations/chronopay/notification.rb +158 -0
- data/lib/active_merchant/billing/integrations/chronopay/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/direc_pay.rb +41 -0
- data/lib/active_merchant/billing/integrations/direc_pay/helper.rb +200 -0
- data/lib/active_merchant/billing/integrations/direc_pay/notification.rb +76 -0
- data/lib/active_merchant/billing/integrations/direc_pay/return.rb +32 -0
- data/lib/active_merchant/billing/integrations/direc_pay/status.rb +37 -0
- data/lib/active_merchant/billing/integrations/directebanking.rb +47 -0
- data/lib/active_merchant/billing/integrations/directebanking/helper.rb +90 -0
- data/lib/active_merchant/billing/integrations/directebanking/notification.rb +120 -0
- data/lib/active_merchant/billing/integrations/directebanking/return.rb +11 -0
- data/lib/active_merchant/billing/integrations/dwolla.rb +30 -0
- data/lib/active_merchant/billing/integrations/dwolla/helper.rb +31 -0
- data/lib/active_merchant/billing/integrations/dwolla/notification.rb +55 -0
- data/lib/active_merchant/billing/integrations/dwolla/return.rb +38 -0
- data/lib/active_merchant/billing/integrations/e_payment_plans.rb +48 -0
- data/lib/active_merchant/billing/integrations/e_payment_plans/helper.rb +34 -0
- data/lib/active_merchant/billing/integrations/e_payment_plans/notification.rb +84 -0
- data/lib/active_merchant/billing/integrations/gestpay.rb +25 -0
- data/lib/active_merchant/billing/integrations/gestpay/common.rb +42 -0
- data/lib/active_merchant/billing/integrations/gestpay/helper.rb +70 -0
- data/lib/active_merchant/billing/integrations/gestpay/notification.rb +85 -0
- data/lib/active_merchant/billing/integrations/gestpay/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/helper.rb +113 -0
- data/lib/active_merchant/billing/integrations/hi_trust.rb +27 -0
- data/lib/active_merchant/billing/integrations/hi_trust/helper.rb +58 -0
- data/lib/active_merchant/billing/integrations/hi_trust/notification.rb +59 -0
- data/lib/active_merchant/billing/integrations/hi_trust/return.rb +67 -0
- data/lib/active_merchant/billing/integrations/moneybookers.rb +26 -0
- data/lib/active_merchant/billing/integrations/moneybookers/helper.rb +59 -0
- data/lib/active_merchant/billing/integrations/moneybookers/notification.rb +129 -0
- data/lib/active_merchant/billing/integrations/nochex.rb +88 -0
- data/lib/active_merchant/billing/integrations/nochex/helper.rb +68 -0
- data/lib/active_merchant/billing/integrations/nochex/notification.rb +94 -0
- data/lib/active_merchant/billing/integrations/nochex/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/notification.rb +62 -0
- data/lib/active_merchant/billing/integrations/payflow_link.rb +21 -0
- data/lib/active_merchant/billing/integrations/payflow_link/helper.rb +100 -0
- data/lib/active_merchant/billing/integrations/payflow_link/notification.rb +78 -0
- data/lib/active_merchant/billing/integrations/paypal.rb +39 -0
- data/lib/active_merchant/billing/integrations/paypal/helper.rb +119 -0
- data/lib/active_merchant/billing/integrations/paypal/notification.rb +154 -0
- data/lib/active_merchant/billing/integrations/paypal/return.rb +10 -0
- data/lib/active_merchant/billing/integrations/quickpay.rb +21 -0
- data/lib/active_merchant/billing/integrations/quickpay/helper.rb +72 -0
- data/lib/active_merchant/billing/integrations/quickpay/notification.rb +74 -0
- data/lib/active_merchant/billing/integrations/return.rb +42 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form.rb +37 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/encryption.rb +33 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/helper.rb +127 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/notification.rb +210 -0
- data/lib/active_merchant/billing/integrations/sage_pay_form/return.rb +31 -0
- data/lib/active_merchant/billing/integrations/two_checkout.rb +22 -0
- data/lib/active_merchant/billing/integrations/two_checkout/helper.rb +59 -0
- data/lib/active_merchant/billing/integrations/two_checkout/notification.rb +114 -0
- data/lib/active_merchant/billing/integrations/two_checkout/return.rb +17 -0
- data/lib/active_merchant/billing/integrations/valitor.rb +33 -0
- data/lib/active_merchant/billing/integrations/valitor/helper.rb +86 -0
- data/lib/active_merchant/billing/integrations/valitor/notification.rb +13 -0
- data/lib/active_merchant/billing/integrations/valitor/response_fields.rb +97 -0
- data/lib/active_merchant/billing/integrations/valitor/return.rb +13 -0
- data/lib/active_merchant/billing/integrations/world_pay.rb +27 -0
- data/lib/active_merchant/billing/integrations/world_pay/helper.rb +100 -0
- data/lib/active_merchant/billing/integrations/world_pay/notification.rb +160 -0
- data/lib/active_merchant/billing/response.rb +32 -0
- data/lib/active_merchant/version.rb +3 -0
- data/lib/activemerchant.rb +1 -0
- data/lib/support/gateway_support.rb +58 -0
- data/lib/support/outbound_hosts.rb +25 -0
- metadata +411 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
|
2
|
+
module Billing #:nodoc:
|
|
3
|
+
class ModernPaymentsCimGateway < Gateway #:nodoc:
|
|
4
|
+
TEST_URL = "https://secure.modpay.com/netservices/test/ModpayTest.asmx"
|
|
5
|
+
LIVE_URL = 'https://secure.modpay.com/ws/modpay.asmx'
|
|
6
|
+
|
|
7
|
+
LIVE_XMLNS = "https://secure.modpay.com/ws/"
|
|
8
|
+
TEST_XMLNS = "https://secure.modpay.com/netservices/test/"
|
|
9
|
+
|
|
10
|
+
self.supported_countries = ['US']
|
|
11
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
|
12
|
+
self.homepage_url = 'http://www.modpay.com'
|
|
13
|
+
self.display_name = 'Modern Payments'
|
|
14
|
+
|
|
15
|
+
SUCCESS_MESSAGE = "Transaction accepted"
|
|
16
|
+
FAILURE_MESSAGE = "Transaction failed"
|
|
17
|
+
ERROR_MESSAGE = "Transaction error"
|
|
18
|
+
|
|
19
|
+
PAYMENT_METHOD = {
|
|
20
|
+
:check => 1,
|
|
21
|
+
:credit_card => 2
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
def initialize(options = {})
|
|
25
|
+
requires!(options, :login, :password)
|
|
26
|
+
@options = options
|
|
27
|
+
super
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def create_customer(options = {})
|
|
31
|
+
post = {}
|
|
32
|
+
add_customer_data(post, options)
|
|
33
|
+
add_address(post, options)
|
|
34
|
+
|
|
35
|
+
commit('CreateCustomer', post)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def modify_customer_credit_card(customer_id, credit_card)
|
|
39
|
+
raise ArgumentError, "The customer_id cannot be blank" if customer_id.blank?
|
|
40
|
+
|
|
41
|
+
post = {}
|
|
42
|
+
add_customer_id(post, customer_id)
|
|
43
|
+
add_credit_card(post, credit_card)
|
|
44
|
+
|
|
45
|
+
commit('ModifyCustomerCreditCard', post)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def authorize_credit_card_payment(customer_id, amount)
|
|
49
|
+
raise ArgumentError, "The customer_id cannot be blank" if customer_id.blank?
|
|
50
|
+
|
|
51
|
+
post = {}
|
|
52
|
+
add_customer_id(post, customer_id)
|
|
53
|
+
add_amount(post, amount)
|
|
54
|
+
|
|
55
|
+
commit('AuthorizeCreditCardPayment', post)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def create_payment(customer_id, amount, options = {})
|
|
59
|
+
raise ArgumentError, "The customer_id cannot be blank" if customer_id.blank?
|
|
60
|
+
|
|
61
|
+
post = {}
|
|
62
|
+
add_customer_id(post, customer_id)
|
|
63
|
+
add_amount(post, amount)
|
|
64
|
+
add_payment_details(post, options)
|
|
65
|
+
|
|
66
|
+
commit('CreatePayment', post)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
def add_payment_details(post, options)
|
|
71
|
+
post[:pmtDate] = (options[:payment_date] || Time.now.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
72
|
+
post[:pmtType] = PAYMENT_METHOD[options[:payment_method] || :credit_card]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def add_amount(post, money)
|
|
76
|
+
post[:pmtAmount] = amount(money)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def add_customer_id(post, customer_id)
|
|
80
|
+
post[:custId] = customer_id
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def add_customer_data(post, options)
|
|
84
|
+
post[:acctNum] = options[:customer]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def add_address(post, options)
|
|
88
|
+
address = options[:billing_address] || options[:address] || {}
|
|
89
|
+
|
|
90
|
+
if name = address[:name]
|
|
91
|
+
segments = name.split(' ')
|
|
92
|
+
post[:lastName] = segments.pop
|
|
93
|
+
post[:firstName] = segments.join(' ')
|
|
94
|
+
else
|
|
95
|
+
post[:firstName] = address[:first_name]
|
|
96
|
+
post[:lastName] = address[:last_name]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
post[:address] = address[:address1]
|
|
100
|
+
post[:city] = address[:city]
|
|
101
|
+
post[:state] = address[:state]
|
|
102
|
+
post[:zip] = address[:zip]
|
|
103
|
+
post[:phone] = address[:phone]
|
|
104
|
+
post[:fax] = address[:fax]
|
|
105
|
+
post[:email] = options[:email]
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def add_credit_card(post, credit_card)
|
|
109
|
+
post[:ccName] = credit_card.name
|
|
110
|
+
post[:ccNum] = credit_card.number
|
|
111
|
+
post[:expMonth] = credit_card.month
|
|
112
|
+
post[:expYear] = credit_card.year
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def build_request(action, params)
|
|
116
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
|
117
|
+
xml.instruct!
|
|
118
|
+
xml.tag! 'env:Envelope',
|
|
119
|
+
{ 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
|
|
120
|
+
'xmlns:env' => 'http://schemas.xmlsoap.org/soap/envelope/',
|
|
121
|
+
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance' } do
|
|
122
|
+
|
|
123
|
+
xml.tag! 'env:Body' do
|
|
124
|
+
xml.tag! action, { "xmlns" => xmlns(action) } do
|
|
125
|
+
xml.tag! "clientId", @options[:login]
|
|
126
|
+
xml.tag! "clientCode", @options[:password]
|
|
127
|
+
params.each {|key, value| xml.tag! key, value }
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
xml.target!
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def xmlns(action)
|
|
135
|
+
if test? && action == 'AuthorizeCreditCardPayment'
|
|
136
|
+
TEST_XMLNS
|
|
137
|
+
else
|
|
138
|
+
LIVE_XMLNS
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def url(action)
|
|
143
|
+
if test? && action == 'AuthorizeCreditCardPayment'
|
|
144
|
+
TEST_URL
|
|
145
|
+
else
|
|
146
|
+
LIVE_URL
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def commit(action, params)
|
|
151
|
+
data = ssl_post(url(action), build_request(action, params),
|
|
152
|
+
{ 'Content-Type' =>'text/xml; charset=utf-8',
|
|
153
|
+
'SOAPAction' => "#{xmlns(action)}#{action}" }
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
response = parse(action, data)
|
|
157
|
+
Response.new(successful?(action, response), message_from(action, response), response,
|
|
158
|
+
:test => test?,
|
|
159
|
+
:authorization => authorization_from(action, response),
|
|
160
|
+
:avs_result => { :code => response[:avs_code] }
|
|
161
|
+
)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def authorization_from(action, response)
|
|
165
|
+
response[authorization_key(action)]
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def authorization_key(action)
|
|
169
|
+
action == "AuthorizeCreditCardPayment" ? :trans_id : "#{action.underscore}_result".to_sym
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def successful?(action, response)
|
|
173
|
+
key = authorization_key(action)
|
|
174
|
+
|
|
175
|
+
if key == :trans_id
|
|
176
|
+
response[:approved] == "true"
|
|
177
|
+
else
|
|
178
|
+
response[key].to_i > 0
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def message_from(action, response)
|
|
183
|
+
if response[:faultcode]
|
|
184
|
+
ERROR_MESSAGE
|
|
185
|
+
elsif successful?(action, response)
|
|
186
|
+
SUCCESS_MESSAGE
|
|
187
|
+
else
|
|
188
|
+
FAILURE_MESSAGE
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def parse(action, xml)
|
|
193
|
+
response = {}
|
|
194
|
+
response[:action] = action
|
|
195
|
+
|
|
196
|
+
xml = REXML::Document.new(xml)
|
|
197
|
+
if root = REXML::XPath.first(xml, "//#{action}Response")
|
|
198
|
+
root.elements.to_a.each do |node|
|
|
199
|
+
parse_element(response, node)
|
|
200
|
+
end
|
|
201
|
+
elsif root = REXML::XPath.first(xml, "//soap:Fault")
|
|
202
|
+
root.elements.to_a.each do |node|
|
|
203
|
+
response[node.name.underscore.to_sym] = node.text
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
response
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def parse_element(response, node)
|
|
211
|
+
if node.has_elements?
|
|
212
|
+
node.elements.each{|e| parse_element(response, e) }
|
|
213
|
+
else
|
|
214
|
+
response[node.name.underscore.to_sym] = node.text.to_s.strip
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
require 'rexml/document'
|
|
2
|
+
|
|
3
|
+
module ActiveMerchant #:nodoc:
|
|
4
|
+
module Billing #:nodoc:
|
|
5
|
+
|
|
6
|
+
# To learn more about the Moneris gateway, please contact
|
|
7
|
+
# eselectplus@moneris.com for a copy of their integration guide. For
|
|
8
|
+
# information on remote testing, please see "Test Environment Penny Value
|
|
9
|
+
# Response Table", and "Test Environment eFraud (AVS and CVD) Penny
|
|
10
|
+
# Response Values", available at Moneris' {eSelect Plus Documentation
|
|
11
|
+
# Centre}[https://www3.moneris.com/connect/en/documents/index.html].
|
|
12
|
+
class MonerisGateway < Gateway
|
|
13
|
+
TEST_URL = 'https://esqa.moneris.com/gateway2/servlet/MpgRequest'
|
|
14
|
+
LIVE_URL = 'https://www3.moneris.com/gateway2/servlet/MpgRequest'
|
|
15
|
+
|
|
16
|
+
self.supported_countries = ['CA']
|
|
17
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :discover]
|
|
18
|
+
self.homepage_url = 'http://www.moneris.com/'
|
|
19
|
+
self.display_name = 'Moneris'
|
|
20
|
+
|
|
21
|
+
# login is your Store ID
|
|
22
|
+
# password is your API Token
|
|
23
|
+
def initialize(options = {})
|
|
24
|
+
requires!(options, :login, :password)
|
|
25
|
+
@options = { :crypt_type => 7 }.update(options)
|
|
26
|
+
super
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Referred to as "PreAuth" in the Moneris integration guide, this action
|
|
30
|
+
# verifies and locks funds on a customer's card, which then must be
|
|
31
|
+
# captured at a later date.
|
|
32
|
+
#
|
|
33
|
+
# Pass in +order_id+ and optionally a +customer+ parameter.
|
|
34
|
+
def authorize(money, creditcard, options = {})
|
|
35
|
+
debit_commit 'preauth', money, creditcard, options
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# This action verifies funding on a customer's card, and readies them for
|
|
39
|
+
# deposit in a merchant's account.
|
|
40
|
+
#
|
|
41
|
+
# Pass in <tt>order_id</tt> and optionally a <tt>customer</tt> parameter
|
|
42
|
+
def purchase(money, creditcard, options = {})
|
|
43
|
+
debit_commit 'purchase', money, creditcard, options
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# This method retrieves locked funds from a customer's account (from a
|
|
47
|
+
# PreAuth) and prepares them for deposit in a merchant's account.
|
|
48
|
+
#
|
|
49
|
+
# Note: Moneris requires both the order_id and the transaction number of
|
|
50
|
+
# the original authorization. To maintain the same interface as the other
|
|
51
|
+
# gateways the two numbers are concatenated together with a ; separator as
|
|
52
|
+
# the authorization number returned by authorization
|
|
53
|
+
def capture(money, authorization, options = {})
|
|
54
|
+
commit 'completion', crediting_params(authorization, :comp_amount => amount(money))
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Voiding requires the original transaction ID and order ID of some open
|
|
58
|
+
# transaction. Closed transactions must be refunded. Note that the only
|
|
59
|
+
# methods which may be voided are +capture+ and +purchase+.
|
|
60
|
+
#
|
|
61
|
+
# Concatenate your transaction number and order_id by using a semicolon
|
|
62
|
+
# (';'). This is to keep the Moneris interface consistent with other
|
|
63
|
+
# gateways. (See +capture+ for details.)
|
|
64
|
+
def void(authorization, options = {})
|
|
65
|
+
commit 'purchasecorrection', crediting_params(authorization)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Performs a refund. This method requires that the original transaction
|
|
69
|
+
# number and order number be included. Concatenate your transaction
|
|
70
|
+
# number and order_id by using a semicolon (';'). This is to keep the
|
|
71
|
+
# Moneris interface consistent with other gateways. (See +capture+ for
|
|
72
|
+
# details.)
|
|
73
|
+
def credit(money, authorization, options = {})
|
|
74
|
+
deprecated CREDIT_DEPRECATION_MESSAGE
|
|
75
|
+
refund(money, authorization, options)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def refund(money, authorization, options = {})
|
|
79
|
+
commit 'refund', crediting_params(authorization, :amount => amount(money))
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def test?
|
|
83
|
+
@options[:test] || super
|
|
84
|
+
end
|
|
85
|
+
private # :nodoc: all
|
|
86
|
+
|
|
87
|
+
def expdate(creditcard)
|
|
88
|
+
sprintf("%.4i", creditcard.year)[-2..-1] + sprintf("%.2i", creditcard.month)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def debit_commit(commit_type, money, creditcard, options)
|
|
92
|
+
requires!(options, :order_id)
|
|
93
|
+
commit(commit_type, debit_params(money, creditcard, options))
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Common params used amongst the +purchase+ and +authorization+ methods
|
|
97
|
+
def debit_params(money, creditcard, options = {})
|
|
98
|
+
{
|
|
99
|
+
:order_id => options[:order_id],
|
|
100
|
+
:cust_id => options[:customer],
|
|
101
|
+
:amount => amount(money),
|
|
102
|
+
:pan => creditcard.number,
|
|
103
|
+
:expdate => expdate(creditcard),
|
|
104
|
+
:crypt_type => options[:crypt_type] || @options[:crypt_type],
|
|
105
|
+
:cvv => creditcard.verification_value,
|
|
106
|
+
:billing_address => options[:address] || options[:billing_address]
|
|
107
|
+
}
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Common params used amongst the +credit+, +void+ and +capture+ methods
|
|
111
|
+
def crediting_params(authorization, options = {})
|
|
112
|
+
{
|
|
113
|
+
:txn_number => split_authorization(authorization).first,
|
|
114
|
+
:order_id => split_authorization(authorization).last,
|
|
115
|
+
:crypt_type => options[:crypt_type] || @options[:crypt_type]
|
|
116
|
+
}.merge(options)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Splits an +authorization+ param and retrives the order id and
|
|
120
|
+
# transaction number in that order.
|
|
121
|
+
def split_authorization(authorization)
|
|
122
|
+
if authorization.nil? || authorization.empty? || authorization !~ /;/
|
|
123
|
+
raise ArgumentError, 'You must include a valid authorization code (e.g. "1234;567")'
|
|
124
|
+
else
|
|
125
|
+
authorization.split(';')
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def commit(action, parameters = {})
|
|
130
|
+
response = parse(ssl_post(test? ? TEST_URL : LIVE_URL, post_data(action, parameters)))
|
|
131
|
+
|
|
132
|
+
Response.new(successful?(response), message_from(response[:message]), response,
|
|
133
|
+
:test => test?,
|
|
134
|
+
:authorization => authorization_from(response),
|
|
135
|
+
:avs_result => {:code => response[:avs_result_code]},
|
|
136
|
+
:cvv_result => response[:cvd_result_code] && response[:cvd_result_code].last
|
|
137
|
+
)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Generates a Moneris authorization string of the form 'trans_id;receipt_id'.
|
|
141
|
+
def authorization_from(response = {})
|
|
142
|
+
if response[:trans_id] && response[:receipt_id]
|
|
143
|
+
"#{response[:trans_id]};#{response[:receipt_id]}"
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# Tests for a successful response from Moneris' servers
|
|
148
|
+
def successful?(response)
|
|
149
|
+
response[:response_code] &&
|
|
150
|
+
response[:complete] &&
|
|
151
|
+
(0..49).include?(response[:response_code].to_i)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def parse(xml)
|
|
155
|
+
response = { :message => "Global Error Receipt", :complete => false }
|
|
156
|
+
hashify_xml!(xml, response)
|
|
157
|
+
response
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def hashify_xml!(xml, response)
|
|
161
|
+
xml = REXML::Document.new(xml)
|
|
162
|
+
return if xml.root.nil?
|
|
163
|
+
xml.elements.each('//receipt/*') do |node|
|
|
164
|
+
response[node.name.underscore.to_sym] = normalize(node.text)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def post_data(action, parameters = {})
|
|
169
|
+
xml = REXML::Document.new
|
|
170
|
+
root = xml.add_element("request")
|
|
171
|
+
root.add_element("store_id").text = options[:login]
|
|
172
|
+
root.add_element("api_token").text = options[:password]
|
|
173
|
+
transaction = root.add_element(action)
|
|
174
|
+
|
|
175
|
+
# Must add the elements in the correct order
|
|
176
|
+
actions[action].each do |key|
|
|
177
|
+
transaction.add_element(key.to_s).text = parameters[key] unless parameters[key].blank?
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
add_avs_info(transaction, parameters)
|
|
181
|
+
add_cvd_info(transaction, parameters)
|
|
182
|
+
|
|
183
|
+
xml.to_s
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def add_avs_info(transaction, parameters)
|
|
187
|
+
if address = parameters[:billing_address]
|
|
188
|
+
street_number, street_name = address[:address1].split(' ', 2)
|
|
189
|
+
|
|
190
|
+
avs_info = transaction.add_element('avs_info')
|
|
191
|
+
avs_info.add_element('avs_street_number').text = street_number
|
|
192
|
+
avs_info.add_element('avs_street_name').text = street_name
|
|
193
|
+
avs_info.add_element('avs_zipcode').text = address[:zip]
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def add_cvd_info(transaction, parameters)
|
|
198
|
+
if cvd_value = parameters[:cvv]
|
|
199
|
+
cvd_info = transaction.add_element('cvd_info')
|
|
200
|
+
cvd_info.add_element('cvd_indicator').text = '1'
|
|
201
|
+
cvd_info.add_element('cvd_value').text = cvd_value
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def message_from(message)
|
|
206
|
+
return 'Unspecified error' if message.blank?
|
|
207
|
+
message.gsub(/[^\w]/, ' ').split.join(" ").capitalize
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Make a Ruby type out of the response string
|
|
211
|
+
def normalize(field)
|
|
212
|
+
case field
|
|
213
|
+
when "true" then true
|
|
214
|
+
when "false" then false
|
|
215
|
+
when '', "null" then nil
|
|
216
|
+
else field
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
def actions
|
|
221
|
+
{
|
|
222
|
+
"purchase" => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type],
|
|
223
|
+
"preauth" => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type],
|
|
224
|
+
"command" => [:order_id],
|
|
225
|
+
"refund" => [:order_id, :amount, :txn_number, :crypt_type],
|
|
226
|
+
"indrefund" => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type],
|
|
227
|
+
"completion" => [:order_id, :comp_amount, :txn_number, :crypt_type],
|
|
228
|
+
"purchasecorrection" => [:order_id, :txn_number, :crypt_type],
|
|
229
|
+
"cavvpurcha" => [:order_id, :cust_id, :amount, :pan, :expdate, :cav],
|
|
230
|
+
"cavvpreaut" => [:order_id, :cust_id, :amount, :pan, :expdate, :cavv],
|
|
231
|
+
"transact" => [:order_id, :cust_id, :amount, :pan, :expdate, :crypt_type],
|
|
232
|
+
"Batchcloseall" => [],
|
|
233
|
+
"opentotals" => [:ecr_number],
|
|
234
|
+
"batchclose" => [:ecr_number]
|
|
235
|
+
}
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
end
|