activemerchant 1.106.0 → 1.107.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f734d2204b43b893e645e5c47b9afe26506c0c383b355af486ac93cd6a8677ed
4
- data.tar.gz: 611450e08256619a1d8aea5bc5795c47ff9220f0abde707f0facc82dd76e1661
3
+ metadata.gz: 88249628bc56fb775fc6cc669fceea51b9040ced2f7c2dea503cd276a37202d1
4
+ data.tar.gz: f538ae45a677ec066b40dbb68742b1df9ccea5e7d45e0bd9e28d88968ae77334
5
5
  SHA512:
6
- metadata.gz: 98fa68d855a398089f9a088d8fa12edae2b34e8ed9fecab64511dc7e64b1ead409977adc00c3bc6aaf18f3f552f2b1fa3a38b8ceb5779d4a32a91e171a5556c8
7
- data.tar.gz: 78a05f047cb7de339104b39785394b75ca51be7d33368ba44549006e2429e3d2a2796a10d30a18a38fae4aff34e6f4a605f862ec3103ad101c9805c09af586f7
6
+ metadata.gz: 06c755605d7633a83cc1e2b9cfbf0cdf00d320e8bcd345cfdb6539ad814b9795ac4e33e075941f9b0761768ae9a6f3cb2bad90dd2ed35eca0fce7a8aa9642f55
7
+ data.tar.gz: e35ac5cfa97a22fdc416c0031e20f398b62189bb091e20b9c17fc815d2db2d481aa5463d047a5d718ec07574249c57acf1defec69c5ff7156f9be80220361b3d
data/CHANGELOG CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  == HEAD
4
4
 
5
+ == Version 1.107.1 (Apr 1, 2020)
6
+ * Add `allowed_push_host` to gemspec [mdeloupy]
7
+
8
+ == Version 1.107.0 (Apr 1, 2020)
9
+ * Stripe Payment Intents: Early return failed `payment_methods` response [chinhle23] #3570
10
+ * Borgun: Support `passengerItineraryData` [therufs] #3572
11
+ * Ingenico GlobalCollect: support optional `requires_approval` field [fatcatt316] #3571
12
+ * CenPOS: Update failing remote tests [britth] #3575
13
+ * Realex: Update remote tests [britth] #3576
14
+ * FirstData e4 v27: Properly tag stored credential initiation field in request [britth] #3578
15
+ * Orbital: Fix stored credentials [chinhle23] #3579
16
+ * Acapture(Opp): Update gateway credentials [molbrown] #3574
17
+ * Ingenico GlobalCollect: support `requires_approval` field [fatcatt316] #3577
18
+ * CyberSource: Fix `void` for `purchase` transactions [chinhle23] #3581
19
+ * Checkout V2: Begin to add support for using network tokens for transactions. [arbianchi] #3580
20
+ * Opp: Update remote test fixtures [ccarruitero] #3582
21
+ * Optimal Payment: Add support for store [britth] #3585
22
+ * SecurePay Australia : Update test URL (#3586)
23
+
5
24
  == Version 1.106.0 (Mar 10, 2020)
6
25
  * PayJunctionV2: Send billing address in `auth` and `purchase` transactions [naashton] #3538
7
26
  * Adyen: Fix some remote tests [curiousepic] #3541
@@ -34,7 +34,7 @@ module ActiveMerchant #:nodoc:
34
34
  post[:TransType] = '5'
35
35
  add_invoice(post, money, options)
36
36
  add_payment_method(post, payment)
37
- commit('authonly', post)
37
+ commit('authonly', post, options)
38
38
  end
39
39
 
40
40
  def capture(money, authorization, options={})
@@ -125,12 +125,12 @@ module ActiveMerchant #:nodoc:
125
125
  response
126
126
  end
127
127
 
128
- def commit(action, post)
128
+ def commit(action, post, options={})
129
129
  post[:Version] = '1000'
130
130
  post[:Processor] = @options[:processor]
131
131
  post[:MerchantID] = @options[:merchant_id]
132
132
 
133
- request = build_request(action, post)
133
+ request = build_request(action, post, options)
134
134
  raw = ssl_post(url(action), request, headers)
135
135
  pairs = parse(raw)
136
136
  success = success_from(pairs)
@@ -180,7 +180,7 @@ module ActiveMerchant #:nodoc:
180
180
  }
