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,803 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/orbital/orbital_soft_descriptors'
|
2
|
+
require "rexml/document"
|
3
|
+
|
4
|
+
module ActiveMerchant #:nodoc:
|
5
|
+
module Billing #:nodoc:
|
6
|
+
# For more information on Orbital, visit the {integration center}[http://download.chasepaymentech.com]
|
7
|
+
#
|
8
|
+
# ==== Authentication Options
|
9
|
+
#
|
10
|
+
# The Orbital Gateway supports two methods of authenticating incoming requests:
|
11
|
+
# Source IP authentication and Connection Username/Password authentication
|
12
|
+
#
|
13
|
+
# In addition, these IP addresses/Connection Usernames must be affiliated with the Merchant IDs
|
14
|
+
# for which the client should be submitting transactions.
|
15
|
+
#
|
16
|
+
# This does allow Third Party Hosting service organizations presenting on behalf of other
|
17
|
+
# merchants to submit transactions. However, each time a new customer is added, the
|
18
|
+
# merchant or Third-Party hosting organization needs to ensure that the new Merchant IDs
|
19
|
+
# or Chain IDs are affiliated with the hosting companies IPs or Connection Usernames.
|
20
|
+
#
|
21
|
+
# If the merchant expects to have more than one merchant account with the Orbital
|
22
|
+
# Gateway, it should have its IP addresses/Connection Usernames affiliated at the Chain
|
23
|
+
# level hierarchy within the Orbital Gateway. Each time a new merchant ID is added, as
|
24
|
+
# long as it is placed within the same Chain, it will simply work. Otherwise, the additional
|
25
|
+
# MIDs will need to be affiliated with the merchant IPs or Connection Usernames respectively.
|
26
|
+
# For example, we generally affiliate all Salem accounts [BIN 000001] with
|
27
|
+
# their Company Number [formerly called MA #] number so all MIDs or Divisions under that
|
28
|
+
# Company will automatically be affiliated.
|
29
|
+
|
30
|
+
class OrbitalGateway < Gateway
|
31
|
+
API_VERSION = "5.6"
|
32
|
+
|
33
|
+
POST_HEADERS = {
|
34
|
+
"MIME-Version" => "1.1",
|
35
|
+
"Content-Type" => "application/PTI56",
|
36
|
+
"Content-transfer-encoding" => "text",
|
37
|
+
"Request-number" => '1',
|
38
|
+
"Document-type" => "Request",
|
39
|
+
"Interface-Version" => "Ruby|ActiveMerchant|Proprietary Gateway"
|
40
|
+
}
|
41
|
+
|
42
|
+
SUCCESS = '0'
|
43
|
+
|
44
|
+
APPROVED = [
|
45
|
+
'00', # Approved
|
46
|
+
'08', # Approved authorization, honor with ID
|
47
|
+
'11', # Approved authorization, VIP approval
|
48
|
+
'24', # Validated
|
49
|
+
'26', # Pre-noted
|
50
|
+
'27', # No reason to decline
|
51
|
+
'28', # Received and stored
|
52
|
+
'29', # Provided authorization
|
53
|
+
'31', # Request received
|
54
|
+
'32', # BIN alert
|
55
|
+
'34', # Approved for partial
|
56
|
+
'91', # Approved low fraud
|
57
|
+
'92', # Approved medium fraud
|
58
|
+
'93', # Approved high fraud
|
59
|
+
'94', # Approved fraud service unavailable
|
60
|
+
'E7', # Stored
|
61
|
+
'PA' # Partial approval
|
62
|
+
]
|
63
|
+
|
64
|
+
class_attribute :secondary_test_url, :secondary_live_url
|
65
|
+
|
66
|
+
self.test_url = "https://orbitalvar1.paymentech.net/authorize"
|
67
|
+
self.secondary_test_url = "https://orbitalvar2.paymentech.net/authorize"
|
68
|
+
|
69
|
+
self.live_url = "https://orbital1.paymentech.net/authorize"
|
70
|
+
self.secondary_live_url = "https://orbital2.paymentech.net/authorize"
|
71
|
+
|
72
|
+
self.supported_countries = ["US", "CA"]
|
73
|
+
self.default_currency = "CAD"
|
74
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb]
|
75
|
+
|
76
|
+
self.display_name = 'Orbital Paymentech'
|
77
|
+
self.homepage_url = 'http://chasepaymentech.com/'
|
78
|
+
|
79
|
+
self.money_format = :cents
|
80
|
+
|
81
|
+
AVS_SUPPORTED_COUNTRIES = ['US', 'CA', 'UK', 'GB']
|
82
|
+
|
83
|
+
CURRENCY_CODES = {
|
84
|
+
"AUD" => '036',
|
85
|
+
"CAD" => '124',
|
86
|
+
"CZK" => '203',
|
87
|
+
"DKK" => '208',
|
88
|
+
"HKD" => '344',
|
89
|
+
"ICK" => '352',
|
90
|
+
"JPY" => '392',
|
91
|
+
"MXN" => '484',
|
92
|
+
"NZD" => '554',
|
93
|
+
"NOK" => '578',
|
94
|
+
"SGD" => '702',
|
95
|
+
"SEK" => '752',
|
96
|
+
"CHF" => '756',
|
97
|
+
"GBP" => '826',
|
98
|
+
"USD" => '840',
|
99
|
+
"EUR" => '978'
|
100
|
+
}
|
101
|
+
|
102
|
+
CURRENCY_EXPONENTS = {
|
103
|
+
"AUD" => '2',
|
104
|
+
"CAD" => '2',
|
105
|
+
"CZK" => '2',
|
106
|
+
"DKK" => '2',
|
107
|
+
"HKD" => '2',
|
108
|
+
"ICK" => '2',
|
109
|
+
"JPY" => '0',
|
110
|
+
"MXN" => '2',
|
111
|
+
"NZD" => '2',
|
112
|
+
"NOK" => '2',
|
113
|
+
"SGD" => '2',
|
114
|
+
"SEK" => '2',
|
115
|
+
"CHF" => '2',
|
116
|
+
"GBP" => '2',
|
117
|
+
"USD" => '2',
|
118
|
+
"EUR" => '2'
|
119
|
+
}
|
120
|
+
|
121
|
+
# INDUSTRY TYPES
|
122
|
+
ECOMMERCE_TRANSACTION = 'EC'
|
123
|
+
RECURRING_PAYMENT_TRANSACTION = 'RC'
|
124
|
+
MAIL_ORDER_TELEPHONE_ORDER_TRANSACTION = 'MO'
|
125
|
+
INTERACTIVE_VOICE_RESPONSE = 'IV'
|
126
|
+
# INTERACTIVE_VOICE_RESPONSE = 'IN'
|
127
|
+
|
128
|
+
# Auth Only No Capture
|
129
|
+
AUTH_ONLY = 'A'
|
130
|
+
# AC - Auth and Capture = 'AC'
|
131
|
+
AUTH_AND_CAPTURE = 'AC'
|
132
|
+
# F - Force Auth No Capture and no online authorization = 'F'
|
133
|
+
FORCE_AUTH_ONLY = 'F'
|
134
|
+
# FR - Force Auth No Capture and no online authorization = 'FR'
|
135
|
+
# FC - Force Auth and Capture no online authorization = 'FC'
|
136
|
+
FORCE_AUTH_AND_CAPTURE = 'FC'
|
137
|
+
# Refund and Capture no online authorization
|
138
|
+
REFUND = 'R'
|
139
|
+
|
140
|
+
# Tax Inds
|
141
|
+
TAX_NOT_PROVIDED = 0
|
142
|
+
TAX_INCLUDED = 1
|
143
|
+
NON_TAXABLE_TRANSACTION = 2
|
144
|
+
|
145
|
+
# Customer Profile Actions
|
146
|
+
CREATE = 'C'
|
147
|
+
RETRIEVE = 'R'
|
148
|
+
UPDATE = 'U'
|
149
|
+
DELETE = 'D'
|
150
|
+
|
151
|
+
RECURRING = 'R'
|
152
|
+
DEFERRED = 'D'
|
153
|
+
|
154
|
+
# Status
|
155
|
+
# Profile Status Flag
|
156
|
+
# This field is used to set the status of a Customer Profile.
|
157
|
+
ACTIVE = 'A'
|
158
|
+
INACTIVE = 'I'
|
159
|
+
MANUAL_SUSPEND = 'MS'
|
160
|
+
|
161
|
+
# CustomerProfileOrderOverrideInd
|
162
|
+
# Defines if any Order Data can be pre-populated from
|
163
|
+
# the Customer Reference Number (CustomerRefNum)
|
164
|
+
NO_MAPPING_TO_ORDER_DATA = 'NO'
|
165
|
+
USE_CRN_FOR_ORDER_ID = 'OI'
|
166
|
+
USE_CRN_FOR_COMMENTS = 'OD'
|
167
|
+
USE_CRN_FOR_ORDER_ID_AND_COMMENTS = 'OA'
|
168
|
+
|
169
|
+
# CustomerProfileFromOrderInd
|
170
|
+
# Method to use to Generate the Customer Profile Number
|
171
|
+
# When Customer Profile Action Type = Create, defines
|
172
|
+
# what the Customer Profile Number will be:
|
173
|
+
AUTO_GENERATE = 'A' # Auto-Generate the CustomerRefNum
|
174
|
+
USE_CUSTOMER_REF_NUM = 'S' # Use CustomerRefNum field
|
175
|
+
USE_ORDER_ID = 'O' # Use OrderID field
|
176
|
+
USE_COMMENTS = 'D' # Use Comments field
|
177
|
+
|
178
|
+
SENSITIVE_FIELDS = [:account_num]
|
179
|
+
|
180
|
+
def initialize(options = {})
|
181
|
+
requires!(options, :merchant_id)
|
182
|
+
requires!(options, :login, :password) unless options[:ip_authentication]
|
183
|
+
super
|
184
|
+
end
|
185
|
+
|
186
|
+
# A – Authorization request
|
187
|
+
def authorize(money, creditcard, options = {})
|
188
|
+
order = build_new_order_xml(AUTH_ONLY, money, options) do |xml|
|
189
|
+
add_creditcard(xml, creditcard, options[:currency])
|
190
|
+
add_address(xml, creditcard, options)
|
191
|
+
if @options[:customer_profiles]
|
192
|
+
add_customer_data(xml, creditcard, options)
|
193
|
+
add_managed_billing(xml, options)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
commit(order, :authorize, options[:trace_number])
|
197
|
+
end
|
198
|
+
|
199
|
+
# AC – Authorization and Capture
|
200
|
+
def purchase(money, creditcard, options = {})
|
201
|
+
order = build_new_order_xml(AUTH_AND_CAPTURE, money, options) do |xml|
|
202
|
+
add_creditcard(xml, creditcard, options[:currency])
|
203
|
+
add_address(xml, creditcard, options)
|
204
|
+
if @options[:customer_profiles]
|
205
|
+
add_customer_data(xml, creditcard, options)
|
206
|
+
add_managed_billing(xml, options)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
commit(order, :purchase, options[:trace_number])
|
210
|
+
end
|
211
|
+
|
212
|
+
# MFC - Mark For Capture
|
213
|
+
def capture(money, authorization, options = {})
|
214
|
+
commit(build_mark_for_capture_xml(money, authorization, options), :capture)
|
215
|
+
end
|
216
|
+
|
217
|
+
# R – Refund request
|
218
|
+
def refund(money, authorization, options = {})
|
219
|
+
order = build_new_order_xml(REFUND, money, options.merge(:authorization => authorization)) do |xml|
|
220
|
+
add_refund(xml, options[:currency])
|
221
|
+
xml.tag! :CustomerRefNum, options[:customer_ref_num] if @options[:customer_profiles] && options[:profile_txn]
|
222
|
+
end
|
223
|
+
commit(order, :refund, options[:trace_number])
|
224
|
+
end
|
225
|
+
|
226
|
+
def credit(money, authorization, options= {})
|
227
|
+
ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
|
228
|
+
refund(money, authorization, options)
|
229
|
+
end
|
230
|
+
|
231
|
+
def void(authorization, options = {}, deprecated = {})
|
232
|
+
if(!options.kind_of?(Hash))
|
233
|
+
ActiveMerchant.deprecated("Calling the void method with an amount parameter is deprecated and will be removed in a future version.")
|
234
|
+
return void(options, deprecated.merge(:amount => authorization))
|
235
|
+
end
|
236
|
+
|
237
|
+
order = build_void_request_xml(authorization, options)
|
238
|
+
commit(order, :void, options[:trace_number])
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
# ==== Customer Profiles
|
243
|
+
# :customer_ref_num should be set unless your happy with Orbital providing one
|
244
|
+
#
|
245
|
+
# :customer_profile_order_override_ind can be set to map
|
246
|
+
# the CustomerRefNum to OrderID or Comments. Defaults to 'NO' - no mapping
|
247
|
+
#
|
248
|
+
# 'NO' - No mapping to order data
|
249
|
+
# 'OI' - Use <CustomerRefNum> for <OrderID>
|
250
|
+
# 'OD' - Use <CustomerRefNum> for <Comments>
|
251
|
+
# 'OA' - Use <CustomerRefNum> for <OrderID> and <Comments>
|
252
|
+
#
|
253
|
+
# :order_default_description can be set optionally. 64 char max.
|
254
|
+
#
|
255
|
+
# :order_default_amount can be set optionally. integer as cents.
|
256
|
+
#
|
257
|
+
# :status defaults to Active
|
258
|
+
#
|
259
|
+
# 'A' - Active
|
260
|
+
# 'I' - Inactive
|
261
|
+
# 'MS' - Manual Suspend
|
262
|
+
|
263
|
+
def add_customer_profile(creditcard, options = {})
|
264
|
+
options.merge!(:customer_profile_action => CREATE)
|
265
|
+
order = build_customer_request_xml(creditcard, options)
|
266
|
+
commit(order, :add_customer_profile)
|
267
|
+
end
|
268
|
+
|
269
|
+
def update_customer_profile(creditcard, options = {})
|
270
|
+
options.merge!(:customer_profile_action => UPDATE)
|
271
|
+
order = build_customer_request_xml(creditcard, options)
|
272
|
+
commit(order, :update_customer_profile)
|
273
|
+
end
|
274
|
+
|
275
|
+
def retrieve_customer_profile(customer_ref_num)
|
276
|
+
options = {:customer_profile_action => RETRIEVE, :customer_ref_num => customer_ref_num}
|
277
|
+
order = build_customer_request_xml(nil, options)
|
278
|
+
commit(order, :retrieve_customer_profile)
|
279
|
+
end
|
280
|
+
|
281
|
+
def delete_customer_profile(customer_ref_num)
|
282
|
+
options = {:customer_profile_action => DELETE, :customer_ref_num => customer_ref_num}
|
283
|
+
order = build_customer_request_xml(nil, options)
|
284
|
+
commit(order, :delete_customer_profile)
|
285
|
+
end
|
286
|
+
|
287
|
+
private
|
288
|
+
|
289
|
+
def authorization_string(*args)
|
290
|
+
args.compact.join(";")
|
291
|
+
end
|
292
|
+
|
293
|
+
def split_authorization(authorization)
|
294
|
+
authorization.split(';')
|
295
|
+
end
|
296
|
+
|
297
|
+
def add_customer_data(xml, creditcard, options)
|
298
|
+
if options[:profile_txn]
|
299
|
+
xml.tag! :CustomerRefNum, options[:customer_ref_num]
|
300
|
+
else
|
301
|
+
if options[:customer_ref_num]
|
302
|
+
if creditcard
|
303
|
+
xml.tag! :CustomerProfileFromOrderInd, USE_CUSTOMER_REF_NUM
|
304
|
+
end
|
305
|
+
xml.tag! :CustomerRefNum, options[:customer_ref_num]
|
306
|
+
else
|
307
|
+
xml.tag! :CustomerProfileFromOrderInd, AUTO_GENERATE
|
308
|
+
end
|
309
|
+
xml.tag! :CustomerProfileOrderOverrideInd, options[:customer_profile_order_override_ind] || NO_MAPPING_TO_ORDER_DATA
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
def add_soft_descriptors(xml, soft_desc)
|
314
|
+
xml.tag! :SDMerchantName, soft_desc.merchant_name if soft_desc.merchant_name
|
315
|
+
xml.tag! :SDProductDescription, soft_desc.product_description if soft_desc.product_description
|
316
|
+
xml.tag! :SDMerchantCity, soft_desc.merchant_city if soft_desc.merchant_city
|
317
|
+
xml.tag! :SDMerchantPhone, soft_desc.merchant_phone if soft_desc.merchant_phone
|
318
|
+
xml.tag! :SDMerchantURL, soft_desc.merchant_url if soft_desc.merchant_url
|
319
|
+
xml.tag! :SDMerchantEmail, soft_desc.merchant_email if soft_desc.merchant_email
|
320
|
+
end
|
321
|
+
|
322
|
+
def add_address(xml, creditcard, options)
|
323
|
+
if(address = (options[:billing_address] || options[:address]))
|
324
|
+
avs_supported = AVS_SUPPORTED_COUNTRIES.include?(address[:country].to_s)
|
325
|
+
|
326
|
+
if avs_supported
|
327
|
+
xml.tag! :AVSzip, (address[:zip] ? address[:zip].to_s[0..9] : nil)
|
328
|
+
xml.tag! :AVSaddress1, (address[:address1] ? address[:address1][0..29] : nil)
|
329
|
+
xml.tag! :AVSaddress2, (address[:address2] ? address[:address2][0..29] : nil)
|
330
|
+
xml.tag! :AVScity, (address[:city] ? address[:city][0..19] : nil)
|
331
|
+
xml.tag! :AVSstate, address[:state]
|
332
|
+
xml.tag! :AVSphoneNum, (address[:phone] ? address[:phone].scan(/\d/).join.to_s[0..13] : nil)
|
333
|
+
end
|
334
|
+
# can't look in billing address?
|
335
|
+
xml.tag! :AVSname, ((creditcard && creditcard.name) ? creditcard.name[0..29] : nil)
|
336
|
+
xml.tag! :AVScountryCode, (avs_supported ? address[:country] : '')
|
337
|
+
|
338
|
+
# Needs to come after AVScountryCode
|
339
|
+
add_destination_address(xml, address) if avs_supported
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
def add_destination_address(xml, address)
|
344
|
+
if address[:dest_zip]
|
345
|
+
xml.tag! :AVSDestzip, (address[:dest_zip] ? address[:dest_zip].to_s[0..9] : nil)
|
346
|
+
xml.tag! :AVSDestaddress1, (address[:dest_address1] ? address[:dest_address1][0..29] : nil)
|
347
|
+
xml.tag! :AVSDestaddress2, (address[:dest_address2] ? address[:dest_address2][0..29] : nil)
|
348
|
+
xml.tag! :AVSDestcity, (address[:dest_city] ? address[:dest_city][0..19] : nil)
|
349
|
+
xml.tag! :AVSDeststate, address[:dest_state]
|
350
|
+
xml.tag! :AVSDestphoneNum, (address[:dest_phone] ? address[:dest_phone].scan(/\d/).join.to_s[0..13] : nil)
|
351
|
+
|
352
|
+
xml.tag! :AVSDestname, (address[:dest_name] ? address[:dest_name][0..29] : nil)
|
353
|
+
xml.tag! :AVSDestcountryCode, address[:dest_country]
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
# For Profile requests
|
358
|
+
def add_customer_address(xml, options)
|
359
|
+
if(address = (options[:billing_address] || options[:address]))
|
360
|
+
xml.tag! :CustomerAddress1, (address[:address1] ? address[:address1][0..29] : nil)
|
361
|
+
xml.tag! :CustomerAddress2, (address[:address2] ? address[:address2][0..29] : nil)
|
362
|
+
xml.tag! :CustomerCity, (address[:city] ? address[:city][0..19] : nil)
|
363
|
+
xml.tag! :CustomerState, address[:state]
|
364
|
+
xml.tag! :CustomerZIP, (address[:zip] ? address[:zip].to_s[0..9] : nil)
|
365
|
+
xml.tag! :CustomerEmail, address[:email].to_s[0..49] if address[:email]
|
366
|
+
xml.tag! :CustomerPhone, (address[:phone] ? address[:phone].scan(/\d/).join.to_s : nil)
|
367
|
+
xml.tag! :CustomerCountryCode, (address[:country] ? address[:country][0..1] : nil)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
def add_creditcard(xml, creditcard, currency=nil)
|
372
|
+
unless creditcard.nil?
|
373
|
+
xml.tag! :AccountNum, creditcard.number
|
374
|
+
xml.tag! :Exp, expiry_date(creditcard)
|
375
|
+
end
|
376
|
+
|
377
|
+
xml.tag! :CurrencyCode, currency_code(currency)
|
378
|
+
xml.tag! :CurrencyExponent, currency_exponents(currency)
|
379
|
+
|
380
|
+
# If you are trying to collect a Card Verification Number
|
381
|
+
# (CardSecVal) for a Visa or Discover transaction, pass one of these values:
|
382
|
+
# 1 Value is Present
|
383
|
+
# 2 Value on card but illegible
|
384
|
+
# 9 Cardholder states data not available
|
385
|
+
# If the transaction is not a Visa or Discover transaction:
|
386
|
+
# Null-fill this attribute OR
|
387
|
+
# Do not submit the attribute at all.
|
388
|
+
# - http://download.chasepaymentech.com/docs/orbital/orbital_gateway_xml_specification.pdf
|
389
|
+
unless creditcard.nil?
|
390
|
+
if %w( visa discover ).include?(creditcard.brand)
|
391
|
+
xml.tag! :CardSecValInd, (creditcard.verification_value? ? '1' : '9')
|
392
|
+
end
|
393
|
+
xml.tag! :CardSecVal, creditcard.verification_value if creditcard.verification_value?
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
def add_refund(xml, currency=nil)
|
398
|
+
xml.tag! :AccountNum, nil
|
399
|
+
|
400
|
+
xml.tag! :CurrencyCode, currency_code(currency)
|
401
|
+
xml.tag! :CurrencyExponent, currency_exponents(currency)
|
402
|
+
end
|
403
|
+
|
404
|
+
def add_managed_billing(xml, options)
|
405
|
+
if mb = options[:managed_billing]
|
406
|
+
ActiveMerchant.deprecated RECURRING_DEPRECATION_MESSAGE
|
407
|
+
|
408
|
+
# default to recurring (R). Other option is deferred (D).
|
409
|
+
xml.tag! :MBType, mb[:type] || RECURRING
|
410
|
+
# default to Customer Reference Number
|
411
|
+
xml.tag! :MBOrderIdGenerationMethod, mb[:order_id_generation_method] || 'IO'
|
412
|
+
# By default use MBRecurringEndDate, set to N.
|
413
|
+
# MMDDYYYY
|
414
|
+
xml.tag! :MBRecurringStartDate, mb[:start_date].scan(/\d/).join.to_s if mb[:start_date]
|
415
|
+
# MMDDYYYY
|
416
|
+
xml.tag! :MBRecurringEndDate, mb[:end_date].scan(/\d/).join.to_s if mb[:end_date]
|
417
|
+
# By default listen to any value set in MBRecurringEndDate.
|
418
|
+
xml.tag! :MBRecurringNoEndDateFlag, mb[:no_end_date_flag] || 'N' # 'Y' || 'N' (Yes or No).
|
419
|
+
xml.tag! :MBRecurringMaxBillings, mb[:max_billings] if mb[:max_billings]
|
420
|
+
xml.tag! :MBRecurringFrequency, mb[:frequency] if mb[:frequency]
|
421
|
+
xml.tag! :MBDeferredBillDate, mb[:deferred_bill_date] if mb[:deferred_bill_date]
|
422
|
+
xml.tag! :MBMicroPaymentMaxDollarValue, mb[:max_dollar_value] if mb[:max_dollar_value]
|
423
|
+
xml.tag! :MBMicroPaymentMaxBillingDays, mb[:max_billing_days] if mb[:max_billing_days]
|
424
|
+
xml.tag! :MBMicroPaymentMaxTransactions, mb[:max_transactions] if mb[:max_transactions]
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
def parse(body)
|
429
|
+
response = {}
|
430
|
+
xml = REXML::Document.new(body)
|
431
|
+
root = REXML::XPath.first(xml, "//Response") ||
|
432
|
+
REXML::XPath.first(xml, "//ErrorResponse")
|
433
|
+
if root
|
434
|
+
root.elements.to_a.each do |node|
|
435
|
+
recurring_parse_element(response, node)
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
response.delete_if { |k,_| SENSITIVE_FIELDS.include?(k) }
|
440
|
+
end
|
441
|
+
|
442
|
+
def recurring_parse_element(response, node)
|
443
|
+
if node.has_elements?
|
444
|
+
node.elements.each{|e| recurring_parse_element(response, e) }
|
445
|
+
else
|
446
|
+
response[node.name.underscore.to_sym] = node.text
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
def commit(order, message_type, trace_number=nil)
|
451
|
+
headers = POST_HEADERS.merge("Content-length" => order.size.to_s)
|
452
|
+
headers.merge!( "Trace-number" => trace_number.to_s,
|
453
|
+
"Merchant-Id" => @options[:merchant_id] ) if @options[:retry_logic] && trace_number
|
454
|
+
request = lambda{|url| parse(ssl_post(url, order, headers))}
|
455
|
+
|
456
|
+
# Failover URL will be attempted in the event of a connection error
|
457
|
+
response = begin
|
458
|
+
request.call(remote_url)
|
459
|
+
rescue ConnectionError
|
460
|
+
request.call(remote_url(:secondary))
|
461
|
+
end
|
462
|
+
|
463
|
+
Response.new(success?(response, message_type), message_from(response), response,
|
464
|
+
{
|
465
|
+
:authorization => authorization_string(response[:tx_ref_num], response[:order_id]),
|
466
|
+
:test => self.test?,
|
467
|
+
:avs_result => OrbitalGateway::AVSResult.new(response[:avs_resp_code]),
|
468
|
+
:cvv_result => OrbitalGateway::CVVResult.new(response[:cvv2_resp_code])
|
469
|
+
}
|
470
|
+
)
|
471
|
+
end
|
472
|
+
|
473
|
+
def remote_url(url=:primary)
|
474
|
+
if url == :primary
|
475
|
+
(self.test? ? self.test_url : self.live_url)
|
476
|
+
else
|
477
|
+
(self.test? ? self.secondary_test_url : self.secondary_live_url)
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
def success?(response, message_type)
|
482
|
+
if [:refund, :void].include?(message_type)
|
483
|
+
response[:proc_status] == SUCCESS
|
484
|
+
elsif response[:customer_profile_action]
|
485
|
+
response[:profile_proc_status] == SUCCESS
|
486
|
+
else
|
487
|
+
response[:proc_status] == SUCCESS &&
|
488
|
+
APPROVED.include?(response[:resp_code])
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
def message_from(response)
|
493
|
+
response[:resp_msg] || response[:status_msg] || response[:customer_profile_message]
|
494
|
+
end
|
495
|
+
|
496
|
+
def ip_authentication?
|
497
|
+
@options[:ip_authentication] == true
|
498
|
+
end
|
499
|
+
|
500
|
+
def build_new_order_xml(action, money, parameters = {})
|
501
|
+
requires!(parameters, :order_id)
|
502
|
+
xml = xml_envelope
|
503
|
+
xml.tag! :Request do
|
504
|
+
xml.tag! :NewOrder do
|
505
|
+
add_xml_credentials(xml)
|
506
|
+
# EC - Ecommerce transaction
|
507
|
+
# RC - Recurring Payment transaction
|
508
|
+
# MO - Mail Order Telephone Order transaction
|
509
|
+
# IV - Interactive Voice Response
|
510
|
+
# IN - Interactive Voice Response
|
511
|
+
xml.tag! :IndustryType, parameters[:industry_type] || ECOMMERCE_TRANSACTION
|
512
|
+
# A - Auth Only No Capture
|
513
|
+
# AC - Auth and Capture
|
514
|
+
# F - Force Auth No Capture and no online authorization
|
515
|
+
# FR - Force Auth No Capture and no online authorization
|
516
|
+
# FC - Force Auth and Capture no online authorization
|
517
|
+
# R - Refund and Capture no online authorization
|
518
|
+
xml.tag! :MessageType, action
|
519
|
+
add_bin_merchant_and_terminal(xml, parameters)
|
520
|
+
|
521
|
+
yield xml if block_given?
|
522
|
+
|
523
|
+
xml.tag! :OrderID, format_order_id(parameters[:order_id])
|
524
|
+
xml.tag! :Amount, amount(money)
|
525
|
+
xml.tag! :Comments, parameters[:comments] if parameters[:comments]
|
526
|
+
|
527
|
+
# CustomerAni, AVSPhoneType and AVSDestPhoneType could be added here.
|
528
|
+
|
529
|
+
if parameters[:soft_descriptors].is_a?(OrbitalSoftDescriptors)
|
530
|
+
add_soft_descriptors(xml, parameters[:soft_descriptors])
|
531
|
+
end
|
532
|
+
|
533
|
+
set_recurring_ind(xml, parameters)
|
534
|
+
|
535
|
+
# Append Transaction Reference Number at the end for Refund transactions
|
536
|
+
if action == REFUND
|
537
|
+
tx_ref_num, _ = split_authorization(parameters[:authorization])
|
538
|
+
xml.tag! :TxRefNum, tx_ref_num
|
539
|
+
end
|
540
|
+
end
|
541
|
+
end
|
542
|
+
xml.target!
|
543
|
+
end
|
544
|
+
|
545
|
+
# For Canadian transactions on PNS Tampa on New Order
|
546
|
+
# RF - First Recurring Transaction
|
547
|
+
# RS - Subsequent Recurring Transactions
|
548
|
+
def set_recurring_ind(xml, parameters)
|
549
|
+
if parameters[:recurring_ind]
|
550
|
+
raise "RecurringInd must be set to either \"RF\" or \"RS\"" unless %w(RF RS).include?(parameters[:recurring_ind])
|
551
|
+
xml.tag! :RecurringInd, parameters[:recurring_ind]
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|
555
|
+
def build_mark_for_capture_xml(money, authorization, parameters = {})
|
556
|
+
tx_ref_num, order_id = split_authorization(authorization)
|
557
|
+
xml = xml_envelope
|
558
|
+
xml.tag! :Request do
|
559
|
+
xml.tag! :MarkForCapture do
|
560
|
+
add_xml_credentials(xml)
|
561
|
+
xml.tag! :OrderID, format_order_id(order_id)
|
562
|
+
xml.tag! :Amount, amount(money)
|
563
|
+
add_bin_merchant_and_terminal(xml, parameters)
|
564
|
+
xml.tag! :TxRefNum, tx_ref_num
|
565
|
+
end
|
566
|
+
end
|
567
|
+
xml.target!
|
568
|
+
end
|
569
|
+
|
570
|
+
def build_void_request_xml(authorization, parameters = {})
|
571
|
+
tx_ref_num, order_id = split_authorization(authorization)
|
572
|
+
xml = xml_envelope
|
573
|
+
xml.tag! :Request do
|
574
|
+
xml.tag! :Reversal do
|
575
|
+
add_xml_credentials(xml)
|
576
|
+
xml.tag! :TxRefNum, tx_ref_num
|
577
|
+
xml.tag! :TxRefIdx, parameters[:transaction_index]
|
578
|
+
xml.tag! :AdjustedAmt, parameters[:amount] # setting adjusted amount to nil will void entire amount
|
579
|
+
xml.tag! :OrderID, format_order_id(order_id || parameters[:order_id])
|
580
|
+
add_bin_merchant_and_terminal(xml, parameters)
|
581
|
+
xml.tag! :ReversalRetryNumber, parameters[:reversal_retry_number] if parameters[:reversal_retry_number]
|
582
|
+
xml.tag! :OnlineReversalInd, parameters[:online_reversal_ind] if parameters[:online_reversal_ind]
|
583
|
+
end
|
584
|
+
end
|
585
|
+
xml.target!
|
586
|
+
end
|
587
|
+
|
588
|
+
def currency_code(currency)
|
589
|
+
CURRENCY_CODES[(currency || self.default_currency)].to_s
|
590
|
+
end
|
591
|
+
|
592
|
+
def currency_exponents(currency)
|
593
|
+
CURRENCY_EXPONENTS[(currency || self.default_currency)].to_s
|
594
|
+
end
|
595
|
+
|
596
|
+
def expiry_date(credit_card)
|
597
|
+
"#{format(credit_card.month, :two_digits)}#{format(credit_card.year, :two_digits)}"
|
598
|
+
end
|
599
|
+
|
600
|
+
def bin
|
601
|
+
@options[:bin] || (salem_mid? ? '000001' : '000002')
|
602
|
+
end
|
603
|
+
|
604
|
+
def xml_envelope
|
605
|
+
xml = Builder::XmlMarkup.new(:indent => 2)
|
606
|
+
xml.instruct!(:xml, :version => '1.0', :encoding => 'UTF-8')
|
607
|
+
xml
|
608
|
+
end
|
609
|
+
|
610
|
+
def add_xml_credentials(xml)
|
611
|
+
unless ip_authentication?
|
612
|
+
xml.tag! :OrbitalConnectionUsername, @options[:login]
|
613
|
+
xml.tag! :OrbitalConnectionPassword, @options[:password]
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
617
|
+
def add_bin_merchant_and_terminal(xml, parameters)
|
618
|
+
xml.tag! :BIN, bin
|
619
|
+
xml.tag! :MerchantID, @options[:merchant_id]
|
620
|
+
xml.tag! :TerminalID, parameters[:terminal_id] || '001'
|
621
|
+
end
|
622
|
+
|
623
|
+
def salem_mid?
|
624
|
+
@options[:merchant_id].length == 6
|
625
|
+
end
|
626
|
+
|
627
|
+
# The valid characters include:
|
628
|
+
#
|
629
|
+
# 1. all letters and digits
|
630
|
+
# 2. - , $ @ & and a space character, though the space character cannot be the leading character
|
631
|
+
# 3. PINless Debit transactions can only use uppercase and lowercase alpha (A-Z, a-z) and numeric (0-9)
|
632
|
+
def format_order_id(order_id)
|
633
|
+
illegal_characters = /[^,$@\- \w]/
|
634
|
+
order_id = order_id.to_s.gsub(/\./, '-')
|
635
|
+
order_id.gsub!(illegal_characters, '')
|
636
|
+
order_id[0...22]
|
637
|
+
end
|
638
|
+
|
639
|
+
def build_customer_request_xml(creditcard, options = {})
|
640
|
+
xml = xml_envelope
|
641
|
+
xml.tag! :Request do
|
642
|
+
xml.tag! :Profile do
|
643
|
+
xml.tag! :OrbitalConnectionUsername, @options[:login] unless ip_authentication?
|
644
|
+
xml.tag! :OrbitalConnectionPassword, @options[:password] unless ip_authentication?
|
645
|
+
xml.tag! :CustomerBin, bin
|
646
|
+
xml.tag! :CustomerMerchantID, @options[:merchant_id]
|
647
|
+
xml.tag! :CustomerName, creditcard.name if creditcard
|
648
|
+
xml.tag! :CustomerRefNum, options[:customer_ref_num] if options[:customer_ref_num]
|
649
|
+
|
650
|
+
add_customer_address(xml, options)
|
651
|
+
|
652
|
+
xml.tag! :CustomerProfileAction, options[:customer_profile_action] # C, R, U, D
|
653
|
+
# NO No mapping to order data
|
654
|
+
# OI Use <CustomerRefNum> for <OrderID>
|
655
|
+
# OD Use <CustomerReferNum> for <Comments>
|
656
|
+
# OA Use <CustomerRefNum> for <OrderID> and <Comments>
|
657
|
+
xml.tag! :CustomerProfileOrderOverrideInd, options[:customer_profile_order_override_ind] || NO_MAPPING_TO_ORDER_DATA
|
658
|
+
|
659
|
+
if options[:customer_profile_action] == CREATE
|
660
|
+
# A Auto-Generate the CustomerRefNum
|
661
|
+
# S Use CustomerRefNum field
|
662
|
+
# O Use OrderID field
|
663
|
+
# D Use Comments field
|
664
|
+
xml.tag! :CustomerProfileFromOrderInd, (options[:customer_ref_num] ? USE_CUSTOMER_REF_NUM : AUTO_GENERATE)
|
665
|
+
end
|
666
|
+
|
667
|
+
xml.tag! :OrderDefaultDescription, options[:order_default_description][0..63] if options[:order_default_description]
|
668
|
+
xml.tag! :OrderDefaultAmount, options[:order_default_amount] if options[:order_default_amount]
|
669
|
+
|
670
|
+
if [CREATE, UPDATE].include? options[:customer_profile_action]
|
671
|
+
xml.tag! :CustomerAccountType, 'CC' # Only credit card supported
|
672
|
+
xml.tag! :Status, options[:status] || ACTIVE # Active
|
673
|
+
end
|
674
|
+
|
675
|
+
xml.tag! :CCAccountNum, creditcard.number if creditcard
|
676
|
+
xml.tag! :CCExpireDate, creditcard.expiry_date.expiration.strftime("%m%y") if creditcard
|
677
|
+
|
678
|
+
# This has to come after CCExpireDate.
|
679
|
+
add_managed_billing(xml, options)
|
680
|
+
end
|
681
|
+
end
|
682
|
+
xml.target!
|
683
|
+
end
|
684
|
+
|
685
|
+
# Unfortunately, Orbital uses their own special codes for AVS responses
|
686
|
+
# that are different than the standard codes defined in
|
687
|
+
# <tt>ActiveMerchant::Billing::AVSResult</tt>.
|
688
|
+
#
|
689
|
+
# This class encapsulates the response codes shown on page 240 of their spec:
|
690
|
+
# http://download.chasepaymentech.com/docs/orbital/orbital_gateway_xml_specification.pdf
|
691
|
+
#
|
692
|
+
class AVSResult < ActiveMerchant::Billing::AVSResult
|
693
|
+
CODES = {
|
694
|
+
'1' => 'No address supplied',
|
695
|
+
'2' => 'Bill-to address did not pass Auth Host edit checks',
|
696
|
+
'3' => 'AVS not performed',
|
697
|
+
'4' => 'Issuer does not participate in AVS',
|
698
|
+
'5' => 'Edit-error - AVS data is invalid',
|
699
|
+
'6' => 'System unavailable or time-out',
|
700
|
+
'7' => 'Address information unavailable',
|
701
|
+
'8' => 'Transaction Ineligible for AVS',
|
702
|
+
'9' => 'Zip Match/Zip 4 Match/Locale match',
|
703
|
+
'A' => 'Zip Match/Zip 4 Match/Locale no match',
|
704
|
+
'B' => 'Zip Match/Zip 4 no Match/Locale match',
|
705
|
+
'C' => 'Zip Match/Zip 4 no Match/Locale no match',
|
706
|
+
'D' => 'Zip No Match/Zip 4 Match/Locale match',
|
707
|
+
'E' => 'Zip No Match/Zip 4 Match/Locale no match',
|
708
|
+
'F' => 'Zip No Match/Zip 4 No Match/Locale match',
|
709
|
+
'G' => 'No match at all',
|
710
|
+
'H' => 'Zip Match/Locale match',
|
711
|
+
'J' => 'Issuer does not participate in Global AVS',
|
712
|
+
'JA' => 'International street address and postal match',
|
713
|
+
'JB' => 'International street address match. Postal code not verified',
|
714
|
+
'JC' => 'International street address and postal code not verified',
|
715
|
+
'JD' => 'International postal code match. Street address not verified',
|
716
|
+
'M1' => 'Cardholder name matches',
|
717
|
+
'M2' => 'Cardholder name, billing address, and postal code matches',
|
718
|
+
'M3' => 'Cardholder name and billing code matches',
|
719
|
+
'M4' => 'Cardholder name and billing address match',
|
720
|
+
'M5' => 'Cardholder name incorrect, billing address and postal code match',
|
721
|
+
'M6' => 'Cardholder name incorrect, billing postal code matches',
|
722
|
+
'M7' => 'Cardholder name incorrect, billing address matches',
|
723
|
+
'M8' => 'Cardholder name, billing address and postal code are all incorrect',
|
724
|
+
'N3' => 'Address matches, ZIP not verified',
|
725
|
+
'N4' => 'Address and ZIP code not verified due to incompatible formats',
|
726
|
+
'N5' => 'Address and ZIP code match (International only)',
|
727
|
+
'N6' => 'Address not verified (International only)',
|
728
|
+
'N7' => 'ZIP matches, address not verified',
|
729
|
+
'N8' => 'Address and ZIP code match (International only)',
|
730
|
+
'N9' => 'Address and ZIP code match (UK only)',
|
731
|
+
'R' => 'Issuer does not participate in AVS',
|
732
|
+
'UK' => 'Unknown',
|
733
|
+
'X' => 'Zip Match/Zip 4 Match/Address Match',
|
734
|
+
'Z' => 'Zip Match/Locale no match',
|
735
|
+
}
|
736
|
+
|
737
|
+
# Map vendor's AVS result code to a postal match code
|
738
|
+
ORBITAL_POSTAL_MATCH_CODE = {
|
739
|
+
'Y' => %w( 9 A B C H JA JD M2 M3 M5 N5 N8 N9 X Z ),
|
740
|
+
'N' => %w( D E F G M8 ),
|
741
|
+
'X' => %w( 4 J R ),
|
742
|
+
nil => %w( 1 2 3 5 6 7 8 JB JC M1 M4 M6 M7 N3 N4 N6 N7 UK )
|
743
|
+
}.inject({}) do |map, (type, codes)|
|
744
|
+
codes.each { |code| map[code] = type }
|
745
|
+
map
|
746
|
+
end
|
747
|
+
|
748
|
+
# Map vendor's AVS result code to a street match code
|
749
|
+
ORBITAL_STREET_MATCH_CODE = {
|
750
|
+
'Y' => %w( 9 B D F H JA JB M2 M4 M5 M6 M7 N3 N5 N7 N8 N9 X ),
|
751
|
+
'N' => %w( A C E G M8 Z ),
|
752
|
+
'X' => %w( 4 J R ),
|
753
|
+
nil => %w( 1 2 3 5 6 7 8 JC JD M1 M3 N4 N6 UK )
|
754
|
+
}.inject({}) do |map, (type, codes)|
|
755
|
+
codes.each { |code| map[code] = type }
|
756
|
+
map
|
757
|
+
end
|
758
|
+
|
759
|
+
def self.messages
|
760
|
+
CODES
|
761
|
+
end
|
762
|
+
|
763
|
+
def initialize(code)
|
764
|
+
@code = (code.blank? ? nil : code.to_s.strip.upcase)
|
765
|
+
if @code
|
766
|
+
@message = CODES[@code]
|
767
|
+
@postal_match = ORBITAL_POSTAL_MATCH_CODE[@code]
|
768
|
+
@street_match = ORBITAL_STREET_MATCH_CODE[@code]
|
769
|
+
end
|
770
|
+
end
|
771
|
+
end
|
772
|
+
|
773
|
+
# Unfortunately, Orbital uses their own special codes for CVV responses
|
774
|
+
# that are different than the standard codes defined in
|
775
|
+
# <tt>ActiveMerchant::Billing::CVVResult</tt>.
|
776
|
+
#
|
777
|
+
# This class encapsulates the response codes shown on page 255 of their spec:
|
778
|
+
# http://download.chasepaymentech.com/docs/orbital/orbital_gateway_xml_specification.pdf
|
779
|
+
#
|
780
|
+
class CVVResult < ActiveMerchant::Billing::CVVResult
|
781
|
+
MESSAGES = {
|
782
|
+
'M' => 'Match',
|
783
|
+
'N' => 'No match',
|
784
|
+
'P' => 'Not processed',
|
785
|
+
'S' => 'Should have been present',
|
786
|
+
'U' => 'Unsupported by issuer/Issuer unable to process request',
|
787
|
+
'I' => 'Invalid',
|
788
|
+
'Y' => 'Invalid',
|
789
|
+
'' => 'Not applicable'
|
790
|
+
}
|
791
|
+
|
792
|
+
def self.messages
|
793
|
+
MESSAGES
|
794
|
+
end
|
795
|
+
|
796
|
+
def initialize(code)
|
797
|
+
@code = code.blank? ? '' : code.upcase
|
798
|
+
@message = MESSAGES[@code]
|
799
|
+
end
|
800
|
+
end
|
801
|
+
end
|
802
|
+
end
|
803
|
+
end
|