swiss-crm-activemerchant 1.0.12
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 +4033 -0
- data/CONTRIBUTORS +568 -0
- data/MIT-LICENSE +20 -0
- data/README.md +252 -0
- data/lib/active_merchant/billing/apple_pay_payment_token.rb +22 -0
- data/lib/active_merchant/billing/avs_result.rb +95 -0
- data/lib/active_merchant/billing/base.rb +48 -0
- data/lib/active_merchant/billing/check.rb +112 -0
- data/lib/active_merchant/billing/compatibility.rb +118 -0
- data/lib/active_merchant/billing/credit_card.rb +451 -0
- data/lib/active_merchant/billing/credit_card_formatting.rb +24 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +512 -0
- data/lib/active_merchant/billing/cvv_result.rb +37 -0
- data/lib/active_merchant/billing/gateway.rb +332 -0
- data/lib/active_merchant/billing/gateways/adyen.rb +774 -0
- data/lib/active_merchant/billing/gateways/airwallex.rb +370 -0
- data/lib/active_merchant/billing/gateways/alelo.rb +256 -0
- data/lib/active_merchant/billing/gateways/allied_wallet.rb +205 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +1125 -0
- data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +424 -0
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +977 -0
- data/lib/active_merchant/billing/gateways/axcessms.rb +242 -0
- data/lib/active_merchant/billing/gateways/balanced.rb +263 -0
- data/lib/active_merchant/billing/gateways/bambora_apac.rb +222 -0
- data/lib/active_merchant/billing/gateways/bank_frick.rb +225 -0
- data/lib/active_merchant/billing/gateways/banwire.rb +116 -0
- data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +397 -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/beanstream_core.rb +474 -0
- data/lib/active_merchant/billing/gateways/beanstream.rb +238 -0
- data/lib/active_merchant/billing/gateways/beanstream_interac.rb +57 -0
- data/lib/active_merchant/billing/gateways/blue_pay.rb +549 -0
- data/lib/active_merchant/billing/gateways/blue_snap.rb +644 -0
- data/lib/active_merchant/billing/gateways/bogus.rb +190 -0
- data/lib/active_merchant/billing/gateways/borgun.rb +272 -0
- data/lib/active_merchant/billing/gateways/bpoint.rb +277 -0
- data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +28 -0
- data/lib/active_merchant/billing/gateways/braintree/token_nonce.rb +113 -0
- data/lib/active_merchant/billing/gateways/braintree.rb +19 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +952 -0
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +19 -0
- data/lib/active_merchant/billing/gateways/bridge_pay.rb +244 -0
- data/lib/active_merchant/billing/gateways/cams.rb +230 -0
- data/lib/active_merchant/billing/gateways/card_connect.rb +338 -0
- data/lib/active_merchant/billing/gateways/card_save.rb +21 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +394 -0
- data/lib/active_merchant/billing/gateways/cardknox.rb +327 -0
- data/lib/active_merchant/billing/gateways/cardprocess.rb +256 -0
- data/lib/active_merchant/billing/gateways/cashnet.rb +235 -0
- data/lib/active_merchant/billing/gateways/cc5.rb +198 -0
- data/lib/active_merchant/billing/gateways/cecabank.rb +249 -0
- data/lib/active_merchant/billing/gateways/cenpos.rb +328 -0
- data/lib/active_merchant/billing/gateways/checkout.rb +212 -0
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +587 -0
- data/lib/active_merchant/billing/gateways/citrus_pay.rb +21 -0
- data/lib/active_merchant/billing/gateways/clearhaus.rb +219 -0
- data/lib/active_merchant/billing/gateways/commerce_hub.rb +366 -0
- data/lib/active_merchant/billing/gateways/commercegate.rb +142 -0
- data/lib/active_merchant/billing/gateways/conekta.rb +230 -0
- data/lib/active_merchant/billing/gateways/creditcall.rb +272 -0
- data/lib/active_merchant/billing/gateways/credorax.rb +526 -0
- data/lib/active_merchant/billing/gateways/ct_payment.rb +269 -0
- data/lib/active_merchant/billing/gateways/culqi.rb +279 -0
- data/lib/active_merchant/billing/gateways/cyber_source/cyber_source_common.rb +36 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +1148 -0
- data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +454 -0
- data/lib/active_merchant/billing/gateways/d_local.rb +343 -0
- data/lib/active_merchant/billing/gateways/data_cash.rb +302 -0
- data/lib/active_merchant/billing/gateways/decidir.rb +358 -0
- data/lib/active_merchant/billing/gateways/decidir_plus.rb +344 -0
- data/lib/active_merchant/billing/gateways/dibs.rb +199 -0
- data/lib/active_merchant/billing/gateways/digitzs.rb +295 -0
- data/lib/active_merchant/billing/gateways/ebanx.rb +346 -0
- data/lib/active_merchant/billing/gateways/efsnet.rb +215 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +475 -0
- data/lib/active_merchant/billing/gateways/element.rb +406 -0
- data/lib/active_merchant/billing/gateways/epay.rb +296 -0
- data/lib/active_merchant/billing/gateways/evo_ca.rb +307 -0
- data/lib/active_merchant/billing/gateways/eway.rb +226 -0
- data/lib/active_merchant/billing/gateways/eway_managed.rb +289 -0
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +578 -0
- data/lib/active_merchant/billing/gateways/exact.rb +219 -0
- data/lib/active_merchant/billing/gateways/ezic.rb +195 -0
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +223 -0
- data/lib/active_merchant/billing/gateways/federated_canada.rb +158 -0
- data/lib/active_merchant/billing/gateways/finansbank.rb +22 -0
- data/lib/active_merchant/billing/gateways/first_giving.rb +143 -0
- data/lib/active_merchant/billing/gateways/first_pay.rb +182 -0
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +452 -0
- data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +505 -0
- data/lib/active_merchant/billing/gateways/flo2cash.rb +215 -0
- data/lib/active_merchant/billing/gateways/flo2cash_simple.rb +20 -0
- data/lib/active_merchant/billing/gateways/fluidpay.rb +275 -0
- data/lib/active_merchant/billing/gateways/forte.rb +286 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +256 -0
- data/lib/active_merchant/billing/gateways/global_collect.rb +580 -0
- data/lib/active_merchant/billing/gateways/global_transport.rb +193 -0
- data/lib/active_merchant/billing/gateways/hdfc.rb +205 -0
- data/lib/active_merchant/billing/gateways/hps.rb +472 -0
- data/lib/active_merchant/billing/gateways/iats_payments.rb +312 -0
- data/lib/active_merchant/billing/gateways/in_context_paypal_express.rb +15 -0
- data/lib/active_merchant/billing/gateways/inspire.rb +213 -0
- data/lib/active_merchant/billing/gateways/instapay.rb +159 -0
- data/lib/active_merchant/billing/gateways/ipg.rb +420 -0
- data/lib/active_merchant/billing/gateways/ipp.rb +176 -0
- data/lib/active_merchant/billing/gateways/iridium.rb +467 -0
- data/lib/active_merchant/billing/gateways/itransact.rb +448 -0
- data/lib/active_merchant/billing/gateways/iveri.rb +290 -0
- data/lib/active_merchant/billing/gateways/ixopay.rb +320 -0
- data/lib/active_merchant/billing/gateways/jetpay.rb +395 -0
- data/lib/active_merchant/billing/gateways/jetpay_v2.rb +432 -0
- data/lib/active_merchant/billing/gateways/klarna.rb +317 -0
- data/lib/active_merchant/billing/gateways/komoju.rb +115 -0
- data/lib/active_merchant/billing/gateways/kushki.rb +297 -0
- data/lib/active_merchant/billing/gateways/latitude19.rb +412 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +448 -0
- data/lib/active_merchant/billing/gateways/litle.rb +643 -0
- data/lib/active_merchant/billing/gateways/mastercard.rb +286 -0
- data/lib/active_merchant/billing/gateways/maxipago.rb +220 -0
- data/lib/active_merchant/billing/gateways/mercado_pago.rb +348 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +228 -0
- data/lib/active_merchant/billing/gateways/merchant_one.rb +110 -0
- data/lib/active_merchant/billing/gateways/merchant_partners.rb +245 -0
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +313 -0
- data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +284 -0
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +248 -0
- data/lib/active_merchant/billing/gateways/mercury.rb +352 -0
- data/lib/active_merchant/billing/gateways/metrics_global.rb +293 -0
- data/lib/active_merchant/billing/gateways/micropayment.rb +182 -0
- data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +100 -0
- data/lib/active_merchant/billing/gateways/migs.rb +329 -0
- data/lib/active_merchant/billing/gateways/mit.rb +260 -0
- data/lib/active_merchant/billing/gateways/modern_payments.rb +37 -0
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +215 -0
- data/lib/active_merchant/billing/gateways/moka.rb +290 -0
- data/lib/active_merchant/billing/gateways/monei.rb +424 -0
- data/lib/active_merchant/billing/gateways/moneris.rb +488 -0
- data/lib/active_merchant/billing/gateways/money_movers.rb +150 -0
- data/lib/active_merchant/billing/gateways/mundipagg.rb +366 -0
- data/lib/active_merchant/billing/gateways/nab_transact.rb +299 -0
- data/lib/active_merchant/billing/gateways/ncr_secure_pay.rb +163 -0
- data/lib/active_merchant/billing/gateways/net_registry.rb +198 -0
- data/lib/active_merchant/billing/gateways/netaxept.rb +180 -0
- data/lib/active_merchant/billing/gateways/netbanx.rb +376 -0
- data/lib/active_merchant/billing/gateways/netbilling.rb +229 -0
- data/lib/active_merchant/billing/gateways/netpay.rb +223 -0
- data/lib/active_merchant/billing/gateways/network_merchants.rb +238 -0
- data/lib/active_merchant/billing/gateways/nmi.rb +396 -0
- data/lib/active_merchant/billing/gateways/ogone.rb +509 -0
- data/lib/active_merchant/billing/gateways/omise.rb +323 -0
- data/lib/active_merchant/billing/gateways/openpay.rb +246 -0
- data/lib/active_merchant/billing/gateways/opp.rb +394 -0
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +331 -0
- data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +45 -0
- data/lib/active_merchant/billing/gateways/orbital.rb +1267 -0
- data/lib/active_merchant/billing/gateways/pac_net_raven.rb +206 -0
- data/lib/active_merchant/billing/gateways/pagarme.rb +239 -0
- data/lib/active_merchant/billing/gateways/pago_facil.rb +120 -0
- data/lib/active_merchant/billing/gateways/pay_arc.rb +392 -0
- data/lib/active_merchant/billing/gateways/pay_conex.rb +245 -0
- data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +277 -0
- data/lib/active_merchant/billing/gateways/pay_hub.rb +213 -0
- data/lib/active_merchant/billing/gateways/pay_junction.rb +390 -0
- data/lib/active_merchant/billing/gateways/pay_junction_v2.rb +206 -0
- data/lib/active_merchant/billing/gateways/pay_secure.rb +110 -0
- data/lib/active_merchant/billing/gateways/pay_trace.rb +450 -0
- data/lib/active_merchant/billing/gateways/paybox_direct.rb +224 -0
- data/lib/active_merchant/billing/gateways/payeezy.rb +513 -0
- data/lib/active_merchant/billing/gateways/payex.rb +409 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +235 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_express_response.rb +42 -0
- data/lib/active_merchant/billing/gateways/payflow/payflow_response.rb +13 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +473 -0
- data/lib/active_merchant/billing/gateways/payflow_express.rb +220 -0
- data/lib/active_merchant/billing/gateways/payflow_express_uk.rb +14 -0
- data/lib/active_merchant/billing/gateways/payflow_uk.rb +20 -0
- data/lib/active_merchant/billing/gateways/payment_express.rb +373 -0
- data/lib/active_merchant/billing/gateways/paymentez.rb +365 -0
- data/lib/active_merchant/billing/gateways/paymill.rb +369 -0
- data/lib/active_merchant/billing/gateways/paynetworx.rb +228 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +718 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_express_response.rb +69 -0
- data/lib/active_merchant/billing/gateways/paypal/paypal_recurring_api.rb +262 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +136 -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 +272 -0
- data/lib/active_merchant/billing/gateways/paypal_express_common.rb +30 -0
- data/lib/active_merchant/billing/gateways/paypal_standard.rb +281 -0
- data/lib/active_merchant/billing/gateways/paysafe.rb +420 -0
- data/lib/active_merchant/billing/gateways/payscout.rb +159 -0
- data/lib/active_merchant/billing/gateways/paystation.rb +204 -0
- data/lib/active_merchant/billing/gateways/payu_in.rb +249 -0
- data/lib/active_merchant/billing/gateways/payu_latam.rb +482 -0
- data/lib/active_merchant/billing/gateways/payway.rb +207 -0
- data/lib/active_merchant/billing/gateways/payway_dot_com.rb +253 -0
- data/lib/active_merchant/billing/gateways/pin.rb +273 -0
- data/lib/active_merchant/billing/gateways/pixxels.rb +263 -0
- data/lib/active_merchant/billing/gateways/plexo.rb +308 -0
- data/lib/active_merchant/billing/gateways/plugnpay.rb +283 -0
- data/lib/active_merchant/billing/gateways/priority.rb +392 -0
- data/lib/active_merchant/billing/gateways/pro_pay.rb +325 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +227 -0
- data/lib/active_merchant/billing/gateways/psl_card.rb +295 -0
- data/lib/active_merchant/billing/gateways/qbms.rb +302 -0
- data/lib/active_merchant/billing/gateways/quantum.rb +274 -0
- data/lib/active_merchant/billing/gateways/quickbooks.rb +377 -0
- data/lib/active_merchant/billing/gateways/quickpay/quickpay_common.rb +184 -0
- data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +297 -0
- data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +226 -0
- data/lib/active_merchant/billing/gateways/quickpay.rb +24 -0
- data/lib/active_merchant/billing/gateways/qvalent.rb +305 -0
- data/lib/active_merchant/billing/gateways/rapyd.rb +319 -0
- data/lib/active_merchant/billing/gateways/reach.rb +277 -0
- data/lib/active_merchant/billing/gateways/realex.rb +400 -0
- data/lib/active_merchant/billing/gateways/redsys.rb +723 -0
- data/lib/active_merchant/billing/gateways/s5.rb +247 -0
- data/lib/active_merchant/billing/gateways/safe_charge.rb +298 -0
- data/lib/active_merchant/billing/gateways/sage.rb +446 -0
- data/lib/active_merchant/billing/gateways/sage_pay.rb +434 -0
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +141 -0
- data/lib/active_merchant/billing/gateways/secure_net.rb +260 -0
- data/lib/active_merchant/billing/gateways/secure_pay.rb +191 -0
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +290 -0
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +103 -0
- data/lib/active_merchant/billing/gateways/securion_pay.rb +305 -0
- data/lib/active_merchant/billing/gateways/shift4.rb +345 -0
- data/lib/active_merchant/billing/gateways/simetrik.rb +368 -0
- data/lib/active_merchant/billing/gateways/skip_jack.rb +450 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +274 -0
- data/lib/active_merchant/billing/gateways/so_easy_pay.rb +194 -0
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +354 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +866 -0
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +602 -0
- data/lib/active_merchant/billing/gateways/swipe_checkout.rb +151 -0
- data/lib/active_merchant/billing/gateways/telr.rb +273 -0
- data/lib/active_merchant/billing/gateways/tns.rb +23 -0
- data/lib/active_merchant/billing/gateways/trans_first.rb +240 -0
- data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +612 -0
- data/lib/active_merchant/billing/gateways/transact_pro.rb +222 -0
- data/lib/active_merchant/billing/gateways/transax.rb +21 -0
- data/lib/active_merchant/billing/gateways/transnational.rb +9 -0
- data/lib/active_merchant/billing/gateways/trexle.rb +221 -0
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +500 -0
- data/lib/active_merchant/billing/gateways/usa_epay.rb +24 -0
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +1612 -0
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +367 -0
- data/lib/active_merchant/billing/gateways/vanco.rb +303 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +224 -0
- data/lib/active_merchant/billing/gateways/viaklix.rb +171 -0
- data/lib/active_merchant/billing/gateways/visanet_peru.rb +250 -0
- data/lib/active_merchant/billing/gateways/vpos.rb +223 -0
- data/lib/active_merchant/billing/gateways/webpay.rb +97 -0
- data/lib/active_merchant/billing/gateways/wepay.rb +235 -0
- data/lib/active_merchant/billing/gateways/wirecard.rb +430 -0
- data/lib/active_merchant/billing/gateways/wompi.rb +197 -0
- data/lib/active_merchant/billing/gateways/world_net.rb +345 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +1050 -0
- data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +208 -0
- data/lib/active_merchant/billing/gateways/worldpay_us.rb +221 -0
- data/lib/active_merchant/billing/gateways.rb +14 -0
- data/lib/active_merchant/billing/model.rb +30 -0
- data/lib/active_merchant/billing/network_tokenization_credit_card.rb +39 -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 +121 -0
- data/lib/active_merchant/billing/three_d_secure_eci_mapper.rb +27 -0
- data/lib/active_merchant/billing.rb +16 -0
- data/lib/active_merchant/connection.rb +194 -0
- data/lib/active_merchant/country.rb +338 -0
- data/lib/active_merchant/empty.rb +20 -0
- data/lib/active_merchant/errors.rb +38 -0
- data/lib/active_merchant/net_http_ssl_connection.rb +11 -0
- data/lib/active_merchant/network_connection_retries.rb +78 -0
- data/lib/active_merchant/post_data.rb +26 -0
- data/lib/active_merchant/posts_data.rb +92 -0
- data/lib/active_merchant/version.rb +3 -0
- data/lib/active_merchant.rb +63 -0
- data/lib/activemerchant.rb +1 -0
- data/lib/certs/cacert.pem +3214 -0
- data/lib/support/gateway_support.rb +69 -0
- data/lib/support/outbound_hosts.rb +28 -0
- data/lib/support/ssl_verify.rb +88 -0
- data/lib/support/ssl_version.rb +86 -0
- metadata +506 -0
@@ -0,0 +1,352 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
# The Mercury gateway integration by default requires that the Mercury
|
4
|
+
# account being used has tokenization turned. This enables the use of
|
5
|
+
# capture/refund/void without having to pass the credit card back in each
|
6
|
+
# time. Only the "OneTime" tokenization is used; there is no use of
|
7
|
+
# "Recurring" tokenization.
|
8
|
+
#
|
9
|
+
# If you don't wish to enable Mercury tokenization, you can pass
|
10
|
+
# <code>:tokenization => false</code> as an option when creating the
|
11
|
+
# gateway. If you do so, then passing a +:credit_card+ option to +capture+
|
12
|
+
# and +refund+ will become mandatory.
|
13
|
+
class MercuryGateway < Gateway
|
14
|
+
URLS = {
|
15
|
+
test: 'https://w1.mercurycert.net/ws/ws.asmx',
|
16
|
+
live: 'https://w1.mercurypay.com/ws/ws.asmx'
|
17
|
+
}
|
18
|
+
|
19
|
+
self.homepage_url = 'http://www.mercurypay.com'
|
20
|
+
self.display_name = 'Mercury'
|
21
|
+
self.supported_countries = %w[US CA]
|
22
|
+
self.supported_cardtypes = %i[visa master american_express discover diners_club jcb]
|
23
|
+
self.default_currency = 'USD'
|
24
|
+
|
25
|
+
STANDARD_ERROR_CODE_MAPPING = {
|
26
|
+
'100204' => STANDARD_ERROR_CODE[:invalid_number],
|
27
|
+
'100205' => STANDARD_ERROR_CODE[:invalid_expiry_date],
|
28
|
+
'000000' => STANDARD_ERROR_CODE[:card_declined]
|
29
|
+
}
|
30
|
+
|
31
|
+
def initialize(options = {})
|
32
|
+
requires!(options, :login, :password)
|
33
|
+
@use_tokenization = (!options.has_key?(:tokenization) || options[:tokenization])
|
34
|
+
super
|
35
|
+
end
|
36
|
+
|
37
|
+
def purchase(money, credit_card, options = {})
|
38
|
+
requires!(options, :order_id)
|
39
|
+
|
40
|
+
request = build_non_authorized_request('Sale', money, credit_card, options)
|
41
|
+
commit('Sale', request)
|
42
|
+
end
|
43
|
+
|
44
|
+
def credit(money, credit_card, options = {})
|
45
|
+
requires!(options, :order_id)
|
46
|
+
|
47
|
+
request = build_non_authorized_request('Return', money, credit_card, options)
|
48
|
+
commit('Return', request)
|
49
|
+
end
|
50
|
+
|
51
|
+
def authorize(money, credit_card, options = {})
|
52
|
+
requires!(options, :order_id)
|
53
|
+
|
54
|
+
request = build_non_authorized_request('PreAuth', money, credit_card, options.merge(authorized: money))
|
55
|
+
commit('PreAuth', request)
|
56
|
+
end
|
57
|
+
|
58
|
+
def capture(money, authorization, options = {})
|
59
|
+
requires!(options, :credit_card) unless @use_tokenization
|
60
|
+
|
61
|
+
request = build_authorized_request('PreAuthCapture', money, authorization, options[:credit_card], options.merge(authorized: money))
|
62
|
+
commit('PreAuthCapture', request)
|
63
|
+
end
|
64
|
+
|
65
|
+
def refund(money, authorization, options = {})
|
66
|
+
requires!(options, :credit_card) unless @use_tokenization
|
67
|
+
|
68
|
+
request = build_authorized_request('Return', money, authorization, options[:credit_card], options)
|
69
|
+
commit('Return', request)
|
70
|
+
end
|
71
|
+
|
72
|
+
def void(authorization, options = {})
|
73
|
+
requires!(options, :credit_card) unless @use_tokenization
|
74
|
+
|
75
|
+
request = build_authorized_request('VoidSale', nil, authorization, options[:credit_card], options)
|
76
|
+
commit('VoidSale', request)
|
77
|
+
end
|
78
|
+
|
79
|
+
def store(credit_card, options = {})
|
80
|
+
request = build_card_lookup_request(credit_card, options)
|
81
|
+
commit('CardLookup', request)
|
82
|
+
end
|
83
|
+
|
84
|
+
def supports_scrubbing?
|
85
|
+
true
|
86
|
+
end
|
87
|
+
|
88
|
+
def scrub(transcript)
|
89
|
+
transcript.
|
90
|
+
gsub(%r(<), '<').
|
91
|
+
gsub(%r(>), '>').
|
92
|
+
gsub(%r((<pw>).*(</pw>))i, '\1[FILTERED]\2').
|
93
|
+
gsub(%r((<AcctNo>)(\d|x)*(</AcctNo>))i, '\1[FILTERED]\3').
|
94
|
+
gsub(%r((<CVVData>)\d*(</CVVData>))i, '\1[FILTERED]\2')
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def build_non_authorized_request(action, money, credit_card, options)
|
100
|
+
xml = Builder::XmlMarkup.new
|
101
|
+
|
102
|
+
xml.tag! 'TStream' do
|
103
|
+
xml.tag! 'Transaction' do
|
104
|
+
xml.tag! 'TranType', 'Credit'
|
105
|
+
xml.tag! 'TranCode', action
|
106
|
+
xml.tag! 'PartialAuth', 'Allow' if options[:allow_partial_auth] && %w[PreAuth Sale].include?(action)
|
107
|
+
add_invoice(xml, options[:order_id], nil, options)
|
108
|
+
add_reference(xml, 'RecordNumberRequested')
|
109
|
+
add_customer_data(xml, options)
|
110
|
+
add_amount(xml, money, options)
|
111
|
+
add_credit_card(xml, credit_card, action)
|
112
|
+
add_address(xml, options) unless credit_card.track_data.present?
|
113
|
+
end
|
114
|
+
end
|
115
|
+
xml = xml.target!
|
116
|
+
end
|
117
|
+
|
118
|
+
def build_authorized_request(action, money, authorization, credit_card, options)
|
119
|
+
xml = Builder::XmlMarkup.new
|
120
|
+
|
121
|
+
invoice_no, ref_no, auth_code, acq_ref_data, process_data, record_no, amount = split_authorization(authorization)
|
122
|
+
ref_no = '1' if ref_no.blank?
|
123
|
+
|
124
|
+
xml.tag! 'TStream' do
|
125
|
+
xml.tag! 'Transaction' do
|
126
|
+
xml.tag! 'TranType', 'Credit'
|
127
|
+
xml.tag! 'PartialAuth', 'Allow' if options[:allow_partial_auth] && (action == 'PreAuthCapture')
|
128
|
+
xml.tag! 'TranCode', (@use_tokenization ? (action + 'ByRecordNo') : action)
|
129
|
+
add_invoice(xml, invoice_no, ref_no, options)
|
130
|
+
add_reference(xml, record_no)
|
131
|
+
add_customer_data(xml, options)
|
132
|
+
add_amount(xml, (money || amount.to_i), options)
|
133
|
+
add_credit_card(xml, credit_card, action) if credit_card
|
134
|
+
add_address(xml, options)
|
135
|
+
xml.tag! 'TranInfo' do
|
136
|
+
xml.tag! 'AuthCode', auth_code
|
137
|
+
xml.tag! 'AcqRefData', acq_ref_data
|
138
|
+
xml.tag! 'ProcessData', process_data
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
xml = xml.target!
|
143
|
+
end
|
144
|
+
|
145
|
+
def build_card_lookup_request(credit_card, options)
|
146
|
+
xml = Builder::XmlMarkup.new
|
147
|
+
|
148
|
+
xml.tag! 'TStream' do
|
149
|
+
xml.tag! 'Transaction' do
|
150
|
+
xml.tag! 'TranType', 'CardLookup'
|
151
|
+
xml.tag! 'RecordNo', 'RecordNumberRequested'
|
152
|
+
xml.tag! 'Frequency', 'OneTime'
|
153
|
+
|
154
|
+
xml.tag! 'Memo', options[:description]
|
155
|
+
add_customer_data(xml, options)
|
156
|
+
add_credit_card(xml, credit_card, options)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
xml.target!
|
160
|
+
end
|
161
|
+
|
162
|
+
def add_invoice(xml, invoice_no, ref_no, options)
|
163
|
+
xml.tag! 'InvoiceNo', invoice_no
|
164
|
+
xml.tag! 'RefNo', (ref_no || invoice_no)
|
165
|
+
xml.tag! 'OperatorID', options[:merchant] if options[:merchant]
|
166
|
+
xml.tag! 'Memo', options[:description] if options[:description]
|
167
|
+
end
|
168
|
+
|
169
|
+
def add_reference(xml, record_no)
|
170
|
+
if @use_tokenization
|
171
|
+
xml.tag! 'Frequency', 'OneTime'
|
172
|
+
xml.tag! 'RecordNo', record_no
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def add_customer_data(xml, options)
|
177
|
+
xml.tag! 'IpAddress', options[:ip] if options[:ip]
|
178
|
+
if options[:customer]
|
179
|
+
xml.tag! 'TranInfo' do
|
180
|
+
xml.tag! 'CustomerCode', options[:customer]
|
181
|
+
end
|
182
|
+
end
|
183
|
+
xml.tag! 'MerchantID', @options[:login]
|
184
|
+
end
|
185
|
+
|
186
|
+
def add_amount(xml, money, options = {})
|
187
|
+
xml.tag! 'Amount' do
|
188
|
+
xml.tag! 'Purchase', amount(money)
|
189
|
+
xml.tag! 'Tax', options[:tax] if options[:tax]
|
190
|
+
xml.tag! 'Authorize', amount(options[:authorized]) if options[:authorized]
|
191
|
+
xml.tag! 'Gratuity', amount(options[:tip]) if options[:tip]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
CARD_CODES = {
|
196
|
+
'visa' => 'VISA',
|
197
|
+
'master' => 'M/C',
|
198
|
+
'american_express' => 'AMEX',
|
199
|
+
'discover' => 'DCVR',
|
200
|
+
'diners_club' => 'DCLB',
|
201
|
+
'jcb' => 'JCB'
|
202
|
+
}
|
203
|
+
|
204
|
+
def add_credit_card(xml, credit_card, action)
|
205
|
+
xml.tag! 'Account' do
|
206
|
+
if credit_card.track_data.present?
|
207
|
+
# Track 1 has a start sentinel (STX) of '%' and track 2 is ';'
|
208
|
+
# Track 1 and 2 have identical end sentinels (ETX) of '?'
|
209
|
+
# Tracks may or may not have checksum (LRC) after the ETX
|
210
|
+
# If the track has no STX or is corrupt, we send it as track 1, to let Mercury
|
211
|
+
# handle with the validation error as it sees fit.
|
212
|
+
# Track 2 requires having the STX and ETX stripped. Track 1 does not.
|
213
|
+
# Max-length track 1s require having the STX and ETX stripped. Max is 79 bytes including LRC.
|
214
|
+
is_track2 = credit_card.track_data[0] == ';'
|
215
|
+
etx_index = credit_card.track_data.rindex('?') || credit_card.track_data.length
|
216
|
+
is_max_track1 = etx_index >= 77
|
217
|
+
|
218
|
+
if is_track2
|
219
|
+
xml.tag! 'Track2', credit_card.track_data[1...etx_index]
|
220
|
+
elsif is_max_track1
|
221
|
+
xml.tag! 'Track1', credit_card.track_data[1...etx_index]
|
222
|
+
else
|
223
|
+
xml.tag! 'Track1', credit_card.track_data
|
224
|
+
end
|
225
|
+
else
|
226
|
+
xml.tag! 'AcctNo', credit_card.number
|
227
|
+
xml.tag! 'ExpDate', expdate(credit_card)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
xml.tag! 'CardType', CARD_CODES[credit_card.brand] if credit_card.brand
|
231
|
+
|
232
|
+
include_cvv = !%w(Return PreAuthCapture).include?(action) && !credit_card.track_data.present?
|
233
|
+
xml.tag! 'CVVData', credit_card.verification_value if include_cvv && credit_card.verification_value
|
234
|
+
end
|
235
|
+
|
236
|
+
def add_address(xml, options)
|
237
|
+
if billing_address = options[:billing_address] || options[:address]
|
238
|
+
xml.tag! 'AVS' do
|
239
|
+
xml.tag! 'Address', billing_address[:address1]
|
240
|
+
xml.tag! 'Zip', billing_address[:zip]
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def parse(action, body)
|
246
|
+
response = {}
|
247
|
+
hashify_xml!(unescape_xml(body), response)
|
248
|
+
response
|
249
|
+
end
|
250
|
+
|
251
|
+
def hashify_xml!(xml, response)
|
252
|
+
xml = REXML::Document.new(xml)
|
253
|
+
|
254
|
+
xml.elements.each('//CmdResponse/*') do |node|
|
255
|
+
response[node.name.underscore.to_sym] = node.text
|
256
|
+
end
|
257
|
+
|
258
|
+
xml.elements.each('//TranResponse/*') do |node|
|
259
|
+
if node.name.to_s == 'Amount'
|
260
|
+
node.elements.each do |amt|
|
261
|
+
response[amt.name.underscore.to_sym] = amt.text
|
262
|
+
end
|
263
|
+
else
|
264
|
+
response[node.name.underscore.to_sym] = node.text
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def endpoint_url
|
270
|
+
URLS[test? ? :test : :live]
|
271
|
+
end
|
272
|
+
|
273
|
+
def build_soap_request(body)
|
274
|
+
xml = Builder::XmlMarkup.new
|
275
|
+
|
276
|
+
xml.instruct!
|
277
|
+
xml.tag! 'soap:Envelope', ENVELOPE_NAMESPACES do
|
278
|
+
xml.tag! 'soap:Body' do
|
279
|
+
xml.tag! 'CreditTransaction', 'xmlns' => homepage_url do
|
280
|
+
xml.tag! 'tran' do
|
281
|
+
xml << escape_xml(body)
|
282
|
+
end
|
283
|
+
xml.tag! 'pw', @options[:password]
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
xml.target!
|
288
|
+
end
|
289
|
+
|
290
|
+
def build_header
|
291
|
+
{
|
292
|
+
'SOAPAction' => 'http://www.mercurypay.com/CreditTransaction',
|
293
|
+
'Content-Type' => 'text/xml; charset=utf-8'
|
294
|
+
}
|
295
|
+
end
|
296
|
+
|
297
|
+
SUCCESS_CODES = %w[Approved Success]
|
298
|
+
|
299
|
+
def commit(action, request)
|
300
|
+
response = parse(action, ssl_post(endpoint_url, build_soap_request(request), build_header))
|
301
|
+
|
302
|
+
success = SUCCESS_CODES.include?(response[:cmd_status])
|
303
|
+
message = success ? 'Success' : message_from(response)
|
304
|
+
|
305
|
+
Response.new(success, message, response,
|
306
|
+
test: test?,
|
307
|
+
authorization: authorization_from(response),
|
308
|
+
avs_result: { code: response[:avs_result] },
|
309
|
+
cvv_result: response[:cvv_result],
|
310
|
+
error_code: success ? nil : STANDARD_ERROR_CODE_MAPPING[response[:dsix_return_code]])
|
311
|
+
end
|
312
|
+
|
313
|
+
def message_from(response)
|
314
|
+
response[:text_response]
|
315
|
+
end
|
316
|
+
|
317
|
+
def authorization_from(response)
|
318
|
+
dollars, cents = (response[:purchase] || '').split('.').collect(&:to_i)
|
319
|
+
dollars ||= 0
|
320
|
+
cents ||= 0
|
321
|
+
[
|
322
|
+
response[:invoice_no],
|
323
|
+
response[:ref_no],
|
324
|
+
response[:auth_code],
|
325
|
+
response[:acq_ref_data],
|
326
|
+
response[:process_data],
|
327
|
+
response[:record_no],
|
328
|
+
((dollars * 100) + cents).to_s
|
329
|
+
].join(';')
|
330
|
+
end
|
331
|
+
|
332
|
+
def split_authorization(authorization)
|
333
|
+
invoice_no, ref_no, auth_code, acq_ref_data, process_data, record_no, amount = authorization.split(';')
|
334
|
+
[invoice_no, ref_no, auth_code, acq_ref_data, process_data, record_no, amount]
|
335
|
+
end
|
336
|
+
|
337
|
+
ENVELOPE_NAMESPACES = {
|
338
|
+
'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
|
339
|
+
'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/',
|
340
|
+
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance'
|
341
|
+
}
|
342
|
+
|
343
|
+
def escape_xml(xml)
|
344
|
+
"\n<![CDATA[\n#{xml}\n]]>\n"
|
345
|
+
end
|
346
|
+
|
347
|
+
def unescape_xml(escaped_xml)
|
348
|
+
escaped_xml.gsub(/\>/, '>').gsub(/\</, '<')
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
@@ -0,0 +1,293 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
# For more information on the Metrics Global Payment Gateway, visit the {Metrics Global website}[www.metricsglobal.com].
|
4
|
+
# Further documentation on AVS and CVV response codes are available under the support section of the Metrics Global
|
5
|
+
# control panel.
|
6
|
+
#
|
7
|
+
# === Metrics Global Payment Gateway Authentication
|
8
|
+
#
|
9
|
+
# The login and password for the gateway are the same as the username and password used to log in to the Metrics Global
|
10
|
+
# control panel. Contact Metrics Global support to receive credentials for the control panel.
|
11
|
+
#
|
12
|
+
# === Demo Account
|
13
|
+
#
|
14
|
+
# There is a public demo account available with the following credentials:
|
15
|
+
#
|
16
|
+
# Login: demo
|
17
|
+
# Password: password
|
18
|
+
class MetricsGlobalGateway < Gateway
|
19
|
+
API_VERSION = '3.1'
|
20
|
+
|
21
|
+
class_attribute :test_url, :live_url
|
22
|
+
|
23
|
+
self.test_url = 'https://secure.metricsglobalgateway.com/gateway/transact.dll?testing=true'
|
24
|
+
self.live_url = 'https://secure.metricsglobalgateway.com/gateway/transact.dll'
|
25
|
+
|
26
|
+
class_attribute :duplicate_window
|
27
|
+
|
28
|
+
APPROVED, DECLINED, ERROR, FRAUD_REVIEW = 1, 2, 3, 4
|
29
|
+
|
30
|
+
RESPONSE_CODE, RESPONSE_REASON_CODE, RESPONSE_REASON_TEXT = 0, 2, 3
|
31
|
+
AVS_RESULT_CODE, TRANSACTION_ID, CARD_CODE_RESPONSE_CODE = 5, 6, 38
|
32
|
+
|
33
|
+
self.supported_countries = ['US']
|
34
|
+
self.supported_cardtypes = %i[visa master american_express discover diners_club jcb]
|
35
|
+
self.homepage_url = 'http://www.metricsglobal.com'
|
36
|
+
self.display_name = 'Metrics Global'
|
37
|
+
|
38
|
+
CARD_CODE_ERRORS = %w(N S)
|
39
|
+
AVS_ERRORS = %w(A E N R W Z)
|
40
|
+
AVS_REASON_CODES = %w(27 45)
|
41
|
+
|
42
|
+
# Creates a new MetricsGlobalGateway
|
43
|
+
#
|
44
|
+
# The gateway requires that a valid login and password be passed
|
45
|
+
# in the +options+ hash.
|
46
|
+
#
|
47
|
+
# ==== Options
|
48
|
+
#
|
49
|
+
# * <tt>:login</tt> -- The username required to access the Metrics Global control panel. (REQUIRED)
|
50
|
+
# * <tt>:password</tt> -- The password required to access the Metrics Global control panel. (REQUIRED)
|
51
|
+
# * <tt>:test</tt> -- +true+ or +false+. If true, perform transactions against the test server.
|
52
|
+
# Otherwise, perform transactions against the production server.
|
53
|
+
def initialize(options = {})
|
54
|
+
requires!(options, :login, :password)
|
55
|
+
super
|
56
|
+
end
|
57
|
+
|
58
|
+
# Performs an authorization, which reserves the funds on the customer's credit card, but does not
|
59
|
+
# charge the card.
|
60
|
+
#
|
61
|
+
# ==== Parameters
|
62
|
+
#
|
63
|
+
# * <tt>money</tt> -- The amount to be authorized as an Integer value in cents.
|
64
|
+
# * <tt>creditcard</tt> -- The CreditCard details for the transaction.
|
65
|
+
# * <tt>options</tt> -- A hash of optional parameters.
|
66
|
+
def authorize(money, creditcard, options = {})
|
67
|
+
post = {}
|
68
|
+
add_invoice(post, options)
|
69
|
+
add_creditcard(post, creditcard)
|
70
|
+
add_address(post, options)
|
71
|
+
add_customer_data(post, options)
|
72
|
+
add_duplicate_window(post)
|
73
|
+
|
74
|
+
commit('AUTH_ONLY', money, post)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Perform a purchase, which is essentially an authorization and capture in a single operation.
|
78
|
+
#
|
79
|
+
# ==== Parameters
|
80
|
+
#
|
81
|
+
# * <tt>money</tt> -- The amount to be purchased as an Integer value in cents.
|
82
|
+
# * <tt>creditcard</tt> -- The CreditCard details for the transaction.
|
83
|
+
# * <tt>options</tt> -- A hash of optional parameters.
|
84
|
+
def purchase(money, creditcard, options = {})
|
85
|
+
post = {}
|
86
|
+
add_invoice(post, options)
|
87
|
+
add_creditcard(post, creditcard)
|
88
|
+
add_address(post, options)
|
89
|
+
add_customer_data(post, options)
|
90
|
+
add_duplicate_window(post)
|
91
|
+
|
92
|
+
commit('AUTH_CAPTURE', money, post)
|
93
|
+
end
|
94
|
+
|
95
|
+
# Captures the funds from an authorized transaction.
|
96
|
+
#
|
97
|
+
# ==== Parameters
|
98
|
+
#
|
99
|
+
# * <tt>money</tt> -- The amount to be captured as an Integer value in cents.
|
100
|
+
# * <tt>authorization</tt> -- The authorization returned from the previous authorize request.
|
101
|
+
def capture(money, authorization, options = {})
|
102
|
+
post = { trans_id: authorization }
|
103
|
+
add_customer_data(post, options)
|
104
|
+
commit('PRIOR_AUTH_CAPTURE', money, post)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Void a previous transaction
|
108
|
+
#
|
109
|
+
# ==== Parameters
|
110
|
+
#
|
111
|
+
# * <tt>authorization</tt> - The authorization returned from the previous authorize request.
|
112
|
+
def void(authorization, options = {})
|
113
|
+
post = { trans_id: authorization }
|
114
|
+
add_duplicate_window(post)
|
115
|
+
commit('VOID', nil, post)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Refund a transaction.
|
119
|
+
#
|
120
|
+
# This transaction indicates to the gateway that
|
121
|
+
# money should flow from the merchant to the customer.
|
122
|
+
#
|
123
|
+
# ==== Parameters
|
124
|
+
#
|
125
|
+
# * <tt>money</tt> -- The amount to be credited to the customer as an Integer value in cents.
|
126
|
+
# * <tt>identification</tt> -- The ID of the original transaction against which the refund is being issued.
|
127
|
+
# * <tt>options</tt> -- A hash of parameters.
|
128
|
+
#
|
129
|
+
# ==== Options
|
130
|
+
#
|
131
|
+
# * <tt>:card_number</tt> -- The credit card number the refund is being issued to. (REQUIRED)
|
132
|
+
# * <tt>:first_name</tt> -- The first name of the account being refunded.
|
133
|
+
# * <tt>:last_name</tt> -- The last name of the account being refunded.
|
134
|
+
# * <tt>:zip</tt> -- The postal code of the account being refunded.
|
135
|
+
def refund(money, identification, options = {})
|
136
|
+
requires!(options, :card_number)
|
137
|
+
|
138
|
+
post = { trans_id: identification,
|
139
|
+
card_num: options[:card_number] }
|
140
|
+
|
141
|
+
post[:first_name] = options[:first_name] if options[:first_name]
|
142
|
+
post[:last_name] = options[:last_name] if options[:last_name]
|
143
|
+
post[:zip] = options[:zip] if options[:zip]
|
144
|
+
|
145
|
+
add_invoice(post, options)
|
146
|
+
add_duplicate_window(post)
|
147
|
+
|
148
|
+
commit('CREDIT', money, post)
|
149
|
+
end
|
150
|
+
|
151
|
+
def credit(money, identification, options = {})
|
152
|
+
ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
|
153
|
+
refund(money, identification, options)
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
def commit(action, money, parameters)
|
159
|
+
parameters[:amount] = amount(money) unless action == 'VOID'
|
160
|
+
|
161
|
+
# Only activate the test_request when the :test option is passed in
|
162
|
+
parameters[:test_request] = @options[:test] ? 'TRUE' : 'FALSE'
|
163
|
+
|
164
|
+
url = test? ? self.test_url : self.live_url
|
165
|
+
data = ssl_post url, post_data(action, parameters)
|
166
|
+
|
167
|
+
response = parse(data)
|
168
|
+
|
169
|
+
message = message_from(response)
|
170
|
+
|
171
|
+
# Return the response. The authorization can be taken out of the transaction_id
|
172
|
+
# Test Mode on/off is something we have to parse from the response text.
|
173
|
+
# It usually looks something like this
|
174
|
+
#
|
175
|
+
# (TESTMODE) Successful Sale
|
176
|
+
test_mode = test? || message =~ /TESTMODE/
|
177
|
+
|
178
|
+
Response.new(success?(response), message, response,
|
179
|
+
test: test_mode,
|
180
|
+
authorization: response[:transaction_id],
|
181
|
+
fraud_review: fraud_review?(response),
|
182
|
+
avs_result: { code: response[:avs_result_code] },
|
183
|
+
cvv_result: response[:card_code])
|
184
|
+
end
|
185
|
+
|
186
|
+
def success?(response)
|
187
|
+
response[:response_code] == APPROVED
|
188
|
+
end
|
189
|
+
|
190
|
+
def fraud_review?(response)
|
191
|
+
response[:response_code] == FRAUD_REVIEW
|
192
|
+
end
|
193
|
+
|
194
|
+
def parse(body)
|
195
|
+
fields = split(body)
|
196
|
+
|
197
|
+
results = {
|
198
|
+
response_code: fields[RESPONSE_CODE].to_i,
|
199
|
+
response_reason_code: fields[RESPONSE_REASON_CODE],
|
200
|
+
response_reason_text: fields[RESPONSE_REASON_TEXT],
|
201
|
+
avs_result_code: fields[AVS_RESULT_CODE],
|
202
|
+
transaction_id: fields[TRANSACTION_ID],
|
203
|
+
card_code: fields[CARD_CODE_RESPONSE_CODE]
|
204
|
+
}
|
205
|
+
results
|
206
|
+
end
|
207
|
+
|
208
|
+
def post_data(action, parameters = {})
|
209
|
+
post = {}
|
210
|
+
|
211
|
+
post[:version] = API_VERSION
|
212
|
+
post[:login] = @options[:login]
|
213
|
+
post[:tran_key] = @options[:password]
|
214
|
+
post[:relay_response] = 'FALSE'
|
215
|
+
post[:type] = action
|
216
|
+
post[:delim_data] = 'TRUE'
|
217
|
+
post[:delim_char] = ','
|
218
|
+
post[:encap_char] = '$'
|
219
|
+
post[:solution_ID] = application_id if application_id
|
220
|
+
|
221
|
+
request = post.merge(parameters).collect { |key, value| "x_#{key}=#{CGI.escape(value.to_s)}" }.join('&')
|
222
|
+
request
|
223
|
+
end
|
224
|
+
|
225
|
+
def add_invoice(post, options)
|
226
|
+
post[:invoice_num] = options[:order_id]
|
227
|
+
post[:description] = options[:description]
|
228
|
+
end
|
229
|
+
|
230
|
+
def add_creditcard(post, creditcard)
|
231
|
+
post[:card_num] = creditcard.number
|
232
|
+
post[:card_code] = creditcard.verification_value if creditcard.verification_value?
|
233
|
+
post[:exp_date] = expdate(creditcard)
|
234
|
+
post[:first_name] = creditcard.first_name
|
235
|
+
post[:last_name] = creditcard.last_name
|
236
|
+
end
|
237
|
+
|
238
|
+
def add_customer_data(post, options)
|
239
|
+
if options.has_key? :email
|
240
|
+
post[:email] = options[:email]
|
241
|
+
post[:email_customer] = false
|
242
|
+
end
|
243
|
+
|
244
|
+
post[:cust_id] = options[:customer] if options.has_key? :customer
|
245
|
+
|
246
|
+
post[:customer_ip] = options[:ip] if options.has_key? :ip
|
247
|
+
end
|
248
|
+
|
249
|
+
# x_duplicate_window won't be sent by default, because sending it changes the response.
|
250
|
+
# "If this field is present in the request with or without a value, an enhanced duplicate transaction response will be sent."
|
251
|
+
def add_duplicate_window(post)
|
252
|
+
post[:duplicate_window] = duplicate_window unless duplicate_window.nil?
|
253
|
+
end
|
254
|
+
|
255
|
+
def add_address(post, options)
|
256
|
+
if address = options[:billing_address] || options[:address]
|
257
|
+
post[:address] = address[:address1].to_s
|
258
|
+
post[:company] = address[:company].to_s
|
259
|
+
post[:phone] = address[:phone].to_s
|
260
|
+
post[:zip] = address[:zip].to_s
|
261
|
+
post[:city] = address[:city].to_s
|
262
|
+
post[:country] = address[:country].to_s
|
263
|
+
post[:state] = address[:state].blank? ? 'n/a' : address[:state]
|
264
|
+
end
|
265
|
+
|
266
|
+
if address = options[:shipping_address]
|
267
|
+
post[:ship_to_first_name] = address[:first_name].to_s
|
268
|
+
post[:ship_to_last_name] = address[:last_name].to_s
|
269
|
+
post[:ship_to_address] = address[:address1].to_s
|
270
|
+
post[:ship_to_company] = address[:company].to_s
|
271
|
+
post[:ship_to_phone] = address[:phone].to_s
|
272
|
+
post[:ship_to_zip] = address[:zip].to_s
|
273
|
+
post[:ship_to_city] = address[:city].to_s
|
274
|
+
post[:ship_to_country] = address[:country].to_s
|
275
|
+
post[:ship_to_state] = address[:state].blank? ? 'n/a' : address[:state]
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def message_from(results)
|
280
|
+
if results[:response_code] == DECLINED
|
281
|
+
return CVVResult.messages[results[:card_code]] if CARD_CODE_ERRORS.include?(results[:card_code])
|
282
|
+
return AVSResult.messages[results[:avs_result_code]] if AVS_REASON_CODES.include?(results[:response_reason_code]) && AVS_ERRORS.include?(results[:avs_result_code])
|
283
|
+
end
|
284
|
+
|
285
|
+
(results[:response_reason_text] ? results[:response_reason_text].chomp('.') : '')
|
286
|
+
end
|
287
|
+
|
288
|
+
def split(response)
|
289
|
+
response[1..-2].split(/\$,\$/)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|