aktivemerchant 2.0.0
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.
- checksums.yaml +7 -0
- data/CHANGELOG +1596 -0
- data/CONTRIBUTORS +511 -0
- data/MIT-LICENSE +20 -0
- data/README.md +18 -0
- data/lib/active_merchant.rb +108 -0
- data/lib/active_merchant/billing.rb +13 -0
- data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
- data/lib/active_merchant/billing/avs_result.rb +98 -0
- data/lib/active_merchant/billing/base.rb +72 -0
- data/lib/active_merchant/billing/check.rb +76 -0
- data/lib/active_merchant/billing/compatibility.rb +120 -0
- data/lib/active_merchant/billing/credit_card.rb +352 -0
- data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +160 -0
- data/lib/active_merchant/billing/cvv_result.rb +38 -0
- data/lib/active_merchant/billing/gateway.rb +268 -0
- data/lib/active_merchant/billing/gateways.rb +17 -0
- data/lib/active_merchant/billing/gateways/adyen.rb +209 -0
- data/lib/active_merchant/billing/gateways/alfabank.rb +117 -0
- data/lib/active_merchant/billing/gateways/app55.rb +176 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +419 -0
- data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +417 -0
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +976 -0
- data/lib/active_merchant/billing/gateways/balanced.rb +256 -0
- data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
- data/lib/active_merchant/billing/gateways/banwire.rb +105 -0
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +314 -0
- data/lib/active_merchant/billing/gateways/barclays_epdq_extra_plus.rb +15 -0
- data/lib/active_merchant/billing/gateways/be2bill.rb +131 -0
- data/lib/active_merchant/billing/gateways/beanstream.rb +188 -0
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +393 -0
- data/lib/active_merchant/billing/gateways/beanstream_interac.rb +54 -0
- data/lib/active_merchant/billing/gateways/blue_pay.rb +506 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +140 -0
- data/lib/active_merchant/billing/gateways/borgun.rb +210 -0
- data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
- data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +9 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +515 -0
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +20 -0
- data/lib/active_merchant/billing/gateways/bridge_pay.rb +189 -0
- data/lib/active_merchant/billing/gateways/card_save.rb +23 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +220 -0
- data/lib/active_merchant/billing/gateways/cashnet.rb +191 -0
- data/lib/active_merchant/billing/gateways/cc5.rb +201 -0
- data/lib/active_merchant/billing/gateways/cecabank.rb +229 -0
- data/lib/active_merchant/billing/gateways/certo_direct.rb +278 -0
- data/lib/active_merchant/billing/gateways/checkout.rb +213 -0
- data/lib/active_merchant/billing/gateways/commercegate.rb +143 -0
- data/lib/active_merchant/billing/gateways/conekta.rb +209 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +709 -0
- data/lib/active_merchant/billing/gateways/data_cash.rb +600 -0
- data/lib/active_merchant/billing/gateways/efsnet.rb +219 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +348 -0
- data/lib/active_merchant/billing/gateways/epay.rb +275 -0
- data/lib/active_merchant/billing/gateways/evo_ca.rb +308 -0
- data/lib/active_merchant/billing/gateways/eway.rb +214 -0
- data/lib/active_merchant/billing/gateways/eway_managed.rb +291 -0
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +524 -0
- data/lib/active_merchant/billing/gateways/exact.rb +218 -0
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +173 -0
- data/lib/active_merchant/billing/gateways/federated_canada.rb +160 -0
- data/lib/active_merchant/billing/gateways/finansbank.rb +23 -0
- data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
- data/lib/active_merchant/billing/gateways/first_pay.rb +160 -0
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +355 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +257 -0
- data/lib/active_merchant/billing/gateways/global_transport.rb +183 -0
- data/lib/active_merchant/billing/gateways/hdfc.rb +207 -0
- data/lib/active_merchant/billing/gateways/hps.rb +288 -0
- data/lib/active_merchant/billing/gateways/iats_payments.rb +251 -0
- data/lib/active_merchant/billing/gateways/ideal/ideal_base.rb +246 -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 +66 -0
- data/lib/active_merchant/billing/gateways/inspire.rb +213 -0
- data/lib/active_merchant/billing/gateways/instapay.rb +163 -0
- data/lib/active_merchant/billing/gateways/iridium.rb +457 -0
- data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
- data/lib/active_merchant/billing/gateways/jetpay.rb +275 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +438 -0
- data/lib/active_merchant/billing/gateways/litle.rb +346 -0
- data/lib/active_merchant/billing/gateways/maxipago.rb +197 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +170 -0
- data/lib/active_merchant/billing/gateways/merchant_one.rb +114 -0
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +319 -0
- data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +268 -0
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +195 -0
- data/lib/active_merchant/billing/gateways/mercury.rb +333 -0
- data/lib/active_merchant/billing/gateways/metrics_global.rb +303 -0
- data/lib/active_merchant/billing/gateways/migs.rb +265 -0
- data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
- data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +219 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +309 -0
- data/lib/active_merchant/billing/gateways/moneris_us.rb +291 -0
- data/lib/active_merchant/billing/gateways/money_movers.rb +152 -0
- data/lib/active_merchant/billing/gateways/nab_transact.rb +280 -0
- data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
- data/lib/active_merchant/billing/gateways/netaxept.rb +181 -0
- data/lib/active_merchant/billing/gateways/netbilling.rb +190 -0
- data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
- data/lib/active_merchant/billing/gateways/network_merchants.rb +242 -0
- data/lib/active_merchant/billing/gateways/nmi.rb +256 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +435 -0
- data/lib/active_merchant/billing/gateways/openpay.rb +194 -0
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +313 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +803 -0
- data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +47 -0
- data/lib/active_merchant/billing/gateways/pac_net_raven.rb +207 -0
- data/lib/active_merchant/billing/gateways/pago_facil.rb +122 -0
- data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +261 -0
- data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
- data/lib/active_merchant/billing/gateways/pay_secure.rb +112 -0
- data/lib/active_merchant/billing/gateways/pay_u_latam.rb +462 -0
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +188 -0
- data/lib/active_merchant/billing/gateways/payex.rb +412 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +304 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +209 -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 +224 -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 +353 -0
- data/lib/active_merchant/billing/gateways/paymill.rb +281 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +117 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +670 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +65 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
- data/lib/active_merchant/billing/gateways/paypal_ca.rb +13 -0
- data/lib/active_merchant/billing/gateways/paypal_digital_goods.rb +44 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +264 -0
- data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
- data/lib/active_merchant/billing/gateways/payscout.rb +162 -0
- data/lib/active_merchant/billing/gateways/paystation.rb +199 -0
- data/lib/active_merchant/billing/gateways/payway.rb +207 -0
- data/lib/active_merchant/billing/gateways/pin.rb +197 -0
- data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +216 -0
- data/lib/active_merchant/billing/gateways/psl_card.rb +303 -0
- data/lib/active_merchant/billing/gateways/qbms.rb +292 -0
- data/lib/active_merchant/billing/gateways/quantum.rb +276 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +367 -0
- data/lib/active_merchant/billing/gateways/realex.rb +298 -0
- data/lib/active_merchant/billing/gateways/redsys.rb +391 -0
- data/lib/active_merchant/billing/gateways/sage.rb +175 -0
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +87 -0
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +114 -0
- data/lib/active_merchant/billing/gateways/sage/sage_vault.rb +149 -0
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +102 -0
- data/lib/active_merchant/billing/gateways/sage_pay.rb +398 -0
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +143 -0
- data/lib/active_merchant/billing/gateways/secure_net.rb +252 -0
- data/lib/active_merchant/billing/gateways/secure_pay.rb +201 -0
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +281 -0
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +105 -0
- data/lib/active_merchant/billing/gateways/skip_jack.rb +452 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +283 -0
- data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +247 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +411 -0
- data/lib/active_merchant/billing/gateways/swipe_checkout.rb +157 -0
- data/lib/active_merchant/billing/gateways/tns.rb +227 -0
- data/lib/active_merchant/billing/gateways/trans_first.rb +126 -0
- data/lib/active_merchant/billing/gateways/transax.rb +23 -0
- data/lib/active_merchant/billing/gateways/transnational.rb +10 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +416 -0
- data/lib/active_merchant/billing/gateways/usa_epay.rb +25 -0
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1516 -0
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +254 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +225 -0
- data/lib/active_merchant/billing/gateways/viaklix.rb +183 -0
- data/lib/active_merchant/billing/gateways/vindicia.rb +385 -0
- data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
- data/lib/active_merchant/billing/gateways/wepay.rb +189 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +421 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +331 -0
- data/lib/active_merchant/billing/gateways/worldpay_us.rb +181 -0
- data/lib/active_merchant/billing/model.rb +30 -0
- data/lib/active_merchant/billing/payment_token.rb +21 -0
- data/lib/active_merchant/billing/rails.rb +3 -0
- data/lib/active_merchant/billing/response.rb +91 -0
- data/lib/active_merchant/country.rb +332 -0
- data/lib/active_merchant/empty.rb +20 -0
- data/lib/active_merchant/errors.rb +29 -0
- data/lib/active_merchant/offsite_payments_shim.rb +19 -0
- data/lib/active_merchant/version.rb +3 -0
- data/lib/activemerchant.rb +1 -0
- data/lib/support/gateway_support.rb +71 -0
- data/lib/support/outbound_hosts.rb +25 -0
- data/lib/support/ssl_verify.rb +93 -0
- metadata +400 -0
@@ -0,0 +1,319 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class MerchantWareGateway < Gateway
|
4
|
+
class_attribute :v4_live_url
|
5
|
+
|
6
|
+
self.live_url = self.test_url = 'https://ps1.merchantware.net/MerchantWARE/ws/RetailTransaction/TXRetail.asmx'
|
7
|
+
self.v4_live_url = 'https://ps1.merchantware.net/Merchantware/ws/RetailTransaction/v4/Credit.asmx'
|
8
|
+
|
9
|
+
self.supported_countries = ['US']
|
10
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
11
|
+
self.homepage_url = 'http://merchantwarehouse.com/merchantware'
|
12
|
+
self.display_name = 'MerchantWARE'
|
13
|
+
|
14
|
+
ENV_NAMESPACES = { "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
|
15
|
+
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
|
16
|
+
"xmlns:env" => "http://schemas.xmlsoap.org/soap/envelope/"
|
17
|
+
}
|
18
|
+
ENV_NAMESPACES_V4 = { "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
|
19
|
+
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
|
20
|
+
"xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/"
|
21
|
+
}
|
22
|
+
|
23
|
+
TX_NAMESPACE = "http://merchantwarehouse.com/MerchantWARE/Client/TransactionRetail"
|
24
|
+
TX_NAMESPACE_V4 = "http://schemas.merchantwarehouse.com/merchantware/40/Credit/"
|
25
|
+
|
26
|
+
ACTIONS = {
|
27
|
+
:purchase => "IssueKeyedSale",
|
28
|
+
:authorize => "IssueKeyedPreAuth",
|
29
|
+
:capture => "IssuePostAuth",
|
30
|
+
:void => "VoidPreAuthorization",
|
31
|
+
:credit => "IssueKeyedRefund",
|
32
|
+
:reference_credit => "IssueRefundByReference"
|
33
|
+
}
|
34
|
+
|
35
|
+
# Creates a new MerchantWareGateway
|
36
|
+
#
|
37
|
+
# The gateway requires that a valid login, password, and name be passed
|
38
|
+
# in the +options+ hash.
|
39
|
+
#
|
40
|
+
# ==== Options
|
41
|
+
#
|
42
|
+
# * <tt>:login</tt> - The MerchantWARE SiteID.
|
43
|
+
# * <tt>:password</tt> - The MerchantWARE Key.
|
44
|
+
# * <tt>:name</tt> - The MerchantWARE Name.
|
45
|
+
def initialize(options = {})
|
46
|
+
requires!(options, :login, :password, :name)
|
47
|
+
super
|
48
|
+
end
|
49
|
+
|
50
|
+
# Authorize a credit card for a given amount.
|
51
|
+
#
|
52
|
+
# ==== Parameters
|
53
|
+
# * <tt>money</tt> - The amount to be authorized as an Integer value in cents.
|
54
|
+
# * <tt>credit_card</tt> - The CreditCard details for the transaction.
|
55
|
+
# * <tt>options</tt>
|
56
|
+
# * <tt>:order_id</tt> - A unique reference for this order (required).
|
57
|
+
# * <tt>:billing_address</tt> - The billing address for the cardholder.
|
58
|
+
def authorize(money, credit_card, options = {})
|
59
|
+
request = build_purchase_request(:authorize, money, credit_card, options)
|
60
|
+
commit(:authorize, request)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Authorize and immediately capture funds from a credit card.
|
64
|
+
#
|
65
|
+
# ==== Parameters
|
66
|
+
# * <tt>money</tt> - The amount to be authorized as anInteger value in cents.
|
67
|
+
# * <tt>credit_card</tt> - The CreditCard details for the transaction.
|
68
|
+
# * <tt>options</tt>
|
69
|
+
# * <tt>:order_id</tt> - A unique reference for this order (required).
|
70
|
+
# * <tt>:billing_address</tt> - The billing address for the cardholder.
|
71
|
+
def purchase(money, credit_card, options = {})
|
72
|
+
request = build_purchase_request(:purchase, money, credit_card, options)
|
73
|
+
commit(:purchase, request)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Capture authorized funds from a credit card.
|
77
|
+
#
|
78
|
+
# ==== Parameters
|
79
|
+
# * <tt>money</tt> - The amount to be captured as anInteger value in cents.
|
80
|
+
# * <tt>authorization</tt> - The authorization string returned from the initial authorization.
|
81
|
+
def capture(money, authorization, options = {})
|
82
|
+
request = build_capture_request(:capture, money, authorization, options)
|
83
|
+
commit(:capture, request)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Void a transaction.
|
87
|
+
#
|
88
|
+
# ==== Parameters
|
89
|
+
# * <tt>authorization</tt> - The authorization string returned from the initial authorization or purchase.
|
90
|
+
def void(authorization, options = {})
|
91
|
+
reference, options[:order_id] = split_reference(authorization)
|
92
|
+
request = v4_soap_request(:void) do |xml|
|
93
|
+
add_reference_token(xml, reference)
|
94
|
+
end
|
95
|
+
commit(:void, request, true)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Refund an amount back a cardholder
|
99
|
+
#
|
100
|
+
# ==== Parameters
|
101
|
+
#
|
102
|
+
# * <tt>money</tt> - The amount to be refunded as an Integer value in cents.
|
103
|
+
# * <tt>identification</tt> - The credit card you want to refund or the authorization for the existing transaction you are refunding.
|
104
|
+
# * <tt>options</tt>
|
105
|
+
# * <tt>:order_id</tt> - A unique reference for this order (required when performing a non-referenced credit)
|
106
|
+
def credit(money, identification, options = {})
|
107
|
+
if identification.is_a?(String)
|
108
|
+
ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
|
109
|
+
refund(money, identification, options)
|
110
|
+
else
|
111
|
+
perform_credit(money, identification, options)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def refund(money, reference, options = {})
|
116
|
+
perform_reference_credit(money, reference, options)
|
117
|
+
end
|
118
|
+
|
119
|
+
private
|
120
|
+
|
121
|
+
def soap_request(action)
|
122
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
123
|
+
xml.instruct!
|
124
|
+
xml.tag! "env:Envelope", ENV_NAMESPACES do
|
125
|
+
xml.tag! "env:Body" do
|
126
|
+
xml.tag! ACTIONS[action], "xmlns" => TX_NAMESPACE do
|
127
|
+
add_credentials(xml)
|
128
|
+
yield xml
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
xml.target!
|
133
|
+
end
|
134
|
+
|
135
|
+
def v4_soap_request(action)
|
136
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
137
|
+
xml.instruct!
|
138
|
+
xml.tag! "soap:Envelope", ENV_NAMESPACES_V4 do
|
139
|
+
xml.tag! "soap:Body" do
|
140
|
+
xml.tag! ACTIONS[:void], "xmlns" => TX_NAMESPACE_V4 do
|
141
|
+
xml.tag! "merchantName", @options[:name]
|
142
|
+
xml.tag! "merchantSiteId", @options[:login]
|
143
|
+
xml.tag! "merchantKey", @options[:password]
|
144
|
+
yield xml
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
xml.target!
|
149
|
+
end
|
150
|
+
|
151
|
+
def build_purchase_request(action, money, credit_card, options)
|
152
|
+
requires!(options, :order_id)
|
153
|
+
|
154
|
+
soap_request(action) do |xml|
|
155
|
+
add_invoice(xml, options)
|
156
|
+
add_amount(xml, money)
|
157
|
+
add_credit_card(xml, credit_card)
|
158
|
+
add_address(xml, options)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def build_capture_request(action, money, identification, options)
|
163
|
+
reference, options[:order_id] = split_reference(identification)
|
164
|
+
|
165
|
+
soap_request(action) do |xml|
|
166
|
+
add_reference(xml, reference)
|
167
|
+
add_invoice(xml, options)
|
168
|
+
add_amount(xml, money)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def perform_reference_credit(money, identification, options)
|
173
|
+
reference, options[:order_id] = split_reference(identification)
|
174
|
+
|
175
|
+
request = soap_request(:reference_credit) do |xml|
|
176
|
+
add_reference(xml, reference)
|
177
|
+
add_invoice(xml, options)
|
178
|
+
add_amount(xml, money, "strOverrideAmount")
|
179
|
+
end
|
180
|
+
|
181
|
+
commit(:reference_credit, request)
|
182
|
+
end
|
183
|
+
|
184
|
+
def perform_credit(money, credit_card, options)
|
185
|
+
requires!(options, :order_id)
|
186
|
+
|
187
|
+
request = soap_request(:credit) do |xml|
|
188
|
+
add_invoice(xml, options)
|
189
|
+
add_amount(xml, money)
|
190
|
+
add_credit_card(xml, credit_card)
|
191
|
+
end
|
192
|
+
|
193
|
+
commit(:credit, request)
|
194
|
+
end
|
195
|
+
|
196
|
+
def add_credentials(xml)
|
197
|
+
xml.tag! "strSiteId", @options[:login]
|
198
|
+
xml.tag! "strKey", @options[:password]
|
199
|
+
xml.tag! "strName", @options[:name]
|
200
|
+
end
|
201
|
+
|
202
|
+
def add_invoice(xml, options)
|
203
|
+
xml.tag! "strOrderNumber", options[:order_id].to_s.gsub(/[^\w]/, '').slice(0, 25)
|
204
|
+
end
|
205
|
+
|
206
|
+
def add_amount(xml, money, tag = "strAmount")
|
207
|
+
xml.tag! tag, amount(money)
|
208
|
+
end
|
209
|
+
|
210
|
+
def add_reference(xml, reference)
|
211
|
+
xml.tag! "strReferenceCode", reference
|
212
|
+
end
|
213
|
+
|
214
|
+
def add_reference_token(xml, reference)
|
215
|
+
xml.tag! "token", reference
|
216
|
+
end
|
217
|
+
|
218
|
+
def add_address(xml, options)
|
219
|
+
if address = options[:billing_address] || options[:address]
|
220
|
+
xml.tag! "strAVSStreetAddress", address[:address1]
|
221
|
+
xml.tag! "strAVSZipCode", address[:zip]
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def add_credit_card(xml, credit_card)
|
226
|
+
if credit_card.respond_to?(:track_data) && credit_card.track_data.present?
|
227
|
+
xml.tag! "trackData", credit_card.track_data
|
228
|
+
else
|
229
|
+
xml.tag! "strPAN", credit_card.number
|
230
|
+
xml.tag! "strExpDate", expdate(credit_card)
|
231
|
+
xml.tag! "strCardHolder", credit_card.name
|
232
|
+
xml.tag! "strCVCode", credit_card.verification_value if credit_card.verification_value?
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
def split_reference(reference)
|
237
|
+
reference.to_s.split(";")
|
238
|
+
end
|
239
|
+
|
240
|
+
def parse(action, data)
|
241
|
+
response = {}
|
242
|
+
xml = REXML::Document.new(data)
|
243
|
+
|
244
|
+
root = REXML::XPath.first(xml, "//#{ACTIONS[action]}Response/#{ACTIONS[action]}Result")
|
245
|
+
|
246
|
+
root.elements.each do |element|
|
247
|
+
response[element.name] = element.text
|
248
|
+
end
|
249
|
+
|
250
|
+
status, code, message = response["ApprovalStatus"].split(";")
|
251
|
+
response[:status] = status
|
252
|
+
|
253
|
+
if response[:success] = status == "APPROVED"
|
254
|
+
response[:message] = status
|
255
|
+
else
|
256
|
+
response[:message] = message
|
257
|
+
response[:failure_code] = code
|
258
|
+
end
|
259
|
+
|
260
|
+
response
|
261
|
+
end
|
262
|
+
|
263
|
+
def parse_error(http_response)
|
264
|
+
response = {}
|
265
|
+
response[:http_code] = http_response.code
|
266
|
+
response[:http_message] = http_response.message
|
267
|
+
response[:success] = false
|
268
|
+
|
269
|
+
document = REXML::Document.new(http_response.body)
|
270
|
+
|
271
|
+
node = REXML::XPath.first(document, "//soap:Fault")
|
272
|
+
|
273
|
+
node.elements.each do |element|
|
274
|
+
response[element.name] = element.text
|
275
|
+
end
|
276
|
+
|
277
|
+
response[:message] = response["faultstring"].to_s.gsub("\n", " ")
|
278
|
+
response
|
279
|
+
rescue REXML::ParseException
|
280
|
+
response[:http_body] = http_response.body
|
281
|
+
response[:message] = "Failed to parse the failed response"
|
282
|
+
response
|
283
|
+
end
|
284
|
+
|
285
|
+
def soap_action(action, v4 = false)
|
286
|
+
v4 ? "#{TX_NAMESPACE_V4}#{ACTIONS[action]}" : "#{TX_NAMESPACE}/#{ACTIONS[action]}"
|
287
|
+
end
|
288
|
+
|
289
|
+
def url(v4 = false)
|
290
|
+
v4 ? v4_live_url : live_url
|
291
|
+
end
|
292
|
+
|
293
|
+
def commit(action, request, v4 = false)
|
294
|
+
begin
|
295
|
+
data = ssl_post(url(v4), request,
|
296
|
+
"Content-Type" => 'text/xml; charset=utf-8',
|
297
|
+
"SOAPAction" => soap_action(action, v4)
|
298
|
+
)
|
299
|
+
response = parse(action, data)
|
300
|
+
rescue ActiveMerchant::ResponseError => e
|
301
|
+
response = parse_error(e.response)
|
302
|
+
end
|
303
|
+
|
304
|
+
Response.new(response[:success], response[:message], response,
|
305
|
+
:test => test?,
|
306
|
+
:authorization => authorization_from(response),
|
307
|
+
:avs_result => { :code => response["AVSResponse"] },
|
308
|
+
:cvv_result => response["CVResponse"]
|
309
|
+
)
|
310
|
+
end
|
311
|
+
|
312
|
+
def authorization_from(response)
|
313
|
+
if response[:success]
|
314
|
+
[ response["ReferenceID"], response["OrderNumber"] ].join(";")
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
@@ -0,0 +1,268 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class MerchantWareVersionFourGateway < Gateway
|
4
|
+
self.live_url = 'https://ps1.merchantware.net/Merchantware/ws/RetailTransaction/v4/Credit.asmx'
|
5
|
+
self.test_url = 'https://staging.merchantware.net/Merchantware/ws/RetailTransaction/v4/Credit.asmx'
|
6
|
+
|
7
|
+
self.supported_countries = ['US']
|
8
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
9
|
+
self.homepage_url = 'http://merchantwarehouse.com/merchantware'
|
10
|
+
self.display_name = 'MerchantWARE'
|
11
|
+
|
12
|
+
ENV_NAMESPACES = { "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
|
13
|
+
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
|
14
|
+
"xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/" }
|
15
|
+
|
16
|
+
TX_NAMESPACE = "http://schemas.merchantwarehouse.com/merchantware/40/Credit/"
|
17
|
+
|
18
|
+
ACTIONS = {
|
19
|
+
:purchase => "SaleKeyed",
|
20
|
+
:reference_purchase => 'RepeatSale',
|
21
|
+
:authorize => "PreAuthorizationKeyed",
|
22
|
+
:capture => "PostAuthorization",
|
23
|
+
:void => "VoidPreAuthorization",
|
24
|
+
:refund => "Refund"
|
25
|
+
}
|
26
|
+
|
27
|
+
# Creates a new MerchantWareVersionFourGateway
|
28
|
+
#
|
29
|
+
# The gateway requires that a valid login, password, and name be passed
|
30
|
+
# in the +options+ hash.
|
31
|
+
#
|
32
|
+
# ==== Options
|
33
|
+
#
|
34
|
+
# * <tt>:login</tt> - The MerchantWARE SiteID.
|
35
|
+
# * <tt>:password</tt> - The MerchantWARE Key.
|
36
|
+
# * <tt>:name</tt> - The MerchantWARE Name.
|
37
|
+
def initialize(options = {})
|
38
|
+
requires!(options, :login, :password, :name)
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
# Authorize a credit card for a given amount.
|
43
|
+
#
|
44
|
+
# ==== Parameters
|
45
|
+
# * <tt>money</tt> - The amount to be authorized as an Integer value in cents.
|
46
|
+
# * <tt>credit_card</tt> - The CreditCard details for the transaction.
|
47
|
+
# * <tt>options</tt>
|
48
|
+
# * <tt>:order_id</tt> - A unique reference for this order (required).
|
49
|
+
# * <tt>:billing_address</tt> - The billing address for the cardholder.
|
50
|
+
def authorize(money, credit_card, options = {})
|
51
|
+
request = build_purchase_request(:authorize, money, credit_card, options)
|
52
|
+
commit(:authorize, request)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Authorize and immediately capture funds from a credit card.
|
56
|
+
#
|
57
|
+
# ==== Parameters
|
58
|
+
# * <tt>money</tt> - The amount to be authorized as anInteger value in cents.
|
59
|
+
# * <tt>payment_source</tt> - The CreditCard details or 'token' from prior transaction
|
60
|
+
# * <tt>options</tt>
|
61
|
+
# * <tt>:order_id</tt> - A unique reference for this order (required).
|
62
|
+
# * <tt>:billing_address</tt> - The billing address for the cardholder.
|
63
|
+
def purchase(money, payment_source, options = {})
|
64
|
+
action = payment_source.is_a?(String) ? :reference_purchase : :purchase
|
65
|
+
request = build_purchase_request(action, money, payment_source, options)
|
66
|
+
commit(action, request)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Capture authorized funds from a credit card.
|
70
|
+
#
|
71
|
+
# ==== Parameters
|
72
|
+
# * <tt>money</tt> - The amount to be captured as anInteger value in cents.
|
73
|
+
# * <tt>authorization</tt> - The authorization string returned from the initial authorization.
|
74
|
+
def capture(money, authorization, options = {})
|
75
|
+
request = build_capture_request(:capture, money, authorization, options)
|
76
|
+
commit(:capture, request)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Void a transaction.
|
80
|
+
#
|
81
|
+
# ==== Parameters
|
82
|
+
# * <tt>authorization</tt> - The authorization string returned from the initial authorization or purchase.
|
83
|
+
def void(authorization, options = {})
|
84
|
+
reference, options[:order_id] = split_reference(authorization)
|
85
|
+
request = soap_request(:void) do |xml|
|
86
|
+
add_reference_token(xml, reference)
|
87
|
+
end
|
88
|
+
commit(:void, request)
|
89
|
+
end
|
90
|
+
|
91
|
+
# Refund an amount back a cardholder
|
92
|
+
#
|
93
|
+
# ==== Parameters
|
94
|
+
#
|
95
|
+
# * <tt>money</tt> - The amount to be refunded as an Integer value in cents.
|
96
|
+
# * <tt>identification</tt> - The credit card you want to refund or the authorization for the existing transaction you are refunding.
|
97
|
+
# * <tt>options</tt>
|
98
|
+
# * <tt>:order_id</tt> - A unique reference for this order (required when performing a non-referenced credit)
|
99
|
+
def refund(money, identification, options = {})
|
100
|
+
reference, options[:order_id] = split_reference(identification)
|
101
|
+
|
102
|
+
request = soap_request(:refund) do |xml|
|
103
|
+
add_reference_token(xml, reference)
|
104
|
+
add_invoice(xml, options)
|
105
|
+
add_amount(xml, money, "overrideAmount")
|
106
|
+
end
|
107
|
+
|
108
|
+
commit(:refund, request)
|
109
|
+
end
|
110
|
+
|
111
|
+
private
|
112
|
+
|
113
|
+
def soap_request(action)
|
114
|
+
xml = Builder::XmlMarkup.new :indent => 2
|
115
|
+
xml.instruct!
|
116
|
+
xml.tag! "soap:Envelope", ENV_NAMESPACES do
|
117
|
+
xml.tag! "soap:Body" do
|
118
|
+
xml.tag! ACTIONS[action], "xmlns" => TX_NAMESPACE do
|
119
|
+
xml.tag! "merchantName", @options[:name]
|
120
|
+
xml.tag! "merchantSiteId", @options[:login]
|
121
|
+
xml.tag! "merchantKey", @options[:password]
|
122
|
+
yield xml
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
xml.target!
|
127
|
+
end
|
128
|
+
|
129
|
+
def build_purchase_request(action, money, payment_source, options)
|
130
|
+
requires!(options, :order_id)
|
131
|
+
|
132
|
+
soap_request(action) do |xml|
|
133
|
+
add_invoice(xml, options)
|
134
|
+
add_amount(xml, money)
|
135
|
+
add_payment_source(xml, payment_source)
|
136
|
+
add_address(xml, options)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def build_capture_request(action, money, identification, options)
|
141
|
+
reference, options[:order_id] = split_reference(identification)
|
142
|
+
|
143
|
+
soap_request(action) do |xml|
|
144
|
+
add_reference_token(xml, reference)
|
145
|
+
add_invoice(xml, options)
|
146
|
+
add_amount(xml, money)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def add_invoice(xml, options)
|
151
|
+
xml.tag! "invoiceNumber", options[:order_id].to_s.gsub(/[^\w]/, '').slice(0, 25)
|
152
|
+
end
|
153
|
+
|
154
|
+
def add_amount(xml, money, tag = "amount")
|
155
|
+
xml.tag! tag, amount(money)
|
156
|
+
end
|
157
|
+
|
158
|
+
def add_reference_token(xml, reference)
|
159
|
+
xml.tag! "token", reference
|
160
|
+
end
|
161
|
+
|
162
|
+
def add_address(xml, options)
|
163
|
+
address = options[:billing_address] || options[:address] || {}
|
164
|
+
xml.tag! "avsStreetAddress", address[:address1]
|
165
|
+
xml.tag! "avsStreetZipCode", address[:zip]
|
166
|
+
end
|
167
|
+
|
168
|
+
def add_payment_source(xml, source)
|
169
|
+
if source.is_a?(String)
|
170
|
+
add_reference_token(xml, source)
|
171
|
+
else
|
172
|
+
add_credit_card(xml, source)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def add_credit_card(xml, credit_card)
|
177
|
+
xml.tag! "cardNumber", credit_card.number
|
178
|
+
xml.tag! "expirationDate", expdate(credit_card)
|
179
|
+
xml.tag! "cardholder", credit_card.name
|
180
|
+
xml.tag! "cardSecurityCode", credit_card.verification_value if credit_card.verification_value?
|
181
|
+
end
|
182
|
+
|
183
|
+
def split_reference(reference)
|
184
|
+
reference.to_s.split(";")
|
185
|
+
end
|
186
|
+
|
187
|
+
def parse(action, data)
|
188
|
+
response = {}
|
189
|
+
xml = REXML::Document.new(data)
|
190
|
+
|
191
|
+
root = REXML::XPath.first(xml, "//#{ACTIONS[action]}Response/#{ACTIONS[action]}Result")
|
192
|
+
|
193
|
+
root.elements.each do |element|
|
194
|
+
response[element.name] = element.text
|
195
|
+
end
|
196
|
+
|
197
|
+
if response["ErrorMessage"].present?
|
198
|
+
response[:message] = response["ErrorMessage"]
|
199
|
+
response[:success] = false
|
200
|
+
else
|
201
|
+
status, code, message = response["ApprovalStatus"].split(";")
|
202
|
+
response[:status] = status
|
203
|
+
|
204
|
+
if response[:success] = status == "APPROVED"
|
205
|
+
response[:message] = status
|
206
|
+
else
|
207
|
+
response[:message] = message
|
208
|
+
response[:failure_code] = code
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
response
|
213
|
+
end
|
214
|
+
|
215
|
+
def parse_error(http_response, action)
|
216
|
+
response = {}
|
217
|
+
response[:http_code] = http_response.code
|
218
|
+
response[:http_message] = http_response.message
|
219
|
+
response[:success] = false
|
220
|
+
|
221
|
+
document = REXML::Document.new(http_response.body)
|
222
|
+
node = REXML::XPath.first(document, "//#{ACTIONS[action]}Response/#{ACTIONS[action]}Result")
|
223
|
+
|
224
|
+
node.elements.each do |element|
|
225
|
+
response[element.name] = element.text
|
226
|
+
end
|
227
|
+
|
228
|
+
response[:message] = response["ErrorMessage"].to_s.gsub("\n", " ")
|
229
|
+
response
|
230
|
+
rescue REXML::ParseException
|
231
|
+
response[:http_body] = http_response.body
|
232
|
+
response[:message] = "Failed to parse the failed response"
|
233
|
+
response
|
234
|
+
end
|
235
|
+
|
236
|
+
def soap_action(action)
|
237
|
+
"#{TX_NAMESPACE}#{ACTIONS[action]}"
|
238
|
+
end
|
239
|
+
|
240
|
+
def url
|
241
|
+
test? ? test_url : live_url
|
242
|
+
end
|
243
|
+
|
244
|
+
def commit(action, request)
|
245
|
+
begin
|
246
|
+
data = ssl_post(url, request,
|
247
|
+
"Content-Type" => 'text/xml; charset=utf-8',
|
248
|
+
"SOAPAction" => soap_action(action)
|
249
|
+
)
|
250
|
+
response = parse(action, data)
|
251
|
+
rescue ActiveMerchant::ResponseError => e
|
252
|
+
response = parse_error(e.response, action)
|
253
|
+
end
|
254
|
+
|
255
|
+
Response.new(response[:success], response[:message], response,
|
256
|
+
:test => test?,
|
257
|
+
:authorization => authorization_from(response),
|
258
|
+
:avs_result => { :code => response["AvsResponse"] },
|
259
|
+
:cvv_result => response["CvResponse"]
|
260
|
+
)
|
261
|
+
end
|
262
|
+
|
263
|
+
def authorization_from(response)
|
264
|
+
response['Token']
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|