181
181
  end
182
182
 
183
- def build_request(action, post)
183
+ def build_request(action, post, options={})
184
184
  mode = action == 'void' ? 'cancel' : 'get'
185
185
  xml = Builder::XmlMarkup.new indent: 18
186
186
  xml.instruct!(:xml, version: '1.0', encoding: 'utf-8')
@@ -188,11 +188,22 @@ module ActiveMerchant #:nodoc:
188
188
  post.each do |field, value|
189
189
  xml.tag!(field, value)
190
190
  end
191
+ build_airline_xml(xml, options[:passenger_itinerary_data]) if options[:passenger_itinerary_data]
191
192
  end
192
193
  inner = CGI.escapeHTML(xml.target!)
193
194
  envelope(mode).sub(/{{ :body }}/, inner)
194
195
  end
195
196
 
197
+ def build_airline_xml(xml, airline_data)
198
+ xml.tag!('PassengerItineraryData') do
199
+ xml.tag!('A1') do
200
+ airline_data.each do |field, value|
201
+ xml.tag!(field, value)
202
+ end
203
+ end
204
+ end
205
+ end
206
+
196
207
  def envelope(mode)
197
208
  <<-EOS
198
209
  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:aut="http://Borgun/Heimir/pub/ws/Authorization">
@@ -102,13 +102,21 @@ module ActiveMerchant #:nodoc:
102
102
 
103
103
  def add_payment_method(post, payment_method, options)
104
104
  post[:source] = {}
105
- post[:source][:type] = 'card'
106
- post[:source][:name] = payment_method.name
107
- post[:source][:number] = payment_method.number
108
- post[:source][:cvv] = payment_method.verification_value
105
+ if payment_method.is_a?(NetworkTokenizationCreditCard) && payment_method.source == :network_token
106
+ post[:source][:type] = 'network_token'
107
+ post[:source][:token] = payment_method.number
108
+ post[:source][:token_type] = payment_method.brand == 'visa' ? 'vts' : 'mdes'
109
+ post[:source][:cryptogram] = payment_method.payment_cryptogram
110
+ post[:source][:eci] = options[:eci] || '05'
111
+ else
112
+ post[:source][:type] = 'card'
113
+ post[:source][:name] = payment_method.name
114
+ post[:source][:number] = payment_method.number
115
+ post[:source][:cvv] = payment_method.verification_value
116
+ post[:source][:stored] = 'true' if options[:card_on_file] == true
117
+ end
109
118
  post[:source][:expiry_year] = format(payment_method.year, :four_digits)
110
119
  post[:source][:expiry_month] = format(payment_method.month, :two_digits)
111
- post[:source][:stored] = 'true' if options[:card_on_file] == true
112
120
  end
113
121
 
114
122
  def add_customer_data(post, options)
@@ -325,7 +325,8 @@ module ActiveMerchant #:nodoc:
325
325
  options[:order_id] = order_id
326
326
 
327
327
  xml = Builder::XmlMarkup.new indent: 2
328
- if action == 'capture'
328
+ case action
329
+ when 'capture', 'purchase'
329
330
  add_mdd_fields(xml, options)
330
331
  add_void_service(xml, request_id, request_token)
331
332
  else
@@ -319,7 +319,7 @@ module ActiveMerchant #:nodoc:
319
319
  xml.tag! 'StoredCredentials' do
320
320
  xml.tag! 'Indicator', stored_credential_indicator(xml, card, options)
321
321
  if initiator = options.dig(:stored_credential, :initiator)
322
- xml.tag! initiator == 'merchant' ? 'M' : 'C'
322
+ xml.tag! 'Initiation', initiator == 'merchant' ? 'M' : 'C'
323
323
  end
