activemerchant 1.123.0 → 1.125.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +131 -0
  3. data/lib/active_merchant/billing/check.rb +5 -8
  4. data/lib/active_merchant/billing/credit_card.rb +10 -0
  5. data/lib/active_merchant/billing/credit_card_methods.rb +6 -3
  6. data/lib/active_merchant/billing/gateway.rb +1 -1
  7. data/lib/active_merchant/billing/gateways/adyen.rb +61 -9
  8. data/lib/active_merchant/billing/gateways/card_stream.rb +17 -13
  9. data/lib/active_merchant/billing/gateways/cashnet.rb +15 -5
  10. data/lib/active_merchant/billing/gateways/checkout_v2.rb +33 -4
  11. data/lib/active_merchant/billing/gateways/cyber_source.rb +11 -3
  12. data/lib/active_merchant/billing/gateways/d_local.rb +12 -6
  13. data/lib/active_merchant/billing/gateways/decidir_plus.rb +173 -0
  14. data/lib/active_merchant/billing/gateways/ebanx.rb +16 -1
  15. data/lib/active_merchant/billing/gateways/elavon.rb +6 -3
  16. data/lib/active_merchant/billing/gateways/element.rb +20 -2
  17. data/lib/active_merchant/billing/gateways/global_collect.rb +111 -16
  18. data/lib/active_merchant/billing/gateways/ipg.rb +416 -0
  19. data/lib/active_merchant/billing/gateways/kushki.rb +7 -0
  20. data/lib/active_merchant/billing/gateways/mercado_pago.rb +3 -1
  21. data/lib/active_merchant/billing/gateways/mit.rb +260 -0
  22. data/lib/active_merchant/billing/gateways/moka.rb +24 -11
  23. data/lib/active_merchant/billing/gateways/mundipagg.rb +8 -6
  24. data/lib/active_merchant/billing/gateways/nmi.rb +15 -1
  25. data/lib/active_merchant/billing/gateways/orbital.rb +19 -3
  26. data/lib/active_merchant/billing/gateways/pay_arc.rb +9 -7
  27. data/lib/active_merchant/billing/gateways/pay_conex.rb +3 -1
  28. data/lib/active_merchant/billing/gateways/pay_trace.rb +1 -1
  29. data/lib/active_merchant/billing/gateways/payflow.rb +14 -6
  30. data/lib/active_merchant/billing/gateways/paymentez.rb +9 -2
  31. data/lib/active_merchant/billing/gateways/paysafe.rb +144 -23
  32. data/lib/active_merchant/billing/gateways/payu_latam.rb +6 -1
  33. data/lib/active_merchant/billing/gateways/payway_dot_com.rb +3 -3
  34. data/lib/active_merchant/billing/gateways/pin.rb +31 -4
  35. data/lib/active_merchant/billing/gateways/priority.rb +347 -0
  36. data/lib/active_merchant/billing/gateways/realex.rb +18 -0
  37. data/lib/active_merchant/billing/gateways/safe_charge.rb +6 -2
  38. data/lib/active_merchant/billing/gateways/stripe.rb +27 -7
  39. data/lib/active_merchant/billing/gateways/stripe_payment_intents.rb +96 -38
  40. data/lib/active_merchant/billing/gateways/trans_first_transaction_express.rb +2 -1
  41. data/lib/active_merchant/billing/gateways/trust_commerce.rb +2 -1
  42. data/lib/active_merchant/billing/gateways/usa_epay_transaction.rb +20 -6
  43. data/lib/active_merchant/billing/gateways/wompi.rb +193 -0
  44. data/lib/active_merchant/billing/gateways/worldpay.rb +196 -64
  45. data/lib/active_merchant/billing/network_tokenization_credit_card.rb +1 -1
  46. data/lib/active_merchant/billing/response.rb +4 -0
  47. data/lib/active_merchant/version.rb +1 -1
  48. metadata +7 -2
