activemerchant 1.62.0 → 1.79.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +420 -2
- data/README.md +1 -2
- data/lib/active_merchant/billing/credit_card.rb +13 -14
- data/lib/active_merchant/billing/credit_card_methods.rb +3 -1
- data/lib/active_merchant/billing/gateway.rb +25 -9
- data/lib/active_merchant/billing/gateways/adyen.rb +299 -0
- data/lib/active_merchant/billing/gateways/authorize_net.rb +168 -56
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +4 -2
- data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +65 -22
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +87 -7
- data/lib/active_merchant/billing/gateways/beanstream.rb +2 -0
- data/lib/active_merchant/billing/gateways/blue_snap.rb +3 -8
- data/lib/active_merchant/billing/gateways/borgun.rb +10 -10
- data/lib/active_merchant/billing/gateways/braintree/braintree_common.rb +1 -0
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +49 -15
- data/lib/active_merchant/billing/gateways/card_connect.rb +286 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +97 -2
- data/lib/active_merchant/billing/gateways/cardprocess.rb +254 -0
- data/lib/active_merchant/billing/gateways/cashnet.rb +14 -2
- data/lib/active_merchant/billing/gateways/cenpos.rb +1 -1
- data/lib/active_merchant/billing/gateways/checkout.rb +1 -1
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +44 -14
- data/lib/active_merchant/billing/gateways/citrus_pay.rb +0 -1
- data/lib/active_merchant/billing/gateways/clearhaus.rb +0 -2
- data/lib/active_merchant/billing/gateways/conekta.rb +4 -4
- data/lib/active_merchant/billing/gateways/creditcall.rb +71 -9
- data/lib/active_merchant/billing/gateways/credorax.rb +117 -5
- data/lib/active_merchant/billing/gateways/culqi.rb +279 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +54 -15
- data/lib/active_merchant/billing/gateways/data_cash.rb +12 -0
- data/lib/active_merchant/billing/gateways/dibs.rb +0 -1
- data/lib/active_merchant/billing/gateways/digitzs.rb +292 -0
- data/lib/active_merchant/billing/gateways/ebanx.rb +296 -0
- data/lib/active_merchant/billing/gateways/elavon.rb +37 -95
- data/lib/active_merchant/billing/gateways/element.rb +11 -1
- data/lib/active_merchant/billing/gateways/fat_zebra.rb +3 -29
- data/lib/active_merchant/billing/gateways/first_pay.rb +12 -10
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +37 -20
- data/lib/active_merchant/billing/gateways/forte.rb +0 -1
- data/lib/active_merchant/billing/gateways/global_collect.rb +55 -16
- data/lib/active_merchant/billing/gateways/global_transport.rb +16 -2
- data/lib/active_merchant/billing/gateways/hps.rb +12 -1
- data/lib/active_merchant/billing/gateways/iats_payments.rb +2 -2
- data/lib/active_merchant/billing/gateways/iveri.rb +251 -0
- data/lib/active_merchant/billing/gateways/jetpay.rb +12 -9
- data/lib/active_merchant/billing/gateways/jetpay_v2.rb +437 -0
- data/lib/active_merchant/billing/gateways/kushki.rb +227 -0
- data/lib/active_merchant/billing/gateways/linkpoint.rb +2 -2
- data/lib/active_merchant/billing/gateways/litle.rb +107 -30
- data/lib/active_merchant/billing/gateways/mercado_pago.rb +262 -0
- data/lib/active_merchant/billing/gateways/merchant_e_solutions.rb +11 -0
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +16 -4
- data/lib/active_merchant/billing/gateways/mercury.rb +14 -1
- data/lib/active_merchant/billing/gateways/migs.rb +28 -6
- data/lib/active_merchant/billing/gateways/moneris.rb +20 -12
- data/lib/active_merchant/billing/gateways/moneris_us.rb +11 -0
- data/lib/active_merchant/billing/gateways/mundipagg.rb +292 -0
- data/lib/active_merchant/billing/gateways/nab_transact.rb +4 -4
- data/lib/active_merchant/billing/gateways/netbanx.rb +60 -16
- data/lib/active_merchant/billing/gateways/netbilling.rb +0 -1
- data/lib/active_merchant/billing/gateways/nmi.rb +12 -1
- data/lib/active_merchant/billing/gateways/ogone.rb +1 -1
- data/lib/active_merchant/billing/gateways/omise.rb +9 -5
- data/lib/active_merchant/billing/gateways/openpay.rb +13 -0
- data/lib/active_merchant/billing/gateways/opp.rb +124 -114
- data/lib/active_merchant/billing/gateways/optimal_payment.rb +14 -1
- data/lib/active_merchant/billing/gateways/orbital.rb +83 -14
- data/lib/active_merchant/billing/gateways/pay_hub.rb +2 -2
- data/lib/active_merchant/billing/gateways/payeezy.rb +152 -46
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +12 -2
- data/lib/active_merchant/billing/gateways/payflow.rb +24 -2
- data/lib/active_merchant/billing/gateways/payment_express.rb +3 -2
- data/lib/active_merchant/billing/gateways/paymentez.rb +276 -0
- data/lib/active_merchant/billing/gateways/paymill.rb +18 -10
- data/lib/active_merchant/billing/gateways/paypal/paypal_common_api.rb +14 -0
- data/lib/active_merchant/billing/gateways/paypal.rb +0 -12
- data/lib/active_merchant/billing/gateways/paystation.rb +14 -1
- data/lib/active_merchant/billing/gateways/payu_latam.rb +102 -62
- data/lib/active_merchant/billing/gateways/pin.rb +5 -0
- data/lib/active_merchant/billing/gateways/pro_pay.rb +326 -0
- data/lib/active_merchant/billing/gateways/psigate.rb +12 -1
- data/lib/active_merchant/billing/gateways/qbms.rb +11 -0
- data/lib/active_merchant/billing/gateways/quickbooks.rb +10 -0
- data/lib/active_merchant/billing/gateways/quickpay/quickpay_v10.rb +21 -17
- data/lib/active_merchant/billing/gateways/quickpay.rb +3 -3
- data/lib/active_merchant/billing/gateways/qvalent.rb +60 -3
- data/lib/active_merchant/billing/gateways/realex.rb +16 -6
- data/lib/active_merchant/billing/gateways/redsys.rb +8 -2
- data/lib/active_merchant/billing/gateways/safe_charge.rb +262 -0
- data/lib/active_merchant/billing/gateways/sage.rb +8 -3
- data/lib/active_merchant/billing/gateways/sage_pay.rb +29 -13
- data/lib/active_merchant/billing/gateways/secure_net.rb +11 -1
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +12 -0
- data/lib/active_merchant/billing/gateways/smart_ps.rb +1 -1
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +53 -7
- data/lib/active_merchant/billing/gateways/stripe.rb +84 -26
- data/lib/active_merchant/billing/gateways/tns.rb +0 -1
- data/lib/active_merchant/billing/gateways/trans_first.rb +3 -2
- data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +61 -26
- data/lib/active_merchant/billing/gateways/trexle.rb +217 -0
- data/lib/active_merchant/billing/gateways/usa_epay_advanced.rb +114 -9
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +45 -22
- data/lib/active_merchant/billing/gateways/vanco.rb +1 -1
- data/lib/active_merchant/billing/gateways/wepay.rb +79 -46
- data/lib/active_merchant/billing/gateways/wirecard.rb +5 -4
- data/lib/active_merchant/billing/gateways/worldpay.rb +85 -20
- data/lib/active_merchant/billing/gateways/worldpay_us.rb +27 -8
- data/lib/active_merchant/billing/network_tokenization_credit_card.rb +1 -1
- data/lib/active_merchant/connection.rb +48 -12
- data/lib/active_merchant/net_http_ssl_connection.rb +9 -0
- data/lib/active_merchant/network_connection_retries.rb +6 -4
- data/lib/active_merchant/posts_data.rb +11 -1
- data/lib/active_merchant/version.rb +1 -1
- data/lib/active_merchant.rb +2 -5
- data/lib/certs/cacert.pem +85 -0
- data/lib/support/ssl_version.rb +87 -0
- metadata +25 -9
- data/lib/active_merchant/billing/gateways/barclays_epdq.rb +0 -314
@@ -0,0 +1,254 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class CardprocessGateway < Gateway
|
4
|
+
self.test_url = 'https://test.vr-pay-ecommerce.de/v1/payments'
|
5
|
+
self.live_url = 'https://vr-pay-ecommerce.de/v1/payments'
|
6
|
+
|
7
|
+
self.supported_countries = %w[ BE BG CZ DK DE EE IE ES FR HR IT CY LV LT LU
|
8
|
+
MT HU NL AT PL PT RO SI SK FI SE GB IS LI NO
|
9
|
+
CH ME MK AL RS TR BA ]
|
10
|
+
self.default_currency = 'EUR'
|
11
|
+
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb]
|
12
|
+
|
13
|
+
self.homepage_url = 'https://vr-pay-ecommerce.docs.oppwa.com/'
|
14
|
+
self.display_name = 'CardProcess VR-Pay'
|
15
|
+
self.money_format = :dollars
|
16
|
+
|
17
|
+
STANDARD_ERROR_CODE_MAPPING = {}
|
18
|
+
|
19
|
+
# Creates a new CardProcess Gateway
|
20
|
+
#
|
21
|
+
# The gateway requires a valid login, password, and entity ID
|
22
|
+
# to be passed in the +options+ hash.
|
23
|
+
#
|
24
|
+
# === Options
|
25
|
+
#
|
26
|
+
# * <tt>:user_id</tt> -- The CardProcess user ID
|
27
|
+
# * <tt>:password</tt> -- The CardProcess password
|
28
|
+
# * <tt>:entity_id</tt> -- The CardProcess channel or entity ID for any transactions
|
29
|
+
def initialize(options={})
|
30
|
+
requires!(options, :user_id, :password, :entity_id)
|
31
|
+
super
|
32
|
+
# This variable exists purely to allow remote tests to force error codes;
|
33
|
+
# the lack of a setter despite its usage is intentional.
|
34
|
+
@test_options = {}
|
35
|
+
end
|
36
|
+
|
37
|
+
def purchase(money, payment, options = {})
|
38
|
+
post = {}
|
39
|
+
add_invoice(post, money, options)
|
40
|
+
add_payment(post, payment)
|
41
|
+
add_address(post, payment, options)
|
42
|
+
add_customer_data(post, options)
|
43
|
+
|
44
|
+
commit('DB', post)
|
45
|
+
end
|
46
|
+
|
47
|
+
def authorize(money, payment, options = {})
|
48
|
+
post = {}
|
49
|
+
add_invoice(post, money, options)
|
50
|
+
add_payment(post, payment)
|
51
|
+
add_address(post, payment, options)
|
52
|
+
add_customer_data(post, options)
|
53
|
+
|
54
|
+
commit('PA', post)
|
55
|
+
end
|
56
|
+
|
57
|
+
def capture(money, authorization, options = {})
|
58
|
+
post = {
|
59
|
+
id: authorization
|
60
|
+
}
|
61
|
+
add_invoice(post, money, options)
|
62
|
+
commit('CP', post)
|
63
|
+
end
|
64
|
+
|
65
|
+
def refund(money, authorization, options = {})
|
66
|
+
post = {
|
67
|
+
id: authorization
|
68
|
+
}
|
69
|
+
add_invoice(post, money, options)
|
70
|
+
commit('RF', post)
|
71
|
+
end
|
72
|
+
|
73
|
+
def credit(money, payment, options = {})
|
74
|
+
post = {}
|
75
|
+
add_invoice(post, money, options)
|
76
|
+
add_payment(post, payment)
|
77
|
+
add_address(post, payment, options)
|
78
|
+
add_customer_data(post, options)
|
79
|
+
|
80
|
+
commit('CD', post)
|
81
|
+
end
|
82
|
+
|
83
|
+
def void(authorization, _options = {})
|
84
|
+
post = {
|
85
|
+
id: authorization
|
86
|
+
}
|
87
|
+
commit('RV', post)
|
88
|
+
end
|
89
|
+
|
90
|
+
def verify(credit_card, options = {})
|
91
|
+
MultiResponse.run do |r|
|
92
|
+
r.process { authorize(100, credit_card, options) }
|
93
|
+
r.process { void(r.authorization, options) }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def supports_scrubbing?
|
98
|
+
true
|
99
|
+
end
|
100
|
+
|
101
|
+
def scrub(transcript)
|
102
|
+
transcript
|
103
|
+
.gsub(%r{(authentication\.[^=]+=)[^&]+}, '\1[FILTERED]')
|
104
|
+
.gsub(%r{(card\.number=)\d+}, '\1[FILTERED]')
|
105
|
+
.gsub(%r{(cvv=)\d{3,4}}, '\1[FILTERED]\2')
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def add_customer_data(post, options)
|
111
|
+
post['customer.ip'] = options[:ip] if options[:ip]
|
112
|
+
end
|
113
|
+
|
114
|
+
def add_address(post, _card, options)
|
115
|
+
if (address = options[:billing_address] || options[:address])
|
116
|
+
post[:billing] = hashify_address(address)
|
117
|
+
end
|
118
|
+
|
119
|
+
if (shipping = options[:shipping_address])
|
120
|
+
post[:shipping] = hashify_address(shipping)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def add_invoice(post, money, options)
|
125
|
+
return if money.nil?
|
126
|
+
post[:amount] = amount(money)
|
127
|
+
post[:currency] = (options[:currency] || currency(money))
|
128
|
+
post[:merchantInvoiceId] = options[:merchant_invoice_id] if options[:merchant_invoice_id]
|
129
|
+
post[:merchantTransactionId] = options[:merchant_transaction_id] if options[:merchant_transaction_id]
|
130
|
+
post[:transactionCategory] = options[:transaction_category] if options[:transaction_category]
|
131
|
+
end
|
132
|
+
|
133
|
+
def add_payment(post, payment)
|
134
|
+
return if payment.is_a?(String)
|
135
|
+
post[:paymentBrand] = payment.brand.upcase if payment.brand
|
136
|
+
post[:card] ||= {}
|
137
|
+
post[:card][:number] = payment.number
|
138
|
+
post[:card][:holder] = payment.name
|
139
|
+
post[:card][:expiryMonth] = sprintf('%02d', payment.month)
|
140
|
+
post[:card][:expiryYear] = sprintf('%02d', payment.year)
|
141
|
+
post[:card][:cvv] = payment.verification_value
|
142
|
+
end
|
143
|
+
|
144
|
+
def parse(body)
|
145
|
+
JSON.parse(body)
|
146
|
+
end
|
147
|
+
|
148
|
+
def commit(action, parameters)
|
149
|
+
url = (test? ? test_url : live_url)
|
150
|
+
if (id = parameters.delete(:id))
|
151
|
+
url += "/#{id}"
|
152
|
+
end
|
153
|
+
|
154
|
+
begin
|
155
|
+
raw_response = ssl_post(url, post_data(action, parameters.merge(@test_options)))
|
156
|
+
rescue ResponseError => e
|
157
|
+
raw_response = e.response.body
|
158
|
+
end
|
159
|
+
response = parse(raw_response)
|
160
|
+
|
161
|
+
Response.new(
|
162
|
+
success_from(response),
|
163
|
+
message_from(response),
|
164
|
+
response,
|
165
|
+
authorization: authorization_from(response),
|
166
|
+
avs_result: AVSResult.new(code: response['result']['avsResponse']),
|
167
|
+
cvv_result: CVVResult.new(response['result']['cvvResponse']),
|
168
|
+
test: test?,
|
169
|
+
error_code: error_code_from(response)
|
170
|
+
)
|
171
|
+
end
|
172
|
+
|
173
|
+
def success_from(response)
|
174
|
+
!(response['result']['code'] =~ /^(000\.000\.|000\.100\.1|000\.[36])/).nil?
|
175
|
+
end
|
176
|
+
|
177
|
+
def message_from(response)
|
178
|
+
response['result']['description']
|
179
|
+
end
|
180
|
+
|
181
|
+
def authorization_from(response)
|
182
|
+
response['id']
|
183
|
+
end
|
184
|
+
|
185
|
+
def post_data(action, parameters = {})
|
186
|
+
post = parameters.clone
|
187
|
+
post[:authentication] ||= {}
|
188
|
+
post[:authentication][:userId] = @options[:user_id]
|
189
|
+
post[:authentication][:password] = @options[:password]
|
190
|
+
post[:authentication][:entityId] = @options[:entity_id]
|
191
|
+
post[:paymentType] = action
|
192
|
+
dot_flatten_hash(post).map {|key, value| "#{key}=#{CGI.escape(value.to_s)}"}.join("&")
|
193
|
+
end
|
194
|
+
|
195
|
+
def error_code_from(response)
|
196
|
+
unless success_from(response)
|
197
|
+
case response['result']['code']
|
198
|
+
when '100.100.101'
|
199
|
+
STANDARD_ERROR_CODE[:incorrect_number]
|
200
|
+
when '100.100.303'
|
201
|
+
STANDARD_ERROR_CODE[:expired_card]
|
202
|
+
when /100\.100\.(201|301|305)/
|
203
|
+
STANDARD_ERROR_CODE[:invalid_expiry_date]
|
204
|
+
when /100.100.60[01]/
|
205
|
+
STANDARD_ERROR_CODE[:invalid_cvc]
|
206
|
+
when '800.100.151'
|
207
|
+
STANDARD_ERROR_CODE[:invalid_number]
|
208
|
+
when '800.100.153'
|
209
|
+
STANDARD_ERROR_CODE[:incorrect_cvc]
|
210
|
+
when /800.800.(102|302)/
|
211
|
+
STANDARD_ERROR_CODE[:incorrect_address]
|
212
|
+
when '800.800.202'
|
213
|
+
STANDARD_ERROR_CODE[:invalid_zip]
|
214
|
+
when '800.100.166'
|
215
|
+
STANDARD_ERROR_CODE[:incorrect_pin]
|
216
|
+
when '800.100.171'
|
217
|
+
STANDARD_ERROR_CODE[:pickup_card]
|
218
|
+
when /^(200|700)\./
|
219
|
+
STANDARD_ERROR_CODE[:config_error]
|
220
|
+
when /^(800\.[17]00|800\.800\.[123])/
|
221
|
+
STANDARD_ERROR_CODE[:card_declined]
|
222
|
+
when /^(900\.[1234]00)/
|
223
|
+
STANDARD_ERROR_CODE[:processing_error]
|
224
|
+
else
|
225
|
+
STANDARD_ERROR_CODE[:processing_error]
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def hashify_address(address)
|
231
|
+
hash = {}
|
232
|
+
hash[:street1] = address[:address1] if address[:address1]
|
233
|
+
hash[:street2] = address[:address2] if address[:address2]
|
234
|
+
hash[:city] = address[:city] if address[:city]
|
235
|
+
hash[:state] = address[:state] if address[:state]
|
236
|
+
hash[:postcode] = address[:zip] if address[:zip]
|
237
|
+
hash[:country] = address[:country] if address[:country]
|
238
|
+
hash
|
239
|
+
end
|
240
|
+
|
241
|
+
def dot_flatten_hash(hash, prefix = '')
|
242
|
+
h = {}
|
243
|
+
hash.each_pair do |k, v|
|
244
|
+
if v.is_a?(Hash)
|
245
|
+
h.merge!(dot_flatten_hash(v, prefix + k.to_s + '.'))
|
246
|
+
else
|
247
|
+
h[prefix + k.to_s] = v
|
248
|
+
end
|
249
|
+
end
|
250
|
+
h
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
@@ -3,7 +3,8 @@ module ActiveMerchant #:nodoc:
|
|
3
3
|
class CashnetGateway < Gateway
|
4
4
|
include Empty
|
5
5
|
|
6
|
-
self.live_url
|
6
|
+
self.live_url = "https://commerce.cashnet.com/"
|
7
|
+
self.test_url = "https://train.cashnet.com/"
|
7
8
|
|
8
9
|
self.supported_countries = ["US"]
|
9
10
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb]
|
@@ -54,11 +55,22 @@ module ActiveMerchant #:nodoc:
|
|
54
55
|
commit('REFUND', money, post)
|
55
56
|
end
|
56
57
|
|
58
|
+
def supports_scrubbing?
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
def scrub(transcript)
|
63
|
+
transcript
|
64
|
+
.gsub(%r{(password=)[^&]+}, '\1[FILTERED]')
|
65
|
+
.gsub(%r{(cardno=)[^&]+}, '\1[FILTERED]')
|
66
|
+
.gsub(%r{(cid=)[^&]+}, '\1[FILTERED]')
|
67
|
+
end
|
68
|
+
|
57
69
|
private
|
58
70
|
|
59
71
|
def commit(action, money, fields)
|
60
72
|
fields[:amount] = amount(money)
|
61
|
-
url = live_url + CGI.escape(@options[:merchant_gateway_name])
|
73
|
+
url = (test? ? test_url : live_url) + CGI.escape(@options[:merchant_gateway_name])
|
62
74
|
raw_response = ssl_post(url, post_data(action, fields))
|
63
75
|
parsed_response = parse(raw_response)
|
64
76
|
|
@@ -180,7 +180,7 @@ module ActiveMerchant #:nodoc:
|
|
180
180
|
|
181
181
|
def headers
|
182
182
|
{
|
183
|
-
"Accept-Encoding" => "
|
183
|
+
"Accept-Encoding" => "identity",
|
184
184
|
"Content-Type" => "text/xml;charset=UTF-8",
|
185
185
|
"SOAPAction" => "http://tempuri.org/Transactional/ProcessCreditCard"
|
186
186
|
}
|
@@ -5,7 +5,7 @@ module ActiveMerchant #:nodoc:
|
|
5
5
|
module Billing #:nodoc:
|
6
6
|
class CheckoutGateway < Gateway
|
7
7
|
self.default_currency = 'USD'
|
8
|
-
self.money_format = :
|
8
|
+
self.money_format = :cents
|
9
9
|
|
10
10
|
self.supported_countries = ['AD', 'AT', 'BE', 'BG', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FO', 'FI', 'FR', 'GB', 'GI', 'GL', 'GR', 'HR', 'HU', 'IE', 'IS', 'IL', 'IT', 'LI', 'LT', 'LU', 'LV', 'MC', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SI', 'SM', 'SK', 'SJ', 'TR', 'VA']
|
11
11
|
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
|
@@ -4,9 +4,9 @@ module ActiveMerchant #:nodoc:
|
|
4
4
|
self.display_name = "Checkout.com V2 Gateway"
|
5
5
|
self.homepage_url = "https://www.checkout.com/"
|
6
6
|
self.live_url = "https://api2.checkout.com/v2"
|
7
|
-
self.test_url = "
|
7
|
+
self.test_url = "https://sandbox.checkout.com/api2/v2"
|
8
8
|
|
9
|
-
self.supported_countries = ['AD', 'AT', 'BE', 'BG', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FO', 'FI', 'FR', 'GB', 'GI', 'GL', 'GR', 'HR', 'HU', 'IE', 'IS', 'IL', 'IT', 'LI', 'LT', 'LU', 'LV', 'MC', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SI', 'SM', 'SK', 'SJ', 'TR', 'VA']
|
9
|
+
self.supported_countries = ['AD', 'AE', 'AT', 'BE', 'BG', 'CH', 'CY', 'CZ', 'DE', 'DK', 'EE', 'ES', 'FO', 'FI', 'FR', 'GB', 'GI', 'GL', 'GR', 'HR', 'HU', 'IE', 'IS', 'IL', 'IT', 'LI', 'LT', 'LU', 'LV', 'MC', 'MT', 'NL', 'NO', 'PL', 'PT', 'RO', 'SE', 'SI', 'SM', 'SK', 'SJ', 'TR', 'VA']
|
10
10
|
self.default_currency = "USD"
|
11
11
|
self.money_format = :cents
|
12
12
|
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club]
|
@@ -17,10 +17,15 @@ module ActiveMerchant #:nodoc:
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def purchase(amount, payment_method, options={})
|
20
|
-
MultiResponse.run do |r|
|
20
|
+
multi = MultiResponse.run do |r|
|
21
21
|
r.process { authorize(amount, payment_method, options) }
|
22
22
|
r.process { capture(amount, r.authorization, options) }
|
23
23
|
end
|
24
|
+
|
25
|
+
merged_params = multi.responses.map { |r| r.params }.reduce({}, :merge)
|
26
|
+
succeeded = success_from(merged_params)
|
27
|
+
|
28
|
+
response(:purchase, succeeded, merged_params)
|
24
29
|
end
|
25
30
|
|
26
31
|
def authorize(amount, payment_method, options={})
|
@@ -29,6 +34,7 @@ module ActiveMerchant #:nodoc:
|
|
29
34
|
add_invoice(post, amount, options)
|
30
35
|
add_payment_method(post, payment_method)
|
31
36
|
add_customer_data(post, options)
|
37
|
+
add_transaction_data(post, options)
|
32
38
|
|
33
39
|
commit(:authorize, post)
|
34
40
|
end
|
@@ -75,7 +81,7 @@ module ActiveMerchant #:nodoc:
|
|
75
81
|
private
|
76
82
|
|
77
83
|
def add_invoice(post, money, options)
|
78
|
-
post[:value] =
|
84
|
+
post[:value] = localized_amount(money, options[:currency])
|
79
85
|
post[:trackId] = options[:order_id]
|
80
86
|
post[:currency] = options[:currency] || currency(money)
|
81
87
|
post[:descriptor] = {}
|
@@ -94,11 +100,12 @@ module ActiveMerchant #:nodoc:
|
|
94
100
|
|
95
101
|
def add_customer_data(post, options)
|
96
102
|
post[:email] = options[:email] || "unspecified@example.com"
|
103
|
+
post[:customerIp] = options[:ip] if options[:ip]
|
97
104
|
address = options[:billing_address]
|
98
105
|
if(address && post[:card])
|
99
106
|
post[:card][:billingDetails] = {}
|
100
|
-
post[:card][:billingDetails][:
|
101
|
-
post[:card][:billingDetails][:
|
107
|
+
post[:card][:billingDetails][:addressLine1] = address[:address1]
|
108
|
+
post[:card][:billingDetails][:addressLine2] = address[:address2]
|
102
109
|
post[:card][:billingDetails][:city] = address[:city]
|
103
110
|
post[:card][:billingDetails][:state] = address[:state]
|
104
111
|
post[:card][:billingDetails][:country] = address[:country]
|
@@ -107,6 +114,12 @@ module ActiveMerchant #:nodoc:
|
|
107
114
|
end
|
108
115
|
end
|
109
116
|
|
117
|
+
def add_transaction_data(post, options={})
|
118
|
+
post[:cardOnFile] = true if options[:card_on_file] == true
|
119
|
+
post[:transactionIndicator] = options[:transaction_indicator] || 1
|
120
|
+
post[:previousChargeId] = options[:previous_charge_id] if options[:previous_charge_id]
|
121
|
+
end
|
122
|
+
|
110
123
|
def commit(action, post, authorization = nil)
|
111
124
|
begin
|
112
125
|
raw_response = ssl_post(url(post, action, authorization), post.to_json, headers)
|
@@ -117,6 +130,15 @@ module ActiveMerchant #:nodoc:
|
|
117
130
|
end
|
118
131
|
|
119
132
|
succeeded = success_from(response)
|
133
|
+
|
134
|
+
response(action, succeeded, response)
|
135
|
+
end
|
136
|
+
|
137
|
+
def response(action, succeeded, response)
|
138
|
+
successful_response = succeeded && action == :purchase || action == :authorize
|
139
|
+
avs_result = successful_response ? avs_result(response) : nil
|
140
|
+
cvv_result = successful_response ? cvv_result(response) : nil
|
141
|
+
|
120
142
|
Response.new(
|
121
143
|
succeeded,
|
122
144
|
message_from(succeeded, response),
|
@@ -124,8 +146,9 @@ module ActiveMerchant #:nodoc:
|
|
124
146
|
authorization: authorization_from(response),
|
125
147
|
error_code: error_code_from(succeeded, response),
|
126
148
|
test: test?,
|
127
|
-
avs_result: avs_result
|
128
|
-
cvv_result: cvv_result
|
149
|
+
avs_result: avs_result,
|
150
|
+
cvv_result: cvv_result
|
151
|
+
)
|
129
152
|
end
|
130
153
|
|
131
154
|
def headers
|
@@ -147,12 +170,12 @@ module ActiveMerchant #:nodoc:
|
|
147
170
|
test? ? test_url : live_url
|
148
171
|
end
|
149
172
|
|
150
|
-
def avs_result(
|
151
|
-
|
173
|
+
def avs_result(response)
|
174
|
+
response['card'] && response['card']['avsCheck'] ? AVSResult.new(code: response['card']['avsCheck']) : nil
|
152
175
|
end
|
153
176
|
|
154
|
-
def cvv_result(
|
155
|
-
|
177
|
+
def cvv_result(response)
|
178
|
+
response['card'] && response['card']['cvvCheck'] ? CVVResult.new(response['card']['cvvCheck']) : nil
|
156
179
|
end
|
157
180
|
|
158
181
|
def parse(body)
|
@@ -165,7 +188,7 @@ module ActiveMerchant #:nodoc:
|
|
165
188
|
end
|
166
189
|
|
167
190
|
def success_from(response)
|
168
|
-
response["responseCode"] ==
|
191
|
+
(response["responseCode"] == "10000" && !response["responseMessage"].start_with?("40")) || response["responseCode"] == "10100"
|
169
192
|
end
|
170
193
|
|
171
194
|
def message_from(succeeded, response)
|
@@ -196,7 +219,14 @@ module ActiveMerchant #:nodoc:
|
|
196
219
|
end
|
197
220
|
|
198
221
|
def error_code_from(succeeded, response)
|
199
|
-
|
222
|
+
return if succeeded
|
223
|
+
if response["errorCode"] && response["errorMessageCodes"]
|
224
|
+
"#{response["errorCode"]}: #{response["errorMessageCodes"].join(", ")}"
|
225
|
+
elsif response["errorCode"]
|
226
|
+
response["errorCode"]
|
227
|
+
else
|
228
|
+
STANDARD_ERROR_CODE_MAPPING[response["responseCode"]]
|
229
|
+
end
|
200
230
|
end
|
201
231
|
end
|
202
232
|
end
|
@@ -16,7 +16,6 @@ module ActiveMerchant
|
|
16
16
|
self.supported_countries = %w(AR AU BR FR DE HK MX NZ SG GB US)
|
17
17
|
self.default_currency = 'USD'
|
18
18
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover, :diners_club, :jcb, :maestro, :laser]
|
19
|
-
self.ssl_version = :TLSv1
|
20
19
|
|
21
20
|
end
|
22
21
|
end
|
@@ -77,21 +77,21 @@ module ActiveMerchant #:nodoc:
|
|
77
77
|
post[:description] = options[:description] || "Active Merchant Purchase"
|
78
78
|
post[:reference_id] = options[:order_id] if options[:order_id]
|
79
79
|
post[:currency] = (options[:currency] || currency(money)).downcase
|
80
|
+
post[:monthly_installments] = options[:monthly_installments] if options[:monthly_installments]
|
80
81
|
post[:amount] = amount(money)
|
81
82
|
end
|
82
83
|
|
83
84
|
def add_details_data(post, options)
|
84
85
|
details = {}
|
85
|
-
details[:name] = options[:customer] if options[:
|
86
|
+
details[:name] = options[:customer] || (options[:billing_address][:name] if options[:billing_address])
|
87
|
+
details[:phone] = options[:phone] || (options[:billing_address][:phone] if options[:billing_address])
|
86
88
|
details[:email] = options[:email] if options[:email]
|
87
|
-
details[:phone] = options[:phone] if options[:phone]
|
88
|
-
post[:device_fingerprint] = options[:device_fingerprint] if options[:device_fingerprint]
|
89
89
|
details[:ip] = options[:ip] if options[:ip]
|
90
90
|
add_billing_address(details, options)
|
91
91
|
add_line_items(details, options)
|
92
92
|
add_shipment(details, options)
|
93
|
-
|
94
93
|
post[:details] = details
|
94
|
+
post[:device_fingerprint] = options[:device_fingerprint] if options[:device_fingerprint]
|
95
95
|
end
|
96
96
|
|
97
97
|
def add_shipment(post, options)
|
@@ -14,6 +14,32 @@ module ActiveMerchant #:nodoc:
|
|
14
14
|
|
15
15
|
self.homepage_url = 'https://www.creditcall.com'
|
16
16
|
self.display_name = 'Creditcall'
|
17
|
+
|
18
|
+
CVV_CODE = {
|
19
|
+
"matched" => "M",
|
20
|
+
"notmatched" => "N",
|
21
|
+
"notchecked" => "P",
|
22
|
+
"partialmatch" => "N"
|
23
|
+
}
|
24
|
+
|
25
|
+
AVS_CODE = {
|
26
|
+
"matched;matched" => "D",
|
27
|
+
"matched;notchecked" =>"B",
|
28
|
+
"matched;notmatched" => "A",
|
29
|
+
"matched;partialmatch" => "A",
|
30
|
+
"notchecked;matched" => "P",
|
31
|
+
"notchecked;notchecked" =>"I",
|
32
|
+
"notchecked;notmatched" => "I",
|
33
|
+
"notchecked;partialmatch" => "I",
|
34
|
+
"notmatched;matched" => "W",
|
35
|
+
"notmatched;notchecked" =>"C",
|
36
|
+
"notmatched;notmatched" => "C",
|
37
|
+
"notmatched;partialmatch" => "C",
|
38
|
+
"partialmatched;matched" => "W",
|
39
|
+
"partialmatched;notchecked" =>"C",
|
40
|
+
"partialmatched;notmatched" => "C",
|
41
|
+
"partialmatched;partialmatch" => "C"
|
42
|
+
}
|
17
43
|
|
18
44
|
def initialize(options={})
|
19
45
|
requires!(options, :terminal_id, :transaction_key)
|
@@ -26,11 +52,16 @@ module ActiveMerchant #:nodoc:
|
|
26
52
|
r.process { capture(money, r.authorization, options) }
|
27
53
|
end
|
28
54
|
|
55
|
+
merged_params = multi_response.responses.map { |r| r.params }.reduce({}, :merge)
|
56
|
+
|
29
57
|
Response.new(
|
30
58
|
multi_response.primary_response.success?,
|
31
59
|
multi_response.primary_response.message,
|
32
|
-
|
60
|
+
merged_params,
|
33
61
|
authorization: multi_response.responses.first.authorization,
|
62
|
+
avs_result: AVSResult.new(code: avs_result_code_from(merged_params)),
|
63
|
+
cvv_result: CVVResult.new(cvv_result_code_from(merged_params)),
|
64
|
+
error_code: error_result_code_from(merged_params),
|
34
65
|
test: test?
|
35
66
|
)
|
36
67
|
end
|
@@ -92,6 +123,18 @@ module ActiveMerchant #:nodoc:
|
|
92
123
|
|
93
124
|
private
|
94
125
|
|
126
|
+
def avs_result_code_from(params)
|
127
|
+
AVS_CODE["#{params['Address']};#{params['Zip']}"]
|
128
|
+
end
|
129
|
+
|
130
|
+
def cvv_result_code_from(params)
|
131
|
+
CVV_CODE[params["CSC"]]
|
132
|
+
end
|
133
|
+
|
134
|
+
def error_result_code_from(params)
|
135
|
+
params["ErrorCode"]
|
136
|
+
end
|
137
|
+
|
95
138
|
def build_xml_request
|
96
139
|
builder = Nokogiri::XML::Builder.new do |xml|
|
97
140
|
xml.Request(type: "CardEaseXML", version: "1.0.0") do
|
@@ -120,17 +163,22 @@ module ActiveMerchant #:nodoc:
|
|
120
163
|
|
121
164
|
def add_card_details(xml, payment_method, options={})
|
122
165
|
xml.CardDetails do
|
123
|
-
xml.Manual(type:
|
166
|
+
xml.Manual(type: manual_type(options)) do
|
124
167
|
xml.PAN payment_method.number
|
125
168
|
xml.ExpiryDate exp_date(payment_method)
|
126
169
|
xml.CSC payment_method.verification_value unless empty?(payment_method.verification_value)
|
127
170
|
end
|
128
171
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
172
|
+
add_additional_verification(xml, options)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def add_additional_verification(xml, options)
|
177
|
+
return unless (options[:verify_zip].to_s == 'true') || (options[:verify_address].to_s == 'true')
|
178
|
+
if address = options[:billing_address]
|
179
|
+
xml.AdditionalVerification do
|
180
|
+
xml.Zip address[:zip] if options[:verify_zip].to_s == 'true'
|
181
|
+
xml.Address address[:address1] if options[:verify_address].to_s == 'true'
|
134
182
|
end
|
135
183
|
end
|
136
184
|
end
|
@@ -157,6 +205,16 @@ module ActiveMerchant #:nodoc:
|
|
157
205
|
end
|
158
206
|
end
|
159
207
|
|
208
|
+
node = xml.xpath("//Response/CardDetails")
|
209
|
+
node.children.each do |childnode|
|
210
|
+
if childnode.elements.empty?
|
211
|
+
response[childnode.name] = childnode.text
|
212
|
+
else
|
213
|
+
childnode_to_response(response, childnode)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
|
160
218
|
response
|
161
219
|
end
|
162
220
|
|
@@ -179,8 +237,9 @@ module ActiveMerchant #:nodoc:
|
|
179
237
|
message_from(response),
|
180
238
|
response,
|
181
239
|
authorization: authorization_from(response),
|
182
|
-
avs_result: AVSResult.new(code: response
|
183
|
-
cvv_result: CVVResult.new(response
|
240
|
+
avs_result: AVSResult.new(code: avs_result_code_from(response)),
|
241
|
+
cvv_result: CVVResult.new(cvv_result_code_from(response)),
|
242
|
+
error_code: error_result_code_from(response),
|
184
243
|
test: test?
|
185
244
|
)
|
186
245
|
end
|
@@ -205,6 +264,9 @@ module ActiveMerchant #:nodoc:
|
|
205
264
|
response["CardEaseReference"]
|
206
265
|
end
|
207
266
|
|
267
|
+
def manual_type(options)
|
268
|
+
options[:manual_type] ? options[:manual_type] : "ecommerce"
|
269
|
+
end
|
208
270
|
end
|
209
271
|
end
|
210
272
|
end
|