324
324
  if reason_type = options.dig(:stored_credential, :reason_type)
325
325
  xml.tag! 'Schedule', reason_type == 'unscheduled' ? 'U' : 'S'
@@ -7,10 +7,10 @@ module ActiveMerchant #:nodoc:
7
7
  self.test_url = 'https://eu.sandbox.api-ingenico.com'
8
8
  self.live_url = 'https://api.globalcollect.com'
9
9
 
10
- self.supported_countries = ['AD', 'AE', 'AG', 'AI', 'AL', 'AM', 'AO', 'AR', 'AS', 'AT', 'AU', 'AW', 'AX', 'AZ', 'BA', 'BB', 'BD', 'BE', 'BF', 'BG', 'BH', 'BI', 'BJ', 'BL', 'BM', 'BN', 'BO', 'BQ', 'BR', 'BS', 'BT', 'BW', 'BY', 'BZ', 'CA', 'CC', 'CD', 'CF', 'CH', 'CI', 'CK', 'CL', 'CM', 'CN', 'CO', 'CR', 'CU', 'CV', 'CW', 'CX', 'CY', 'CZ', 'DE', 'DJ', 'DK', 'DM', 'DO', 'DZ', 'EC', 'EE', 'EG', 'ER', 'ES', 'ET', 'FI', 'FJ', 'FK', 'FM', 'FO', 'FR', 'GA', 'GB', 'GD', 'GE', 'GF', 'GH', 'GI', 'GL', 'GM', 'GN', 'GP', 'GQ', 'GR', 'GS', 'GT', 'GU', 'GW', 'GY', 'HK', 'HN', 'HR', 'HT', 'HU', 'ID', 'IE', 'IL', 'IM', 'IN', 'IS', 'IT', 'JM', 'JO', 'JP', 'KE', 'KG', 'KH', 'KI', 'KM', 'KN', 'KR', 'KW', 'KY', 'KZ', 'LA', 'LB', 'LC', 'LI', 'LK', 'LR', 'LS', 'LT', 'LU', 'LV', 'MA', 'MC', 'MD', 'ME', 'MF', 'MG', 'MH', 'MK', 'MM', 'MN', 'MO', 'MP', 'MQ', 'MR', 'MS', 'MT', 'MU', 'MV', 'MW', 'MX', 'MY', 'MZ', 'NA', 'NC', 'NE', 'NG', 'NI', 'NL', 'NO', 'NP', 'NR', 'NU', 'NZ', 'OM', 'PA', 'PE', 'PF', 'PG', 'PH', 'PL', 'PN', 'PS', 'PT', 'PW', 'QA', 'RE', 'RO', 'RS', 'RU', 'RW', 'SA', 'SB', 'SC', 'SE', 'SG', 'SH', 'SI', 'SJ', 'SK', 'SL', 'SM', 'SN', 'SR', 'ST', 'SV', 'SZ', 'TC', 'TD', 'TG', 'TH', 'TJ', 'TL', 'TM', 'TN', 'TO', 'TR', 'TT', 'TV', 'TW', 'TZ', 'UA', 'UG', 'US', 'UY', 'UZ', 'VC', 'VE', 'VG', 'VI', 'VN', 'WF', 'WS', 'ZA', 'ZM', 'ZW']
10
+ self.supported_countries = %w[AD AE AG AI AL AM AO AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BR BS BT BW BY BZ CA CC CD CF CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ EC EE EG ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GH GI GL GM GN GP GQ GR GS GT GU GW GY HK HN HR HT HU ID IE IL IM IN IS IT JM JO JP KE KG KH KI KM KN KR KW KY KZ LA LB LC LI LK LR LS LT LU LV MA MC MD ME MF MG MH MK MM MN MO MP MQ MR MS MT MU MV MW MX MY MZ NA NC NE NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PL PN PS PT PW QA RE RO RS RU RW SA SB SC SE SG SH SI SJ SK SL SM SN SR ST SV SZ TC TD TG TH TJ TL TM TN TO TR TT TV TW TZ UA UG US UY UZ VC VE VG VI VN WF WS ZA ZM ZW]
11
11
  self.default_currency = 'USD'