@@ -4,7 +4,7 @@ module ActiveMerchant #:nodoc:
4
4
  self.test_url = 'https://sandbox.dlocal.com'
5
5
  self.live_url = 'https://api.dlocal.com'
6
6
 
7
- self.supported_countries = %w[AR BR CL CO MX PE UY TR]
7
+ self.supported_countries = %w[AR BD BO BR CL CM CN CO CR DO EC EG GH IN ID KE MY MX MA NG PA PY PE PH SN ZA TR UY VN]
8
8
  self.default_currency = 'USD'
9
9
  self.supported_cardtypes = %i[visa master american_express discover jcb diners_club maestro naranja cabal elo alia carnet]
10
10
 
@@ -26,6 +26,7 @@ module ActiveMerchant #:nodoc:
26
26
  def authorize(money, payment, options = {})
27
27
  post = {}
28
28
  add_auth_purchase_params(post, money, payment, 'authorize', options)
29
+ post[:card][:verify] = true if options[:verify].to_s == 'true'
29
30
 
30
31
  commit('authorize', post, options)
31
32
  end
@@ -52,10 +53,7 @@ module ActiveMerchant #:nodoc:
52
53
  end
53
54
 
54
55
  def verify(credit_card, options = {})
55
- MultiResponse.run(:use_first_response) do |r|
56
- r.process { authorize(100, credit_card, options) }
57
- r.process(:ignore_result) { void(r.authorization, options) }
58
- end
56
+ authorize(0, credit_card, options.merge(verify: 'true'))
59
57
  end
60
58
 
61
59
  def supports_scrubbing?
@@ -78,6 +76,7 @@ module ActiveMerchant #:nodoc:
78
76
  add_country(post, card, options)
79
77
  add_payer(post, card, options)
80
78
  add_card(post, card, action, options)
79
+ add_additional_data(post, options)
81
80
  post[:order_id] = options[:order_id] || generate_unique_id
82
81
  post[:description] = options[:description] if options[:description]
83
82
  end
@@ -87,6 +86,10 @@ module ActiveMerchant #:nodoc:
87
86
  post[:currency] = (options[:currency] || currency(money))
88
87
  end
89
88
 
89
+ def add_additional_data(post, options)
90
+ post[:additional_risk_data] = options[:additional_data]
91
+ end
92
+
90
93
  def add_country(post, card, options)
91
94
  return unless address = options[:billing_address] || options[:address]
92
95
 
@@ -109,6 +112,8 @@ module ActiveMerchant #:nodoc:
109
112
  post[:payer][:document] = options[:document] if options[:document]
110
113
  post[:payer][:document2] = options[:document2] if options[:document2]
111
114
  post[:payer][:user_reference] = options[:user_reference] if options[:user_reference]
115
+ post[:payer][:event_uuid] = options[:device_id] if options[:device_id]
116
+ post[:payer][:onboarding_ip_address] = options[:ip] if options[:ip]
112
117
  post[:payer][:address] = add_address(post, card, options)
113
118
  end
114
119
 
@@ -184,7 +189,7 @@ module ActiveMerchant #:nodoc:
184
189
  def success_from(action, response)
185
190
  return false unless response['status_code']
186
191
 
187
- %w[100 200 400 600].include? response['status_code'].to_s
192
+ %w[100 200 400 600 700].include? response['status_code'].to_s
188
193
  end
189
194
 
190
195
  def message_from(action, response)
@@ -228,6 +233,7 @@ module ActiveMerchant #:nodoc:
228
233
  'X-Date' => timestamp,
229
234
  'X-Login' => @options[:login],
230
235
  'X-Trans-Key' => @options[:trans_key],
236
+ 'X-Version' => '2.1',
231
237
  'Authorization' => signature(post, timestamp)
232
238
  }
233
239
  headers.merge('X-Idempotency-Key' => options[:idempotency_key]) if options[:idempotency_key]
