activemerchant 1.119.0 → 1.124.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 +216 -1
- data/README.md +4 -2
- data/lib/active_merchant/billing/check.rb +19 -12
- data/lib/active_merchant/billing/credit_card.rb +3 -0
- data/lib/active_merchant/billing/credit_card_formatting.rb +1 -0
- data/lib/active_merchant/billing/credit_card_methods.rb +32 -14
- data/lib/active_merchant/billing/gateways/adyen.rb +94 -25
- data/lib/active_merchant/billing/gateways/authorize_net.rb +19 -11
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +3 -0
- data/lib/active_merchant/billing/gateways/blue_pay.rb +29 -0
- data/lib/active_merchant/billing/gateways/blue_snap.rb +2 -2
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +52 -8
- data/lib/active_merchant/billing/gateways/card_stream.rb +17 -13
- data/lib/active_merchant/billing/gateways/cashnet.rb +7 -2
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +31 -0
- data/lib/active_merchant/billing/gateways/credorax.rb +15 -9
- data/lib/active_merchant/billing/gateways/cyber_source.rb +53 -6
- data/lib/active_merchant/billing/gateways/d_local.rb +9 -2
- data/lib/active_merchant/billing/gateways/decidir.rb +7 -1
- data/lib/active_merchant/billing/gateways/elavon.rb +70 -28
- data/lib/active_merchant/billing/gateways/element.rb +2 -0
- data/lib/active_merchant/billing/gateways/forte.rb +12 -0
- data/lib/active_merchant/billing/gateways/global_collect.rb +24 -10
- data/lib/active_merchant/billing/gateways/hps.rb +55 -1
- data/lib/active_merchant/billing/gateways/kushki.rb +23 -0
- data/lib/active_merchant/billing/gateways/litle.rb +1 -1
- data/lib/active_merchant/billing/gateways/mercado_pago.rb +5 -4
- data/lib/active_merchant/billing/gateways/merchant_warrior.rb +2 -0
- data/lib/active_merchant/billing/gateways/mit.rb +260 -0
- data/lib/active_merchant/billing/gateways/moka.rb +290 -0
- data/lib/active_merchant/billing/gateways/monei.rb +228 -144
- data/lib/active_merchant/billing/gateways/mundipagg.rb +14 -5
- data/lib/active_merchant/billing/gateways/netbanx.rb +26 -2
- data/lib/active_merchant/billing/gateways/nmi.rb +27 -9
- data/lib/active_merchant/billing/gateways/orbital.rb +99 -59
- data/lib/active_merchant/billing/gateways/pay_arc.rb +392 -0
- data/lib/active_merchant/billing/gateways/pay_conex.rb +3 -1
- data/lib/active_merchant/billing/gateways/pay_trace.rb +404 -0
- data/lib/active_merchant/billing/gateways/payeezy.rb +34 -6
- data/lib/active_merchant/billing/gateways/payflow/payflow_common_api.rb +1 -0
- data/lib/active_merchant/billing/gateways/payflow.rb +21 -4
- data/lib/active_merchant/billing/gateways/payment_express.rb +5 -5
- data/lib/active_merchant/billing/gateways/paymentez.rb +5 -0
- data/lib/active_merchant/billing/gateways/paypal_express.rb +1 -0
- data/lib/active_merchant/billing/gateways/paysafe.rb +376 -0
- data/lib/active_merchant/billing/gateways/payu_latam.rb +3 -3
- data/lib/active_merchant/billing/gateways/payway_dot_com.rb +253 -0
- data/lib/active_merchant/billing/gateways/qvalent.rb +23 -9
- data/lib/active_merchant/billing/gateways/realex.rb +18 -0
- data/lib/active_merchant/billing/gateways/redsys.rb +42 -24
- data/lib/active_merchant/billing/gateways/safe_charge.rb +25 -13
- data/lib/active_merchant/billing/gateways/spreedly_core.rb +13 -4
- data/lib/active_merchant/billing/gateways/stripe.rb +18 -8
- data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +126 -48
- data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +2 -1
- data/lib/active_merchant/billing/gateways/trust_commerce.rb +2 -1
- data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +1 -1
- data/lib/active_merchant/billing/gateways/vpos.rb +220 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +78 -18
- data/lib/active_merchant/billing/response.rb +4 -0
- data/lib/active_merchant/billing/three_d_secure_eci_mapper.rb +27 -0
- data/lib/active_merchant/billing.rb +1 -0
- data/lib/active_merchant/version.rb +1 -1
- data/lib/certs/cacert.pem +1582 -2431
- metadata +11 -3
@@ -0,0 +1,290 @@
|
|
1
|
+
module ActiveMerchant #:nodoc:
|
2
|
+
module Billing #:nodoc:
|
3
|
+
class MokaGateway < Gateway
|
4
|
+
self.test_url = 'https://service.refmoka.com'
|
5
|
+
self.live_url = 'https://service.moka.com'
|
6
|
+
|
7
|
+
self.supported_countries = %w[GB TR US]
|
8
|
+
self.default_currency = 'TRY'
|
9
|
+
self.money_format = :dollars
|
10
|
+
self.supported_cardtypes = %i[visa master american_express discover]
|
11
|
+
|
12
|
+
self.homepage_url = 'http://developer.moka.com/'
|
13
|
+
self.display_name = 'Moka'
|
14
|
+
|
15
|
+
ERROR_CODE_MAPPING = {
|
16
|
+
'000' => 'General error',
|
17
|
+
'001' => '3D Not authenticated',
|
18
|
+
'002' => 'Limit is insufficient',
|
19
|
+
'003' => 'Credit card number format is wrong',
|
20
|
+
'004' => 'General decline',
|
21
|
+
'005' => 'This process is invalid for the card owner',
|
22
|
+
'006' => 'Expiration date is wrong',
|
23
|
+
'007' => 'Invalid transaction',
|
24
|
+
'008' => 'Connection with the bank not established',
|
25
|
+
'009' => 'Undefined error code',
|
26
|
+
'010' => 'Bank SSL error',
|
27
|
+
'011' => 'Call the bank for the manual authentication',
|
28
|
+
'012' => 'Card info is wrong - Kart Number or CVV2',
|
29
|
+
'013' => '3D secure is not supported other than Visa MC cards',
|
30
|
+
'014' => 'Invalid account number',
|
31
|
+
'015' => 'CVV is wrong',
|
32
|
+
'016' => 'Authentication process is not present',
|
33
|
+
'017' => 'System error',
|
34
|
+
'018' => 'Stolen card',
|
35
|
+
'019' => 'Lost card',
|
36
|
+
'020' => 'Card with limited properties',
|
37
|
+
'021' => 'Timeout',
|
38
|
+
'022' => 'Invalid merchant',
|
39
|
+
'023' => 'False authentication',
|
40
|
+
'024' => '3D authorization is successful but the process cannot be completed',
|
41
|
+
'025' => '3D authorization failure',
|
42
|
+
'026' => 'Either the issuer bank or the card is not enrolled to the 3D process',
|
43
|
+
'027' => 'The bank did not allow the process',
|
44
|
+
'028' => 'Fraud suspect',
|
45
|
+
'029' => 'The card is closed to the e-commerce operations'
|
46
|
+
}
|
47
|
+
|
48
|
+
def initialize(options = {})
|
49
|
+
requires!(options, :dealer_code, :username, :password)
|
50
|
+
super
|
51
|
+
end
|
52
|
+
|
53
|
+
def purchase(money, payment, options = {})
|
54
|
+
post = {}
|
55
|
+
post[:PaymentDealerRequest] = {}
|
56
|
+
options[:pre_auth] = 0
|
57
|
+
add_auth_purchase(post, money, payment, options)
|
58
|
+
add_3ds_data(post, options) if options[:execute_threed]
|
59
|
+
|
60
|
+
action = options[:execute_threed] ? 'three_ds_purchase' : 'purchase'
|
61
|
+
commit(action, post)
|
62
|
+
end
|
63
|
+
|
64
|
+
def authorize(money, payment, options = {})
|
65
|
+
post = {}
|
66
|
+
post[:PaymentDealerRequest] = {}
|
67
|
+
options[:pre_auth] = 1
|
68
|
+
add_auth_purchase(post, money, payment, options)
|
69
|
+
add_3ds_data(post, options) if options[:execute_threed]
|
70
|
+
|
71
|
+
action = options[:execute_threed] ? 'three_ds_authorize' : 'authorize'
|
72
|
+
commit(action, post)
|
73
|
+
end
|
74
|
+
|
75
|
+
def capture(money, authorization, options = {})
|
76
|
+
post = {}
|
77
|
+
post[:PaymentDealerRequest] = {}
|
78
|
+
add_payment_dealer_authentication(post)
|
79
|
+
add_transaction_reference(post, authorization)
|
80
|
+
add_invoice(post, money, options)
|
81
|
+
|
82
|
+
commit('capture', post)
|
83
|
+
end
|
84
|
+
|
85
|
+
def refund(money, authorization, options = {})
|
86
|
+
post = {}
|
87
|
+
post[:PaymentDealerRequest] = {}
|
88
|
+
add_payment_dealer_authentication(post)
|
89
|
+
add_transaction_reference(post, authorization)
|
90
|
+
add_void_refund_reason(post)
|
91
|
+
add_amount(post, money)
|
92
|
+
|
93
|
+
commit('refund', post)
|
94
|
+
end
|
95
|
+
|
96
|
+
def void(authorization, options = {})
|
97
|
+
post = {}
|
98
|
+
post[:PaymentDealerRequest] = {}
|
99
|
+
add_payment_dealer_authentication(post)
|
100
|
+
add_transaction_reference(post, authorization)
|
101
|
+
add_void_refund_reason(post)
|
102
|
+
|
103
|
+
commit('void', post)
|
104
|
+
end
|
105
|
+
|
106
|
+
def verify(credit_card, options = {})
|
107
|
+
MultiResponse.run(:use_first_response) do |r|
|
108
|
+
r.process { authorize(100, credit_card, options) }
|
109
|
+
r.process(:ignore_result) { void(r.authorization, options) }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def supports_scrubbing?
|
114
|
+
true
|
115
|
+
end
|
116
|
+
|
117
|
+
def scrub(transcript)
|
118
|
+
transcript.
|
119
|
+
gsub(%r(("CardNumber\\?":\\?")[^"]*)i, '\1[FILTERED]').
|
120
|
+
gsub(%r(("CvcNumber\\?":\\?")[^"]*)i, '\1[FILTERED]').
|
121
|
+
gsub(%r(("DealerCode\\?":\\?"?)[^"?]*)i, '\1[FILTERED]').
|
122
|
+
gsub(%r(("Username\\?":\\?")[^"]*)i, '\1[FILTERED]').
|
123
|
+
gsub(%r(("Password\\?":\\?")[^"]*)i, '\1[FILTERED]').
|
124
|
+
gsub(%r(("CheckKey\\?":\\?")[^"]*)i, '\1[FILTERED]')
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
def add_auth_purchase(post, money, payment, options)
|
130
|
+
add_payment_dealer_authentication(post)
|
131
|
+
add_invoice(post, money, options)
|
132
|
+
add_payment(post, payment)
|
133
|
+
add_additional_auth_purchase_data(post, options)
|
134
|
+
add_additional_transaction_data(post, options)
|
135
|
+
add_buyer_information(post, payment, options)
|
136
|
+
add_basket_product(post, options[:basket_product]) if options[:basket_product]
|
137
|
+
end
|
138
|
+
|
139
|
+
def add_3ds_data(post, options)
|
140
|
+
post[:PaymentDealerRequest][:ReturnHash] = 1
|
141
|
+
post[:PaymentDealerRequest][:RedirectUrl] = options[:redirect_url] || ''
|
142
|
+
post[:PaymentDealerRequest][:RedirectType] = options[:redirect_type] || 0
|
143
|
+
end
|
144
|
+
|
145
|
+
def add_payment_dealer_authentication(post)
|
146
|
+
post[:PaymentDealerAuthentication] = {
|
147
|
+
DealerCode: @options[:dealer_code],
|
148
|
+
Username: @options[:username],
|
149
|
+
Password: @options[:password],
|
150
|
+
CheckKey: check_key
|
151
|
+
}
|
152
|
+
end
|
153
|
+
|
154
|
+
def check_key
|
155
|
+
str = "#{@options[:dealer_code]}MK#{@options[:username]}PD#{@options[:password]}"
|
156
|
+
Digest::SHA256.hexdigest(str)
|
157
|
+
end
|
158
|
+
|
159
|
+
def add_invoice(post, money, options)
|
160
|
+
post[:PaymentDealerRequest][:Amount] = amount(money) || 0
|
161
|
+
post[:PaymentDealerRequest][:Currency] = options[:currency] || 'TL'
|
162
|
+
end
|
163
|
+
|
164
|
+
def add_payment(post, card)
|
165
|
+
post[:PaymentDealerRequest][:CardHolderFullName] = card.name
|
166
|
+
post[:PaymentDealerRequest][:CardNumber] = card.number
|
167
|
+
post[:PaymentDealerRequest][:ExpMonth] = card.month.to_s.rjust(2, '0')
|
168
|
+
post[:PaymentDealerRequest][:ExpYear] = card.year
|
169
|
+
post[:PaymentDealerRequest][:CvcNumber] = card.verification_value || ''
|
170
|
+
end
|
171
|
+
|
172
|
+
def add_amount(post, money)
|
173
|
+
post[:PaymentDealerRequest][:Amount] = amount(money) || 0
|
174
|
+
end
|
175
|
+
|
176
|
+
def add_additional_auth_purchase_data(post, options)
|
177
|
+
post[:PaymentDealerRequest][:IsPreAuth] = options[:pre_auth]
|
178
|
+
post[:PaymentDealerRequest][:Description] = options[:description] if options[:description]
|
179
|
+
post[:PaymentDealerRequest][:InstallmentNumber] = options[:installment_number].to_i if options[:installment_number]
|
180
|
+
post[:SubMerchantName] = options[:sub_merchant_name] if options[:sub_merchant_name]
|
181
|
+
post[:IsPoolPayment] = options[:is_pool_payment] || 0
|
182
|
+
end
|
183
|
+
|
184
|
+
def add_buyer_information(post, card, options)
|
185
|
+
obj = {}
|
186
|
+
|
187
|
+
obj[:BuyerFullName] = card.name || ''
|
188
|
+
obj[:BuyerEmail] = options[:email] if options[:email]
|
189
|
+
obj[:BuyerAddress] = options[:billing_address][:address1] if options[:billing_address]
|
190
|
+
obj[:BuyerGsmNumber] = options[:billing_address][:phone] if options[:billing_address]
|
191
|
+
|
192
|
+
post[:PaymentDealerRequest][:BuyerInformation] = obj
|
193
|
+
end
|
194
|
+
|
195
|
+
def add_basket_product(post, basket_options)
|
196
|
+
basket = []
|
197
|
+
|
198
|
+
basket_options.each do |product|
|
199
|
+
obj = {}
|
200
|
+
obj[:ProductId] = product[:product_id] if product[:product_id]
|
201
|
+
obj[:ProductCode] = product[:product_code] if product[:product_code]
|
202
|
+
obj[:UnitPrice] = amount(product[:unit_price]) if product[:unit_price]
|
203
|
+
obj[:Quantity] = product[:quantity] if product[:quantity]
|
204
|
+
basket << obj
|
205
|
+
end
|
206
|
+
|
207
|
+
post[:PaymentDealerRequest][:BasketProduct] = basket
|
208
|
+
end
|
209
|
+
|
210
|
+
def add_additional_transaction_data(post, options)
|
211
|
+
post[:PaymentDealerRequest][:ClientIP] = options[:ip] if options[:ip]
|
212
|
+
post[:PaymentDealerRequest][:OtherTrxCode] = options[:order_id] if options[:order_id]
|
213
|
+
end
|
214
|
+
|
215
|
+
def add_transaction_reference(post, authorization)
|
216
|
+
post[:PaymentDealerRequest][:VirtualPosOrderId] = authorization
|
217
|
+
end
|
218
|
+
|
219
|
+
def add_void_refund_reason(post)
|
220
|
+
post[:PaymentDealerRequest][:VoidRefundReason] = 2
|
221
|
+
end
|
222
|
+
|
223
|
+
def commit(action, parameters)
|
224
|
+
response = parse(ssl_post(url(action), post_data(parameters), request_headers))
|
225
|
+
Response.new(
|
226
|
+
success_from(response),
|
227
|
+
message_from(response),
|
228
|
+
response,
|
229
|
+
authorization: authorization_from(response),
|
230
|
+
test: test?,
|
231
|
+
error_code: error_code_from(response)
|
232
|
+
)
|
233
|
+
end
|
234
|
+
|
235
|
+
def url(action)
|
236
|
+
host = (test? ? test_url : live_url)
|
237
|
+
endpoint = endpoint(action)
|
238
|
+
|
239
|
+
"#{host}/PaymentDealer/#{endpoint}"
|
240
|
+
end
|
241
|
+
|
242
|
+
def endpoint(action)
|
243
|
+
case action
|
244
|
+
when 'three_ds_authorize', 'three_ds_purchase'
|
245
|
+
'DoDirectPaymentThreeD'
|
246
|
+
when 'purchase', 'authorize'
|
247
|
+
'DoDirectPayment'
|
248
|
+
when 'capture'
|
249
|
+
'DoCapture'
|
250
|
+
when 'void'
|
251
|
+
'DoVoid'
|
252
|
+
when 'refund'
|
253
|
+
'DoCreateRefundRequest'
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def request_headers
|
258
|
+
{ 'Content-Type' => 'application/json' }
|
259
|
+
end
|
260
|
+
|
261
|
+
def post_data(parameters = {})
|
262
|
+
JSON.generate(parameters)
|
263
|
+
end
|
264
|
+
|
265
|
+
def parse(body)
|
266
|
+
JSON.parse(body)
|
267
|
+
end
|
268
|
+
|
269
|
+
def success_from(response)
|
270
|
+
return response.dig('Data', 'IsSuccessful') if response.dig('Data', 'IsSuccessful').to_s.present?
|
271
|
+
|
272
|
+
response['ResultCode']&.casecmp('success') == 0
|
273
|
+
end
|
274
|
+
|
275
|
+
def message_from(response)
|
276
|
+
response.dig('Data', 'ResultMessage').presence || response['ResultCode']
|
277
|
+
end
|
278
|
+
|
279
|
+
def authorization_from(response)
|
280
|
+
response.dig('Data', 'VirtualPosOrderId')
|
281
|
+
end
|
282
|
+
|
283
|
+
def error_code_from(response)
|
284
|
+
codes = [response['ResultCode'], response.dig('Data', 'ResultCode')].flatten
|
285
|
+
codes.reject! { |code| code.blank? || code.casecmp('success').zero? }
|
286
|
+
codes.map { |code| ERROR_CODE_MAPPING[code] || code }.join(', ')
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|