12
12
  self.money_format = :cents
13
- self.supported_cardtypes = [:visa, :master, :american_express, :discover, :naranja, :cabal]
13
+ self.supported_cardtypes = %i[visa master american_express discover naranja cabal]
14
14
 
15
15
  def initialize(options={})
16
16
  requires!(options, :merchant_id, :api_key_id, :secret_api_key)
@@ -20,7 +20,7 @@ module ActiveMerchant #:nodoc:
20
20
  def purchase(money, payment, options={})
21
21
  MultiResponse.run do |r|
22
22
  r.process { authorize(money, payment, options) }
23
- r.process { capture(money, r.authorization, options) } unless capture_requested?(r)
23
+ r.process { capture(money, r.authorization, options) } if should_request_capture?(r, options[:requires_approval])
24
24
  end
25
25
  end
26
26
 
@@ -32,7 +32,6 @@ module ActiveMerchant #:nodoc:
32
32
  add_address(post, payment, options)
33
33
  add_creator_info(post, options)
34
34
  add_fraud_fields(post, options)
35
-
36
35
  commit(:authorize, post)
37
36
  end
38
37
 
@@ -161,6 +160,8 @@ module ActiveMerchant #:nodoc:
161
160
  'skipFraudService' => 'true',
162
161
  'authorizationMode' => pre_authorization
163
162
  }
