activemerchant 1.62.0 → 1.63.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 -0
- data/lib/active_merchant/billing/credit_card.rb +1 -1
- data/lib/active_merchant/billing/gateways/authorize_net.rb +28 -16
- data/lib/active_merchant/billing/gateways/card_stream.rb +3 -0
- data/lib/active_merchant/billing/gateways/culqi.rb +279 -0
- data/lib/active_merchant/billing/gateways/cyber_source.rb +1 -1
- data/lib/active_merchant/billing/gateways/element.rb +10 -0
- data/lib/active_merchant/billing/gateways/firstdata_e4.rb +1 -1
- data/lib/active_merchant/billing/gateways/global_collect.rb +5 -1
- data/lib/active_merchant/billing/gateways/payment_express.rb +1 -1
- data/lib/active_merchant/billing/gateways/secure_pay_au.rb +12 -0
- data/lib/active_merchant/billing/gateways/stripe.rb +1 -1
- data/lib/active_merchant/billing/gateways/vanco.rb +1 -1
- data/lib/active_merchant/billing/gateways/wepay.rb +61 -38
- data/lib/active_merchant/billing/gateways/wirecard.rb +1 -0
- data/lib/active_merchant/billing/gateways/worldpay.rb +7 -2
- data/lib/active_merchant/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a16e6e0f311ac3b77069a4f05f5f257b6a69fc60
|
4
|
+
data.tar.gz: 666b86bb155b6ff98a608bf8c38714a54af46627
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd479af93c39120f8a447058524d56de326189f0f3fc26ace5af2681166761fc81a967a66368f9d50e4d7a5a0b64c7a4867c7f61dc2b37e368b0aa19141c87c2
|
7
|
+
data.tar.gz: b9f8ea0507a585f672f9abce5cf4c2359dbeeb781fe8cdda5e05413aa24fa638fc25a0f83279c4143e72278f8cf4e82f12a1987190390640a7c21ff52f488389
|
data/CHANGELOG
CHANGED
@@ -2,6 +2,29 @@
|
|
2
2
|
|
3
3
|
== HEAD
|
4
4
|
|
5
|
+
== Version 1.63.0 (February 2, 2017)
|
6
|
+
* Authorize.net: Add #unstore support [jimryan] #2293
|
7
|
+
* AuthorizeNet: Fix line items quirk [shasum]
|
8
|
+
* CardStream: Add dynamic descriptor option fields [curiousepic]
|
9
|
+
* CardStream: Support PEN currency [shasum]
|
10
|
+
* Culqi: Add new gateway [shasum]
|
11
|
+
* CyberSource: Add Lebanon to supported countries [shasum]
|
12
|
+
* Element: Add AVS and CVV codes to response [shasum]
|
13
|
+
* Firstdata E4 (Payeezy): Set correct ECI value for card present swipes [jasonwebster] #2318
|
14
|
+
* GlobalCollect: On purchase skip capture if not required [davidsantoso]
|
15
|
+
* PaymentExpress: Update supported countries [shasum]
|
16
|
+
* Remove leading or trailing whitespace from credit card name [davidsantoso]
|
17
|
+
* Remove support for Ruby 2.0 [jasonwebster]
|
18
|
+
* Secure Pay AU: Add scrubbing support to Secure Pay AU [bruno] #2253
|
19
|
+
* Stripe: Fix error in handling of track-only contactless EMV data [jasonwebster]
|
20
|
+
* Vanco: Update test URL [davidsantoso]
|
21
|
+
* WePay: Build fee structure correctly [curiousepic]
|
22
|
+
* WePay: Remove null address fields from request [davidsantoso]
|
23
|
+
* WePay: Update WePay to API version 2016-12-07 [davidsantoso]
|
24
|
+
* Wirecard: Send customer data in requests [davidsantoso]
|
25
|
+
* Worldpay: Add session id attribute [shasum]
|
26
|
+
* Worldpay: Do not default address when not provided [shasum]
|
27
|
+
|
5
28
|
== Version 1.62.0 (December 5, 2016)
|
6
29
|
* AuthorizeNet: Map to standard AVSResult codes [shasum]
|
7
30
|
* CitrusPay: Add 3DSecureId field [davidsantoso]
|
@@ -159,7 +159,6 @@ module ActiveMerchant
|
|
159
159
|
add_payment_source(xml, payment)
|
160
160
|
add_invoice(xml, options)
|
161
161
|
add_customer_data(xml, payment, options)
|
162
|
-
add_line_items(xml, options)
|
163
162
|
add_settings(xml, payment, options)
|
164
163
|
add_user_fields(xml, amount, options)
|
165
164
|
end
|
@@ -181,6 +180,12 @@ module ActiveMerchant
|
|
181
180
|
end
|
182
181
|
end
|
183
182
|
|
183
|
+
def unstore(authorization)
|
184
|
+
customer_profile_id, _, _ = split_authorization(authorization)
|
185
|
+
|
186
|
+
delete_customer_profile(customer_profile_id)
|
187
|
+
end
|
188
|
+
|
184
189
|
def verify_credentials
|
185
190
|
response = commit(:verify_credentials) { }
|
186
191
|
response.success?
|
@@ -233,7 +238,6 @@ module ActiveMerchant
|
|
233
238
|
add_invoice(xml, options)
|
234
239
|
add_customer_data(xml, payment, options)
|
235
240
|
add_market_type_device_type(xml, payment, options)
|
236
|
-
add_line_items(xml, options)
|
237
241
|
add_settings(xml, payment, options)
|
238
242
|
add_user_fields(xml, amount, options)
|
239
243
|
end
|
@@ -347,19 +351,6 @@ module ActiveMerchant
|
|
347
351
|
end
|
348
352
|
end
|
349
353
|
|
350
|
-
def add_line_items(xml, options)
|
351
|
-
return unless options[:line_items]
|
352
|
-
xml.lineItems do
|
353
|
-
options[:line_items].each do |line_item|
|
354
|
-
xml.lineItem do
|
355
|
-
line_item.each do |key, value|
|
356
|
-
xml.send(camel_case_lower(key), value)
|
357
|
-
end
|
358
|
-
end
|
359
|
-
end
|
360
|
-
end
|
361
|
-
end
|
362
|
-
|
363
354
|
def camel_case_lower(key)
|
364
355
|
String(key).split('_').inject([]){ |buffer,e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
|
365
356
|
end
|
@@ -575,6 +566,19 @@ module ActiveMerchant
|
|
575
566
|
xml.invoiceNumber(truncate(options[:order_id], 20))
|
576
567
|
xml.description(truncate(options[:description], 255))
|
577
568
|
end
|
569
|
+
|
570
|
+
# Authorize.net API requires lineItems to be placed directly after order tag
|
571
|
+
if options[:line_items]
|
572
|
+
xml.lineItems do
|
573
|
+
options[:line_items].each do |line_item|
|
574
|
+
xml.lineItem do
|
575
|
+
line_item.each do |key, value|
|
576
|
+
xml.send(camel_case_lower(key), value)
|
577
|
+
end
|
578
|
+
end
|
579
|
+
end
|
580
|
+
end
|
581
|
+
end
|
578
582
|
end
|
579
583
|
|
580
584
|
def create_customer_payment_profile(credit_card, options)
|
@@ -616,6 +620,12 @@ module ActiveMerchant
|
|
616
620
|
end
|
617
621
|
end
|
618
622
|
|
623
|
+
def delete_customer_profile(customer_profile_id)
|
624
|
+
commit(:cim_store_delete_customer) do |xml|
|
625
|
+
xml.customerProfileId(customer_profile_id)
|
626
|
+
end
|
627
|
+
end
|
628
|
+
|
619
629
|
def names_from(payment_source, address, options)
|
620
630
|
if payment_source && !payment_source.is_a?(PaymentToken) && !payment_source.is_a?(String)
|
621
631
|
first_name, last_name = split_names(address[:name])
|
@@ -683,6 +693,8 @@ module ActiveMerchant
|
|
683
693
|
"createCustomerProfileRequest"
|
684
694
|
elsif action == :cim_store_update
|
685
695
|
"createCustomerPaymentProfileRequest"
|
696
|
+
elsif action == :cim_store_delete_customer
|
697
|
+
"deleteCustomerProfileRequest"
|
686
698
|
elsif action == :verify_credentials
|
687
699
|
"authenticateTestRequest"
|
688
700
|
elsif is_cim_action?(action)
|
@@ -827,7 +839,7 @@ module ActiveMerchant
|
|
827
839
|
end
|
828
840
|
|
829
841
|
def cim?(action)
|
830
|
-
(action == :cim_store) || (action == :cim_store_update)
|
842
|
+
(action == :cim_store) || (action == :cim_store_update) || (action == :cim_store_delete_customer)
|
831
843
|
end
|
832
844
|
|
833
845
|
def transaction_id_from(authorization)
|
@@ -28,6 +28,7 @@ module ActiveMerchant #:nodoc:
|
|
28
28
|
"MXN" => "484",
|
29
29
|
"NOK" => "578",
|
30
30
|
"NZD" => "554",
|
31
|
+
"PEN" => "604",
|
31
32
|
"SEK" => "752",
|
32
33
|
"SGD" => "702",
|
33
34
|
"USD" => "840",
|
@@ -154,6 +155,8 @@ module ActiveMerchant #:nodoc:
|
|
154
155
|
def add_invoice(post, credit_card_or_reference, money, options)
|
155
156
|
add_pair(post, :transactionUnique, options[:order_id], :required => true)
|
156
157
|
add_pair(post, :orderRef, options[:description] || options[:order_id], :required => true)
|
158
|
+
add_pair(post, :statementNarrative1, options[:merchant_name]) if options[:merchant_name]
|
159
|
+
add_pair(post, :statementNarrative2, options[:dynamic_descriptor]) if options[:dynamic_descriptor]
|
157
160
|
if credit_card_or_reference.respond_to?(:number)
|
158
161
|
if ['american_express', 'diners_club'].include?(card_brand(credit_card_or_reference).to_s)
|
159
162
|
add_pair(post, :item1Quantity, 1)
|
@@ -0,0 +1,279 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
|
3
|
+
module ActiveMerchant #:nodoc:
|
4
|
+
module Billing #:nodoc:
|
5
|
+
# Important note:
|
6
|
+
# ===
|
7
|
+
# Culqi merchant accounts are configured for either purchase or auth/capture
|
8
|
+
# modes. This is configured by Culqi when setting up a merchant account and
|
9
|
+
# largely depends on the transaction acquiring bank. Be sure to understand how
|
10
|
+
# your account was configured prior to using this gateway.
|
11
|
+
class CulqiGateway < Gateway
|
12
|
+
self.display_name = "Culqi"
|
13
|
+
self.homepage_url = "https://www.culqi.com"
|
14
|
+
|
15
|
+
self.test_url = "https://staging.paymentz.com/transaction/"
|
16
|
+
self.live_url = "https://secure.culqi.com/transaction/"
|
17
|
+
|
18
|
+
self.supported_countries = ["PE"]
|
19
|
+
self.default_currency = "PEN"
|
20
|
+
self.money_format = :dollars
|
21
|
+
self.supported_cardtypes = [:visa, :master, :diners_club, :american_express]
|
22
|
+
|
23
|
+
def initialize(options={})
|
24
|
+
requires!(options, :merchant_id, :terminal_id, :secret_key)
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
def purchase(amount, payment_method, options={})
|
29
|
+
authorize(amount, payment_method, options)
|
30
|
+
end
|
31
|
+
|
32
|
+
def authorize(amount, payment_method, options={})
|
33
|
+
if payment_method.is_a?(String)
|
34
|
+
action = :tokenpay
|
35
|
+
else
|
36
|
+
action = :authorize
|
37
|
+
end
|
38
|
+
post = {}
|
39
|
+
add_credentials(post)
|
40
|
+
add_invoice(action, post, amount, options)
|
41
|
+
add_payment_method(post, payment_method, action, options)
|
42
|
+
add_customer_data(post, options)
|
43
|
+
add_checksum(action, post)
|
44
|
+
|
45
|
+
commit(action, post)
|
46
|
+
end
|
47
|
+
|
48
|
+
def capture(amount, authorization, options={})
|
49
|
+
action = :capture
|
50
|
+
post = {}
|
51
|
+
add_credentials(post)
|
52
|
+
add_invoice(action, post, amount, options)
|
53
|
+
add_reference(post, authorization)
|
54
|
+
add_checksum(action, post)
|
55
|
+
|
56
|
+
commit(action, post)
|
57
|
+
end
|
58
|
+
|
59
|
+
def void(authorization, options={})
|
60
|
+
action = :void
|
61
|
+
post = {}
|
62
|
+
add_credentials(post)
|
63
|
+
add_invoice(action, post, nil, options)
|
64
|
+
add_reference(post, authorization)
|
65
|
+
add_checksum(action, post)
|
66
|
+
|
67
|
+
commit(action, post)
|
68
|
+
end
|
69
|
+
|
70
|
+
def refund(amount, authorization, options={})
|
71
|
+
action = :refund
|
72
|
+
post = {}
|
73
|
+
add_credentials(post)
|
74
|
+
add_invoice(action, post, amount, options)
|
75
|
+
add_reference(post, authorization)
|
76
|
+
add_checksum(action, post)
|
77
|
+
|
78
|
+
commit(action, post)
|
79
|
+
end
|
80
|
+
|
81
|
+
def verify(credit_card, options={})
|
82
|
+
MultiResponse.run(:use_first_response) do |r|
|
83
|
+
r.process { authorize(1000, credit_card, options) }
|
84
|
+
r.process(:ignore_result) { void(r.authorization, options) }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def verify_credentials
|
89
|
+
response = void("0", order_id: "0")
|
90
|
+
response.message.include? "Transaction not found"
|
91
|
+
end
|
92
|
+
|
93
|
+
def store(credit_card, options={})
|
94
|
+
action = :tokenize
|
95
|
+
post = {}
|
96
|
+
post[:partnerid] = options[:partner_id] if options[:partner_id]
|
97
|
+
post[:cardholderid] = options[:cardholder_id] if options[:cardholder_id]
|
98
|
+
add_credentials(post)
|
99
|
+
add_payment_method(post, credit_card, action, options)
|
100
|
+
add_customer_data(post, options)
|
101
|
+
add_checksum(action, post)
|
102
|
+
|
103
|
+
commit(action, post)
|
104
|
+
end
|
105
|
+
|
106
|
+
def invalidate(authorization, options={})
|
107
|
+
action = :invalidate
|
108
|
+
post = {}
|
109
|
+
post[:partnerid] = options[:partner_id] if options[:partner_id]
|
110
|
+
add_credentials(post)
|
111
|
+
post[:token] = authorization
|
112
|
+
add_checksum(action, post)
|
113
|
+
|
114
|
+
commit(action, post)
|
115
|
+
end
|
116
|
+
|
117
|
+
def supports_scrubbing?
|
118
|
+
true
|
119
|
+
end
|
120
|
+
|
121
|
+
def scrub(transcript)
|
122
|
+
transcript.
|
123
|
+
gsub(%r((cardnumber=)\d+), '\1[FILTERED]').
|
124
|
+
gsub(%r((cvv=)\d+), '\1[FILTERED]')
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
def add_credentials(post)
|
130
|
+
post[:toid] = @options[:merchant_id]
|
131
|
+
post[:totype] = 'Culqi'
|
132
|
+
post[:terminalid] = @options[:terminal_id]
|
133
|
+
post[:language] = 'ENG'
|
134
|
+
end
|
135
|
+
|
136
|
+
def add_invoice(action, post, money, options)
|
137
|
+
case action
|
138
|
+
when :capture
|
139
|
+
post[:captureamount] = amount(money)
|
140
|
+
when :refund
|
141
|
+
post[:refundamount] = amount(money)
|
142
|
+
post[:reason] = 'none'
|
143
|
+
else
|
144
|
+
post[:amount] = amount(money)
|
145
|
+
end
|
146
|
+
|
147
|
+
post[:description] = options[:order_id]
|
148
|
+
post[:redirecturl] = options[:redirect_url] || 'http://www.example.com'
|
149
|
+
end
|
150
|
+
|
151
|
+
def add_payment_method(post, payment_method, action, options)
|
152
|
+
if payment_method.is_a?(String)
|
153
|
+
post[:token] = payment_method
|
154
|
+
post[:cvv] = options[:cvv] if options[:cvv]
|
155
|
+
else
|
156
|
+
post[:cardnumber] = payment_method.number
|
157
|
+
post[:cvv] = payment_method.verification_value
|
158
|
+
post[:firstname], post[:lastname] = payment_method.name.split(' ')
|
159
|
+
if action == :tokenize
|
160
|
+
post[:expirymonth] = format(payment_method.month, :two_digits)
|
161
|
+
post[:expiryyear] = format(payment_method.year, :four_digits)
|
162
|
+
else
|
163
|
+
post[:expiry_month] = format(payment_method.month, :two_digits)
|
164
|
+
post[:expiry_year] = format(payment_method.year, :four_digits)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def add_customer_data(post, options)
|
170
|
+
post[:emailaddr] = options[:email] || 'unspecified@example.com'
|
171
|
+
if (billing_address = options[:billing_address] || options[:address])
|
172
|
+
post[:street] = [billing_address[:address1], billing_address[:address2]].join(' ')
|
173
|
+
post[:city] = billing_address[:city]
|
174
|
+
post[:state] = billing_address[:state]
|
175
|
+
post[:countrycode] = billing_address[:country]
|
176
|
+
post[:zip] = billing_address[:zip]
|
177
|
+
post[:telno] = billing_address[:phone]
|
178
|
+
post[:telnocc] = options[:telephone_country_code] || '051'
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def add_checksum(action, post)
|
183
|
+
checksum_elements = case action
|
184
|
+
when :capture; [post[:toid], post[:trackingid], post[:captureamount], @options[:secret_key]]
|
185
|
+
when :void; [post[:toid], post[:description], post[:trackingid], @options[:secret_key]]
|
186
|
+
when :refund; [post[:toid], post[:trackingid], post[:refundamount], @options[:secret_key]]
|
187
|
+
when :tokenize; [post[:partnerid], post[:cardnumber], post[:cvv], @options[:secret_key]]
|
188
|
+
when :invalidate; [post[:partnerid], post[:token], @options[:secret_key]]
|
189
|
+
else [post[:toid], post[:totype], post[:amount], post[:description], post[:redirecturl],
|
190
|
+
post[:cardnumber] || post[:token], @options[:secret_key]]
|
191
|
+
end
|
192
|
+
|
193
|
+
post[:checksum] = Digest::MD5.hexdigest(checksum_elements.compact.join('|'))
|
194
|
+
end
|
195
|
+
|
196
|
+
def add_reference(post, authorization)
|
197
|
+
post[:trackingid] = authorization
|
198
|
+
end
|
199
|
+
|
200
|
+
ACTIONS = {
|
201
|
+
authorize: "SingleCallGenericServlet",
|
202
|
+
capture: "SingleCallGenericCaptureServlet",
|
203
|
+
void: "SingleCallGenericVoid",
|
204
|
+
refund: "SingleCallGenericReverse",
|
205
|
+
tokenize: "SingleCallTokenServlet",
|
206
|
+
invalidate: "SingleCallInvalidateToken",
|
207
|
+
tokenpay: "SingleCallTokenTransaction",
|
208
|
+
}
|
209
|
+
|
210
|
+
def commit(action, params)
|
211
|
+
response = begin
|
212
|
+
parse(ssl_post(url + ACTIONS[action], post_data(action, params), headers))
|
213
|
+
rescue ResponseError => e
|
214
|
+
parse(e.response.body)
|
215
|
+
end
|
216
|
+
|
217
|
+
success = success_from(response)
|
218
|
+
|
219
|
+
Response.new(
|
220
|
+
success,
|
221
|
+
message_from(response),
|
222
|
+
response,
|
223
|
+
authorization: success ? authorization_from(response) : nil,
|
224
|
+
cvv_result: success ? cvvresult_from(response) : nil,
|
225
|
+
error_code: success ? nil : error_from(response),
|
226
|
+
test: test?
|
227
|
+
)
|
228
|
+
end
|
229
|
+
|
230
|
+
def headers
|
231
|
+
{
|
232
|
+
"Accept" => "application/json",
|
233
|
+
"Content-Type" => "application/x-www-form-urlencoded;charset=UTF-8"
|
234
|
+
}
|
235
|
+
end
|
236
|
+
|
237
|
+
def post_data(action, params)
|
238
|
+
params.map {|k, v| "#{k}=#{CGI.escape(v.to_s)}"}.join('&')
|
239
|
+
end
|
240
|
+
|
241
|
+
def url
|
242
|
+
test? ? test_url : live_url
|
243
|
+
end
|
244
|
+
|
245
|
+
def parse(body)
|
246
|
+
begin
|
247
|
+
JSON.parse(body)
|
248
|
+
rescue JSON::ParserError
|
249
|
+
message = "Invalid JSON response received from CulqiGateway. Please contact CulqiGateway if you continue to receive this message."
|
250
|
+
message += "(The raw response returned by the API was #{body.inspect})"
|
251
|
+
{
|
252
|
+
"status" => "N",
|
253
|
+
"statusdescription" => message
|
254
|
+
}
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def success_from(response)
|
259
|
+
response['status'] == 'Y'
|
260
|
+
end
|
261
|
+
|
262
|
+
def message_from(response)
|
263
|
+
response['statusdescription'] || response['statusDescription']
|
264
|
+
end
|
265
|
+
|
266
|
+
def authorization_from(response)
|
267
|
+
response['trackingid'] || response['token']
|
268
|
+
end
|
269
|
+
|
270
|
+
def cvvresult_from(response)
|
271
|
+
CVVResult.new(response['cvvresult'])
|
272
|
+
end
|
273
|
+
|
274
|
+
def error_from(response)
|
275
|
+
response['resultcode']
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
@@ -27,7 +27,7 @@ module ActiveMerchant #:nodoc:
|
|
27
27
|
XSD_VERSION = "1.121"
|
28
28
|
|
29
29
|
self.supported_cardtypes = [:visa, :master, :american_express, :discover]
|
30
|
-
self.supported_countries = %w(US BR CA CN DK FI FR DE JP MX NO SE GB SG)
|
30
|
+
self.supported_countries = %w(US BR CA CN DK FI FR DE JP MX NO SE GB SG LB)
|
31
31
|
|
32
32
|
self.default_currency = 'USD'
|
33
33
|
self.currencies_without_fractions = %w(JPY)
|
@@ -274,6 +274,8 @@ module ActiveMerchant #:nodoc:
|
|
274
274
|
message_from(response),
|
275
275
|
response,
|
276
276
|
authorization: authorization_from(action, response, amount),
|
277
|
+
avs_result: success_from(response) ? avs_from(response) : nil,
|
278
|
+
cvv_result: success_from(response) ? cvv_from(response) : nil,
|
277
279
|
test: test?
|
278
280
|
)
|
279
281
|
end
|
@@ -294,6 +296,14 @@ module ActiveMerchant #:nodoc:
|
|
294
296
|
response["expressresponsemessage"]
|
295
297
|
end
|
296
298
|
|
299
|
+
def avs_from(response)
|
300
|
+
AVSResult.new(code: response["card"]["avsresponsecode"]) if response["card"]
|
301
|
+
end
|
302
|
+
|
303
|
+
def cvv_from(response)
|
304
|
+
CVVResult.new(response["card"]["cvvresponsecode"]) if response["card"]
|
305
|
+
end
|
306
|
+
|
297
307
|
def split_authorization(authorization)
|
298
308
|
authorization.split("|")
|
299
309
|
end
|
@@ -226,9 +226,9 @@ module ActiveMerchant #:nodoc:
|
|
226
226
|
end
|
227
227
|
|
228
228
|
def add_credit_card(xml, credit_card, options)
|
229
|
-
|
230
229
|
if credit_card.respond_to?(:track_data) && credit_card.track_data.present?
|
231
230
|
xml.tag! "Track1", credit_card.track_data
|
231
|
+
xml.tag! "Ecommerce_Flag", "R"
|
232
232
|
else
|
233
233
|
xml.tag! "Card_Number", credit_card.number
|
234
234
|
xml.tag! "Expiry_Date", expdate(credit_card)
|
@@ -23,7 +23,7 @@ module ActiveMerchant #:nodoc:
|
|
23
23
|
def purchase(money, payment, options={})
|
24
24
|
MultiResponse.run do |r|
|
25
25
|
r.process { authorize(money, payment, options) }
|
26
|
-
r.process { capture(money, r.authorization, options) }
|
26
|
+
r.process { capture(money, r.authorization, options) } unless capture_requested?(r)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
@@ -290,6 +290,10 @@ EOS
|
|
290
290
|
def nestable_hash
|
291
291
|
Hash.new {|h,k| h[k] = Hash.new(&h.default_proc) }
|
292
292
|
end
|
293
|
+
|
294
|
+
def capture_requested?(response)
|
295
|
+
response.params.try(:[], "payment").try(:[], "status") == "CAPTURE_REQUESTED"
|
296
|
+
end
|
293
297
|
end
|
294
298
|
end
|
295
299
|
end
|
@@ -16,7 +16,7 @@ module ActiveMerchant #:nodoc:
|
|
16
16
|
# However, regular accounts with DPS only support VISA and Mastercard
|
17
17
|
self.supported_cardtypes = [ :visa, :master, :american_express, :diners_club, :jcb ]
|
18
18
|
|
19
|
-
self.supported_countries = %w[ AU
|
19
|
+
self.supported_countries = %w[ AU FJ GB HK IE MY NZ PG SG US ]
|
20
20
|
|
21
21
|
self.homepage_url = 'http://www.paymentexpress.com/'
|
22
22
|
self.display_name = 'PaymentExpress'
|
@@ -103,6 +103,18 @@ module ActiveMerchant #:nodoc:
|
|
103
103
|
commit_periodic(build_periodic_item(:remove_triggered, options[:amount], nil, options))
|
104
104
|
end
|
105
105
|
|
106
|
+
def supports_scrubbing?
|
107
|
+
true
|
108
|
+
end
|
109
|
+
|
110
|
+
def scrub(transcript)
|
111
|
+
transcript.
|
112
|
+
gsub(%r((<merchantID>).+(</merchantID>)), '\1[FILTERED]\2').
|
113
|
+
gsub(%r((<password>).+(</password>)), '\1[FILTERED]\2').
|
114
|
+
gsub(%r((<cardNumber>).+(</cardNumber>)), '\1[FILTERED]\2').
|
115
|
+
gsub(%r((<cvv>).+(</cvv>)), '\1[FILTERED]\2')
|
116
|
+
end
|
117
|
+
|
106
118
|
private
|
107
119
|
|
108
120
|
def build_purchase_request(money, credit_card, options)
|
@@ -380,7 +380,7 @@ module ActiveMerchant #:nodoc:
|
|
380
380
|
card[:swipe_data] = creditcard.track_data
|
381
381
|
card[:fallback_reason] = creditcard.fallback_reason if creditcard.fallback_reason
|
382
382
|
card[:read_method] = "contactless" if creditcard.contactless_emv
|
383
|
-
|
383
|
+
card[:read_method] = "contactless_magstripe_mode" if creditcard.contactless_magstripe
|
384
384
|
else
|
385
385
|
card[:number] = creditcard.number
|
386
386
|
card[:exp_month] = creditcard.month
|
@@ -5,7 +5,7 @@ module ActiveMerchant
|
|
5
5
|
class VancoGateway < Gateway
|
6
6
|
include Empty
|
7
7
|
|
8
|
-
self.test_url = 'https://
|
8
|
+
self.test_url = 'https://uat.vancopayments.com/cgi-bin/ws2.vps'
|
9
9
|
self.live_url = 'https://myvanco.vancopayments.com/cgi-bin/ws2.vps'
|
10
10
|
|
11
11
|
self.supported_countries = ['US']
|
@@ -10,6 +10,8 @@ module ActiveMerchant #:nodoc:
|
|
10
10
|
self.default_currency = 'USD'
|
11
11
|
self.display_name = 'WePay'
|
12
12
|
|
13
|
+
API_VERSION = "2016-12-07"
|
14
|
+
|
13
15
|
def initialize(options = {})
|
14
16
|
requires!(options, :client_id, :account_id, :access_token)
|
15
17
|
super(options)
|
@@ -18,38 +20,47 @@ module ActiveMerchant #:nodoc:
|
|
18
20
|
def purchase(money, payment_method, options = {})
|
19
21
|
post = {}
|
20
22
|
if payment_method.is_a?(String)
|
21
|
-
|
23
|
+
MultiResponse.run do |r|
|
24
|
+
r.process { authorize_with_token(post, money, payment_method, options) }
|
25
|
+
r.process { capture(money, r.authorization, options) }
|
26
|
+
end
|
22
27
|
else
|
23
28
|
MultiResponse.run do |r|
|
24
29
|
r.process { store(payment_method, options) }
|
25
|
-
r.process {
|
30
|
+
r.process { authorize_with_token(post, money, r.authorization, options) }
|
31
|
+
r.process { capture(money, r.authorization, options) }
|
26
32
|
end
|
27
33
|
end
|
28
34
|
end
|
29
35
|
|
30
36
|
def authorize(money, payment_method, options = {})
|
31
|
-
post = {
|
37
|
+
post = {}
|
32
38
|
if payment_method.is_a?(String)
|
33
|
-
|
39
|
+
authorize_with_token(post, money, payment_method, options)
|
34
40
|
else
|
35
41
|
MultiResponse.run do |r|
|
36
42
|
r.process { store(payment_method, options) }
|
37
|
-
r.process {
|
43
|
+
r.process { authorize_with_token(post, money, r.authorization, options) }
|
38
44
|
end
|
39
45
|
end
|
40
46
|
end
|
41
47
|
|
42
48
|
def capture(money, identifier, options = {})
|
49
|
+
checkout_id, original_amount = split_authorization(identifier)
|
50
|
+
|
43
51
|
post = {}
|
44
|
-
post[:checkout_id] =
|
45
|
-
|
52
|
+
post[:checkout_id] = checkout_id
|
53
|
+
if(money && (original_amount != amount(money)))
|
54
|
+
post[:amount] = amount(money)
|
55
|
+
end
|
56
|
+
commit('/checkout/capture', post, options)
|
46
57
|
end
|
47
58
|
|
48
59
|
def void(identifier, options = {})
|
49
60
|
post = {}
|
50
61
|
post[:checkout_id] = split_authorization(identifier).first
|
51
62
|
post[:cancel_reason] = (options[:description] || "Void")
|
52
|
-
commit('/checkout/cancel', post)
|
63
|
+
commit('/checkout/cancel', post, options)
|
53
64
|
end
|
54
65
|
|
55
66
|
def refund(money, identifier, options = {})
|
@@ -61,10 +72,9 @@ module ActiveMerchant #:nodoc:
|
|
61
72
|
post[:amount] = amount(money)
|
62
73
|
end
|
63
74
|
post[:refund_reason] = (options[:description] || "Refund")
|
64
|
-
post[:app_fee] = options[:application_fee] if options[:application_fee]
|
65
75
|
post[:payer_email_message] = options[:payer_email_message] if options[:payer_email_message]
|
66
76
|
post[:payee_email_message] = options[:payee_email_message] if options[:payee_email_message]
|
67
|
-
commit("/checkout/refund", post)
|
77
|
+
commit("/checkout/refund", post, options)
|
68
78
|
end
|
69
79
|
|
70
80
|
def store(creditcard, options = {})
|
@@ -76,53 +86,46 @@ module ActiveMerchant #:nodoc:
|
|
76
86
|
post[:email] = options[:email] || "unspecified@example.com"
|
77
87
|
post[:cc_number] = creditcard.number
|
78
88
|
post[:cvv] = creditcard.verification_value unless options[:recurring]
|
79
|
-
post[:expiration_month] =
|
80
|
-
post[:expiration_year] =
|
89
|
+
post[:expiration_month] = creditcard.month
|
90
|
+
post[:expiration_year] = creditcard.year
|
81
91
|
post[:original_ip] = options[:ip] if options[:ip]
|
82
92
|
post[:original_device] = options[:device_fingerprint] if options[:device_fingerprint]
|
93
|
+
|
83
94
|
if(billing_address = (options[:billing_address] || options[:address]))
|
84
|
-
post[:address] = {
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
post[:address]["zip"] = billing_address[:zip]
|
91
|
-
post[:address]["state"] = billing_address[:state]
|
92
|
-
else
|
93
|
-
post[:address]["region"] = billing_address[:state]
|
94
|
-
post[:address]["postcode"] = billing_address[:zip]
|
95
|
-
end
|
95
|
+
post[:address] = {}
|
96
|
+
post[:address]["address1"] = billing_address[:address1] if billing_address[:address1]
|
97
|
+
post[:address]["city"] = billing_address[:city] if billing_address[:city]
|
98
|
+
post[:address]["country"] = billing_address[:country] if billing_address[:country]
|
99
|
+
post[:address]["region"] = billing_address[:state] if billing_address[:state]
|
100
|
+
post[:address]["postal_code"] = billing_address[:zip]
|
96
101
|
end
|
97
102
|
|
98
103
|
if options[:recurring] == true
|
99
104
|
post[:client_secret] = @options[:client_secret]
|
100
|
-
commit('/credit_card/transfer', post)
|
105
|
+
commit('/credit_card/transfer', post, options)
|
101
106
|
else
|
102
|
-
commit('/credit_card/create', post)
|
107
|
+
commit('/credit_card/create', post, options)
|
103
108
|
end
|
104
109
|
end
|
105
110
|
|
106
111
|
private
|
107
112
|
|
108
|
-
def
|
113
|
+
def authorize_with_token(post, money, token, options)
|
109
114
|
add_token(post, token)
|
110
115
|
add_product_data(post, money, options)
|
111
|
-
commit('/checkout/create', post)
|
116
|
+
commit('/checkout/create', post, options)
|
112
117
|
end
|
113
118
|
|
114
119
|
def add_product_data(post, money, options)
|
115
120
|
post[:account_id] = @options[:account_id]
|
116
121
|
post[:amount] = amount(money)
|
117
122
|
post[:short_description] = (options[:description] || "Purchase")
|
118
|
-
post[:type] = (options[:type] || "
|
123
|
+
post[:type] = (options[:type] || "goods")
|
119
124
|
post[:currency] = (options[:currency] || currency(money))
|
120
125
|
post[:long_description] = options[:long_description] if options[:long_description]
|
121
126
|
post[:payer_email_message] = options[:payer_email_message] if options[:payer_email_message]
|
122
127
|
post[:payee_email_message] = options[:payee_email_message] if options[:payee_email_message]
|
123
128
|
post[:reference_id] = options[:order_id] if options[:order_id]
|
124
|
-
post[:app_fee] = options[:application_fee] if options[:application_fee]
|
125
|
-
post[:fee_payer] = options[:fee_payer] if options[:fee_payer]
|
126
129
|
post[:redirect_uri] = options[:redirect_uri] if options[:redirect_uri]
|
127
130
|
post[:callback_uri] = options[:callback_uri] if options[:callback_uri]
|
128
131
|
post[:fallback_uri] = options[:fallback_uri] if options[:fallback_uri]
|
@@ -133,11 +136,26 @@ module ActiveMerchant #:nodoc:
|
|
133
136
|
post[:preapproval_id] = options[:preapproval_id] if options[:preapproval_id]
|
134
137
|
post[:prefill_info] = options[:prefill_info] if options[:prefill_info]
|
135
138
|
post[:funding_sources] = options[:funding_sources] if options[:funding_sources]
|
139
|
+
add_fee(post, options)
|
136
140
|
end
|
137
141
|
|
138
142
|
def add_token(post, token)
|
139
|
-
|
140
|
-
|
143
|
+
payment_method = {}
|
144
|
+
payment_method[:type] = "credit_card"
|
145
|
+
payment_method[:credit_card] = {
|
146
|
+
id: token,
|
147
|
+
auto_capture: false
|
148
|
+
}
|
149
|
+
|
150
|
+
post[:payment_method] = payment_method
|
151
|
+
end
|
152
|
+
|
153
|
+
def add_fee(post, options)
|
154
|
+
if options[:application_fee] || options[:fee_payer]
|
155
|
+
post[:fee] = {}
|
156
|
+
post[:fee][:app_fee] = options[:application_fee] if options[:application_fee]
|
157
|
+
post[:fee][:fee_payer] = options[:fee_payer] if options[:fee_payer]
|
158
|
+
end
|
141
159
|
end
|
142
160
|
|
143
161
|
def parse(response)
|
@@ -149,7 +167,7 @@ module ActiveMerchant #:nodoc:
|
|
149
167
|
response = parse(ssl_post(
|
150
168
|
((test? ? test_url : live_url) + action),
|
151
169
|
params.to_json,
|
152
|
-
headers
|
170
|
+
headers(options)
|
153
171
|
))
|
154
172
|
rescue ResponseError => e
|
155
173
|
response = parse(e.response.body)
|
@@ -178,7 +196,8 @@ module ActiveMerchant #:nodoc:
|
|
178
196
|
def authorization_from(response, params)
|
179
197
|
return response["credit_card_id"].to_s if response["credit_card_id"]
|
180
198
|
|
181
|
-
|
199
|
+
original_amount = response["amount"].nil? ? nil : sprintf("%0.02f", response["amount"])
|
200
|
+
[response["checkout_id"], original_amount].join('|')
|
182
201
|
end
|
183
202
|
|
184
203
|
def split_authorization(authorization)
|
@@ -192,14 +211,18 @@ module ActiveMerchant #:nodoc:
|
|
192
211
|
return Response.new(false, message)
|
193
212
|
end
|
194
213
|
|
195
|
-
def headers
|
214
|
+
def headers(options)
|
196
215
|
{
|
197
216
|
"Content-Type" => "application/json",
|
198
217
|
"User-Agent" => "ActiveMerchantBindings/#{ActiveMerchant::VERSION}",
|
199
|
-
"Authorization" => "Bearer #{@options[:access_token]}"
|
218
|
+
"Authorization" => "Bearer #{@options[:access_token]}",
|
219
|
+
"Api-Version" => api_version(options)
|
200
220
|
}
|
201
221
|
end
|
222
|
+
|
223
|
+
def api_version(options)
|
224
|
+
options[:version] || API_VERSION
|
225
|
+
end
|
202
226
|
end
|
203
227
|
end
|
204
228
|
end
|
205
|
-
|
@@ -223,8 +223,11 @@ module ActiveMerchant #:nodoc:
|
|
223
223
|
|
224
224
|
add_address(xml, (options[:billing_address] || options[:address]))
|
225
225
|
end
|
226
|
-
if options[:ip]
|
227
|
-
xml.tag! 'session', 'shopperIPAddress' => options[:ip]
|
226
|
+
if options[:ip] && options[:session_id]
|
227
|
+
xml.tag! 'session', 'shopperIPAddress' => options[:ip], 'id' => options[:session_id]
|
228
|
+
else
|
229
|
+
xml.tag! 'session', 'shopperIPAddress' => options[:ip] if options[:ip]
|
230
|
+
xml.tag! 'session', 'id' => options[:session_id] if options[:session_id]
|
228
231
|
end
|
229
232
|
end
|
230
233
|
end
|
@@ -238,6 +241,8 @@ module ActiveMerchant #:nodoc:
|
|
238
241
|
end
|
239
242
|
|
240
243
|
def add_address(xml, address)
|
244
|
+
return unless address
|
245
|
+
|
241
246
|
address = address_with_defaults(address)
|
242
247
|
|
243
248
|
xml.tag! 'cardAddress' do
|
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.63.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:
|
11
|
+
date: 2017-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -202,6 +202,7 @@ files:
|
|
202
202
|
- lib/active_merchant/billing/gateways/conekta.rb
|
203
203
|
- lib/active_merchant/billing/gateways/creditcall.rb
|
204
204
|
- lib/active_merchant/billing/gateways/credorax.rb
|
205
|
+
- lib/active_merchant/billing/gateways/culqi.rb
|
205
206
|
- lib/active_merchant/billing/gateways/cyber_source.rb
|
206
207
|
- lib/active_merchant/billing/gateways/data_cash.rb
|
207
208
|
- lib/active_merchant/billing/gateways/dibs.rb
|
@@ -395,7 +396,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
395
396
|
requirements:
|
396
397
|
- - ">="
|
397
398
|
- !ruby/object:Gem::Version
|
398
|
-
version: '2'
|
399
|
+
version: '2.1'
|
399
400
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
400
401
|
requirements:
|
401
402
|
- - ">="
|