@@ -0,0 +1,173 @@
1
+ module ActiveMerchant #:nodoc:
2
+ module Billing #:nodoc:
3
+ class DecidirPlusGateway < Gateway
4
+ self.test_url = 'https://developers.decidir.com/api/v2'
5
+ self.live_url = 'https://live.decidir.com/api/v2'
6
+
7
+ self.supported_countries = ['AR']
8
+ self.default_currency = 'ARS'
9
+ self.supported_cardtypes = %i[visa master american_express discover]
10
+
11
+ self.homepage_url = 'http://decidir.com.ar/home'
12
+ self.display_name = 'Decidir Plus'
13
+
14
+ def initialize(options = {})
15
+ requires!(options, :public_key, :private_key)
16
+ super
17
+ end
18
+
19
+ def purchase(money, payment, options = {})
20
+ post = {}
21
+
22
+ add_payment(post, payment, options)
23
+ add_purchase_data(post, money, payment, options)
24
+
25
+ commit(:post, 'payments', post)
26
+ end
27
+
28
+ def refund(money, authorization, options = {})
29
+ post = {}
30
+ post[:amount] = money
31
+
32
+ commit(:post, "payments/#{add_reference(authorization)}/refunds")
33
+ end
34
+
35
+ def store(payment, options = {})
36
+ post = {}
37
+ add_payment(post, payment, options)
38
+
39
+ commit(:post, 'tokens', post)
40
+ end
41
+
42
+ def supports_scrubbing?
43
+ true
44
+ end
45
+
46
+ def scrub(transcript)
47
+ transcript.
48
+ gsub(%r((Apikey: )\w+), '\1[FILTERED]').
49
+ gsub(%r(("card_number\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]').
50
+ gsub(%r(("security_code\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]')
51
+ end
52
+
53
+ private
54
+
55
+ def add_reference(authorization)
56
+ return unless authorization
57
+
58
+ authorization.split('|')[0]
59
+ end
60
+
61
+ def add_payment(post, payment, options = {})
62
+ if payment.is_a?(String)
63
+ token, bin = payment.split('|')
64
+ post[:token] = token
65
+ post[:bin] = bin
66
+ else
67
+ post[:card_number] = payment.number
68
+ post[:card_expiration_month] = payment.month.to_s.rjust(2, '0')
69
+ post[:card_expiration_year] = payment.year.to_s[-2..-1]
70
+ post[:security_code] = payment.verification_value.to_s
71
+ post[:card_holder_name] = payment.name
72
+ post[:card_holder_identification] = {}
73
+ post[:card_holder_identification][:type] = options[:dni]
74
+ post[:card_holder_identification][:number] = options[:card_holder_identification_number]
75
+ end
76
+ end
77
+
78
+ def add_purchase_data(post, money, payment, options = {})
79
+ post[:site_transaction_id] = options[:site_transaction_id] || SecureRandom.hex
80
+ post[:payment_method_id] = 1
81
+ post[:amount] = money
82
+ post[:currency] = options[:currency] || self.default_currency
83
+ post[:installments] = options[:installments] || 1
84
+ post[:payment_type] = options[:payment_type] || 'single'
85
+ add_sub_payments(post, options)
86
+ end
87
+
88
+ def add_sub_payments(post, options)
89
+ # sub_payments field is required for purchase transactions, even if empty
90
+ post[:sub_payments] = []
91
+
92
+ return unless sub_payments = options[:sub_payments]
93
+
94
+ sub_payments.each do |sub_payment|
95
+ sub_payment_hash = {
96
+ site_id: sub_payment[:site_id],
97
+ installments: sub_payment[:installments],
98
+ amount: sub_payment[:amount]
99
+ }
100
+ post[:sub_payments] << sub_payment_hash
101
+ end
102
+ end
103
+
104
+ def parse(body)
105
+ JSON.parse(body)
106
+ end
107
+
108
+ def commit(method, endpoint, parameters = {}, options = {})
109
+ begin
110
+ raw_response = ssl_request(method, url(endpoint), post_data(parameters), headers(endpoint))
111
+ response = parse(raw_response)
112
+ rescue ResponseError => e
113
+ raw_response = e.response.body
114
+ response = parse(raw_response)
115
+ end
116
+
117
+ Response.new(
118
+ success_from(response),
119
+ message_from(response),
120
+ response,
121
+ authorization: authorization_from(response),
122
+ avs_result: AVSResult.new(code: response['some_avs_response_key']),
123
+ cvv_result: CVVResult.new(response['some_cvv_response_key']),
124
+ test: test?,
125
+ error_code: error_code_from(response)
126
+ )
127
+ end
128
+
129
+ def headers(endpoint)
130
+ {
131
+ 'Content-Type' => 'application/json',
132
+ 'apikey' => endpoint == 'tokens' ? @options[:public_key] : @options[:private_key]
133
+ }
134
+ end
135
+
136
+ def url(action, options = {})
137
+ base_url = (test? ? test_url : live_url)
138
+
139
+ return "#{base_url}/#{action}"
140
+ end
141
+
142
+ def success_from(response)
143
+ response.dig('status') == 'approved' || response.dig('status') == 'active'
144
+ end
145
+
146
+ def message_from(response)
147
+ response.dig('status') || error_message(response) || response.dig('message')
148
+ end
149
+
150
+ def authorization_from(response)
151
+ return nil unless response.dig('id') || response.dig('bin')
152
+
153
+ "#{response.dig('id')}|#{response.dig('bin')}"
154
+ end
155
+
156
+ def post_data(parameters = {})
157
+ parameters.to_json
158
+ end
159
+
160
+ def error_code_from(response)
161
+ response.dig('error_type') unless success_from(response)
162
+ end
163
+
164
+ def error_message(response)
165
+ return error_code_from(response) unless validation_errors = response.dig('validation_errors')
166
+
167
+ validation_errors = validation_errors[0]
168
+
169
+ "#{validation_errors.dig('code')}: #{validation_errors.dig('param')}"
170
+ end
171
+ end
172
+ end
173
+ end
@@ -214,6 +214,7 @@ module ActiveMerchant #:nodoc:
214
214
  post[:metadata] = options[:metadata] if options[:metadata]
215
215
  post[:metadata] = {} if post[:metadata].nil?
216
216
  post[:metadata][:merchant_payment_code] = options[:order_id] if options[:order_id]
217
+ post[:processing_type] = options[:processing_type] if options[:processing_type]
217
218
  end
218
219
 
219
220
  def parse(body)
@@ -222,7 +223,8 @@ module ActiveMerchant #:nodoc:
222
223
 
223
224
  def commit(action, parameters)
224
225
  url = url_for((test? ? test_url : live_url), action, parameters)
225
- response = parse(ssl_request(HTTP_METHOD[action], url, post_data(action, parameters), { 'x-ebanx-client-user-agent': "ActiveMerchant/#{ActiveMerchant::VERSION}" }))
226
+
227
+ response = parse(ssl_request(HTTP_METHOD[action], url, post_data(action, parameters), headers(parameters)))
226
228
 
227
229
  success = success_from(action, response)
228
230
 
@@ -236,6 +238,19 @@ module ActiveMerchant #:nodoc:
236
238
  )
237
239
  end
238
240
 
241
+ def headers(params)
242
+ processing_type = params[:processing_type]
243
+ commit_headers = { 'x-ebanx-client-user-agent': "ActiveMerchant/#{ActiveMerchant::VERSION}" }
244
+
245
+ add_processing_type_to_commit_headers(commit_headers, processing_type) if processing_type == 'local'
246
+
247
+ commit_headers
248
+ end
249
+
250
+ def add_processing_type_to_commit_headers(commit_headers, processing_type)
251
+ commit_headers['x-ebanx-api-processing-type'] = processing_type
252
+ end
253
+
239
254
  def success_from(action, response)
240
255
  if %i[purchase capture refund].include?(action)
241
256
  response.try(:[], 'payment').try(:[], 'status') == 'CO'
@@ -298,7 +298,7 @@ module ActiveMerchant #:nodoc:
298
298
  xml.ssl_dynamic_dba options[:dba] if options.has_key?(:dba)
299
299
  xml.ssl_merchant_initiated_unscheduled merchant_initiated_unscheduled(options) if merchant_initiated_unscheduled(options)
300
300
  xml.ssl_add_token options[:add_recurring_token] if options.has_key?(:add_recurring_token)
301
- xml.ssl_token options[:ssl_token] if options.has_key?(:ssl_token)
301
+ xml.ssl_token options[:ssl_token] if options[:ssl_token]
302
302
  xml.ssl_customer_code options[:customer] if options.has_key?(:customer)
303
303
  xml.ssl_customer_number options[:customer_number] if options.has_key?(:customer_number)
304
304
  xml.ssl_entry_mode entry_mode(options) if entry_mode(options)
@@ -393,6 +393,7 @@ module ActiveMerchant #:nodoc:
393
393
 
394
394
  def commit(request)
395
395
  request = "xmldata=#{request}".delete('&')
396
+ store_action = request.match?('CCGETTOKEN')
396
397
 
397
398
  response = parse(ssl_post(test? ? self.test_url : self.live_url, request, headers))
398
399
  response = hash_html_decode(response)
@@ -402,7 +403,7 @@ module ActiveMerchant #:nodoc:
402
403
  response[:result_message] || response[:errorMessage],
403
404
  response,
404
405
  test: @options[:test] || test?,
405
- authorization: authorization_from(response),
406
+ authorization: authorization_from(response, store_action),
406
407
  error_code: response[:errorCode],
407
408
  avs_result: { code: response[:avs_response] },
408
409
  cvv_result: response[:cvv2_response],
@@ -428,7 +429,9 @@ module ActiveMerchant #:nodoc:
428
429
  response.deep_transform_keys { |key| key.gsub('ssl_', '').to_sym }
429
430
  end
430
431
 
431
- def authorization_from(response)
432
+ def authorization_from(response, store_action)
433
+ return response[:token] if store_action
434
+
432
435
  [response[:approval_code], response[:txn_id]].join(';')
433
436
  end
434
437
 
@@ -82,6 +82,19 @@ module ActiveMerchant #:nodoc:
82
82
  commit('CreditCardReturn', request, money)
83
83
  end
84
84
 
85
+ def credit(money, payment, options = {})
86
+ request = build_soap_request do |xml|
87
+ xml.CreditCardCredit(xmlns: 'https://transaction.elementexpress.com') do
88
+ add_credentials(xml)
89
+ add_payment_method(xml, payment)
90
+ add_transaction(xml, money, options)
91
+ add_terminal(xml, options)
92
+ end
93
+ end
94
+
95
+ commit('CreditCardCredit', request, money)
96
+ end
97
+
85
98
  def void(authorization, options = {})
86
99
  trans_id, trans_amount = split_authorization(authorization)
87
100
  options.merge!({ trans_id: trans_id, trans_amount: trans_amount, reversal_type: 'Full' })
@@ -186,9 +199,10 @@ module ActiveMerchant #:nodoc:
186
199
  xml.ReversalType options[:reversal_type] if options[:reversal_type]
187
200
  xml.TransactionID options[:trans_id] if options[:trans_id]
188
201
  xml.TransactionAmount amount(money.to_i) if money
189
- xml.MarketCode 'Default' if money
202
+ xml.MarketCode market_code(money, options) if options[:market_code] || money
190
203
  xml.ReferenceNumber options[:order_id] || SecureRandom.hex(20)
191
-
204
+ xml.TicketNumber options[:ticket_number] if options[:ticket_number]
205
+ xml.MerchantSuppliedTransactionId options[:merchant_supplied_transaction_id] if options[:merchant_supplied_transaction_id]
192
206
  xml.PaymentType options[:payment_type] if options[:payment_type]
193
207
  xml.SubmissionType options[:submission_type] if options[:submission_type]
194
208
  xml.DuplicateCheckDisableFlag options[:duplicate_check_disable_flag].to_s == 'true' ? 'True' : 'False' unless options[:duplicate_check_disable_flag].nil?
@@ -197,6 +211,10 @@ module ActiveMerchant #:nodoc:
197
211
  end
198
212
  end
199
213
 
214
+ def market_code(money, options)
215
+ options[:market_code] || 'Default'
216
+ end
217
+
200
218
  def add_terminal(xml, options)
201
219
  xml.terminal do
202
220
  xml.TerminalID options[:terminal_id] || '01'
@@ -1,11 +1,14 @@
1
1
  module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
3
  class GlobalCollectGateway < Gateway
4
+ class_attribute :preproduction_url
5
+
4
6
  self.display_name = 'GlobalCollect'
5
7
  self.homepage_url = 'http://www.globalcollect.com/'
6
8
 
7
9
  self.test_url = 'https://eu.sandbox.api-ingenico.com'
8
- self.live_url = 'https://api.globalcollect.com'
10
+ self.preproduction_url = 'https://world.preprod.api-ingenico.com'
11
+ self.live_url = 'https://world.api-ingenico.com'
9
12
 
10
13
  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
14
  self.default_currency = 'USD'
@@ -100,36 +103,126 @@ module ActiveMerchant #:nodoc:
100
103
  post['order']['references']['invoiceData'] = {
101
104
  'invoiceNumber' => options[:invoice]
102
105
  }
103
- add_airline_data(post, options) if options[:airline_data]
106
+ add_airline_data(post, options)
107
+ add_lodging_data(post, options)
104
108
  add_number_of_installments(post, options) if options[:number_of_installments]
105
109
  end
106
110
 
107
111
  def add_airline_data(post, options)
112
+ return unless airline_options = options[:airline_data]
113
+
108
114
  airline_data = {}
109
115
 
110
- flight_date = options[:airline_data][:flight_date]
111
- passenger_name = options[:airline_data][:passenger_name]
112
- code = options[:airline_data][:code]
113
- name = options[:airline_data][:name]
116
+ airline_data['flightDate'] = airline_options[:flight_date] if airline_options[:flight_date]
117
+ airline_data['passengerName'] = airline_options[:passenger_name] if airline_options[:passenger_name]
118
+ airline_data['code'] = airline_options[:code] if airline_options[:code]
119
+ airline_data['name'] = airline_options[:name] if airline_options[:name]
120
+ airline_data['invoiceNumber'] = options[:airline_data][:invoice_number] if options[:airline_data][:invoice_number]
121
+ airline_data['isETicket'] = options[:airline_data][:is_eticket] if options[:airline_data][:is_eticket]
122
+ airline_data['isRestrictedTicket'] = options[:airline_data][:is_restricted_ticket] if options[:airline_data][:is_restricted_ticket]
123
+ airline_data['isThirdParty'] = options[:airline_data][:is_third_party] if options[:airline_data][:is_third_party]
124
+ airline_data['issueDate'] = options[:airline_data][:issue_date] if options[:airline_data][:issue_date]
125
+ airline_data['merchantCustomerId'] = options[:airline_data][:merchant_customer_id] if options[:airline_data][:merchant_customer_id]
126
+ airline_data['flightLegs'] = add_flight_legs(airline_options)
127
+ airline_data['passengers'] = add_passengers(airline_options)
114
128
 
115
- airline_data['flightDate'] = flight_date if flight_date
116
- airline_data['passengerName'] = passenger_name if passenger_name
117
- airline_data['code'] = code if code
118
- airline_data['name'] = name if name
129
+ post['order']['additionalInput']['airlineData'] = airline_data
130
+ end
119
131
 
132
+ def add_flight_legs(airline_options)
120
133
  flight_legs = []
121
- options[:airline_data][:flight_legs]&.each do |fl|
134
+ airline_options[:flight_legs]&.each do |fl|
122
135
  leg = {}
136
+ leg['airlineClass'] = fl[:airline_class] if fl[:airline_class]
123
137
  leg['arrivalAirport'] = fl[:arrival_airport] if fl[:arrival_airport]
124
- leg['originAirport'] = fl[:origin_airport] if fl[:origin_airport]
138
+ leg['arrivalTime'] = fl[:arrival_time] if fl[:arrival_time]
139
+ leg['carrierCode'] = fl[:carrier_code] if fl[:carrier_code]
140
+ leg['conjunctionTicket'] = fl[:conjunction_ticket] if fl[:conjunction_ticket]
141
+ leg['couponNumber'] = fl[:coupon_number] if fl[:coupon_number]
125
142
  leg['date'] = fl[:date] if fl[:date]
143
+ leg['departureTime'] = fl[:departure_time] if fl[:departure_time]
144
+ leg['endorsementOrRestriction'] = fl[:endorsement_or_restriction] if fl[:endorsement_or_restriction]
145
+ leg['exchangeTicket'] = fl[:exchange_ticket] if fl[:exchange_ticket]
146
+ leg['fare'] = fl[:fare] if fl[:fare]
147
+ leg['fareBasis'] = fl[:fare_basis] if fl[:fare_basis]
148
+ leg['fee'] = fl[:fee] if fl[:fee]
149
+ leg['flightNumber'] = fl[:flight_number] if fl[:flight_number]
126
150
  leg['number'] = fl[:number] if fl[:number]
127
- leg['carrierCode'] = fl[:carrier_code] if fl[:carrier_code]
128
- leg['airlineClass'] = fl[:carrier_code] if fl[:airline_class]
151
+ leg['originAirport'] = fl[:origin_airport] if fl[:origin_airport]
152
+ leg['passengerClass'] = fl[:passenger_class] if fl[:passenger_class]
153
+ leg['stopoverCode'] = fl[:stopover_code] if fl[:stopover_code]
154
+ leg['taxes'] = fl[:taxes] if fl[:taxes]
129
155
  flight_legs << leg
130
156
  end
131
- airline_data['flightLegs'] = flight_legs
132
- post['order']['additionalInput']['airlineData'] = airline_data
157
+ flight_legs
158
+ end
159
+
160
+ def add_passengers(airline_options)
161
+ passengers = []
162
+ airline_options[:passengers]&.each do |flyer|
163
+ passenger = {}
164
+ passenger['firstName'] = flyer[:first_name] if flyer[:first_name]
165
+ passenger['surname'] = flyer[:surname] if flyer[:surname]
166
+ passenger['surnamePrefix'] = flyer[:surname_prefix] if flyer[:surname_prefix]
167
+ passenger['title'] = flyer[:title] if flyer[:title]
168
+ passengers << passenger
169
+ end
170
+ passengers
171
+ end
172
+
173
+ def add_lodging_data(post, options)
174
+ return unless lodging_options = options[:lodging_data]
175
+
176
+ lodging_data = {}
177
+
178
+ lodging_data['charges'] = add_charges(lodging_options)
179
+ lodging_data['checkInDate'] = lodging_options[:check_in_date] if lodging_options[:check_in_date]
180
+ lodging_data['checkOutDate'] = lodging_options[:check_out_date] if lodging_options[:check_out_date]
181
+ lodging_data['folioNumber'] = lodging_options[:folio_number] if lodging_options[:folio_number]
182
+ lodging_data['isConfirmedReservation'] = lodging_options[:is_confirmed_reservation] if lodging_options[:is_confirmed_reservation]
183
+ lodging_data['isFacilityFireSafetyConform'] = lodging_options[:is_facility_fire_safety_conform] if lodging_options[:is_facility_fire_safety_conform]
184
+ lodging_data['isNoShow'] = lodging_options[:is_no_show] if lodging_options[:is_no_show]
185
+ lodging_data['isPreferenceSmokingRoom'] = lodging_options[:is_preference_smoking_room] if lodging_options[:is_preference_smoking_room]
186
+ lodging_data['numberOfAdults'] = lodging_options[:number_of_adults] if lodging_options[:number_of_adults]
187
+ lodging_data['numberOfNights'] = lodging_options[:number_of_nights] if lodging_options[:number_of_nights]
188
+ lodging_data['numberOfRooms'] = lodging_options[:number_of_rooms] if lodging_options[:number_of_rooms]
189
+ lodging_data['programCode'] = lodging_options[:program_code] if lodging_options[:program_code]
190
+ lodging_data['propertyCustomerServicePhoneNumber'] = lodging_options[:property_customer_service_phone_number] if lodging_options[:property_customer_service_phone_number]
191
+ lodging_data['propertyPhoneNumber'] = lodging_options[:property_phone_number] if lodging_options[:property_phone_number]
192
+ lodging_data['renterName'] = lodging_options[:renter_name] if lodging_options[:renter_name]
193
+ lodging_data['rooms'] = add_rooms(lodging_options)
194
+
195
+ post['order']['additionalInput']['lodgingData'] = lodging_data
196
+ end
197
+
198
+ def add_charges(lodging_options)
199
+ charges = []
200
+ lodging_options[:charges]&.each do |item|
201
+ charge = {}
202
+ charge['chargeAmount'] = item[:charge_amount] if item[:charge_amount]
203
+ charge['chargeAmountCurrencyCode'] = item[:charge_amount_currency_code] if item[:charge_amount_currency_code]
204
+ charge['chargeType'] = item[:charge_type] if item[:charge_type]
205
+ charges << charge
206
+ end
207
+ charges
208
+ end
209
+
210
+ def add_rooms(lodging_options)
211
+ rooms = []
212
+ lodging_options[:rooms]&.each do |item|
213
+ room = {}
214
+ room['dailyRoomRate'] = item[:daily_room_rate] if item[:daily_room_rate]
215
+ room['dailyRoomRateCurrencyCode'] = item[:daily_room_rate_currency_code] if item[:daily_room_rate_currency_code]
216
+ room['dailyRoomTaxAmount'] = item[:daily_room_tax_amount] if item[:daily_room_tax_amount]
217
+ room['dailyRoomTaxAmountCurrencyCode'] = item[:daily_room_tax_amount_currency_code] if item[:daily_room_tax_amount_currency_code]
218
+ room['numberOfNightsAtRoomRate'] = item[:number_of_nights_at_room_rate] if item[:number_of_nights_at_room_rate]
219
+ room['roomLocation'] = item[:room_location] if item[:room_location]
220
+ room['roomNumber'] = item[:room_number] if item[:room_number]
221
+ room['typeOfBed'] = item[:type_of_bed] if item[:type_of_bed]
222
+ room['typeOfRoom'] = item[:type_of_room] if item[:type_of_room]
223
+ rooms << room
224
+ end
225
+ rooms
133
226
  end
134
227
 
135
228
  def add_creator_info(post, options)
@@ -260,6 +353,8 @@ module ActiveMerchant #:nodoc:
260
353
  end
261
354
 
262
355
  def url(action, authorization)
356
+ return preproduction_url + uri(action, authorization) if @options[:url_override].to_s == 'preproduction'
357
+
263
358
  (test? ? test_url : live_url) + uri(action, authorization)
264
359
  end
265
360