163
+ post['cardPaymentMethodSpecificInput']['requiresApproval'] = options[:requires_approval] unless options[:requires_approval].nil?
164
+
164
165
  post['cardPaymentMethodSpecificInput']['card'] = {
165
166
  'cvv' => payment.verification_value,
166
167
  'cardNumber' => payment.number,
@@ -283,7 +284,7 @@ module ActiveMerchant #:nodoc:
283
284
 
284
285
  def headers(action, post, authorization = nil)
285
286
  {
286
- 'Content-Type' => content_type,
287
+ 'Content-Type' => content_type,
287
288
  'Authorization' => auth_digest(action, post, authorization),
288
289
  'Date' => date
289
290
  }
@@ -314,18 +315,16 @@ POST
314
315
  end
315
316
 
316
317
  def message_from(succeeded, response)
317
- if succeeded
318
- 'Succeeded'
318
+ return 'Succeeded' if succeeded
319
+
320
+ if errors = response['errors']
321
+ errors.first.try(:[], 'message')
322
+ elsif response['error_message']
323
+ response['error_message']
324
+ elsif response['status']
325
+ 'Status: ' + response['status']
319
326
  else
320
- if errors = response['errors']
321
- errors.first.try(:[], 'message')
322
- elsif response['error_message']
323
- response['error_message']
324
- elsif response['status']
325
- 'Status: ' + response['status']
326
- else
327
- 'No message available'
328
- end
327
+ 'No message available'
329
328
  end
330
329
  end
331
330
 
@@ -340,14 +339,14 @@ POST
340
339
  end
341
340
 
342
341
  def error_code_from(succeeded, response)
343
- unless succeeded
344
- if errors = response['errors']
345
- errors.first.try(:[], 'code')
346
- elsif status = response.try(:[], 'statusOutput').try(:[], 'statusCode')
347
- status.to_s
348
- else
349
- 'No error code available'
350
- end
342
+ return if succeeded
343
+
344
+ if errors = response['errors']
345
+ errors.first.try(:[], 'code')
346
+ elsif status = response.try(:[], 'statusOutput').try(:[], 'statusCode')
347
+ status.to_s
348
+ else
349
+ 'No error code available'
351
350
  end
352
351
  end
353
352
 
@@ -355,6 +354,13 @@ POST
355
354
  Hash.new { |h, k| h[k] = Hash.new(&h.default_proc) }
356
355
  end
357
356
 
357
+ # Capture hasn't already been requested,
358
+ # and
359
+ # `requires_approval` is not false
360
+ def should_request_capture?(response, requires_approval)
361
+ !capture_requested?(response) && requires_approval != false
362
+ end
363
+
358
364
  def capture_requested?(response)
359
365
  response.params.try(:[], 'payment').try(:[], 'status') == 'CAPTURE_REQUESTED'
360
366
  end
@@ -13,8 +13,7 @@ module ActiveMerchant #:nodoc:
13
13
  # == Usage
14
14
  #
15
15
  # gateway = ActiveMerchant::Billing::OppGateway.new(
16
- # user_id: 'merchant user id',
17
- # password: 'password',
16
+ # access_token: 'access_token',
18
17
  # entity_id: 'entity id',
19
18
  # )
20
19
  #
@@ -119,7 +118,7 @@ module ActiveMerchant #:nodoc:
119
118
  self.display_name = 'Open Payment Platform'
120
119
 
121
120
  def initialize(options={})
122
- requires!(options, :user_id, :password, :entity_id)
121
+ requires!(options, :access_token, :entity_id)
123
122
  super
124
123
  end
125
124
 
@@ -167,7 +166,7 @@ module ActiveMerchant #:nodoc:
167
166
 
168
167
  def scrub(transcript)
169
168
  transcript.
170
- gsub(%r((authentication\.password=)\w+), '\1[FILTERED]').
169
+ gsub(%r((Authorization: Bearer )\w+)i, '\1[FILTERED]').
171
170
  gsub(%r((card\.number=)\d+), '\1[FILTERED]').
172
171
  gsub(%r((card\.cvv=)\d+), '\1[FILTERED]')
173
172
  end
@@ -203,7 +202,7 @@ module ActiveMerchant #:nodoc:
203
202
  end
204
203
 
205
204
  def add_authentication(post)
206
- post[:authentication] = { entityId: @options[:entity_id], password: @options[:password], userId: @options[:user_id]}
205
+ post[:authentication] = { entityId: @options[:entity_id] }
207
206
  end
208
207
 
209
208
  def add_customer_data(post, payment, options)
@@ -316,7 +315,7 @@ module ActiveMerchant #:nodoc:
316
315
  ssl_post(
317
316
  url,
318
317
  post.collect { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&'),
319
- 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8'
318
+ headers
320
319
  )
321
320
  )
322
321
  rescue ResponseError => e
@@ -335,6 +334,13 @@ module ActiveMerchant #:nodoc:
335
334
  )
336
335
  end
337
336
 
337
+ def headers
338
+ {
339
+ 'Content-Type' => 'application/x-www-form-urlencoded;charset=UTF-8',
340
+ 'Authorization' => "Bearer #{@options[:access_token]}"
341
+ }
342
+ end
343
+
338
344
  def parse(body)
339
345
  JSON.parse(body)
340
346
  rescue JSON::ParserError
@@ -65,6 +65,10 @@ module ActiveMerchant #:nodoc:
65
65
  commit('ccVerification', 0, options)
66
66
  end
67
67
 
68
+ def store(credit_card, options = {})
69
+ verify(credit_card, options)
70
+ end
71
+
68
72
  def supports_scrubbing?
69
73
  true
70
74
  end
@@ -569,7 +569,7 @@ module ActiveMerchant #:nodoc:
569
569
 
570
570
  initiator =
571
571
  case parameters[:stored_credential][:initiator]
572
- when 'customer' then 'C'
572
+ when 'cardholder', 'customer' then 'C'
573
573
  when 'merchant' then 'M'
574
574
  end
575
575
  reason =
@@ -8,7 +8,7 @@ module ActiveMerchant #:nodoc:
8
8
 
9
9
  class_attribute :test_periodic_url, :live_periodic_url
10
10
 
11
- self.test_url = 'https://api.securepay.com.au/test/payment'
11
+ self.test_url = 'https://test.api.securepay.com.au/xmlapi/payment'
12
12
  self.live_url = 'https://api.securepay.com.au/xmlapi/payment'
