activemerchant 1.133.0 → 1.137.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 +4 -4
- data/CHANGELOG +240 -0
- data/lib/active_merchant/billing/check.rb +2 -2
- data/lib/active_merchant/billing/compatibility.rb +4 -4
- data/lib/active_merchant/billing/credit_card.rb +11 -8
- data/lib/active_merchant/billing/credit_card_formatting.rb +4 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +59 -6
- data/lib/active_merchant/billing/gateway.rb +9 -0
- data/lib/active_merchant/billing/gateways/adyen.rb +162 -43
- data/lib/active_merchant/billing/gateways/airwallex.rb +26 -12
- data/lib/active_merchant/billing/gateways/alelo.rb +23 -5
- data/lib/active_merchant/billing/gateways/authorize_net.rb +43 -35
- data/lib/active_merchant/billing/gateways/authorize_net_arb.rb +10 -6
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +1 -3
- data/lib/active_merchant/billing/gateways/axcessms.rb +6 -2
- data/lib/active_merchant/billing/gateways/banwire.rb +4 -2
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +7 -3
- data/lib/active_merchant/billing/gateways/blue_pay.rb +13 -5
- data/lib/active_merchant/billing/gateways/blue_snap.rb +5 -5
- data/lib/active_merchant/billing/gateways/braintree/token_nonce.rb +65 -20
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +226 -73
- data/lib/active_merchant/billing/gateways/braintree_orange.rb +1 -1
- data/lib/active_merchant/billing/gateways/card_connect.rb +5 -2
- data/lib/active_merchant/billing/gateways/card_stream.rb +4 -6
- data/lib/active_merchant/billing/gateways/cashnet.rb +1 -1
- data/lib/active_merchant/billing/gateways/cecabank/cecabank_common.rb +36 -0
- data/lib/active_merchant/billing/gateways/cecabank/cecabank_json.rb +316 -0
- data/lib/active_merchant/billing/gateways/cecabank/cecabank_xml.rb +220 -0
- data/lib/active_merchant/billing/gateways/cecabank.rb +7 -240
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +238 -34
- data/lib/active_merchant/billing/gateways/commerce_hub.rb +63 -6
- data/lib/active_merchant/billing/gateways/credorax.rb +3 -5
- data/lib/active_merchant/billing/gateways/cyber_source.rb +185 -47
- data/lib/active_merchant/billing/gateways/cyber_source_rest.rb +102 -58
- data/lib/active_merchant/billing/gateways/d_local.rb +26 -15
- data/lib/active_merchant/billing/gateways/data_cash.rb +21 -17
- data/lib/active_merchant/billing/gateways/datatrans.rb +279 -0
- data/lib/active_merchant/billing/gateways/decidir.rb +53 -18
- data/lib/active_merchant/billing/gateways/decidir_plus.rb +4 -1
- data/lib/active_merchant/billing/gateways/deepstack.rb +382 -0
- data/lib/active_merchant/billing/gateways/ebanx.rb +40 -36
- data/lib/active_merchant/billing/gateways/efsnet.rb +6 -2
- data/lib/active_merchant/billing/gateways/elavon.rb +99 -33
- data/lib/active_merchant/billing/gateways/element.rb +36 -7
- data/lib/active_merchant/billing/gateways/epay.rb +6 -2
- data/lib/active_merchant/billing/gateways/evo_ca.rb +6 -2
- data/lib/active_merchant/billing/gateways/eway.rb +4 -2
- data/lib/active_merchant/billing/gateways/eway_managed.rb +6 -2
- data/lib/active_merchant/billing/gateways/exact.rb +6 -2
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +31 -3
- data/lib/active_merchant/billing/gateways/federated_canada.rb +6 -2
- data/lib/active_merchant/billing/gateways/first_pay/first_pay_common.rb +15 -0
- data/lib/active_merchant/billing/gateways/first_pay/first_pay_json.rb +190 -0
- data/lib/active_merchant/billing/gateways/first_pay/first_pay_xml.rb +183 -0
- data/lib/active_merchant/billing/gateways/first_pay.rb +6 -172
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +6 -2
- data/lib/active_merchant/billing/gateways/firstdata_e4_v27.rb +7 -3
- data/lib/active_merchant/billing/gateways/flex_charge.rb +347 -0
- data/lib/active_merchant/billing/gateways/garanti.rb +4 -2
- data/lib/active_merchant/billing/gateways/global_collect.rb +45 -37
- data/lib/active_merchant/billing/gateways/hi_pay.rb +286 -0
- data/lib/active_merchant/billing/gateways/hps.rb +1 -1
- data/lib/active_merchant/billing/gateways/iats_payments.rb +7 -2
- data/lib/active_merchant/billing/gateways/inspire.rb +6 -4
- data/lib/active_merchant/billing/gateways/instapay.rb +7 -4
- data/lib/active_merchant/billing/gateways/ipg.rb +9 -5
- data/lib/active_merchant/billing/gateways/iridium.rb +15 -5
- data/lib/active_merchant/billing/gateways/itransact.rb +6 -2
- data/lib/active_merchant/billing/gateways/iveri.rb +3 -3
- data/lib/active_merchant/billing/gateways/ixopay.rb +2 -2
- data/lib/active_merchant/billing/gateways/jetpay.rb +4 -2
- data/lib/active_merchant/billing/gateways/jetpay_v2.rb +4 -2
- data/lib/active_merchant/billing/gateways/kushki.rb +72 -12
- data/lib/active_merchant/billing/gateways/linkpoint.rb +6 -2
- data/lib/active_merchant/billing/gateways/litle.rb +33 -50
- data/lib/active_merchant/billing/gateways/mastercard.rb +4 -4
- data/lib/active_merchant/billing/gateways/maxipago.rb +2 -2
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +8 -5
- data/lib/active_merchant/billing/gateways/merchant_ware.rb +11 -4
- data/lib/active_merchant/billing/gateways/merchant_ware_version_four.rb +11 -4
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +19 -3
- data/lib/active_merchant/billing/gateways/mercury.rb +6 -2
- data/lib/active_merchant/billing/gateways/metrics_global.rb +8 -6
- data/lib/active_merchant/billing/gateways/migs/migs_codes.rb +1 -0
- data/lib/active_merchant/billing/gateways/migs.rb +6 -2
- data/lib/active_merchant/billing/gateways/mit.rb +8 -3
- data/lib/active_merchant/billing/gateways/modern_payments_cim.rb +18 -10
- data/lib/active_merchant/billing/gateways/monei.rb +1 -1
- data/lib/active_merchant/billing/gateways/moneris.rb +9 -3
- data/lib/active_merchant/billing/gateways/money_movers.rb +6 -2
- data/lib/active_merchant/billing/gateways/nab_transact.rb +12 -4
- data/lib/active_merchant/billing/gateways/net_registry.rb +6 -2
- data/lib/active_merchant/billing/gateways/netbanx.rb +1 -3
- data/lib/active_merchant/billing/gateways/netbilling.rb +6 -2
- data/lib/active_merchant/billing/gateways/network_merchants.rb +6 -2
- data/lib/active_merchant/billing/gateways/nmi.rb +18 -6
- data/lib/active_merchant/billing/gateways/ogone.rb +6 -2
- data/lib/active_merchant/billing/gateways/openpay.rb +4 -2
- data/lib/active_merchant/billing/gateways/opp.rb +1 -2
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +6 -2
- data/lib/active_merchant/billing/gateways/orbital/orbital_soft_descriptors.rb +1 -3
- data/lib/active_merchant/billing/gateways/orbital.rb +83 -24
- data/lib/active_merchant/billing/gateways/pac_net_raven.rb +7 -4
- data/lib/active_merchant/billing/gateways/pay_gate_xml.rb +6 -2
- data/lib/active_merchant/billing/gateways/pay_hub.rb +4 -2
- data/lib/active_merchant/billing/gateways/pay_junction.rb +6 -2
- data/lib/active_merchant/billing/gateways/pay_secure.rb +6 -2
- data/lib/active_merchant/billing/gateways/pay_trace.rb +31 -18
- data/lib/active_merchant/billing/gateways/payeezy.rb +19 -8
- data/lib/active_merchant/billing/gateways/payex.rb +4 -2
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -1
- data/lib/active_merchant/billing/gateways/payflow.rb +1 -3
- data/lib/active_merchant/billing/gateways/payment_express.rb +8 -4
- data/lib/active_merchant/billing/gateways/paymentez.rb +23 -11
- data/lib/active_merchant/billing/gateways/paysafe.rb +12 -11
- data/lib/active_merchant/billing/gateways/payscout.rb +7 -4
- data/lib/active_merchant/billing/gateways/paystation.rb +7 -3
- data/lib/active_merchant/billing/gateways/payway.rb +6 -2
- data/lib/active_merchant/billing/gateways/payway_dot_com.rb +2 -2
- data/lib/active_merchant/billing/gateways/pin.rb +22 -4
- data/lib/active_merchant/billing/gateways/plexo.rb +49 -10
- data/lib/active_merchant/billing/gateways/plugnpay.rb +6 -2
- data/lib/active_merchant/billing/gateways/priority.rb +6 -5
- data/lib/active_merchant/billing/gateways/psigate.rb +6 -2
- data/lib/active_merchant/billing/gateways/psl_card.rb +6 -2
- data/lib/active_merchant/billing/gateways/qbms.rb +6 -2
- data/lib/active_merchant/billing/gateways/quantum.rb +6 -2
- data/lib/active_merchant/billing/gateways/quickbooks.rb +6 -5
- data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +7 -4
- data/lib/active_merchant/billing/gateways/quickpay/quickpay_v4to7.rb +6 -2
- data/lib/active_merchant/billing/gateways/rapyd.rb +148 -46
- data/lib/active_merchant/billing/gateways/reach.rb +11 -4
- data/lib/active_merchant/billing/gateways/redsys.rb +2 -10
- data/lib/active_merchant/billing/gateways/redsys_rest.rb +507 -0
- data/lib/active_merchant/billing/gateways/s5.rb +3 -3
- data/lib/active_merchant/billing/gateways/safe_charge.rb +36 -16
- data/lib/active_merchant/billing/gateways/sage.rb +12 -4
- data/lib/active_merchant/billing/gateways/sage_pay.rb +79 -5
- data/lib/active_merchant/billing/gateways/sallie_mae.rb +6 -2
- data/lib/active_merchant/billing/gateways/secure_net.rb +6 -2
- data/lib/active_merchant/billing/gateways/secure_pay.rb +8 -6
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +12 -4
- data/lib/active_merchant/billing/gateways/secure_pay_tech.rb +6 -2
- data/lib/active_merchant/billing/gateways/securion_pay.rb +24 -10
- data/lib/active_merchant/billing/gateways/shift4.rb +17 -20
- data/lib/active_merchant/billing/gateways/shift4_v2.rb +117 -0
- data/lib/active_merchant/billing/gateways/simetrik.rb +17 -11
- data/lib/active_merchant/billing/gateways/skip_jack.rb +6 -2
- data/lib/active_merchant/billing/gateways/smart_ps.rb +7 -4
- data/lib/active_merchant/billing/gateways/so_easy_pay.rb +4 -2
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +2 -4
- data/lib/active_merchant/billing/gateways/stripe.rb +53 -21
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +199 -50
- data/lib/active_merchant/billing/gateways/sum_up.rb +223 -0
- data/lib/active_merchant/billing/gateways/swipe_checkout.rb +4 -2
- data/lib/active_merchant/billing/gateways/telr.rb +3 -4
- data/lib/active_merchant/billing/gateways/trans_first.rb +1 -2
- data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +8 -16
- data/lib/active_merchant/billing/gateways/transact_pro.rb +1 -1
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +6 -2
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +9 -8
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +6 -2
- data/lib/active_merchant/billing/gateways/vanco.rb +2 -4
- data/lib/active_merchant/billing/gateways/vantiv_express.rb +587 -0
- data/lib/active_merchant/billing/gateways/verifi.rb +6 -2
- data/lib/active_merchant/billing/gateways/viaklix.rb +6 -2
- data/lib/active_merchant/billing/gateways/visanet_peru.rb +2 -2
- data/lib/active_merchant/billing/gateways/vpos.rb +3 -3
- data/lib/active_merchant/billing/gateways/wirecard.rb +7 -3
- data/lib/active_merchant/billing/gateways/wompi.rb +5 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +140 -73
- data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +13 -10
- data/lib/active_merchant/billing/gateways/xpay.rb +242 -0
- data/lib/active_merchant/billing/network_tokenization_credit_card.rb +1 -1
- data/lib/active_merchant/billing/response.rb +2 -2
- data/lib/active_merchant/connection.rb +3 -17
- data/lib/active_merchant/country.rb +1 -0
- data/lib/active_merchant/errors.rb +10 -0
- data/lib/active_merchant/version.rb +1 -1
- data/lib/support/gateway_support.rb +2 -2
- data/lib/support/ssl_verify.rb +4 -4
- data/lib/support/ssl_version.rb +6 -6
- metadata +30 -9
@@ -0,0 +1,587 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'securerandom'
|
3
|
+
|
4
|
+
module ActiveMerchant #:nodoc:
|
5
|
+
module Billing #:nodoc:
|
6
|
+
class VantivExpressGateway < Gateway
|
7
|
+
self.test_url = 'https://certtransaction.elementexpress.com'
|
8
|
+
self.live_url = 'https://transaction.elementexpress.com'
|
9
|
+
|
10
|
+
self.supported_countries = ['US']
|
11
|
+
self.default_currency = 'USD'
|
12
|
+
self.supported_cardtypes = %i[visa master american_express discover diners_club jcb]
|
13
|
+
|
14
|
+
self.homepage_url = 'http://www.elementps.com'
|
15
|
+
self.display_name = 'Element'
|
16
|
+
|
17
|
+
SERVICE_TEST_URL = 'https://certservices.elementexpress.com'
|
18
|
+
SERVICE_LIVE_URL = 'https://services.elementexpress.com'
|
19
|
+
|
20
|
+
NETWORK_TOKEN_TYPE = {
|
21
|
+
apple_pay: 2,
|
22
|
+
google_pay: 1
|
23
|
+
}
|
24
|
+
|
25
|
+
CARD_PRESENT_CODE = {
|
26
|
+
'Unknown' => 1,
|
27
|
+
'Present' => 2,
|
28
|
+
'NotPresent' => 3
|
29
|
+
}
|
30
|
+
|
31
|
+
MARKET_CODE = {
|
32
|
+
'AutoRental' => 1,
|
33
|
+
'DirectMarketing' => 2,
|
34
|
+
'ECommerce' => 3,
|
35
|
+
'FoodRestaurant' => 4,
|
36
|
+
'HotelLodging' => 5,
|
37
|
+
'Petroleum' => 6,
|
38
|
+
'Retail' => 7,
|
39
|
+
'QSR' => 8,
|
40
|
+
'Grocery' => 9
|
41
|
+
}
|
42
|
+
|
43
|
+
PAYMENT_TYPE = {
|
44
|
+
'NotUsed' => 0,
|
45
|
+
'Recurring' => 1,
|
46
|
+
'Installment' => 2,
|
47
|
+
'CardHolderInitiated' => 3,
|
48
|
+
'CredentialOnFile' => 4
|
49
|
+
}
|
50
|
+
|
51
|
+
REVERSAL_TYPE = {
|
52
|
+
'System' => 0,
|
53
|
+
'Full' => 1,
|
54
|
+
'Partial' => 2
|
55
|
+
}
|
56
|
+
|
57
|
+
SUBMISSION_TYPE = {
|
58
|
+
'NotUsed' => 0,
|
59
|
+
'Initial' => 1,
|
60
|
+
'Subsequent' => 2,
|
61
|
+
'Resubmission' => 3,
|
62
|
+
'ReAuthorization' => 4,
|
63
|
+
'DelayedCharges' => 5,
|
64
|
+
'NoShow' => 6
|
65
|
+
}
|
66
|
+
|
67
|
+
LODGING_PPC = {
|
68
|
+
'NonParticipant' => 0,
|
69
|
+
'DollarLimit500' => 1,
|
70
|
+
'DollarLimit1000' => 2,
|
71
|
+
'DollarLimit1500' => 3
|
72
|
+
}
|
73
|
+
|
74
|
+
LODGING_SPC = {
|
75
|
+
'Default' => 0,
|
76
|
+
'Sale' => 1,
|
77
|
+
'NoShow' => 2,
|
78
|
+
'AdvanceDeposit' => 3
|
79
|
+
}
|
80
|
+
|
81
|
+
LODGING_CHARGE_TYPE = {
|
82
|
+
'Default' => 0,
|
83
|
+
'Restaurant' => 1,
|
84
|
+
'GiftShop' => 2
|
85
|
+
}
|
86
|
+
|
87
|
+
TERMINAL_TYPE = {
|
88
|
+
'Unknown' => 0,
|
89
|
+
'PointOfSale' => 1,
|
90
|
+
'ECommerce' => 2,
|
91
|
+
'MOTO' => 3,
|
92
|
+
'FuelPump' => 4,
|
93
|
+
'ATM' => 5,
|
94
|
+
'Voice' => 6,
|
95
|
+
'Mobile' => 7,
|
96
|
+
'WebSiteGiftCard' => 8
|
97
|
+
}
|
98
|
+
|
99
|
+
CARD_HOLDER_PRESENT_CODE = {
|
100
|
+
'Default' => 0,
|
101
|
+
'Unknown' => 1,
|
102
|
+
'Present' => 2,
|
103
|
+
'NotPresent' => 3,
|
104
|
+
'MailOrder' => 4,
|
105
|
+
'PhoneOrder' => 5,
|
106
|
+
'StandingAuth' => 6,
|
107
|
+
'ECommerce' => 7
|
108
|
+
}
|
109
|
+
|
110
|
+
CARD_INPUT_CODE = {
|
111
|
+
'Default' => 0,
|
112
|
+
'Unknown' => 1,
|
113
|
+
'MagstripeRead' => 2,
|
114
|
+
'ContactlessMagstripeRead' => 3,
|
115
|
+
'ManualKeyed' => 4,
|
116
|
+
'ManualKeyedMagstripeFailure' => 5,
|
117
|
+
'ChipRead' => 6,
|
118
|
+
'ContactlessChipRead' => 7,
|
119
|
+
'ManualKeyedChipReadFailure' => 8,
|
120
|
+
'MagstripeReadChipReadFailure' => 9,
|
121
|
+
'MagstripeReadNonTechnicalFallback' => 10
|
122
|
+
}
|
123
|
+
|
124
|
+
CVV_PRESENCE_CODE = {
|
125
|
+
'UseDefault' => 0,
|
126
|
+
'NotProvided' => 1,
|
127
|
+
'Provided' => 2,
|
128
|
+
'Illegible' => 3,
|
129
|
+
'CustomerIllegible' => 4
|
130
|
+
}
|
131
|
+
|
132
|
+
TERMINAL_CAPABILITY_CODE = {
|
133
|
+
'Default' => 0,
|
134
|
+
'Unknown' => 1,
|
135
|
+
'NoTerminal' => 2,
|
136
|
+
'MagstripeReader' => 3,
|
137
|
+
'ContactlessMagstripeReader' => 4,
|
138
|
+
'KeyEntered' => 5,
|
139
|
+
'ChipReader' => 6,
|
140
|
+
'ContactlessChipReader' => 7
|
141
|
+
}
|
142
|
+
|
143
|
+
TERMINAL_ENVIRONMENT_CODE = {
|
144
|
+
'Default' => 0,
|
145
|
+
'NoTerminal' => 1,
|
146
|
+
'LocalAttended' => 2,
|
147
|
+
'LocalUnattended' => 3,
|
148
|
+
'RemoteAttended' => 4,
|
149
|
+
'RemoteUnattended' => 5,
|
150
|
+
'ECommerce' => 6
|
151
|
+
}
|
152
|
+
|
153
|
+
def initialize(options = {})
|
154
|
+
requires!(options, :account_id, :account_token, :application_id, :acceptor_id, :application_name, :application_version)
|
155
|
+
super
|
156
|
+
end
|
157
|
+
|
158
|
+
def purchase(money, payment, options = {})
|
159
|
+
action = payment.is_a?(Check) ? 'CheckSale' : 'CreditCardSale'
|
160
|
+
eci = parse_eci(payment)
|
161
|
+
|
162
|
+
request = build_xml_request do |xml|
|
163
|
+
xml.send(action, xmlns: live_url) do
|
164
|
+
add_credentials(xml)
|
165
|
+
add_payment_method(xml, payment)
|
166
|
+
add_transaction(xml, money, options, eci)
|
167
|
+
add_terminal(xml, options, eci)
|
168
|
+
add_address(xml, options)
|
169
|
+
add_lodging(xml, options)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
commit(request, money, payment)
|
174
|
+
end
|
175
|
+
|
176
|
+
def authorize(money, payment, options = {})
|
177
|
+
eci = parse_eci(payment)
|
178
|
+
|
179
|
+
request = build_xml_request do |xml|
|
180
|
+
xml.CreditCardAuthorization(xmlns: live_url) do
|
181
|
+
add_credentials(xml)
|
182
|
+
add_payment_method(xml, payment)
|
183
|
+
add_transaction(xml, money, options, eci)
|
184
|
+
add_terminal(xml, options, eci)
|
185
|
+
add_address(xml, options)
|
186
|
+
add_lodging(xml, options)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
commit(request, money, payment)
|
191
|
+
end
|
192
|
+
|
193
|
+
def capture(money, authorization, options = {})
|
194
|
+
trans_id, _, eci = authorization.split('|')
|
195
|
+
options[:trans_id] = trans_id
|
196
|
+
|
197
|
+
request = build_xml_request do |xml|
|
198
|
+
xml.CreditCardAuthorizationCompletion(xmlns: live_url) do
|
199
|
+
add_credentials(xml)
|
200
|
+
add_transaction(xml, money, options, eci)
|
201
|
+
add_terminal(xml, options, eci)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
commit(request, money)
|
206
|
+
end
|
207
|
+
|
208
|
+
def refund(money, authorization, options = {})
|
209
|
+
trans_id, _, eci = authorization.split('|')
|
210
|
+
options[:trans_id] = trans_id
|
211
|
+
|
212
|
+
request = build_xml_request do |xml|
|
213
|
+
xml.CreditCardReturn(xmlns: live_url) do
|
214
|
+
add_credentials(xml)
|
215
|
+
add_transaction(xml, money, options, eci)
|
216
|
+
add_terminal(xml, options, eci)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
commit(request, money)
|
221
|
+
end
|
222
|
+
|
223
|
+
def credit(money, payment, options = {})
|
224
|
+
eci = parse_eci(payment)
|
225
|
+
|
226
|
+
request = build_xml_request do |xml|
|
227
|
+
xml.CreditCardCredit(xmlns: live_url) do
|
228
|
+
add_credentials(xml)
|
229
|
+
add_payment_method(xml, payment)
|
230
|
+
add_transaction(xml, money, options, eci)
|
231
|
+
add_terminal(xml, options, eci)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
commit(request, money, payment)
|
236
|
+
end
|
237
|
+
|
238
|
+
def void(authorization, options = {})
|
239
|
+
trans_id, trans_amount, eci = authorization.split('|')
|
240
|
+
options.merge!({ trans_id: trans_id, trans_amount: trans_amount, reversal_type: 1 })
|
241
|
+
|
242
|
+
request = build_xml_request do |xml|
|
243
|
+
xml.CreditCardReversal(xmlns: live_url) do
|
244
|
+
add_credentials(xml)
|
245
|
+
add_transaction(xml, trans_amount, options, eci)
|
246
|
+
add_terminal(xml, options, eci)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
commit(request, trans_amount)
|
251
|
+
end
|
252
|
+
|
253
|
+
def store(payment, options = {})
|
254
|
+
request = build_xml_request do |xml|
|
255
|
+
xml.PaymentAccountCreate(xmlns: SERVICE_LIVE_URL) do
|
256
|
+
add_credentials(xml)
|
257
|
+
add_payment_method(xml, payment)
|
258
|
+
add_payment_account(xml, payment, options[:payment_account_reference_number] || SecureRandom.hex(20))
|
259
|
+
add_address(xml, options)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
commit(request, payment, nil, :store)
|
264
|
+
end
|
265
|
+
|
266
|
+
def verify(payment, options = {})
|
267
|
+
eci = parse_eci(payment)
|
268
|
+
|
269
|
+
request = build_xml_request do |xml|
|
270
|
+
xml.CreditCardAVSOnly(xmlns: live_url) do
|
271
|
+
add_credentials(xml)
|
272
|
+
add_payment_method(xml, payment)
|
273
|
+
add_transaction(xml, 0, options, eci)
|
274
|
+
add_terminal(xml, options, eci)
|
275
|
+
add_address(xml, options)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
commit(request)
|
280
|
+
end
|
281
|
+
|
282
|
+
def supports_scrubbing?
|
283
|
+
true
|
284
|
+
end
|
285
|
+
|
286
|
+
def scrub(transcript)
|
287
|
+
transcript.
|
288
|
+
gsub(%r((<AccountToken>).+?(</AccountToken>))i, '\1[FILTERED]\2').
|
289
|
+
gsub(%r((<CardNumber>).+?(</CardNumber>))i, '\1[FILTERED]\2').
|
290
|
+
gsub(%r((<CVV>).+?(</CVV>))i, '\1[FILTERED]\2').
|
291
|
+
gsub(%r((<AccountNumber>).+?(</AccountNumber>))i, '\1[FILTERED]\2').
|
292
|
+
gsub(%r((<RoutingNumber>).+?(</RoutingNumber>))i, '\1[FILTERED]\2')
|
293
|
+
end
|
294
|
+
|
295
|
+
private
|
296
|
+
|
297
|
+
def add_credentials(xml)
|
298
|
+
xml.Credentials do
|
299
|
+
xml.AccountID @options[:account_id]
|
300
|
+
xml.AccountToken @options[:account_token]
|
301
|
+
xml.AcceptorID @options[:acceptor_id]
|
302
|
+
end
|
303
|
+
xml.Application do
|
304
|
+
xml.ApplicationID @options[:application_id]
|
305
|
+
xml.ApplicationName @options[:application_name]
|
306
|
+
xml.ApplicationVersion @options[:application_version]
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
def add_payment_method(xml, payment)
|
311
|
+
if payment.is_a?(String)
|
312
|
+
add_payment_account_id(xml, payment)
|
313
|
+
elsif payment.is_a?(Check)
|
314
|
+
add_echeck(xml, payment)
|
315
|
+
elsif payment.is_a?(NetworkTokenizationCreditCard)
|
316
|
+
add_network_tokenization_card(xml, payment)
|
317
|
+
else
|
318
|
+
add_credit_card(xml, payment)
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
def add_payment_account(xml, payment, payment_account_reference_number)
|
323
|
+
xml.PaymentAccount do
|
324
|
+
xml.PaymentAccountType payment_account_type(payment)
|
325
|
+
xml.PaymentAccountReferenceNumber payment_account_reference_number
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
def add_payment_account_id(xml, payment)
|
330
|
+
xml.PaymentAccount do
|
331
|
+
xml.PaymentAccountID payment
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
def add_transaction(xml, money, options = {}, network_token_eci = nil)
|
336
|
+
xml.Transaction do
|
337
|
+
xml.ReversalType REVERSAL_TYPE[options[:reversal_type]] || options[:reversal_type] if options[:reversal_type]
|
338
|
+
xml.TransactionID options[:trans_id] if options[:trans_id]
|
339
|
+
xml.TransactionAmount amount(money.to_i) if money
|
340
|
+
xml.MarketCode market_code(money, options, network_token_eci) if options[:market_code] || money
|
341
|
+
xml.ReferenceNumber options[:order_id].present? ? options[:order_id][0, 50] : SecureRandom.hex(20)
|
342
|
+
xml.TicketNumber options[:ticket_number] || rand(1..999999)
|
343
|
+
xml.MerchantSuppliedTransactionID options[:merchant_supplied_transaction_id] if options[:merchant_supplied_transaction_id]
|
344
|
+
xml.PaymentType PAYMENT_TYPE[options[:payment_type]] || options[:payment_type] if options[:payment_type]
|
345
|
+
xml.SubmissionType SUBMISSION_TYPE[options[:submission_type]] || options[:submission_type] if options[:submission_type]
|
346
|
+
xml.DuplicateCheckDisableFlag 1 if options[:duplicate_check_disable_flag].to_s == 'true' || options[:duplicate_override_flag].to_s == 'true'
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
def parse_eci(payment)
|
351
|
+
return nil unless payment.is_a?(NetworkTokenizationCreditCard)
|
352
|
+
|
353
|
+
if (eci = payment.eci)
|
354
|
+
eci = eci[0] == '0' ? eci.sub!(/^0/, '') : eci
|
355
|
+
return eci
|
356
|
+
else
|
357
|
+
payment.brand == 'american_express' ? '9' : '6'
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
def market_code(money, options, network_token_eci)
|
362
|
+
return 3 if network_token_eci
|
363
|
+
|
364
|
+
MARKET_CODE[options[:market_code]] || options[:market_code] || 0
|
365
|
+
end
|
366
|
+
|
367
|
+
def add_lodging(xml, options)
|
368
|
+
if options[:lodging]
|
369
|
+
lodging = parse_lodging(options[:lodging])
|
370
|
+
xml.ExtendedParameters do
|
371
|
+
xml.Lodging do
|
372
|
+
xml.LodgingAgreementNumber lodging[:agreement_number] if lodging[:agreement_number]
|
373
|
+
xml.LodgingCheckInDate lodging[:check_in_date] if lodging[:check_in_date]
|
374
|
+
xml.LodgingCheckOutDate lodging[:check_out_date] if lodging[:check_out_date]
|
375
|
+
xml.LodgingRoomAmount lodging[:room_amount] if lodging[:room_amount]
|
376
|
+
xml.LodgingRoomTax lodging[:room_tax] if lodging[:room_tax]
|
377
|
+
xml.LodgingNoShowIndicator lodging[:no_show_indicator] if lodging[:no_show_indicator]
|
378
|
+
xml.LodgingDuration lodging[:duration] if lodging[:duration]
|
379
|
+
xml.LodgingCustomerName lodging[:customer_name] if lodging[:customer_name]
|
380
|
+
xml.LodgingClientCode lodging[:client_code] if lodging[:client_code]
|
381
|
+
xml.LodgingExtraChargesDetail lodging[:extra_charges_detail] if lodging[:extra_charges_detail]
|
382
|
+
xml.LodgingExtraChargesAmounts lodging[:extra_charges_amounts] if lodging[:extra_charges_amounts]
|
383
|
+
xml.LodgingPrestigiousPropertyCode lodging[:prestigious_property_code] if lodging[:prestigious_property_code]
|
384
|
+
xml.LodgingSpecialProgramCode lodging[:special_program_code] if lodging[:special_program_code]
|
385
|
+
xml.LodgingChargeType lodging[:charge_type] if lodging[:charge_type]
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
def add_terminal(xml, options, network_token_eci = nil)
|
392
|
+
options = parse_terminal(options)
|
393
|
+
|
394
|
+
xml.Terminal do
|
395
|
+
xml.TerminalID options[:terminal_id] || '01'
|
396
|
+
xml.TerminalType options[:terminal_type] if options[:terminal_type]
|
397
|
+
xml.CardPresentCode options[:card_present_code] || 0
|
398
|
+
xml.CardholderPresentCode options[:card_holder_present_code] || 0
|
399
|
+
xml.CardInputCode options[:card_input_code] || 0
|
400
|
+
xml.CVVPresenceCode options[:cvv_presence_code] || 0
|
401
|
+
xml.TerminalCapabilityCode options[:terminal_capability_code] || 0
|
402
|
+
xml.TerminalEnvironmentCode options[:terminal_environment_code] || 0
|
403
|
+
xml.MotoECICode network_token_eci || 7
|
404
|
+
xml.PartialApprovedFlag options[:partial_approved_flag] if options[:partial_approved_flag]
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
def add_credit_card(xml, payment)
|
409
|
+
xml.Card do
|
410
|
+
xml.CardNumber payment.number
|
411
|
+
xml.ExpirationMonth format(payment.month, :two_digits)
|
412
|
+
xml.ExpirationYear format(payment.year, :two_digits)
|
413
|
+
xml.CardholderName "#{payment.first_name} #{payment.last_name}"
|
414
|
+
xml.CVV payment.verification_value
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
def add_echeck(xml, payment)
|
419
|
+
xml.DemandDepositAccount do
|
420
|
+
xml.AccountNumber payment.account_number
|
421
|
+
xml.RoutingNumber payment.routing_number
|
422
|
+
xml.DDAAccountType payment.account_type == 'checking' ? 0 : 1
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
def add_network_tokenization_card(xml, payment)
|
427
|
+
xml.Card do
|
428
|
+
xml.CardNumber payment.number
|
429
|
+
xml.ExpirationMonth format(payment.month, :two_digits)
|
430
|
+
xml.ExpirationYear format(payment.year, :two_digits)
|
431
|
+
xml.CardholderName "#{payment.first_name} #{payment.last_name}"
|
432
|
+
xml.Cryptogram payment.payment_cryptogram
|
433
|
+
xml.WalletType NETWORK_TOKEN_TYPE[payment.source]
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
def add_address(xml, options)
|
438
|
+
address = address = options[:billing_address] || options[:address]
|
439
|
+
shipping_address = options[:shipping_address]
|
440
|
+
|
441
|
+
if address || shipping_address
|
442
|
+
xml.Address do
|
443
|
+
if address
|
444
|
+
address[:email] ||= options[:email]
|
445
|
+
|
446
|
+
xml.BillingAddress1 address[:address1] if address[:address1]
|
447
|
+
xml.BillingAddress2 address[:address2] if address[:address2]
|
448
|
+
xml.BillingCity address[:city] if address[:city]
|
449
|
+
xml.BillingState address[:state] if address[:state]
|
450
|
+
xml.BillingZipcode address[:zip] if address[:zip]
|
451
|
+
xml.BillingEmail address[:email] if address[:email]
|
452
|
+
xml.BillingPhone address[:phone_number] if address[:phone_number]
|
453
|
+
end
|
454
|
+
|
455
|
+
if shipping_address
|
456
|
+
xml.ShippingAddress1 shipping_address[:address1] if shipping_address[:address1]
|
457
|
+
xml.ShippingAddress2 shipping_address[:address2] if shipping_address[:address2]
|
458
|
+
xml.ShippingCity shipping_address[:city] if shipping_address[:city]
|
459
|
+
xml.ShippingState shipping_address[:state] if shipping_address[:state]
|
460
|
+
xml.ShippingZipcode shipping_address[:zip] if shipping_address[:zip]
|
461
|
+
xml.ShippingEmail shipping_address[:email] if shipping_address[:email]
|
462
|
+
xml.ShippingPhone shipping_address[:phone_number] if shipping_address[:phone_number]
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|
466
|
+
end
|
467
|
+
|
468
|
+
def parse(xml)
|
469
|
+
response = {}
|
470
|
+
|
471
|
+
doc = Nokogiri::XML(xml)
|
472
|
+
doc.remove_namespaces!
|
473
|
+
root = doc.root.xpath('//response/*')
|
474
|
+
|
475
|
+
root = doc.root.xpath('//Response/*') if root.empty?
|
476
|
+
|
477
|
+
root.each do |node|
|
478
|
+
if node.elements.empty?
|
479
|
+
response[node.name.downcase] = node.text
|
480
|
+
else
|
481
|
+
node_name = node.name.downcase
|
482
|
+
response[node_name] = {}
|
483
|
+
|
484
|
+
node.elements.each do |childnode|
|
485
|
+
response[node_name][childnode.name.downcase] = childnode.text
|
486
|
+
end
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
490
|
+
response
|
491
|
+
end
|
492
|
+
|
493
|
+
def parse_lodging(lodging)
|
494
|
+
lodging[:prestigious_property_code] = LODGING_PPC[lodging[:prestigious_property_code]] || lodging[:prestigious_property_code] if lodging[:prestigious_property_code]
|
495
|
+
lodging[:special_program_code] = LODGING_SPC[lodging[:special_program_code]] || lodging[:special_program_code] if lodging[:special_program_code]
|
496
|
+
lodging[:charge_type] = LODGING_CHARGE_TYPE[lodging[:charge_type]] || lodging[:charge_type] if lodging[:charge_type]
|
497
|
+
|
498
|
+
lodging
|
499
|
+
end
|
500
|
+
|
501
|
+
def parse_terminal(options)
|
502
|
+
options[:terminal_type] = TERMINAL_TYPE[options[:terminal_type]] || options[:terminal_type]
|
503
|
+
options[:card_present_code] = CARD_PRESENT_CODE[options[:card_present_code]] || options[:card_present_code]
|
504
|
+
options[:card_holder_present_code] = CARD_HOLDER_PRESENT_CODE[options[:card_holder_present_code]] || options[:card_holder_present_code]
|
505
|
+
options[:card_input_code] = CARD_INPUT_CODE[options[:card_input_code]] || options[:card_input_code]
|
506
|
+
options[:cvv_presence_code] = CVV_PRESENCE_CODE[options[:cvv_presence_code]] || options[:cvv_presence_code]
|
507
|
+
options[:terminal_capability_code] = TERMINAL_CAPABILITY_CODE[options[:terminal_capability_code]] || options[:terminal_capability_code]
|
508
|
+
options[:terminal_environment_code] = TERMINAL_ENVIRONMENT_CODE[options[:terminal_environment_code]] || options[:terminal_environment_code]
|
509
|
+
|
510
|
+
options
|
511
|
+
end
|
512
|
+
|
513
|
+
def commit(xml, amount = nil, payment = nil, action = nil)
|
514
|
+
response = parse(ssl_post(url(action), xml, headers))
|
515
|
+
success = success_from(response)
|
516
|
+
|
517
|
+
Response.new(
|
518
|
+
success,
|
519
|
+
message_from(response),
|
520
|
+
response,
|
521
|
+
authorization: authorization_from(action, response, amount, payment),
|
522
|
+
avs_result: success ? avs_from(response) : nil,
|
523
|
+
cvv_result: success ? cvv_from(response) : nil,
|
524
|
+
test: test?
|
525
|
+
)
|
526
|
+
end
|
527
|
+
|
528
|
+
def authorization_from(action, response, amount, payment)
|
529
|
+
return response.dig('paymentaccount', 'paymentaccountid') if action == :store
|
530
|
+
|
531
|
+
if response['transaction']
|
532
|
+
authorization = "#{response.dig('transaction', 'transactionid')}|#{amount}"
|
533
|
+
authorization << "|#{parse_eci(payment)}" if parse_eci(payment)
|
534
|
+
authorization
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
def success_from(response)
|
539
|
+
response['expressresponsecode'] == '0'
|
540
|
+
end
|
541
|
+
|
542
|
+
def message_from(response)
|
543
|
+
response['expressresponsemessage']
|
544
|
+
end
|
545
|
+
|
546
|
+
def avs_from(response)
|
547
|
+
AVSResult.new(code: response['card']['avsresponsecode']) if response['card']
|
548
|
+
end
|
549
|
+
|
550
|
+
def cvv_from(response)
|
551
|
+
CVVResult.new(response['card']['cvvresponsecode']) if response['card']
|
552
|
+
end
|
553
|
+
|
554
|
+
def build_xml_request(&block)
|
555
|
+
builder = Nokogiri::XML::Builder.new(encoding: 'UTF-8', &block)
|
556
|
+
|
557
|
+
builder.to_xml
|
558
|
+
end
|
559
|
+
|
560
|
+
def payment_account_type(payment)
|
561
|
+
return 0 unless payment.is_a?(Check)
|
562
|
+
|
563
|
+
if payment.account_type == 'checking'
|
564
|
+
1
|
565
|
+
elsif payment.account_type == 'savings'
|
566
|
+
2
|
567
|
+
else
|
568
|
+
3
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
572
|
+
def url(action)
|
573
|
+
if action == :store
|
574
|
+
test? ? SERVICE_TEST_URL : SERVICE_LIVE_URL
|
575
|
+
else
|
576
|
+
test? ? test_url : live_url
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
580
|
+
def headers
|
581
|
+
{
|
582
|
+
'Content-Type' => 'text/xml'
|
583
|
+
}
|
584
|
+
end
|
585
|
+
end
|
586
|
+
end
|
587
|
+
end
|
@@ -194,11 +194,15 @@ module ActiveMerchant #:nodoc:
|
|
194
194
|
|
195
195
|
response = parse(ssl_post(self.live_url, post_data(trx_type, post)))
|
196
196
|
|
197
|
-
Response.new(
|
197
|
+
Response.new(
|
198
|
+
response[:response].to_i == SUCCESS,
|
199
|
+
message_from(response),
|
200
|
+
response,
|
198
201
|
test: test?,
|
199
202
|
authorization: response[:transactionid],
|
200
203
|
avs_result: { code: response[:avsresponse] },
|
201
|
-
cvv_result: response[:cvvresponse]
|
204
|
+
cvv_result: response[:cvvresponse]
|
205
|
+
)
|
202
206
|
end
|
203
207
|
|
204
208
|
def message_from(response)
|
@@ -136,11 +136,15 @@ module ActiveMerchant #:nodoc:
|
|
136
136
|
|
137
137
|
response = parse(ssl_post(test? ? self.test_url : self.live_url, post_data(parameters)))
|
138
138
|
|
139
|
-
Response.new(
|
139
|
+
Response.new(
|
140
|
+
response['result'] == APPROVED,
|
141
|
+
message_from(response),
|
142
|
+
response,
|
140
143
|
test: @options[:test] || test?,
|
141
144
|
authorization: authorization_from(response),
|
142
145
|
avs_result: { code: response['avs_response'] },
|
143
|
-
cvv_result: response['cvv2_response']
|
146
|
+
cvv_result: response['cvv2_response']
|
147
|
+
)
|
144
148
|
end
|
145
149
|
|
146
150
|
def authorization_from(response)
|
@@ -143,12 +143,12 @@ module ActiveMerchant #:nodoc:
|
|
143
143
|
end
|
144
144
|
|
145
145
|
def generate_purchase_number_stamp
|
146
|
-
|
146
|
+
rand(('9' * 12).to_i).to_s.center(12, rand(9).to_s)
|
147
147
|
end
|
148
148
|
|
149
149
|
def commit(action, params, options = {})
|
150
150
|
raw_response = ssl_request(method(action), url(action, params, options), params.to_json, headers)
|
151
|
-
response = parse(raw_response)
|
151
|
+
response = parse(raw_response).merge('purchaseNumber' => params[:purchaseNumber])
|
152
152
|
rescue ResponseError => e
|
153
153
|
raw_response = e.response.body
|
154
154
|
response_error(raw_response, options, action)
|
@@ -137,7 +137,7 @@ module ActiveMerchant #:nodoc:
|
|
137
137
|
card_number = payment.number
|
138
138
|
cvv = payment.verification_value
|
139
139
|
|
140
|
-
payload = { card_number: card_number,
|
140
|
+
payload = { card_number: card_number, cvv: cvv }.to_json
|
141
141
|
|
142
142
|
encryption_key = @encryption_key || OpenSSL::PKey::RSA.new(one_time_public_key)
|
143
143
|
|
@@ -158,10 +158,10 @@ module ActiveMerchant #:nodoc:
|
|
158
158
|
url = build_request_url(action)
|
159
159
|
begin
|
160
160
|
response = parse(ssl_post(url, post_data(parameters)))
|
161
|
-
rescue ResponseError =>
|
161
|
+
rescue ResponseError => e
|
162
162
|
# Errors are returned with helpful data,
|
163
163
|
# but get filtered out by `ssl_post` because of their HTTP status.
|
164
|
-
response = parse(
|
164
|
+
response = parse(e.response.body)
|
165
165
|
end
|
166
166
|
|
167
167
|
Response.new(
|
@@ -179,11 +179,15 @@ module ActiveMerchant #:nodoc:
|
|
179
179
|
message = response[:Message]
|
180
180
|
authorization = response[:GuWID]
|
181
181
|
|
182
|
-
Response.new(
|
182
|
+
Response.new(
|
183
|
+
success,
|
184
|
+
message,
|
185
|
+
response,
|
183
186
|
test: test?,
|
184
187
|
authorization: authorization,
|
185
188
|
avs_result: { code: avs_code(response, options) },
|
186
|
-
cvv_result: response[:CVCResponseCode]
|
189
|
+
cvv_result: response[:CVCResponseCode]
|
190
|
+
)
|
187
191
|
rescue ResponseError => e
|
188
192
|
if e.response.code == '401'
|
189
193
|
return Response.new(false, 'Invalid Login')
|
@@ -405,7 +409,7 @@ module ActiveMerchant #:nodoc:
|
|
405
409
|
'N' => 'I', # CSC Match
|
406
410
|
'U' => 'U', # Data Not Checked
|
407
411
|
'Y' => 'D', # All Data Matched
|
408
|
-
'Z' => 'P'
|
412
|
+
'Z' => 'P' # CSC and Postcode Matched
|
409
413
|
}
|
410
414
|
|
411
415
|
# Amex have different AVS response codes to visa etc
|