activemerchant 1.50.0 → 1.51.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +39 -0
- data/README.md +6 -5
- data/lib/active_merchant/billing/credit_card.rb +22 -6
- data/lib/active_merchant/billing/gateway.rb +15 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +413 -127
- data/lib/active_merchant/billing/gateways/banwire.rb +2 -2
- data/lib/active_merchant/billing/gateways/braintree_blue.rb +4 -0
- data/lib/active_merchant/billing/gateways/card_stream.rb +18 -0
- data/lib/active_merchant/billing/gateways/cenpos.rb +6 -2
- data/lib/active_merchant/billing/gateways/checkout.rb +4 -6
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +200 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +19 -1
- data/lib/active_merchant/billing/gateways/dibs.rb +1 -1
- data/lib/active_merchant/billing/gateways/epay.rb +1 -1
- data/lib/active_merchant/billing/gateways/eway_rapid.rb +5 -5
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +4 -1
- data/lib/active_merchant/billing/gateways/garanti.rb +5 -1
- data/lib/active_merchant/billing/gateways/iats_payments.rb +29 -3
- data/lib/active_merchant/billing/gateways/litle.rb +12 -0
- data/lib/active_merchant/billing/gateways/paystation.rb +19 -23
- data/lib/active_merchant/billing/gateways/payu_in.rb +4 -0
- data/lib/active_merchant/billing/gateways/redsys.rb +4 -3
- data/lib/active_merchant/billing/gateways/s5.rb +3 -3
- data/lib/active_merchant/billing/gateways/sage.rb +8 -10
- data/lib/active_merchant/billing/gateways/sage/sage_bankcard.rb +7 -5
- data/lib/active_merchant/billing/gateways/sage/sage_core.rb +3 -2
- data/lib/active_merchant/billing/gateways/sage/sage_virtual_check.rb +0 -5
- data/lib/active_merchant/billing/gateways/stripe.rb +33 -4
- data/lib/active_merchant/billing/gateways/wepay.rb +13 -6
- data/lib/active_merchant/billing/gateways/worldpay_online_payments.rb +1 -2
- data/lib/active_merchant/version.rb +1 -1
- metadata +3 -2
@@ -109,6 +109,7 @@ module ActiveMerchant #:nodoc:
|
|
109
109
|
doc.registerTokenRequest(transaction_attributes(options)) do
|
110
110
|
doc.orderId(truncate(options[:order_id], 24))
|
111
111
|
doc.accountNumber(creditcard.number)
|
112
|
+
doc.cardValidationNum(creditcard.verification_value) if creditcard.verification_value
|
112
113
|
end
|
113
114
|
end
|
114
115
|
|
@@ -163,6 +164,7 @@ module ActiveMerchant #:nodoc:
|
|
163
164
|
add_payment_method(doc, payment_method)
|
164
165
|
add_pos(doc, payment_method)
|
165
166
|
add_descriptor(doc, options)
|
167
|
+
add_debt_repayment(doc, options)
|
166
168
|
end
|
167
169
|
|
168
170
|
def add_descriptor(doc, options)
|
@@ -174,6 +176,10 @@ module ActiveMerchant #:nodoc:
|
|
174
176
|
end
|
175
177
|
end
|
176
178
|
|
179
|
+
def add_debt_repayment(doc, options)
|
180
|
+
doc.debtRepayment(true) if options[:debt_repayment] == true
|
181
|
+
end
|
182
|
+
|
177
183
|
def add_payment_method(doc, payment_method)
|
178
184
|
if payment_method.is_a?(String)
|
179
185
|
doc.token do
|
@@ -264,6 +270,12 @@ module ActiveMerchant #:nodoc:
|
|
264
270
|
end
|
265
271
|
end
|
266
272
|
|
273
|
+
if parsed.empty?
|
274
|
+
%w(response message).each do |attribute|
|
275
|
+
parsed[attribute.to_sym] = doc.xpath("//litleOnlineResponse").attribute(attribute).value
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
267
279
|
parsed
|
268
280
|
end
|
269
281
|
|
@@ -32,9 +32,7 @@ module ActiveMerchant #:nodoc:
|
|
32
32
|
|
33
33
|
add_invoice(post, options)
|
34
34
|
add_amount(post, money, options)
|
35
|
-
|
36
35
|
add_credit_card(post, credit_card)
|
37
|
-
|
38
36
|
add_authorize_flag(post, options)
|
39
37
|
|
40
38
|
commit(post)
|
@@ -45,7 +43,6 @@ module ActiveMerchant #:nodoc:
|
|
45
43
|
|
46
44
|
add_invoice(post, options)
|
47
45
|
add_amount(post, money, options)
|
48
|
-
|
49
46
|
add_authorization_token(post, authorization_token, options[:credit_card_verification])
|
50
47
|
|
51
48
|
commit(post)
|
@@ -78,6 +75,16 @@ module ActiveMerchant #:nodoc:
|
|
78
75
|
commit(post)
|
79
76
|
end
|
80
77
|
|
78
|
+
|
79
|
+
def refund(money, authorization, options={})
|
80
|
+
post = new_request
|
81
|
+
add_amount(post, money, options)
|
82
|
+
add_invoice(post, options)
|
83
|
+
add_refund_specific_fields(post, authorization)
|
84
|
+
|
85
|
+
commit(post)
|
86
|
+
end
|
87
|
+
|
81
88
|
private
|
82
89
|
|
83
90
|
def new_request
|
@@ -95,40 +102,38 @@ module ActiveMerchant #:nodoc:
|
|
95
102
|
end
|
96
103
|
|
97
104
|
def add_invoice(post, options)
|
98
|
-
|
99
|
-
|
100
|
-
post[:
|
101
|
-
post[:mo] = options[:invoice] # "Order Details", displayed in Paystation Admin
|
102
|
-
post[:mr] = options[:description] # "Merchant Reference Code", seen from Paystation Admin
|
105
|
+
post[:ms] = options[:order_id] || generate_unique_id
|
106
|
+
post[:mo] = options[:invoice]
|
107
|
+
post[:mr] = options[:description]
|
103
108
|
end
|
104
109
|
|
105
110
|
def add_credit_card(post, credit_card)
|
106
|
-
|
107
111
|
post[:cn] = credit_card.number
|
108
112
|
post[:ct] = credit_card.brand
|
109
113
|
post[:ex] = format_date(credit_card.month, credit_card.year)
|
110
114
|
post[:cc] = credit_card.verification_value if credit_card.verification_value?
|
111
|
-
|
112
115
|
end
|
113
116
|
|
114
|
-
# bill a token (stored via "store") rather than a Credit Card
|
115
117
|
def add_token(post, token)
|
116
118
|
post[:fp] = "t" # turn on "future payments" - what paystation calls Token Billing
|
117
119
|
post[:ft] = token
|
118
120
|
end
|
119
121
|
|
120
122
|
def store_credit_card(post, options)
|
121
|
-
|
122
123
|
post[:fp] = "t" # turn on "future payments" - what paystation calls Token Billing
|
123
124
|
post[:fs] = "t" # tells paystation to store right now, not bill
|
124
125
|
post[:ft] = options[:token] if options[:token] # specify a token to use that, or let Paystation generate one
|
125
|
-
|
126
126
|
end
|
127
127
|
|
128
128
|
def add_authorize_flag(post, options)
|
129
129
|
post[:pa] = "t" # tells Paystation that this is a pre-auth authorisation payment (account must be in pre-auth mode)
|
130
130
|
end
|
131
131
|
|
132
|
+
def add_refund_specific_fields(post, authorization)
|
133
|
+
post[:rc] = "t"
|
134
|
+
post[:rt] = authorization
|
135
|
+
end
|
136
|
+
|
132
137
|
def add_authorization_token(post, auth_token, verification_value = nil)
|
133
138
|
post[:cp] = "t" # Capture Payment flag – tells Paystation this transaction should be treated as a capture payment
|
134
139
|
post[:cx] = auth_token
|
@@ -136,10 +141,8 @@ module ActiveMerchant #:nodoc:
|
|
136
141
|
end
|
137
142
|
|
138
143
|
def add_amount(post, money, options)
|
139
|
-
|
140
144
|
post[:am] = amount(money)
|
141
145
|
post[:cu] = options[:currency] || currency(money)
|
142
|
-
|
143
146
|
end
|
144
147
|
|
145
148
|
def parse(xml_response)
|
@@ -147,8 +150,6 @@ module ActiveMerchant #:nodoc:
|
|
147
150
|
|
148
151
|
xml = REXML::Document.new(xml_response)
|
149
152
|
|
150
|
-
# for normal payments, the root node is <Response>
|
151
|
-
# for "future payments", it's <PaystationFuturePaymentResponse>
|
152
153
|
xml.elements.each("#{xml.root.name}/*") do |element|
|
153
154
|
response[element.name.underscore.to_sym] = element.text
|
154
155
|
end
|
@@ -157,12 +158,9 @@ module ActiveMerchant #:nodoc:
|
|
157
158
|
end
|
158
159
|
|
159
160
|
def commit(post)
|
160
|
-
|
161
|
-
post[:tm] = "T" if test? # test mode
|
162
|
-
|
161
|
+
post[:tm] = "T" if test?
|
163
162
|
pstn_prefix_params = post.collect { |key, value| "pstn_#{key}=#{CGI.escape(value.to_s)}" }.join("&")
|
164
163
|
|
165
|
-
# need include paystation param as "initiator flag for payment engine"
|
166
164
|
data = ssl_post(self.live_url, "#{pstn_prefix_params}&paystation=_empty")
|
167
165
|
response = parse(data)
|
168
166
|
message = message_from(response)
|
@@ -188,8 +186,6 @@ module ActiveMerchant #:nodoc:
|
|
188
186
|
end
|
189
187
|
|
190
188
|
class PaystationResponse < Response
|
191
|
-
# add a method to response so we can easily get the token
|
192
|
-
# for Validate transactions
|
193
189
|
def token
|
194
190
|
@params["future_payment_token"]
|
195
191
|
end
|
@@ -38,10 +38,10 @@ module ActiveMerchant #:nodoc:
|
|
38
38
|
self.display_name = "Redsys"
|
39
39
|
|
40
40
|
CURRENCY_CODES = {
|
41
|
-
"ARS" => '
|
42
|
-
"AUD" => '
|
41
|
+
"ARS" => '32',
|
42
|
+
"AUD" => '36',
|
43
43
|
"BRL" => '986',
|
44
|
-
"BOB" => '
|
44
|
+
"BOB" => '68',
|
45
45
|
"CAD" => '124',
|
46
46
|
"CHF" => '756',
|
47
47
|
"CLP" => '152',
|
@@ -50,6 +50,7 @@ module ActiveMerchant #:nodoc:
|
|
50
50
|
"GBP" => '826',
|
51
51
|
"GTQ" => '320',
|
52
52
|
"JPY" => '392',
|
53
|
+
"MYR" => '458',
|
53
54
|
"MXN" => '484',
|
54
55
|
"NZD" => '554',
|
55
56
|
"PEN" => '604',
|
@@ -88,9 +88,9 @@ module ActiveMerchant #:nodoc:
|
|
88
88
|
|
89
89
|
def scrub(transcript)
|
90
90
|
transcript.
|
91
|
-
gsub(%r((pwd=)
|
92
|
-
gsub(%r((<Number>)
|
93
|
-
gsub(%r((<Verification>)
|
91
|
+
gsub(%r((pwd=).+?(/>))i, '\1[FILTERED]\2').
|
92
|
+
gsub(%r((<Number>).+?(</Number>))i, '\1[FILTERED]\2').
|
93
|
+
gsub(%r((<Verification>).+?(</Verification>))i, '\1[FILTERED]\2')
|
94
94
|
end
|
95
95
|
|
96
96
|
private
|
@@ -120,25 +120,23 @@ module ActiveMerchant #:nodoc:
|
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
|
-
def credit(money, source, options = {})
|
124
|
-
ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
|
125
|
-
refund(money, source, options)
|
126
|
-
end
|
127
|
-
|
128
|
-
# Performs a refund transaction.
|
129
123
|
#
|
130
124
|
# ==== Parameters
|
131
125
|
#
|
132
126
|
# * <tt>money</tt> - The amount to be authorized as an integer value in cents.
|
133
|
-
# * <tt>source</tt> - The CreditCard or Check object to be used as the target for the
|
134
|
-
def
|
127
|
+
# * <tt>source</tt> - The CreditCard or Check object to be used as the target for the credit.
|
128
|
+
def credit(money, source, options = {})
|
135
129
|
if card_brand(source) == "check"
|
136
|
-
virtual_check.
|
130
|
+
virtual_check.credit(money, source, options)
|
137
131
|
else
|
138
|
-
bankcard.
|
132
|
+
bankcard.credit(money, source, options)
|
139
133
|
end
|
140
134
|
end
|
141
135
|
|
136
|
+
def refund(money, reference, options={})
|
137
|
+
bankcard.refund(money, reference, options)
|
138
|
+
end
|
139
|
+
|
142
140
|
# Stores a credit card in the Sage vault.
|
143
141
|
#
|
144
142
|
# ==== Parameters
|
@@ -47,17 +47,19 @@ module ActiveMerchant #:nodoc:
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def credit(money, credit_card, options = {})
|
50
|
-
ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
|
51
|
-
refund(money, credit_card, options)
|
52
|
-
end
|
53
|
-
|
54
|
-
def refund(money, credit_card, options = {})
|
55
50
|
post = {}
|
56
51
|
add_credit_card(post, credit_card)
|
57
52
|
add_transaction_data(post, money, options)
|
58
53
|
commit(:credit, post)
|
59
54
|
end
|
60
55
|
|
56
|
+
def refund(money, reference, options={})
|
57
|
+
post = {}
|
58
|
+
add_reference(post, reference)
|
59
|
+
add_transaction_data(post, money, options)
|
60
|
+
commit(:refund, post)
|
61
|
+
end
|
62
|
+
|
61
63
|
private
|
62
64
|
|
63
65
|
def add_credit_card(post, credit_card)
|
@@ -20,7 +20,8 @@ module ActiveMerchant #:nodoc:
|
|
20
20
|
:authorization => '02',
|
21
21
|
:capture => '11',
|
22
22
|
:void => '04',
|
23
|
-
:credit => '06'
|
23
|
+
:credit => '06',
|
24
|
+
:refund => '10'
|
24
25
|
}
|
25
26
|
|
26
27
|
def initialize(options = {})
|
@@ -30,7 +31,7 @@ module ActiveMerchant #:nodoc:
|
|
30
31
|
|
31
32
|
private
|
32
33
|
def add_invoice(post, options)
|
33
|
-
post[:T_ordernum] = options[:order_id].slice(0, 20)
|
34
|
+
post[:T_ordernum] = (options[:order_id] || generate_unique_id).slice(0, 20)
|
34
35
|
post[:T_tax] = amount(options[:tax]) unless options[:tax].blank?
|
35
36
|
post[:T_shipping] = amount(options[:shipping]) unless options[:shipping].blank?
|
36
37
|
end
|
@@ -22,11 +22,6 @@ module ActiveMerchant #:nodoc:
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def credit(money, credit_card, options = {})
|
25
|
-
ActiveMerchant.deprecated CREDIT_DEPRECATION_MESSAGE
|
26
|
-
refund(money, source, options)
|
27
|
-
end
|
28
|
-
|
29
|
-
def refund(money, credit_card, options = {})
|
30
25
|
post = {}
|
31
26
|
add_check(post, credit_card)
|
32
27
|
add_check_customer_data(post, options)
|
@@ -42,6 +42,7 @@ module ActiveMerchant #:nodoc:
|
|
42
42
|
'incorrect_cvc' => STANDARD_ERROR_CODE[:incorrect_cvc],
|
43
43
|
'incorrect_zip' => STANDARD_ERROR_CODE[:incorrect_zip],
|
44
44
|
'card_declined' => STANDARD_ERROR_CODE[:card_declined],
|
45
|
+
'call_issuer' => STANDARD_ERROR_CODE[:call_issuer],
|
45
46
|
'processing_error' => STANDARD_ERROR_CODE[:processing_error]
|
46
47
|
}
|
47
48
|
|
@@ -123,7 +124,7 @@ module ActiveMerchant #:nodoc:
|
|
123
124
|
|
124
125
|
def verify(payment, options = {})
|
125
126
|
MultiResponse.run(:use_first_response) do |r|
|
126
|
-
r.process { authorize(50, payment, options
|
127
|
+
r.process { authorize(50, payment, options) }
|
127
128
|
r.process(:ignore_result) { void(r.authorization, options) }
|
128
129
|
end
|
129
130
|
end
|
@@ -222,6 +223,10 @@ module ActiveMerchant #:nodoc:
|
|
222
223
|
gsub(%r((&?three_d_secure\[cryptogram\]=)[\w=]*(&?)), '\1[FILTERED]\2')
|
223
224
|
end
|
224
225
|
|
226
|
+
def supports_network_tokenization?
|
227
|
+
true
|
228
|
+
end
|
229
|
+
|
225
230
|
private
|
226
231
|
|
227
232
|
class StripePaymentToken < PaymentToken
|
@@ -295,6 +300,11 @@ module ActiveMerchant #:nodoc:
|
|
295
300
|
card = {}
|
296
301
|
if emv_payment?(creditcard)
|
297
302
|
add_emv_creditcard(post, creditcard.icc_data)
|
303
|
+
post[:card][:read_method] = "contactless" if creditcard.contactless
|
304
|
+
if creditcard.encrypted_pin_cryptogram.present? && creditcard.encrypted_pin_ksn.present?
|
305
|
+
post[:card][:encrypted_pin] = creditcard.encrypted_pin_cryptogram
|
306
|
+
post[:card][:encrypted_pin_key_id] = creditcard.encrypted_pin_ksn
|
307
|
+
end
|
298
308
|
elsif creditcard.respond_to?(:number)
|
299
309
|
if creditcard.respond_to?(:track_data) && creditcard.track_data.present?
|
300
310
|
card[:swipe_data] = creditcard.track_data
|
@@ -418,7 +428,7 @@ module ActiveMerchant #:nodoc:
|
|
418
428
|
|
419
429
|
success = !response.key?("error")
|
420
430
|
|
421
|
-
card = response
|
431
|
+
card = card_from_response(response)
|
422
432
|
avs_code = AVS_CODE_TRANSLATOR["line1: #{card["address_line1_check"]}, zip: #{card["address_zip_check"]}"]
|
423
433
|
cvc_code = CVC_CODE_TRANSLATOR[card["cvc_check"]]
|
424
434
|
|
@@ -429,8 +439,8 @@ module ActiveMerchant #:nodoc:
|
|
429
439
|
:authorization => success ? response["id"] : response["error"]["charge"],
|
430
440
|
:avs_result => { :code => avs_code },
|
431
441
|
:cvv_result => cvc_code,
|
432
|
-
:emv_authorization =>
|
433
|
-
:error_code => success ? nil :
|
442
|
+
:emv_authorization => emv_authorization_from_response(response),
|
443
|
+
:error_code => success ? nil : error_code_from(response)
|
434
444
|
)
|
435
445
|
end
|
436
446
|
|
@@ -459,6 +469,25 @@ module ActiveMerchant #:nodoc:
|
|
459
469
|
def emv_payment?(payment)
|
460
470
|
payment.respond_to?(:emv?) && payment.emv?
|
461
471
|
end
|
472
|
+
|
473
|
+
def card_from_response(response)
|
474
|
+
response["card"] || response["active_card"] || response["source"] || {}
|
475
|
+
end
|
476
|
+
|
477
|
+
def emv_authorization_from_response(response)
|
478
|
+
return response["error"]["emv_auth_data"] if response["error"]
|
479
|
+
|
480
|
+
card_from_response(response)["emv_auth_data"]
|
481
|
+
end
|
482
|
+
|
483
|
+
def error_code_from(response)
|
484
|
+
code = response['error']['code']
|
485
|
+
decline_code = response['error']['decline_code'] if code == 'card_declined'
|
486
|
+
|
487
|
+
error_code = STANDARD_ERROR_CODE_MAPPING[decline_code]
|
488
|
+
error_code ||= STANDARD_ERROR_CODE_MAPPING[code]
|
489
|
+
error_code
|
490
|
+
end
|
462
491
|
end
|
463
492
|
end
|
464
493
|
end
|
@@ -73,27 +73,34 @@ module ActiveMerchant #:nodoc:
|
|
73
73
|
post = {}
|
74
74
|
post[:client_id] = @options[:client_id]
|
75
75
|
post[:user_name] = "#{creditcard.first_name} #{creditcard.last_name}"
|
76
|
-
post[:email] = options[:email]
|
76
|
+
post[:email] = options[:email] || "unspecified@example.com"
|
77
77
|
post[:cc_number] = creditcard.number
|
78
|
-
post[:cvv] = creditcard.verification_value
|
79
|
-
post[:expiration_month] = creditcard.month
|
80
|
-
post[:expiration_year] = creditcard.year
|
78
|
+
post[:cvv] = creditcard.verification_value unless options[:recurring]
|
79
|
+
post[:expiration_month] = "#{creditcard.month}"
|
80
|
+
post[:expiration_year] = "#{creditcard.year}"
|
81
81
|
post[:original_ip] = options[:ip] if options[:ip]
|
82
82
|
post[:original_device] = options[:device_fingerprint] if options[:device_fingerprint]
|
83
83
|
if(billing_address = (options[:billing_address] || options[:address]))
|
84
84
|
post[:address] = {
|
85
85
|
"address1" => billing_address[:address1],
|
86
86
|
"city" => billing_address[:city],
|
87
|
-
"state" => billing_address[:state],
|
88
87
|
"country" => billing_address[:country]
|
89
88
|
}
|
90
89
|
if(post[:country] == "US")
|
91
90
|
post[:address]["zip"] = billing_address[:zip]
|
91
|
+
post[:address]["state"] = billing_address[:state]
|
92
92
|
else
|
93
|
+
post[:address]["region"] = billing_address[:state]
|
93
94
|
post[:address]["postcode"] = billing_address[:zip]
|
94
95
|
end
|
95
96
|
end
|
96
|
-
|
97
|
+
|
98
|
+
if options[:recurring] == true
|
99
|
+
post[:client_secret] = @options[:client_secret]
|
100
|
+
commit('/credit_card/transfer', post)
|
101
|
+
else
|
102
|
+
commit('/credit_card/create', post)
|
103
|
+
end
|
97
104
|
end
|
98
105
|
|
99
106
|
private
|
@@ -22,7 +22,6 @@ module ActiveMerchant #:nodoc:
|
|
22
22
|
|
23
23
|
def authorize(money, credit_card, options={})
|
24
24
|
response = create_token(true, credit_card.first_name+' '+credit_card.last_name, credit_card.month, credit_card.year, credit_card.number, credit_card.verification_value)
|
25
|
-
|
26
25
|
if response.success?
|
27
26
|
options[:authorizeOnly] = true
|
28
27
|
post = create_post_for_auth_or_purchase(response.authorization, money, options)
|
@@ -95,7 +94,7 @@ module ActiveMerchant #:nodoc:
|
|
95
94
|
def create_post_for_auth_or_purchase(token, money, options)
|
96
95
|
{
|
97
96
|
"token" => token,
|
98
|
-
"orderDescription" => options[:description],
|
97
|
+
"orderDescription" => options[:description] || 'Worldpay Order',
|
99
98
|
"amount" => money,
|
100
99
|
"currencyCode" => options[:currency] || default_currency,
|
101
100
|
"name" => options[:billing_address]&&options[:billing_address][:name] ? options[:billing_address][:name] : '',
|