13
13
 
14
14
  self.test_periodic_url = 'https://test.securepay.com.au/xmlapi/periodic'
@@ -20,7 +20,9 @@ module ActiveMerchant #:nodoc:
20
20
  add_capture_method(post, options)
21
21
  add_confirmation_method(post, options)
22
22
  add_customer(post, options)
23
- add_payment_method_token(post, payment_method, options)
23
+ payment_method = add_payment_method_token(post, payment_method, options)
24
+ return payment_method if payment_method.is_a?(ActiveMerchant::Billing::Response)
25
+
24
26
  add_metadata(post, options)
25
27
  add_return_url(post, options)
26
28
  add_connected_account(post, options)
@@ -41,7 +43,9 @@ module ActiveMerchant #:nodoc:
41
43
 
42
44
  def confirm_intent(intent_id, payment_method, options = {})
43
45
  post = {}
44
- add_payment_method_token(post, payment_method, options)
46
+ payment_method = add_payment_method_token(post, payment_method, options)
47
+ return payment_method if payment_method.is_a?(ActiveMerchant::Billing::Response)
48
+
45
49
  CONFIRM_INTENT_ATTRIBUTES.each do |attribute|
46
50
  add_whitelisted_attribute(post, options, attribute)
47
51
  end
@@ -65,7 +69,9 @@ module ActiveMerchant #:nodoc:
65
69
  post = {}
66
70
  add_amount(post, money, options)
67
71
 
68
- add_payment_method_token(post, payment_method, options)
72
+ payment_method = add_payment_method_token(post, payment_method, options)
73
+ return payment_method if payment_method.is_a?(ActiveMerchant::Billing::Response)
74
+
69
75
  add_payment_method_types(post, options)
70
76
  add_customer(post, options)
71
77
  add_metadata(post, options)
@@ -121,7 +127,9 @@ module ActiveMerchant #:nodoc:
121
127
  # If customer option is provided, create a payment method and attach to customer id
122
128
  # Otherwise, create a customer, then attach
123
129
  if payment_method.is_a?(StripePaymentToken) || payment_method.is_a?(ActiveMerchant::Billing::CreditCard)
124
- add_payment_method_token(params, payment_method, options)
130
+ payment_method = add_payment_method_token(params, payment_method, options)
131
+ return payment_method if payment_method.is_a?(ActiveMerchant::Billing::Response)
132
+
125
133
  if options[:customer]
126
134
  customer_id = options[:customer]
127
135
  else
@@ -191,6 +199,8 @@ module ActiveMerchant #:nodoc:
191
199
 
192
200
  if payment_method.is_a?(ActiveMerchant::Billing::CreditCard)
193
201
  p = create_payment_method(payment_method, options)
202
+ return p unless p.success?
203
+
194
204
  payment_method = p.params['id']
195
205
  end
196
206
 
@@ -17,7 +17,7 @@ module ActiveMerchant #:nodoc:
17
17
  attr_accessor :payment_cryptogram, :eci, :transaction_id
18
18
  attr_writer :source
19
19
 
20
- SOURCES = %i(apple_pay android_pay google_pay)
20
+ SOURCES = %i(apple_pay android_pay google_pay network_token)
21
21
 
22
22
  def source
23
23
  if defined?(@source) && SOURCES.include?(@source)
@@ -1,3 +1,3 @@
1
1
  module ActiveMerchant
2
- VERSION = '1.106.0'
2
+ VERSION = '1.107.1'
3
3
  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.106.0
4
+ version: 1.107.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Luetke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-10 00:00:00.000000000 Z
11
+ date: 2020-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -412,7 +412,8 @@ files:
412
412
  homepage: http://activemerchant.org/
413
413
  licenses:
414
414
  - MIT
415
- metadata: {}
415
+ metadata:
416
+ allowed_push_host: https://rubygems.org
416
417
  post_install_message:
417
418
  rdoc_options: []
418
419
  require_paths: