activemerchant 1.73.0 → 1.74.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 +23 -2
- data/lib/active_merchant/billing/gateways/adyen.rb +1 -1
- data/lib/active_merchant/billing/gateways/authorize_net_cim.rb +4 -2
- data/lib/active_merchant/billing/gateways/barclaycard_smartpay.rb +46 -18
- data/lib/active_merchant/billing/gateways/beanstream.rb +2 -0
- data/lib/active_merchant/billing/gateways/beanstream/beanstream_core.rb +10 -4
- data/lib/active_merchant/billing/gateways/borgun.rb +9 -8
- data/lib/active_merchant/billing/gateways/checkout_v2.rb +31 -9
- data/lib/active_merchant/billing/gateways/credorax.rb +55 -39
- data/lib/active_merchant/billing/gateways/cyber_source.rb +2 -0
- data/lib/active_merchant/billing/gateways/ebanx.rb +76 -24
- data/lib/active_merchant/billing/gateways/elavon.rb +2 -2
- data/lib/active_merchant/billing/gateways/netbanx.rb +5 -1
- data/lib/active_merchant/billing/gateways/payeezy.rb +137 -38
- data/lib/active_merchant/billing/gateways/payu_latam.rb +2 -1
- data/lib/active_merchant/billing/gateways/redsys.rb +1 -0
- data/lib/active_merchant/billing/gateways/wepay.rb +2 -2
- data/lib/active_merchant/connection.rb +2 -2
- data/lib/active_merchant/network_connection_retries.rb +4 -4
- data/lib/active_merchant/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9058f19bf43858097b6bbd6a911b01a62aafa568
|
|
4
|
+
data.tar.gz: 5fc5302b4559796e838bc675a5b03ce61c42aa11
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 792627ab57f85f7d6036a94ad5192e4fa0bc266154bde86f9a0f643ec35a8637c874749a758ff55c34b6069476829fc62b1df17ba59ae749a0e204545e88e503
|
|
7
|
+
data.tar.gz: 9c382d5af0c5c9794c1091b5706c264fd2317b84ea5a9cc6940f599b7981d45d012692f9af77ab5fc8e342035c8340acfbcd6f49cbc10ada944d2c4019bd7dd6
|
data/CHANGELOG
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
== HEAD
|
|
4
4
|
|
|
5
|
+
== Version 1.74.0 (October 24, 2017)
|
|
6
|
+
* Adyen: Update list of supported countries [dtykocki] #2600
|
|
7
|
+
* Authorize.net CIM: Handle multiple error messages [amandapuff] #2537
|
|
8
|
+
* Barclaycard Smartpay: Pass street and house_number fields, in addition to standard address [deedeelavinder] #2603
|
|
9
|
+
* Barclaycard Smartpay: Use authorization pspReference for refunds [davidsantoso] #2599
|
|
10
|
+
* Beanstream: Pass email fields without address [curiousepic] #2615
|
|
11
|
+
* Beanstream: Support recurringPayment for auth, capture, and purchase transactions [dtykocki] #2617
|
|
12
|
+
* Borgun: Add support for USD transactions [dtykocki] #2602
|
|
13
|
+
* Borgun: Include currency code from split authorization for voids [dtykocki] #2605
|
|
14
|
+
* Checkout V2: Expose AVS and CVV results for purchases [dtykocki] #2619
|
|
15
|
+
* Credorax: Update response codes [curiousepic] #2595
|
|
16
|
+
* CyberSource: Support 3DSecure requests [curiousepic] #2624
|
|
17
|
+
* Ebanx: Pass person_type and name for stored cards [curiousepic] #2621
|
|
18
|
+
* Ebanx: Support Store and person_type option [curiousepic] #2604
|
|
19
|
+
* Elavon: Update endpoint URLs [curiousepic] #2608
|
|
20
|
+
* Netbanx: Fix basic auth by sending the account_number and api_key [anotherjosmith] #2616
|
|
21
|
+
* Payeezy: Adds support for store [deedeelavinder] #2591
|
|
22
|
+
* PayU Latam: Set payment_country gateway attribute [curiousepic] #2611
|
|
23
|
+
* Redsys: Support the DKK currency type [bpollack] #2618
|
|
24
|
+
* WePay: Only send ip and device for non-recurring transactions [dtykocki] #2597
|
|
25
|
+
|
|
5
26
|
== Version 1.73.0 (September 28, 2017)
|
|
6
27
|
* Adyen: Use original authorization pspReference on Refunds [lyverovski] #2589
|
|
7
28
|
* Braintree Blue: Explicitly require braintree-ruby version 2.78 [anotherjosmith]
|
|
@@ -1777,7 +1798,7 @@ value [jduff]
|
|
|
1777
1798
|
* Support default Return class for all Integrations that don't use returns [Soleone]
|
|
1778
1799
|
* Add support for passing additional options when creating a Notification to all Integrations [Soleone]
|
|
1779
1800
|
* Update BraintreeBlue#refund to have consistent method signature [Jonathan Rudenberg]
|
|
1780
|
-
* Add rails/init.rb for gem campatability in Rails [
|
|
1801
|
+
* Add rails/init.rb for gem campatability in Rails [R?dolfs O?i??]
|
|
1781
1802
|
* Fix Paypal Express response parser [Jonathan Rudenberg]
|
|
1782
1803
|
* Braintree/Transax: Add tax field [wisq]
|
|
1783
1804
|
|
|
@@ -2093,7 +2114,7 @@ value [jduff]
|
|
|
2093
2114
|
* Update Secure Pay Au to meet specs for MessageInfo elements [cody]
|
|
2094
2115
|
* Add support for the Australian Secure Pay payment gateway [cody]
|
|
2095
2116
|
* Allow LinkPoint cancellations for recurring billing. [yanagimoto.shin]
|
|
2096
|
-
* Add support for
|
|
2117
|
+
* Add support for ?land Islands to the country list [cody]
|
|
2097
2118
|
|
|
2098
2119
|
== Version 1.3.1 (January 28, 2008)
|
|
2099
2120
|
|
|
@@ -7,7 +7,7 @@ module ActiveMerchant #:nodoc:
|
|
|
7
7
|
self.test_url = 'https://pal-test.adyen.com/pal/servlet/Payment/v18'
|
|
8
8
|
self.live_url = 'https://pal-live.adyen.com/pal/servlet/Payment/v18'
|
|
9
9
|
|
|
10
|
-
self.supported_countries = ['
|
|
10
|
+
self.supported_countries = ['AT','AU','BE','BG','BR','CH','CY','CZ','DE','DK','EE','ES','FI','FR','GB','GI','GR','HK','HU','IE','IS','IT','LI','LT','LU','LV','MC','MT','MX','NL','NO','PL','PT','RO','SE','SG','SK','SI','US']
|
|
11
11
|
self.default_currency = 'USD'
|
|
12
12
|
self.supported_cardtypes = [:visa, :master, :american_express, :diners_club, :jcb, :dankort, :maestro, :discover]
|
|
13
13
|
|
|
@@ -858,7 +858,9 @@ module ActiveMerchant #:nodoc:
|
|
|
858
858
|
|
|
859
859
|
response_params = parse(action, xml)
|
|
860
860
|
|
|
861
|
-
|
|
861
|
+
message_element= response_params["messages"]["message"]
|
|
862
|
+
first_error = message_element.is_a?(Array) ? message_element.first : message_element
|
|
863
|
+
message = first_error['text']
|
|
862
864
|
test_mode = @options[:test_requests] || message =~ /Test Mode/
|
|
863
865
|
success = response_params['messages']['result_code'] == 'Ok'
|
|
864
866
|
response_params['direct_response'] = parse_direct_response(response_params['direct_response']) if response_params['direct_response']
|
|
@@ -867,7 +869,7 @@ module ActiveMerchant #:nodoc:
|
|
|
867
869
|
response_options = {}
|
|
868
870
|
response_options[:test] = test_mode
|
|
869
871
|
response_options[:authorization] = transaction_id || response_params['customer_profile_id'] || (response_params['profile'] ? response_params['profile']['customer_profile_id'] : nil)
|
|
870
|
-
response_options[:error_code] =
|
|
872
|
+
response_options[:error_code] = first_error['code'] unless success
|
|
871
873
|
|
|
872
874
|
Response.new(success, message, response_params, response_options)
|
|
873
875
|
end
|
|
@@ -33,15 +33,8 @@ module ActiveMerchant #:nodoc:
|
|
|
33
33
|
post = payment_request(money, options)
|
|
34
34
|
post[:amount] = amount_hash(money, options[:currency])
|
|
35
35
|
post[:card] = credit_card_hash(creditcard)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
post[:billingAddress] = address_hash(address)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
if options[:shipping_address]
|
|
42
|
-
post[:deliveryAddress] = address_hash(options[:shipping_address])
|
|
43
|
-
end
|
|
44
|
-
|
|
36
|
+
post[:billingAddress] = billing_address_hash(options) if options[:billing_address]
|
|
37
|
+
post[:deliveryAddress] = shipping_address_hash(options) if options[:shipping_address]
|
|
45
38
|
commit('authorise', post)
|
|
46
39
|
end
|
|
47
40
|
|
|
@@ -139,7 +132,7 @@ module ActiveMerchant #:nodoc:
|
|
|
139
132
|
response,
|
|
140
133
|
test: test?,
|
|
141
134
|
avs_result: AVSResult.new(:code => parse_avs_code(response)),
|
|
142
|
-
authorization: response['recurringDetailReference'] || response
|
|
135
|
+
authorization: response['recurringDetailReference'] || authorization_from(post, response)
|
|
143
136
|
)
|
|
144
137
|
|
|
145
138
|
rescue ResponseError => e
|
|
@@ -158,6 +151,13 @@ module ActiveMerchant #:nodoc:
|
|
|
158
151
|
raise
|
|
159
152
|
end
|
|
160
153
|
|
|
154
|
+
def authorization_from(parameters, response)
|
|
155
|
+
authorization = [parameters[:originalReference], response['pspReference']].compact
|
|
156
|
+
|
|
157
|
+
return nil if authorization.empty?
|
|
158
|
+
return authorization.join("#")
|
|
159
|
+
end
|
|
160
|
+
|
|
161
161
|
def parse_avs_code(response)
|
|
162
162
|
AVS_MAPPING[response["avsResult"][0..1].strip] if response["avsResult"]
|
|
163
163
|
end
|
|
@@ -223,17 +223,41 @@ module ActiveMerchant #:nodoc:
|
|
|
223
223
|
end
|
|
224
224
|
end
|
|
225
225
|
|
|
226
|
-
def
|
|
227
|
-
|
|
228
|
-
street =
|
|
229
|
-
house =
|
|
226
|
+
def billing_address_hash(options)
|
|
227
|
+
address = options[:address] || options[:billing_address] if options[:address] || options[:billing_address]
|
|
228
|
+
street = options[:street] || parse_street(address)
|
|
229
|
+
house = options[:house_number] || parse_house_number(address)
|
|
230
|
+
|
|
231
|
+
create_address_hash(address, house, street)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def shipping_address_hash(options)
|
|
235
|
+
address = options[:shipping_address]
|
|
236
|
+
street = options[:shipping_street] || parse_street(address)
|
|
237
|
+
house = options[:shipping_house_number] || parse_house_number(address)
|
|
230
238
|
|
|
239
|
+
create_address_hash(address, house, street)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def parse_street(address)
|
|
243
|
+
address_to_parse = "#{address[:address1]} #{address[:address2]}"
|
|
244
|
+
street = address[:street] || address_to_parse.split(/\s+/).keep_if { |x| x !~ /\d/ }.join(' ')
|
|
245
|
+
street.empty? ? "Not Provided" : street
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def parse_house_number(address)
|
|
249
|
+
address_to_parse = "#{address[:address1]} #{address[:address2]}"
|
|
250
|
+
house = address[:houseNumberOrName] || address_to_parse.split(/\s+/).keep_if { |x| x =~ /\d/ }.join(' ')
|
|
251
|
+
house.empty? ? "Not Provided" : house
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def create_address_hash(address, house, street)
|
|
231
255
|
hash = {}
|
|
256
|
+
hash[:houseNumberOrName] = house
|
|
257
|
+
hash[:street] = street
|
|
232
258
|
hash[:city] = address[:city] if address[:city]
|
|
233
|
-
hash[:street] = street || full_address.split(/\s+/).keep_if { |x| x !~ /\d/ }.join(' ')
|
|
234
|
-
hash[:houseNumberOrName] = house.empty? ? "Not Provided" : house
|
|
235
|
-
hash[:postalCode] = address[:zip] if address[:zip]
|
|
236
259
|
hash[:stateOrProvince] = address[:state] if address[:state]
|
|
260
|
+
hash[:postalCode] = address[:zip] if address[:zip]
|
|
237
261
|
hash[:country] = address[:country] if address[:country]
|
|
238
262
|
hash
|
|
239
263
|
end
|
|
@@ -259,10 +283,14 @@ module ActiveMerchant #:nodoc:
|
|
|
259
283
|
def modification_request(reference, options)
|
|
260
284
|
hash = {}
|
|
261
285
|
hash[:merchantAccount] = @options[:merchant]
|
|
262
|
-
hash[:originalReference] = reference
|
|
286
|
+
hash[:originalReference] = psp_reference_from(reference)
|
|
263
287
|
hash.keep_if { |_, v| v }
|
|
264
288
|
end
|
|
265
289
|
|
|
290
|
+
def psp_reference_from(authorization)
|
|
291
|
+
authorization.nil? ? nil : authorization.split("#").first
|
|
292
|
+
end
|
|
293
|
+
|
|
266
294
|
def payment_request(money, options)
|
|
267
295
|
hash = {}
|
|
268
296
|
hash[:merchantAccount] = @options[:merchant]
|
|
@@ -75,6 +75,7 @@ module ActiveMerchant #:nodoc:
|
|
|
75
75
|
add_address(post, options)
|
|
76
76
|
add_transaction_type(post, :authorization)
|
|
77
77
|
add_customer_ip(post, options)
|
|
78
|
+
add_recurring_payment(post, options)
|
|
78
79
|
commit(post)
|
|
79
80
|
end
|
|
80
81
|
|
|
@@ -86,6 +87,7 @@ module ActiveMerchant #:nodoc:
|
|
|
86
87
|
add_address(post, options)
|
|
87
88
|
add_transaction_type(post, purchase_action(source))
|
|
88
89
|
add_customer_ip(post, options)
|
|
90
|
+
add_recurring_payment(post, options)
|
|
89
91
|
commit(post)
|
|
90
92
|
end
|
|
91
93
|
|
|
@@ -138,7 +138,7 @@ module ActiveMerchant #:nodoc:
|
|
|
138
138
|
|
|
139
139
|
# The homepage URL of the gateway
|
|
140
140
|
base.homepage_url = 'http://www.beanstream.com/'
|
|
141
|
-
base.live_url = 'https://
|
|
141
|
+
base.live_url = 'https://api.na.bambora.com/scripts/process_transaction.asp'
|
|
142
142
|
|
|
143
143
|
# The name of the gateway
|
|
144
144
|
base.display_name = 'Beanstream.com'
|
|
@@ -161,6 +161,7 @@ module ActiveMerchant #:nodoc:
|
|
|
161
161
|
add_amount(post, money)
|
|
162
162
|
add_reference(post, reference)
|
|
163
163
|
add_transaction_type(post, :capture)
|
|
164
|
+
add_recurring_payment(post, options)
|
|
164
165
|
commit(post)
|
|
165
166
|
end
|
|
166
167
|
|
|
@@ -221,11 +222,13 @@ module ActiveMerchant #:nodoc:
|
|
|
221
222
|
end
|
|
222
223
|
|
|
223
224
|
def add_address(post, options)
|
|
225
|
+
post[:ordEmailAddress] = options[:email] if options[:email]
|
|
226
|
+
post[:shipEmailAddress] = options[:shipping_email] || options[:email] if options[:email]
|
|
227
|
+
|
|
224
228
|
prepare_address_for_non_american_countries(options)
|
|
225
229
|
|
|
226
230
|
if billing_address = options[:billing_address] || options[:address]
|
|
227
231
|
post[:ordName] = billing_address[:name]
|
|
228
|
-
post[:ordEmailAddress] = options[:email]
|
|
229
232
|
post[:ordPhoneNumber] = billing_address[:phone]
|
|
230
233
|
post[:ordAddress1] = billing_address[:address1]
|
|
231
234
|
post[:ordAddress2] = billing_address[:address2]
|
|
@@ -234,9 +237,9 @@ module ActiveMerchant #:nodoc:
|
|
|
234
237
|
post[:ordPostalCode] = billing_address[:zip]
|
|
235
238
|
post[:ordCountry] = billing_address[:country]
|
|
236
239
|
end
|
|
240
|
+
|
|
237
241
|
if shipping_address = options[:shipping_address]
|
|
238
242
|
post[:shipName] = shipping_address[:name]
|
|
239
|
-
post[:shipEmailAddress] = options[:email]
|
|
240
243
|
post[:shipPhoneNumber] = shipping_address[:phone]
|
|
241
244
|
post[:shipAddress1] = shipping_address[:address1]
|
|
242
245
|
post[:shipAddress2] = shipping_address[:address2]
|
|
@@ -263,6 +266,10 @@ module ActiveMerchant #:nodoc:
|
|
|
263
266
|
end
|
|
264
267
|
end
|
|
265
268
|
|
|
269
|
+
def add_recurring_payment(post, options)
|
|
270
|
+
post[:recurringPayment] = true if options[:recurring].to_s == 'true'
|
|
271
|
+
end
|
|
272
|
+
|
|
266
273
|
def add_invoice(post, options)
|
|
267
274
|
post[:trnOrderNumber] = options[:order_id]
|
|
268
275
|
post[:trnComments] = options[:description]
|
|
@@ -465,4 +472,3 @@ module ActiveMerchant #:nodoc:
|
|
|
465
472
|
end
|
|
466
473
|
end
|
|
467
474
|
end
|
|
468
|
-
|
|
@@ -26,7 +26,6 @@ module ActiveMerchant #:nodoc:
|
|
|
26
26
|
post[:TransType] = '1'
|
|
27
27
|
add_invoice(post, money, options)
|
|
28
28
|
add_payment_method(post, payment)
|
|
29
|
-
|
|
30
29
|
commit('sale', post)
|
|
31
30
|
end
|
|
32
31
|
|
|
@@ -35,7 +34,6 @@ module ActiveMerchant #:nodoc:
|
|
|
35
34
|
post[:TransType] = '5'
|
|
36
35
|
add_invoice(post, money, options)
|
|
37
36
|
add_payment_method(post, payment)
|
|
38
|
-
|
|
39
37
|
commit('authonly', post)
|
|
40
38
|
end
|
|
41
39
|
|
|
@@ -57,9 +55,10 @@ module ActiveMerchant #:nodoc:
|
|
|
57
55
|
|
|
58
56
|
def void(authorization, options={})
|
|
59
57
|
post = {}
|
|
60
|
-
# TransType and
|
|
61
|
-
_, _, _, _, _, transtype, tramount = split_authorization(authorization)
|
|
58
|
+
# TransType, TrAmount, and currency must match original values from auth or purchase.
|
|
59
|
+
_, _, _, _, _, transtype, tramount, currency = split_authorization(authorization)
|
|
62
60
|
post[:TransType] = transtype
|
|
61
|
+
options[:currency] = options[:currency] || CURRENCY_CODES.key(currency)
|
|
63
62
|
add_invoice(post, tramount.to_i, options)
|
|
64
63
|
add_reference(post, authorization)
|
|
65
64
|
commit('void', post)
|
|
@@ -80,6 +79,7 @@ module ActiveMerchant #:nodoc:
|
|
|
80
79
|
CURRENCY_CODES = Hash.new{|h,k| raise ArgumentError.new("Unsupported currency for HDFC: #{k}")}
|
|
81
80
|
CURRENCY_CODES["ISK"] = "352"
|
|
82
81
|
CURRENCY_CODES["EUR"] = "978"
|
|
82
|
+
CURRENCY_CODES["USD"] = "840"
|
|
83
83
|
|
|
84
84
|
def add_invoice(post, money, options)
|
|
85
85
|
post[:TrAmount] = amount(money)
|
|
@@ -95,7 +95,7 @@ module ActiveMerchant #:nodoc:
|
|
|
95
95
|
end
|
|
96
96
|
|
|
97
97
|
def add_reference(post, authorization)
|
|
98
|
-
dateandtime, batch, transaction, rrn, authcode, _, _ = split_authorization(authorization)
|
|
98
|
+
dateandtime, batch, transaction, rrn, authcode, _, _, _ = split_authorization(authorization)
|
|
99
99
|
post[:DateAndTime] = dateandtime
|
|
100
100
|
post[:Batch] = batch
|
|
101
101
|
post[:Transaction] = transaction
|
|
@@ -166,13 +166,14 @@ module ActiveMerchant #:nodoc:
|
|
|
166
166
|
response[:rrn],
|
|
167
167
|
response[:authcode],
|
|
168
168
|
response[:transtype],
|
|
169
|
-
response[:tramount]
|
|
169
|
+
response[:tramount],
|
|
170
|
+
response[:trcurrency]
|
|
170
171
|
].join("|")
|
|
171
172
|
end
|
|
172
173
|
|
|
173
174
|
def split_authorization(authorization)
|
|
174
|
-
dateandtime, batch, transaction, rrn, authcode, transtype, tramount = authorization.split("|")
|
|
175
|
-
[dateandtime, batch, transaction, rrn, authcode, transtype, tramount]
|
|
175
|
+
dateandtime, batch, transaction, rrn, authcode, transtype, tramount, currency = authorization.split("|")
|
|
176
|
+
[dateandtime, batch, transaction, rrn, authcode, transtype, tramount, currency]
|
|
176
177
|
end
|
|
177
178
|
|
|
178
179
|
def headers
|
|
@@ -17,10 +17,24 @@ 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.new(
|
|
29
|
+
succeeded,
|
|
30
|
+
message_from(succeeded, merged_params),
|
|
31
|
+
merged_params,
|
|
32
|
+
authorization: authorization_from(merged_params),
|
|
33
|
+
avs_result: avs_result(:purchase, succeeded, merged_params),
|
|
34
|
+
cvv_result: cvv_result(:purchase, succeeded, merged_params),
|
|
35
|
+
error_code: error_code_from(succeeded, merged_params),
|
|
36
|
+
test: test?
|
|
37
|
+
)
|
|
24
38
|
end
|
|
25
39
|
|
|
26
40
|
def authorize(amount, payment_method, options={})
|
|
@@ -98,8 +112,8 @@ module ActiveMerchant #:nodoc:
|
|
|
98
112
|
address = options[:billing_address]
|
|
99
113
|
if(address && post[:card])
|
|
100
114
|
post[:card][:billingDetails] = {}
|
|
101
|
-
post[:card][:billingDetails][:
|
|
102
|
-
post[:card][:billingDetails][:
|
|
115
|
+
post[:card][:billingDetails][:addressLine1] = address[:address1]
|
|
116
|
+
post[:card][:billingDetails][:addressLine2] = address[:address2]
|
|
103
117
|
post[:card][:billingDetails][:city] = address[:city]
|
|
104
118
|
post[:card][:billingDetails][:state] = address[:state]
|
|
105
119
|
post[:card][:billingDetails][:country] = address[:country]
|
|
@@ -125,8 +139,8 @@ module ActiveMerchant #:nodoc:
|
|
|
125
139
|
authorization: authorization_from(response),
|
|
126
140
|
error_code: error_code_from(succeeded, response),
|
|
127
141
|
test: test?,
|
|
128
|
-
avs_result: avs_result(action, response),
|
|
129
|
-
cvv_result: cvv_result(action, response))
|
|
142
|
+
avs_result: avs_result(action, succeeded, response),
|
|
143
|
+
cvv_result: cvv_result(action, succeeded, response))
|
|
130
144
|
end
|
|
131
145
|
|
|
132
146
|
def headers
|
|
@@ -148,12 +162,20 @@ module ActiveMerchant #:nodoc:
|
|
|
148
162
|
test? ? test_url : live_url
|
|
149
163
|
end
|
|
150
164
|
|
|
151
|
-
def avs_result(action, response)
|
|
152
|
-
|
|
165
|
+
def avs_result(action, succeeded, response)
|
|
166
|
+
if succeeded
|
|
167
|
+
action == :purchase ? AVSResult.new(code: response["card"]["avsCheck"]) : nil
|
|
168
|
+
else
|
|
169
|
+
nil
|
|
170
|
+
end
|
|
153
171
|
end
|
|
154
172
|
|
|
155
|
-
def cvv_result(action, response)
|
|
156
|
-
|
|
173
|
+
def cvv_result(action, succeeded, response)
|
|
174
|
+
if succeeded
|
|
175
|
+
action == :purchase ? CVVResult.new(response["card"]["cvvCheck"]) : nil
|
|
176
|
+
else
|
|
177
|
+
nil
|
|
178
|
+
end
|
|
157
179
|
end
|
|
158
180
|
|
|
159
181
|
def parse(body)
|
|
@@ -30,71 +30,87 @@ module ActiveMerchant #:nodoc:
|
|
|
30
30
|
"03" => "Invalid merchant",
|
|
31
31
|
"04" => "Pick up card",
|
|
32
32
|
"05" => "Do not Honour",
|
|
33
|
-
"06" => "
|
|
33
|
+
"06" => "Error",
|
|
34
34
|
"07" => "Pick up card special condition",
|
|
35
|
-
"08" => "
|
|
36
|
-
"09" => "
|
|
35
|
+
"08" => "Honour with identification",
|
|
36
|
+
"09" => "Request in progress",
|
|
37
37
|
"10" => "Approved for partial amount",
|
|
38
|
-
"11" => "
|
|
39
|
-
"12" => "Invalid transaction
|
|
38
|
+
"11" => "Approved (VIP)",
|
|
39
|
+
"12" => "Invalid transaction",
|
|
40
40
|
"13" => "Invalid amount",
|
|
41
41
|
"14" => "Invalid card number",
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
42
|
+
"15" => "No such issuer",
|
|
43
|
+
"16" => "Approved, update track 3",
|
|
44
|
+
"17" => "Customer cancellation",
|
|
45
|
+
"18" => "Customer dispute",
|
|
46
|
+
"19" => "Re-enter transaction",
|
|
47
|
+
"20" => "Invalid response",
|
|
48
|
+
"21" => "No action taken",
|
|
49
|
+
"22" => "Suspected malfunction",
|
|
50
|
+
"23" => "Unacceptable transaction fee",
|
|
51
|
+
"24" => "File update not supported by receiver",
|
|
52
|
+
"25" => "No such record",
|
|
53
|
+
"26" => "Duplicate record update, old record replaced",
|
|
54
|
+
"27" => "File update field edit error",
|
|
55
|
+
"28" => "File locked out while update",
|
|
56
|
+
"29" => "File update error, contact acquirer",
|
|
49
57
|
"30" => "Format error",
|
|
50
|
-
"
|
|
58
|
+
"31" => "Issuer signed-off",
|
|
59
|
+
"32" => "Completed partially",
|
|
60
|
+
"33" => "Pick-up, expired card",
|
|
61
|
+
"34" => "Suspect Fraud",
|
|
62
|
+
"35" => "Pick-up, card acceptor contact acquirer",
|
|
63
|
+
"36" => "Pick up, card restricted",
|
|
64
|
+
"37" => "Pick up, call acquirer security",
|
|
65
|
+
"38" => "Pick up, Allowable PIN tries exceeded",
|
|
51
66
|
"39" => "Transaction Not Allowed",
|
|
67
|
+
"40" => "Requested function not supported",
|
|
52
68
|
"41" => "Lost Card, Pickup",
|
|
53
|
-
"42" => "
|
|
54
|
-
"43" => "
|
|
55
|
-
"44" => "
|
|
69
|
+
"42" => "No universal account",
|
|
70
|
+
"43" => "Pick up, stolen card",
|
|
71
|
+
"44" => "No investment account",
|
|
72
|
+
"50" => "Do not renew",
|
|
56
73
|
"51" => "Not sufficient funds",
|
|
57
74
|
"52" => "No checking Account",
|
|
58
75
|
"53" => "No savings account",
|
|
59
76
|
"54" => "Expired card",
|
|
60
77
|
"55" => "Pin incorrect",
|
|
78
|
+
"56" => "No card record",
|
|
61
79
|
"57" => "Transaction not allowed for cardholder",
|
|
62
80
|
"58" => "Transaction not allowed for merchant",
|
|
63
81
|
"59" => "Suspected Fraud",
|
|
82
|
+
"60" => "Card acceptor contact acquirer",
|
|
64
83
|
"61" => "Exceeds withdrawal amount limit",
|
|
65
84
|
"62" => "Restricted card",
|
|
66
|
-
"63" => "
|
|
85
|
+
"63" => "Security violation",
|
|
86
|
+
"64" => "Wrong original amount",
|
|
67
87
|
"65" => "Activity count limit exceeded",
|
|
68
|
-
"66" => "
|
|
69
|
-
"67" => "
|
|
70
|
-
"68" => "Response received too late",
|
|
88
|
+
"66" => "Call acquirers security department",
|
|
89
|
+
"67" => "Card to be picked up at ATM",
|
|
90
|
+
"68" => "Response received too late.",
|
|
91
|
+
"70" => "Invalid transaction; contact card issuer",
|
|
92
|
+
"71" => "Decline PIN not changed",
|
|
71
93
|
"75" => "Pin tries exceeded",
|
|
72
|
-
"76" => "
|
|
73
|
-
"77" => "
|
|
74
|
-
"78" => "
|
|
75
|
-
"79" => "
|
|
76
|
-
"80" => "
|
|
77
|
-
"81" => "
|
|
94
|
+
"76" => "Wrong PIN, number of PIN tries exceeded",
|
|
95
|
+
"77" => "Wrong Reference No.",
|
|
96
|
+
"78" => "Record Not Found",
|
|
97
|
+
"79" => "Already reversed",
|
|
98
|
+
"80" => "Network error",
|
|
99
|
+
"81" => "Foreign network error / PIN cryptographic error",
|
|
78
100
|
"82" => "Time out at issuer system",
|
|
79
|
-
"83" => "
|
|
80
|
-
"84" => "
|
|
81
|
-
"85" => "
|
|
101
|
+
"83" => "Transaction failed",
|
|
102
|
+
"84" => "Pre-authorization timed out",
|
|
103
|
+
"85" => "No reason to decline",
|
|
82
104
|
"86" => "Cannot verify pin",
|
|
83
105
|
"87" => "Purchase amount only, no cashback allowed",
|
|
84
106
|
"88" => "MAC sync Error",
|
|
85
|
-
"89" => "
|
|
107
|
+
"89" => "Authentication failure",
|
|
86
108
|
"91" => "Issuer not available",
|
|
87
109
|
"92" => "Unable to route at acquirer Module",
|
|
88
|
-
"93" => "
|
|
89
|
-
"94" => "Duplicate
|
|
90
|
-
"95" => "
|
|
110
|
+
"93" => "Cannot be completed, violation of law",
|
|
111
|
+
"94" => "Duplicate Transmission",
|
|
112
|
+
"95" => "Reconcile error / Auth Not found",
|
|
91
113
|
"96" => "System malfunction",
|
|
92
|
-
"97" => "No Funds Transfer",
|
|
93
|
-
"98" => "Duplicate Reversal",
|
|
94
|
-
"99" => "Duplicate Transaction",
|
|
95
|
-
"N3" => "Cash Service Not Available",
|
|
96
|
-
"N4" => "Cash Back Request Exceeds Issuer Limit",
|
|
97
|
-
"N7" => "N7 (visa), Decline CVV2 failure",
|
|
98
114
|
"R0" => "Stop Payment Order",
|
|
99
115
|
"R1" => "Revocation of Authorisation Order",
|
|
100
116
|
"R3" => "Revocation of all Authorisations Order"
|
|
@@ -258,6 +258,7 @@ module ActiveMerchant #:nodoc:
|
|
|
258
258
|
add_decision_manager_fields(xml, options)
|
|
259
259
|
add_mdd_fields(xml, options)
|
|
260
260
|
add_auth_service(xml, creditcard_or_reference, options)
|
|
261
|
+
xml.tag! 'payerAuthEnrollService', {'run' => 'true'} if options[:payer_auth_enroll_service]
|
|
261
262
|
add_payment_network_token(xml) if network_tokenization?(creditcard_or_reference)
|
|
262
263
|
add_business_rules_data(xml, creditcard_or_reference, options)
|
|
263
264
|
xml.target!
|
|
@@ -294,6 +295,7 @@ module ActiveMerchant #:nodoc:
|
|
|
294
295
|
add_check_service(xml)
|
|
295
296
|
else
|
|
296
297
|
add_purchase_service(xml, payment_method_or_reference, options)
|
|
298
|
+
xml.tag! 'payerAuthEnrollService', {'run' => 'true'} if options[:payer_auth_enroll_service]
|
|
297
299
|
add_payment_network_token(xml) if network_tokenization?(payment_method_or_reference)
|
|
298
300
|
add_business_rules_data(xml, payment_method_or_reference, options) unless options[:pinless_debit_card]
|
|
299
301
|
end
|
|
@@ -24,7 +24,8 @@ module ActiveMerchant #:nodoc:
|
|
|
24
24
|
authorize: "direct",
|
|
25
25
|
capture: "capture",
|
|
26
26
|
refund: "refund",
|
|
27
|
-
void: "cancel"
|
|
27
|
+
void: "cancel",
|
|
28
|
+
store: "token"
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
HTTP_METHOD = {
|
|
@@ -32,7 +33,8 @@ module ActiveMerchant #:nodoc:
|
|
|
32
33
|
authorize: :post,
|
|
33
34
|
capture: :get,
|
|
34
35
|
refund: :post,
|
|
35
|
-
void: :get
|
|
36
|
+
void: :get,
|
|
37
|
+
store: :post
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
def initialize(options={})
|
|
@@ -46,9 +48,10 @@ module ActiveMerchant #:nodoc:
|
|
|
46
48
|
add_operation(post)
|
|
47
49
|
add_invoice(post, money, options)
|
|
48
50
|
add_customer_data(post, payment, options)
|
|
49
|
-
|
|
51
|
+
add_card_or_token(post, payment)
|
|
50
52
|
add_address(post, options)
|
|
51
|
-
add_customer_responsible_person(post, payment, options)
|
|
53
|
+
add_customer_responsible_person(post, payment, options)
|
|
54
|
+
|
|
52
55
|
commit(:purchase, post)
|
|
53
56
|
end
|
|
54
57
|
|
|
@@ -58,9 +61,9 @@ module ActiveMerchant #:nodoc:
|
|
|
58
61
|
add_operation(post)
|
|
59
62
|
add_invoice(post, money, options)
|
|
60
63
|
add_customer_data(post, payment, options)
|
|
61
|
-
|
|
64
|
+
add_card_or_token(post, payment)
|
|
62
65
|
add_address(post, options)
|
|
63
|
-
add_customer_responsible_person(post, payment, options)
|
|
66
|
+
add_customer_responsible_person(post, payment, options)
|
|
64
67
|
post[:payment][:creditcard][:auto_capture] = false
|
|
65
68
|
|
|
66
69
|
commit(:authorize, post)
|
|
@@ -94,6 +97,15 @@ module ActiveMerchant #:nodoc:
|
|
|
94
97
|
commit(:void, post)
|
|
95
98
|
end
|
|
96
99
|
|
|
100
|
+
def store(credit_card, options={})
|
|
101
|
+
post = {}
|
|
102
|
+
add_integration_key(post)
|
|
103
|
+
add_payment_details(post, credit_card)
|
|
104
|
+
post[:country] = customer_country(options)
|
|
105
|
+
|
|
106
|
+
commit(:store, post)
|
|
107
|
+
end
|
|
108
|
+
|
|
97
109
|
def verify(credit_card, options={})
|
|
98
110
|
MultiResponse.run(:use_first_response) do |r|
|
|
99
111
|
r.process { authorize(100, credit_card, options) }
|
|
@@ -127,17 +139,20 @@ module ActiveMerchant #:nodoc:
|
|
|
127
139
|
end
|
|
128
140
|
|
|
129
141
|
def add_customer_data(post, payment, options)
|
|
130
|
-
post[:payment][:name] = payment
|
|
142
|
+
post[:payment][:name] = customer_name(payment, options)
|
|
131
143
|
post[:payment][:email] = options[:email] || "unspecified@example.com"
|
|
132
144
|
post[:payment][:document] = options[:document]
|
|
133
145
|
post[:payment][:birth_date] = options[:birth_date] if options[:birth_date]
|
|
134
146
|
end
|
|
135
147
|
|
|
136
|
-
def add_customer_responsible_person(post, payment,
|
|
137
|
-
post[:payment][:
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
148
|
+
def add_customer_responsible_person(post, payment, options)
|
|
149
|
+
post[:payment][:person_type] = options[:person_type] if options[:person_type]
|
|
150
|
+
if options[:person_type] && options[:person_type].downcase == 'business'
|
|
151
|
+
post[:payment][:responsible] = {}
|
|
152
|
+
post[:payment][:responsible][:name] = customer_name(payment, options)
|
|
153
|
+
post[:payment][:responsible][:document] = options[:document] if options[:document]
|
|
154
|
+
post[:payment][:responsible][:birth_date] = options[:birth_date] if options[:birth_date]
|
|
155
|
+
end
|
|
141
156
|
end
|
|
142
157
|
|
|
143
158
|
def add_address(post, options)
|
|
@@ -147,7 +162,7 @@ module ActiveMerchant #:nodoc:
|
|
|
147
162
|
post[:payment][:city] = address[:city]
|
|
148
163
|
post[:payment][:state] = address[:state]
|
|
149
164
|
post[:payment][:zipcode] = address[:zip]
|
|
150
|
-
post[:payment][:country] = address[:country]
|
|
165
|
+
post[:payment][:country] = address[:country].downcase
|
|
151
166
|
post[:payment][:phone_number] = address[:phone]
|
|
152
167
|
end
|
|
153
168
|
end
|
|
@@ -159,14 +174,30 @@ module ActiveMerchant #:nodoc:
|
|
|
159
174
|
post[:payment][:instalments] = options[:instalments] || 1
|
|
160
175
|
end
|
|
161
176
|
|
|
162
|
-
def
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
177
|
+
def add_card_or_token(post, payment)
|
|
178
|
+
if payment.is_a?(String)
|
|
179
|
+
payment, brand = payment.split("|")
|
|
180
|
+
end
|
|
181
|
+
post[:payment][:payment_type_code] = payment.is_a?(String) ? brand : CARD_BRAND[payment.brand.to_sym]
|
|
182
|
+
post[:payment][:creditcard] = payment_details(payment)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def add_payment_details(post, payment)
|
|
186
|
+
post[:payment_type_code] = CARD_BRAND[payment.brand.to_sym]
|
|
187
|
+
post[:creditcard] = payment_details(payment)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def payment_details(payment)
|
|
191
|
+
if payment.is_a?(String)
|
|
192
|
+
{ token: payment }
|
|
193
|
+
else
|
|
194
|
+
{
|
|
195
|
+
card_number: payment.number,
|
|
196
|
+
card_name: payment.name,
|
|
197
|
+
card_due_date: "#{payment.month}/#{payment.year}",
|
|
198
|
+
card_cvv: payment.verification_value
|
|
199
|
+
}
|
|
200
|
+
end
|
|
170
201
|
end
|
|
171
202
|
|
|
172
203
|
def parse(body)
|
|
@@ -183,7 +214,7 @@ module ActiveMerchant #:nodoc:
|
|
|
183
214
|
success,
|
|
184
215
|
message_from(response),
|
|
185
216
|
response,
|
|
186
|
-
authorization: authorization_from(response),
|
|
217
|
+
authorization: authorization_from(action, parameters, response),
|
|
187
218
|
test: test?,
|
|
188
219
|
error_code: error_code_from(response, success)
|
|
189
220
|
)
|
|
@@ -196,6 +227,8 @@ module ActiveMerchant #:nodoc:
|
|
|
196
227
|
response.try(:[], "payment").try(:[], "status") == "PE"
|
|
197
228
|
elsif action == :void
|
|
198
229
|
response.try(:[], "payment").try(:[], "status") == "CA"
|
|
230
|
+
elsif action == :store
|
|
231
|
+
response.try(:[], "status") == "SUCCESS"
|
|
199
232
|
else
|
|
200
233
|
false
|
|
201
234
|
end
|
|
@@ -206,8 +239,12 @@ module ActiveMerchant #:nodoc:
|
|
|
206
239
|
response.try(:[], "payment").try(:[], "transaction_status").try(:[], "description")
|
|
207
240
|
end
|
|
208
241
|
|
|
209
|
-
def authorization_from(response)
|
|
210
|
-
|
|
242
|
+
def authorization_from(action, parameters, response)
|
|
243
|
+
if action == :store
|
|
244
|
+
response.try(:[], "token") + "|" + CARD_BRAND[parameters[:payment_type_code].to_sym]
|
|
245
|
+
else
|
|
246
|
+
response.try(:[], "payment").try(:[], "hash")
|
|
247
|
+
end
|
|
211
248
|
end
|
|
212
249
|
|
|
213
250
|
def post_data(action, parameters = {})
|
|
@@ -239,6 +276,21 @@ module ActiveMerchant #:nodoc:
|
|
|
239
276
|
response.try(:[], "payment").try(:[], "transaction_status").try(:[], "code")
|
|
240
277
|
end
|
|
241
278
|
end
|
|
279
|
+
|
|
280
|
+
def customer_country(options)
|
|
281
|
+
if country = options[:country] || (options[:billing_address][:country] if options[:billing_address])
|
|
282
|
+
country.downcase
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def customer_name(payment, options)
|
|
287
|
+
address_name = options[:billing_address][:name] if options[:billing_address] && options[:billing_address][:name]
|
|
288
|
+
if payment.is_a?(String)
|
|
289
|
+
address_name || "Not Provided"
|
|
290
|
+
else
|
|
291
|
+
payment.name
|
|
292
|
+
end
|
|
293
|
+
end
|
|
242
294
|
end
|
|
243
295
|
end
|
|
244
296
|
end
|
|
@@ -7,8 +7,8 @@ module ActiveMerchant #:nodoc:
|
|
|
7
7
|
|
|
8
8
|
class_attribute :test_url, :live_url, :delimiter, :actions
|
|
9
9
|
|
|
10
|
-
self.test_url = 'https://demo.
|
|
11
|
-
self.live_url = 'https://
|
|
10
|
+
self.test_url = 'https://api.demo.convergepay.com/VirtualMerchantDemo/process.do'
|
|
11
|
+
self.live_url = 'https://api.convergepay.com/VirtualMerchant/process.do'
|
|
12
12
|
|
|
13
13
|
self.display_name = 'Elavon MyVirtualMerchant'
|
|
14
14
|
self.supported_countries = %w(US CA PR DE IE NO PL LU BE NL)
|
|
@@ -241,11 +241,15 @@ module ActiveMerchant #:nodoc:
|
|
|
241
241
|
{
|
|
242
242
|
'Accept' => 'application/json',
|
|
243
243
|
'Content-type' => 'application/json',
|
|
244
|
-
'Authorization' => "Basic #{
|
|
244
|
+
'Authorization' => "Basic #{basic_auth}",
|
|
245
245
|
'User-Agent' => "Netbanx-Paysafe v1.0/ActiveMerchant #{ActiveMerchant::VERSION}"
|
|
246
246
|
}
|
|
247
247
|
end
|
|
248
248
|
|
|
249
|
+
def basic_auth
|
|
250
|
+
Base64.strict_encode64("#{@options[:account_number]}:#{@options[:api_key]}")
|
|
251
|
+
end
|
|
252
|
+
|
|
249
253
|
def error_code_from(response)
|
|
250
254
|
unless success_from(response)
|
|
251
255
|
case response['errorCode']
|
|
@@ -3,9 +3,9 @@ module ActiveMerchant
|
|
|
3
3
|
class PayeezyGateway < Gateway
|
|
4
4
|
class_attribute :integration_url
|
|
5
5
|
|
|
6
|
-
self.test_url = 'https://api-cert.payeezy.com/v1
|
|
7
|
-
self.integration_url = 'https://api-cat.payeezy.com/v1
|
|
8
|
-
self.live_url = 'https://api.payeezy.com/v1
|
|
6
|
+
self.test_url = 'https://api-cert.payeezy.com/v1'
|
|
7
|
+
self.integration_url = 'https://api-cat.payeezy.com/v1'
|
|
8
|
+
self.live_url = 'https://api.payeezy.com/v1'
|
|
9
9
|
|
|
10
10
|
self.default_currency = 'USD'
|
|
11
11
|
self.money_format = :cents
|
|
@@ -31,7 +31,7 @@ module ActiveMerchant
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def purchase(amount, payment_method, options = {})
|
|
34
|
-
params = {transaction_type: 'purchase'}
|
|
34
|
+
params = payment_method.is_a?(String) ? { transaction_type: 'recurring' } : { transaction_type: 'purchase' }
|
|
35
35
|
|
|
36
36
|
add_invoice(params, options)
|
|
37
37
|
add_payment_method(params, payment_method, options)
|
|
@@ -73,6 +73,14 @@ module ActiveMerchant
|
|
|
73
73
|
commit(params, options)
|
|
74
74
|
end
|
|
75
75
|
|
|
76
|
+
def store(payment_method, options = {})
|
|
77
|
+
params = {}
|
|
78
|
+
|
|
79
|
+
add_creditcard_for_tokenization(params, payment_method, options)
|
|
80
|
+
|
|
81
|
+
commit(params, options)
|
|
82
|
+
end
|
|
83
|
+
|
|
76
84
|
def void(authorization, options = {})
|
|
77
85
|
params = {transaction_type: 'void'}
|
|
78
86
|
|
|
@@ -119,27 +127,34 @@ module ActiveMerchant
|
|
|
119
127
|
params[:method] = method
|
|
120
128
|
end
|
|
121
129
|
|
|
130
|
+
def add_creditcard_for_tokenization(params, payment_method, options)
|
|
131
|
+
params[:apikey] = @options[:apikey]
|
|
132
|
+
params[:js_security_key] = options[:js_security_key]
|
|
133
|
+
params[:ta_token] = options[:ta_token]
|
|
134
|
+
params[:callback] = 'Payeezy.callback'
|
|
135
|
+
params[:type] = 'FDToken'
|
|
136
|
+
card = add_card_data(payment_method)
|
|
137
|
+
params['credit_card.type'] = card[:type]
|
|
138
|
+
params['credit_card.cardholder_name'] = card[:cardholder_name]
|
|
139
|
+
params['credit_card.card_number'] = card[:card_number]
|
|
140
|
+
params['credit_card.exp_date'] = card[:exp_date]
|
|
141
|
+
params['credit_card.cvv'] = card[:cvv]
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def is_store_action?(params)
|
|
145
|
+
params[:ta_token].present?
|
|
146
|
+
end
|
|
147
|
+
|
|
122
148
|
def add_payment_method(params, payment_method, options)
|
|
123
149
|
if payment_method.is_a? Check
|
|
124
150
|
add_echeck(params, payment_method, options)
|
|
151
|
+
elsif payment_method.is_a? String
|
|
152
|
+
add_token(params, payment_method, options)
|
|
125
153
|
else
|
|
126
154
|
add_creditcard(params, payment_method)
|
|
127
155
|
end
|
|
128
156
|
end
|
|
129
157
|
|
|
130
|
-
def add_creditcard(params, creditcard)
|
|
131
|
-
credit_card = {}
|
|
132
|
-
|
|
133
|
-
credit_card[:type] = CREDIT_CARD_BRAND[creditcard.brand]
|
|
134
|
-
credit_card[:cardholder_name] = creditcard.name
|
|
135
|
-
credit_card[:card_number] = creditcard.number
|
|
136
|
-
credit_card[:exp_date] = "#{format(creditcard.month, :two_digits)}#{format(creditcard.year, :two_digits)}"
|
|
137
|
-
credit_card[:cvv] = creditcard.verification_value if creditcard.verification_value?
|
|
138
|
-
|
|
139
|
-
params[:method] = 'credit_card'
|
|
140
|
-
params[:credit_card] = credit_card
|
|
141
|
-
end
|
|
142
|
-
|
|
143
158
|
def add_echeck(params, echeck, options)
|
|
144
159
|
tele_check = {}
|
|
145
160
|
|
|
@@ -156,6 +171,44 @@ module ActiveMerchant
|
|
|
156
171
|
params[:tele_check] = tele_check
|
|
157
172
|
end
|
|
158
173
|
|
|
174
|
+
def add_token(params, payment_method, options)
|
|
175
|
+
token = {}
|
|
176
|
+
token[:token_type] = 'FDToken'
|
|
177
|
+
|
|
178
|
+
type, cardholder_name, exp_date, card_number = payment_method.split('|')
|
|
179
|
+
|
|
180
|
+
token[:token_data] = {}
|
|
181
|
+
token[:token_data][:type] = type
|
|
182
|
+
token[:token_data][:cardholder_name] = cardholder_name
|
|
183
|
+
token[:token_data][:value] = card_number
|
|
184
|
+
token[:token_data][:exp_date] = exp_date
|
|
185
|
+
token[:token_data][:cvv] = options[:cvv] if options[:cvv]
|
|
186
|
+
|
|
187
|
+
params[:method] = 'token'
|
|
188
|
+
params[:token] = token
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def add_creditcard(params, creditcard)
|
|
192
|
+
credit_card = add_card_data(creditcard)
|
|
193
|
+
|
|
194
|
+
params[:method] = 'credit_card'
|
|
195
|
+
params[:credit_card] = credit_card
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def add_card_data(payment_method)
|
|
199
|
+
card = {}
|
|
200
|
+
card[:type] = CREDIT_CARD_BRAND[payment_method.brand]
|
|
201
|
+
card[:cardholder_name] = payment_method.name
|
|
202
|
+
card[:card_number] = payment_method.number
|
|
203
|
+
card[:exp_date] = format_exp_date(payment_method.month, payment_method.year)
|
|
204
|
+
card[:cvv] = payment_method.verification_value if payment_method.verification_value?
|
|
205
|
+
card
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def format_exp_date(month, year)
|
|
209
|
+
"#{format(month, :two_digits)}#{format(year, :two_digits)}"
|
|
210
|
+
end
|
|
211
|
+
|
|
159
212
|
def add_address(params, options)
|
|
160
213
|
address = options[:billing_address]
|
|
161
214
|
return unless address
|
|
@@ -180,25 +233,18 @@ module ActiveMerchant
|
|
|
180
233
|
end
|
|
181
234
|
|
|
182
235
|
def commit(params, options)
|
|
183
|
-
url =
|
|
184
|
-
integration_url
|
|
185
|
-
elsif test?
|
|
186
|
-
test_url
|
|
187
|
-
else
|
|
188
|
-
live_url
|
|
189
|
-
end
|
|
236
|
+
url = base_url(options) + endpoint(params)
|
|
190
237
|
|
|
191
238
|
if transaction_id = params.delete(:transaction_id)
|
|
192
239
|
url = "#{url}/#{transaction_id}"
|
|
193
240
|
end
|
|
194
241
|
|
|
195
242
|
begin
|
|
196
|
-
|
|
197
|
-
response = parse(ssl_post(url, body, headers(body)))
|
|
243
|
+
response = api_request(url, params)
|
|
198
244
|
rescue ResponseError => e
|
|
199
245
|
response = response_error(e.response.body)
|
|
200
246
|
rescue JSON::ParserError
|
|
201
|
-
response = json_error(
|
|
247
|
+
response = json_error(e.response.body)
|
|
202
248
|
end
|
|
203
249
|
|
|
204
250
|
Response.new(
|
|
@@ -213,17 +259,34 @@ module ActiveMerchant
|
|
|
213
259
|
)
|
|
214
260
|
end
|
|
215
261
|
|
|
216
|
-
def
|
|
217
|
-
|
|
262
|
+
def base_url(options)
|
|
263
|
+
if options[:integration]
|
|
264
|
+
integration_url
|
|
265
|
+
elsif test?
|
|
266
|
+
test_url
|
|
267
|
+
else
|
|
268
|
+
live_url
|
|
269
|
+
end
|
|
218
270
|
end
|
|
219
271
|
|
|
220
|
-
def
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
272
|
+
def endpoint(params)
|
|
273
|
+
is_store_action?(params) ? '/securitytokens' : '/transactions'
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def api_request(url, params)
|
|
277
|
+
if is_store_action?(params)
|
|
278
|
+
callback = ssl_request(:get, "#{url}?#{post_data(params)}", nil, {})
|
|
279
|
+
payload = callback[/{(?:\n|.)*}/]
|
|
280
|
+
parse(payload)
|
|
281
|
+
else
|
|
282
|
+
body = params.to_json
|
|
283
|
+
parse(ssl_post(url, body, headers(body)))
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def post_data(params)
|
|
288
|
+
return nil unless params
|
|
289
|
+
params.reject { |k, v| v.blank? }.collect { |k, v| "#{k}=#{CGI.escape(v.to_s)}" }.join("&")
|
|
227
290
|
end
|
|
228
291
|
|
|
229
292
|
def generate_hmac(nonce, current_timestamp, payload)
|
|
@@ -256,19 +319,55 @@ module ActiveMerchant
|
|
|
256
319
|
response['Error'].to_h['messages'].to_a.map { |e| e['code'] }.join(', ')
|
|
257
320
|
end
|
|
258
321
|
|
|
322
|
+
def success_from(response)
|
|
323
|
+
if response['transaction_status']
|
|
324
|
+
response['transaction_status'] == 'approved'
|
|
325
|
+
elsif response['results']
|
|
326
|
+
response['results']['status'] == 'success'
|
|
327
|
+
else
|
|
328
|
+
false
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
259
332
|
def handle_message(response, success)
|
|
260
|
-
if success
|
|
333
|
+
if success && response['status'].present?
|
|
334
|
+
'Token successfully created.'
|
|
335
|
+
elsif success
|
|
261
336
|
"#{response['gateway_message']} - #{response['bank_message']}"
|
|
262
337
|
elsif %w(401 403).include?(response['code'])
|
|
263
338
|
response['message']
|
|
264
339
|
elsif response.key?('Error')
|
|
265
340
|
response['Error']['messages'].first['description']
|
|
341
|
+
elsif response.key?('results')
|
|
342
|
+
response['results']['Error']['messages'].first['description']
|
|
266
343
|
elsif response.key?('error')
|
|
267
344
|
response['error']
|
|
268
345
|
elsif response.key?('fault')
|
|
269
346
|
response['fault'].to_h['faultstring']
|
|
270
347
|
else
|
|
271
|
-
response['bank_message']
|
|
348
|
+
response['bank_message'] || 'Failure to successfully create token.'
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def authorization_from(params, response)
|
|
353
|
+
if is_store_action?(params)
|
|
354
|
+
if success_from(response)
|
|
355
|
+
[
|
|
356
|
+
response['results']['token']['type'],
|
|
357
|
+
response['results']['token']['cardholder_name'],
|
|
358
|
+
response['results']['token']['exp_date'],
|
|
359
|
+
response['results']['token']['value']
|
|
360
|
+
].join('|')
|
|
361
|
+
else
|
|
362
|
+
nil
|
|
363
|
+
end
|
|
364
|
+
else
|
|
365
|
+
[
|
|
366
|
+
response['transaction_id'],
|
|
367
|
+
response['transaction_tag'],
|
|
368
|
+
params[:method],
|
|
369
|
+
(response['amount'] && response['amount'].to_i)
|
|
370
|
+
].join('|')
|
|
272
371
|
end
|
|
273
372
|
end
|
|
274
373
|
|
|
@@ -31,6 +31,7 @@ module ActiveMerchant #:nodoc:
|
|
|
31
31
|
def initialize(options={})
|
|
32
32
|
requires!(options, :merchant_id, :account_id, :api_login, :api_key)
|
|
33
33
|
super
|
|
34
|
+
@options[:payment_country] ||= options[:payment_country] if options[:payment_country]
|
|
34
35
|
end
|
|
35
36
|
|
|
36
37
|
def purchase(amount, payment_method, options={})
|
|
@@ -138,7 +139,7 @@ module ActiveMerchant #:nodoc:
|
|
|
138
139
|
|
|
139
140
|
def add_transaction_elements(post, type, options)
|
|
140
141
|
transaction = {}
|
|
141
|
-
transaction[:paymentCountry] = options[:payment_country] || (options[:billing_address][:country] if options[:billing_address])
|
|
142
|
+
transaction[:paymentCountry] = @options[:payment_country] || (options[:billing_address][:country] if options[:billing_address])
|
|
142
143
|
transaction[:type] = type
|
|
143
144
|
transaction[:ipAddress] = options[:ip] if options[:ip]
|
|
144
145
|
transaction[:userAgent] = options[:user_agent] if options[:user_agent]
|
|
@@ -84,8 +84,6 @@ module ActiveMerchant #:nodoc:
|
|
|
84
84
|
post[:cvv] = creditcard.verification_value unless options[:recurring]
|
|
85
85
|
post[:expiration_month] = creditcard.month
|
|
86
86
|
post[:expiration_year] = creditcard.year
|
|
87
|
-
post[:original_ip] = options[:ip] if options[:ip]
|
|
88
|
-
post[:original_device] = options[:device_fingerprint] if options[:device_fingerprint]
|
|
89
87
|
|
|
90
88
|
if(billing_address = (options[:billing_address] || options[:address]))
|
|
91
89
|
post[:address] = {}
|
|
@@ -100,6 +98,8 @@ module ActiveMerchant #:nodoc:
|
|
|
100
98
|
post[:client_secret] = @options[:client_secret]
|
|
101
99
|
commit('/credit_card/transfer', post, options)
|
|
102
100
|
else
|
|
101
|
+
post[:original_device] = options[:device_fingerprint] if options[:device_fingerprint]
|
|
102
|
+
post[:original_ip] = options[:ip] if options[:ip]
|
|
103
103
|
commit('/credit_card/create', post, options)
|
|
104
104
|
end
|
|
105
105
|
end
|
|
@@ -49,7 +49,7 @@ module ActiveMerchant
|
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
def request(method, body, headers = {})
|
|
52
|
-
request_start =
|
|
52
|
+
request_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
53
53
|
|
|
54
54
|
retry_exceptions(:max_retries => max_retries, :logger => logger, :tag => tag) do
|
|
55
55
|
begin
|
|
@@ -89,7 +89,7 @@ module ActiveMerchant
|
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
ensure
|
|
92
|
-
info "connection_request_total_time=%.4fs" % [
|
|
92
|
+
info "connection_request_total_time=%.4fs" % [Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start], tag
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
private
|
|
@@ -42,19 +42,19 @@ module ActiveMerchant
|
|
|
42
42
|
request_start = nil
|
|
43
43
|
|
|
44
44
|
begin
|
|
45
|
-
request_start =
|
|
45
|
+
request_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
46
46
|
result = yield
|
|
47
|
-
log_with_retry_details(options[:logger], initial_retries-retries + 1,
|
|
47
|
+
log_with_retry_details(options[:logger], initial_retries-retries + 1, Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start, "success", options[:tag])
|
|
48
48
|
result
|
|
49
49
|
rescue ActiveMerchant::RetriableConnectionError => e
|
|
50
50
|
retries -= 1
|
|
51
51
|
|
|
52
|
-
log_with_retry_details(options[:logger], initial_retries-retries,
|
|
52
|
+
log_with_retry_details(options[:logger], initial_retries-retries, Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start, e.message, options[:tag])
|
|
53
53
|
retry unless retries.zero?
|
|
54
54
|
raise ActiveMerchant::ConnectionError.new(e.message, e)
|
|
55
55
|
rescue ActiveMerchant::ConnectionError, ActiveMerchant::InvalidResponseError => e
|
|
56
56
|
retries -= 1
|
|
57
|
-
log_with_retry_details(options[:logger], initial_retries-retries,
|
|
57
|
+
log_with_retry_details(options[:logger], initial_retries-retries, Process.clock_gettime(Process::CLOCK_MONOTONIC) - request_start, e.message, options[:tag])
|
|
58
58
|
retry if (options[:retry_safe] || retry_safe) && !retries.zero?
|
|
59
59
|
raise
|
|
60
60
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activemerchant
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.74.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tobias Luetke
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-
|
|
11
|
+
date: 2017-10-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -413,7 +413,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
413
413
|
version: '0'
|
|
414
414
|
requirements: []
|
|
415
415
|
rubyforge_project: activemerchant
|
|
416
|
-
rubygems_version: 2.5.2
|
|
416
|
+
rubygems_version: 2.5.2.1
|
|
417
417
|
signing_key:
|
|
418
418
|
specification_version: 4
|
|
419
419
|
summary: Framework and tools for dealing with credit card transactions.
|