activemerchant 1.129.0 → 1.130.0

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: 415c09ab9b38e3503d10b38cd42959b50c131f8b47237f39b36a8da7bc044d82
4
- data.tar.gz: 2b2cdd2955bd0ed6e2b808cad4fa31888749ee6cbe91b2a75c563f1cc09429d6
3
+ metadata.gz: 68d19e25c325eedb9f632b67713bd61ec67f09794560add0c22ba7b45c33cda6
4
+ data.tar.gz: 3c9405afcad2c9d066b76f1ad055d264e55569c14d9b9e322e2c6d3d83867b29
5
5
  SHA512:
6
- metadata.gz: 104444c88b66340a16502ae980ae4c2795f25cd8f9d3a78a05d636d55730a462d9ead8a565291774096dd3fa75149961f64ec472d2a74c7499ce6b472ec6de95
7
- data.tar.gz: bc738912b2788963721d232e43cf02675cc6a672c7aca913c6bd876fd73b72fd0cd0b7d43e734dca7f5494957e9092e8054d75b788b59ef3a2ca25a917d3d949
6
+ metadata.gz: e5c803983440bd24cbadd24fc5c689061ece449436010f3ad2f328dd3bdbaf2cc3c68c43dae86482f4fee84de454d2e626b89bacf54ad67468285410d8860610
7
+ data.tar.gz: 77458ab3d685b3ea7b7f3f1a26617d201eb071ef540414e6934677a1541166bbd68b132bc5f980dbf60656058d97877e70c907ab950b2314a2cfcf205e9e2de3
data/CHANGELOG CHANGED
@@ -3,7 +3,29 @@
3
3
 
4
4
  == HEAD
5
5
 
6
- == Version 1.129.0 (April 24th, 2023)
6
+ == Version 1.130.0 (June 13th, 2023)
7
+ * Payu Latam - Update error code method to surface network code [yunnydang] #4773
8
+ * CyberSource: Handling Canadian bank accounts [heavyblade] #4764
9
+ * CyberSource Rest: Fixing currency detection [heavyblade] #4777
10
+ * CyberSource: Allow business rules for requests with network tokens [aenand] #4764
11
+ * Adyen: Update Mastercard error messaging [kylene-spreedly] #4770
12
+ * Authorize.net: Update mapping for billing address phone number [jcreiff] #4778
13
+ * Braintree: Update mapping for billing address phone number [jcreiff] #4779
14
+ * CommerceHub: Enabling multi-use public key encryption [jherreraa] #4771
15
+ * Ogone: Enable 3ds Global for Ogone Gateway [javierpedrozaing] #4776
16
+ * Worldpay: Fix Google Pay [almalee24] #4774
17
+ * Borgun change default TrCurrencyExponent and MerchantReturnUrl [naashton] #4788
18
+ * Borgun: support for GBP currency [naashton] #4789
19
+ * CyberSource: Enable auto void on r230 [aenand] #4794
20
+ * Redsys: Set appropriate request fields for stored credentials with CITs and MITs [BritneyS] #4784
21
+ * Stripe & Stripe PI: Validate API Key [almalee24] #4801
22
+ * Add BIN for Maestro [jcreiff] #4799
23
+ * D_Local: Add save field on card object [yunnydang] #4805
24
+ * PayPal Express: Adds support for MsgSubID property on DoReferenceTransaction and DoExpressCheckoutPayment [wikiti] #4798
25
+ * Checkout_v2: use credit_card?, not case equality with CreditCard [bbraschi] #4803
26
+ * Shift4: Enable general credit feature [jherreraa] #4790
27
+
28
+ == Version 1.129.0 (May 3rd, 2023)
7
29
  * Adyen: Update selectedBrand mapping for Google Pay [jcreiff] #4763
8
30
  * Shift4: Add vendorReference field [jcreiff] #4762
9
31
  * Shift4: Add OAuth error [aenand] #4760
@@ -109,7 +109,7 @@ module ActiveMerchant #:nodoc:
109
109
  MAESTRO_BINS = Set.new(
110
110
  %w[ 500057
111
111
  501018 501043 501045 501047 501049 501051 501072 501075 501083 501087 501089 501095
112
- 501500
112
+ 501500 501623
113
113
  501879 502113 502120 502121 502301
114
114
  503175 503337 503645 503670
115
115
  504310 504338 504363 504533 504587 504620 504639 504656 504738 504781 504910
@@ -703,8 +703,8 @@ module ActiveMerchant #:nodoc:
703
703
  end
704
704
 
705
705
  def authorize_message_from(response)
706
- if response['refusalReason'] && response['additionalData'] && response['additionalData']['refusalReasonRaw']
707
- "#{response['refusalReason']} | #{response['additionalData']['refusalReasonRaw']}"
706
+ if response['refusalReason'] && response['additionalData'] && (response['additionalData']['merchantAdviceCode'] || response['additionalData']['refusalReasonRaw'])
707
+ "#{response['refusalReason']} | #{response['additionalData']['merchantAdviceCode'] || response['additionalData']['refusalReasonRaw']}"
708
708
  else
709
709
  response['refusalReason'] || response['resultCode'] || response['message'] || response['result']
710
710
  end
@@ -604,6 +604,7 @@ module ActiveMerchant
604
604
  first_name, last_name = names_from(payment_source, address, options)
605
605
  state = state_from(address, options)
606
606
  full_address = "#{address[:address1]} #{address[:address2]}".strip
607
+ phone = address[:phone] || address[:phone_number] || ''
607
608
 
608
609
  xml.firstName(truncate(first_name, 50)) unless empty?(first_name)
609
610
  xml.lastName(truncate(last_name, 50)) unless empty?(last_name)
@@ -613,7 +614,7 @@ module ActiveMerchant
613
614
  xml.state(truncate(state, 40))
614
615
  xml.zip(truncate((address[:zip] || options[:zip]), 20))
615
616
  xml.country(truncate(address[:country], 60))
616
- xml.phoneNumber(truncate(address[:phone], 25)) unless empty?(address[:phone])
617
+ xml.phoneNumber(truncate(phone, 25)) unless empty?(phone)
617
618
  xml.faxNumber(truncate(address[:fax], 25)) unless empty?(address[:fax])
618
619
  end
619
620
  end
@@ -96,6 +96,7 @@ module ActiveMerchant #:nodoc:
96
96
  CURRENCY_CODES['ISK'] = '352'
97
97
  CURRENCY_CODES['EUR'] = '978'
98
98
  CURRENCY_CODES['USD'] = '840'
99
+ CURRENCY_CODES['GBP'] = '826'
99
100
 
100
101
  def add_3ds_fields(post, options)
101
102
  post[:ThreeDSMessageId] = options[:three_ds_message_id] if options[:three_ds_message_id]
@@ -105,17 +106,17 @@ module ActiveMerchant #:nodoc:
105
106
 
106
107
  def add_3ds_preauth_fields(post, options)
107
108
  post[:SaleDescription] = options[:sale_description] || ''
108
- post[:MerchantReturnURL] = options[:merchant_return_url] if options[:merchant_return_url]
109
+ post[:MerchantReturnURL] = options[:redirect_url] if options[:redirect_url]
109
110
  end
110
111
 
111
112
  def add_invoice(post, money, options)
112
113
  post[:TrAmount] = amount(money)
113
114
  post[:TrCurrency] = CURRENCY_CODES[options[:currency] || currency(money)]
114
115
  # The ISK currency must have a currency exponent of 2 on the 3DS request but not on the auth request
115
- if post[:TrCurrency] == '352' && options[:apply_3d_secure] == '1'
116
- post[:TrCurrencyExponent] = 2
117
- else
116
+ if post[:TrCurrency] == '352' && options[:apply_3d_secure] != '1'
118
117
  post[:TrCurrencyExponent] = 0
118
+ else
119
+ post[:TrCurrencyExponent] = 2
119
120
  end
120
121
  post[:TerminalID] = options[:terminal_id] || '1'
121
122
  end
@@ -197,8 +197,7 @@ module ActiveMerchant #:nodoc:
197
197
  first_name: creditcard.first_name,
198
198
  last_name: creditcard.last_name,
199
199
  email: scrub_email(options[:email]),
200
- phone: options[:phone] || (options[:billing_address][:phone] if options[:billing_address] &&
201
- options[:billing_address][:phone]),
200
+ phone: phone_from(options),
202
201
  credit_card: credit_card_params)
203
202
  Response.new(result.success?, message_from_result(result),
204
203
  braintree_customer: (customer_hash(@braintree_gateway.customer.find(vault_id), :include_credit_cards) if result.success?),
@@ -267,8 +266,7 @@ module ActiveMerchant #:nodoc:
267
266
  first_name: creditcard.first_name,
268
267
  last_name: creditcard.last_name,
269
268
  email: scrub_email(options[:email]),
270
- phone: options[:phone] || (options[:billing_address][:phone] if options[:billing_address] &&
271
- options[:billing_address][:phone]),
269
+ phone: phone_from(options),
272
270
  id: options[:customer],
273
271
  device_data: options[:device_data]
274
272
  }.merge credit_card_params
@@ -348,6 +346,10 @@ module ActiveMerchant #:nodoc:
348
346
  parameters
349
347
  end
350
348
 
349
+ def phone_from(options)
350
+ options[:phone] || options.dig(:billing_address, :phone) || options.dig(:billing_address, :phone_number)
351
+ end
352
+
351
353
  def map_address(address)
352
354
  mapped = {
353
355
  street_address: address[:address1],
@@ -628,8 +630,7 @@ module ActiveMerchant #:nodoc:
628
630
  customer: {
629
631
  id: options[:store] == true ? '' : options[:store],
630
632
  email: scrub_email(options[:email]),
631
- phone: options[:phone] || (options[:billing_address][:phone] if options[:billing_address] &&
632
- options[:billing_address][:phone])
633
+ phone: phone_from(options)
633
634
  },
634
635
  options: {
635
636
  store_in_vault: options[:store] ? true : false,
@@ -932,7 +933,7 @@ module ActiveMerchant #:nodoc:
932
933
  first_name: payment_method.first_name,
933
934
  last_name: payment_method.last_name,
934
935
  email: scrub_email(options[:email]),
935
- phone: options[:phone] || options.dig(:billing_address, :phone),
936
+ phone: phone_from(options),
936
937
  device_data: options[:device_data]
937
938
  }.compact
938
939
 
@@ -185,7 +185,7 @@ module ActiveMerchant #:nodoc:
185
185
  post[key][:token_type] = token_type
186
186
  post[key][:cryptogram] = cryptogram if cryptogram
187
187
  post[key][:eci] = eci if eci
188
- when CreditCard
188
+ when ->(pm) { pm.try(:credit_card?) }
189
189
  post[key][:type] = 'card'
190
190
  post[key][:name] = payment_method.name
191
191
  post[key][:number] = payment_method.number
@@ -114,7 +114,7 @@ module ActiveMerchant #:nodoc:
114
114
  post[:transactionInteraction][:origin] = options[:origin] || 'ECOM'
115
115
  post[:transactionInteraction][:eciIndicator] = options[:eci_indicator] || 'CHANNEL_ENCRYPTED'
116
116
  post[:transactionInteraction][:posConditionCode] = options[:pos_condition_code] || 'CARD_NOT_PRESENT_ECOM'
117
- post[:transactionInteraction][:posEntryMode] = options[:pos_entry_mode] || 'MANUAL'
117
+ post[:transactionInteraction][:posEntryMode] = (options[:pos_entry_mode] || 'MANUAL') unless options[:encryption_data].present?
118
118
  post[:transactionInteraction][:additionalPosInformation] = {}
119
119
  post[:transactionInteraction][:additionalPosInformation][:dataEntrySource] = options[:data_entry_source] || 'UNSPECIFIED'
120
120
  end
@@ -256,7 +256,12 @@ module ActiveMerchant #:nodoc:
256
256
  when NetworkTokenizationCreditCard
257
257
  add_decrypted_wallet(source, payment, options)
258
258
  when CreditCard
259
- add_credit_card(source, payment, options)
259
+ if options[:encryption_data].present?
260
+ source[:sourceType] = 'PaymentCard'
261
+ source[:encryptionData] = options[:encryption_data]
262
+ else
263
+ add_credit_card(source, payment, options)
264
+ end
260
265
  when String
261
266
  add_payment_token(source, payment, options)
262
267
  end
@@ -519,11 +519,9 @@ module ActiveMerchant #:nodoc:
519
519
  def add_business_rules_data(xml, payment_method, options)
520
520
  prioritized_options = [options, @options]
521
521
 
522
- unless network_tokenization?(payment_method)
523
- xml.tag! 'businessRules' do
524
- xml.tag!('ignoreAVSResult', 'true') if extract_option(prioritized_options, :ignore_avs).to_s == 'true'
525
- xml.tag!('ignoreCVResult', 'true') if extract_option(prioritized_options, :ignore_cvv).to_s == 'true'
526
- end
522
+ xml.tag! 'businessRules' do
523
+ xml.tag!('ignoreAVSResult', 'true') if extract_option(prioritized_options, :ignore_avs).to_s == 'true'
524
+ xml.tag!('ignoreCVResult', 'true') if extract_option(prioritized_options, :ignore_cvv).to_s == 'true'
527
525
  end
528
526
  end
529
527
 
@@ -705,8 +703,8 @@ module ActiveMerchant #:nodoc:
705
703
  def add_check(xml, check, options)
706
704
  xml.tag! 'check' do
707
705
  xml.tag! 'accountNumber', check.account_number
708
- xml.tag! 'accountType', check.account_type[0]
709
- xml.tag! 'bankTransitNumber', check.routing_number
706
+ xml.tag! 'accountType', check.account_type == 'checking' ? 'C' : 'S'
707
+ xml.tag! 'bankTransitNumber', format_routing_number(check.routing_number, options)
710
708
  xml.tag! 'secCode', options[:sec_code] if options[:sec_code]
711
709
  end
712
710
  end
@@ -1055,6 +1053,8 @@ module ActiveMerchant #:nodoc:
1055
1053
  message = message_from(response)
1056
1054
  authorization = success || in_fraud_review?(response) ? authorization_from(response, action, amount, options) : nil
1057
1055
 
1056
+ message = auto_void?(authorization_from(response, action, amount, options), response, message, options)
1057
+
1058
1058
  Response.new(success, message, response,
1059
1059
  test: test?,
1060
1060
  authorization: authorization,
@@ -1063,6 +1063,14 @@ module ActiveMerchant #:nodoc:
1063
1063
  cvv_result: response[:cvCode])
1064
1064
  end
1065
1065
 
1066
+ def auto_void?(authorization, response, message, options = {})
1067
+ return message unless response[:reasonCode] == '230' && options[:auto_void_230]
1068
+
1069
+ response = void(authorization, options)
1070
+ response&.success? ? message += ' - transaction has been auto-voided.' : message += ' - transaction could not be auto-voided.'
1071
+ message
1072
+ end
1073
+
1066
1074
  # Parse the SOAP response
1067
1075
  # Technique inspired by the Paypal Gateway
1068
1076
  def parse(xml)
@@ -1131,6 +1139,10 @@ module ActiveMerchant #:nodoc:
1131
1139
  def eligible_for_zero_auth?(payment_method, options = {})
1132
1140
  payment_method.is_a?(CreditCard) && options[:zero_amount_auth]
1133
1141
  end
1142
+
1143
+ def format_routing_number(routing_number, options)
1144
+ options[:currency] == 'CAD' && routing_number.length > 8 ? routing_number[-8..-1] : routing_number
1145
+ end
1134
1146
  end
1135
1147
  end
1136
1148
  end
@@ -112,7 +112,7 @@ module ActiveMerchant #:nodoc:
112
112
  add_code(post, options)
113
113
  add_payment(post, payment, options)
114
114
  add_mdd_fields(post, options)
115
- add_amount(post, amount)
115
+ add_amount(post, amount, options)
116
116
  add_address(post, payment, options[:billing_address], options, :billTo)
117
117
  add_address(post, payment, options[:shipping_address], options, :shipTo)
118
118
  add_business_rules_data(post, payment, options)
@@ -125,7 +125,7 @@ module ActiveMerchant #:nodoc:
125
125
  { clientReferenceInformation: {}, orderInformation: {} }.tap do |post|
126
126
  add_code(post, options)
127
127
  add_mdd_fields(post, options)
128
- add_amount(post, amount)
128
+ add_amount(post, amount, options)
129
129
  add_partner_solution_id(post)
130
130
  end.compact
131
131
  end
@@ -135,7 +135,7 @@ module ActiveMerchant #:nodoc:
135
135
  add_code(post, options)
136
136
  add_credit_card(post, payment)
137
137
  add_mdd_fields(post, options)
138
- add_amount(post, amount)
138
+ add_amount(post, amount, options)
139
139
  add_address(post, payment, options[:billing_address], options, :billTo)
140
140
  add_merchant_description(post, options)
141
141
  end.compact
@@ -161,7 +161,7 @@ module ActiveMerchant #:nodoc:
161
161
  }
162
162
  end
163
163
 
164
- def add_amount(post, amount)
164
+ def add_amount(post, amount, options)
165
165
  currency = options[:currency] || currency(amount)
166
166
  post[:orderInformation][:amountDetails] = {
167
167
  totalAmount: localized_amount(amount, currency),
@@ -413,10 +413,8 @@ module ActiveMerchant #:nodoc:
413
413
 
414
414
  def add_business_rules_data(post, payment, options)
415
415
  post[:processingInformation][:authorizationOptions] = {}
416
- unless payment.is_a?(NetworkTokenizationCreditCard)
417
- post[:processingInformation][:authorizationOptions][:ignoreAvsResult] = 'true' if options[:ignore_avs].to_s == 'true'
418
- post[:processingInformation][:authorizationOptions][:ignoreCvResult] = 'true' if options[:ignore_cvv].to_s == 'true'
419
- end
416
+ post[:processingInformation][:authorizationOptions][:ignoreAvsResult] = 'true' if options[:ignore_avs].to_s == 'true'
417
+ post[:processingInformation][:authorizationOptions][:ignoreCvResult] = 'true' if options[:ignore_cvv].to_s == 'true'
420
418
  end
421
419
 
422
420
  def add_mdd_fields(post, options)
@@ -188,6 +188,7 @@ module ActiveMerchant #:nodoc:
188
188
  post[:card][:installments] = options[:installments] if options[:installments]
189
189
  post[:card][:installments_id] = options[:installments_id] if options[:installments_id]
190
190
  post[:card][:force_type] = options[:force_type].to_s.upcase if options[:force_type]
191
+ post[:card][:save] = options[:save] if options[:save]
191
192
  end
192
193
 
193
194
  def parse(body)
@@ -2,6 +2,8 @@ module ActiveMerchant #:nodoc:
2
2
  module Billing #:nodoc:
3
3
  class GlobalCollectGateway < Gateway
4
4
  class_attribute :preproduction_url
5
+ class_attribute :ogone_direct_test
6
+ class_attribute :ogone_direct_live
5
7
 
6
8
  self.display_name = 'GlobalCollect'
7
9
  self.homepage_url = 'http://www.globalcollect.com/'
@@ -9,6 +11,8 @@ module ActiveMerchant #:nodoc:
9
11
  self.test_url = 'https://eu.sandbox.api-ingenico.com'
10
12
  self.preproduction_url = 'https://world.preprod.api-ingenico.com'
11
13
  self.live_url = 'https://world.api-ingenico.com'
14
+ self.ogone_direct_test = 'https://payment.preprod.direct.worldline-solutions.com'
15
+ self.ogone_direct_live = 'https://payment.direct.worldline-solutions.com'
12
16
 
13
17
  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]
14
18
  self.default_currency = 'USD'
@@ -114,7 +118,7 @@ module ActiveMerchant #:nodoc:
114
118
  post['order']['references']['invoiceData'] = {
115
119
  'invoiceNumber' => options[:invoice]
116
120
  }
117
- add_airline_data(post, options)
121
+ add_airline_data(post, options) unless ogone_direct?
118
122
  add_lodging_data(post, options)
119
123
  add_number_of_installments(post, options) if options[:number_of_installments]
120
124
  end
@@ -248,9 +252,10 @@ module ActiveMerchant #:nodoc:
248
252
  end
249
253
 
250
254
  def add_amount(post, money, options = {})
255
+ currency_ogone = 'EUR' if ogone_direct?
251
256
  post['amountOfMoney'] = {
252
257
  'amount' => amount(money),
253
- 'currencyCode' => options[:currency] || currency(money)
258
+ 'currencyCode' => options[:currency] || currency_ogone || currency(money)
254
259
  }
255
260
  end
256
261
 
@@ -262,7 +267,7 @@ module ActiveMerchant #:nodoc:
262
267
  product_id = options[:payment_product_id] || BRAND_MAP[payment.brand]
263
268
  specifics_inputs = {
264
269
  'paymentProductId' => product_id,
265
- 'skipAuthentication' => 'true', # refers to 3DSecure
270
+ 'skipAuthentication' => options[:skip_authentication] || 'true', # refers to 3DSecure
266
271
  'skipFraudService' => 'true',
267
272
  'authorizationMode' => pre_authorization
268
273
  }
@@ -377,18 +382,24 @@ module ActiveMerchant #:nodoc:
377
382
  def add_external_cardholder_authentication_data(post, options)
378
383
  return unless threeds_2_options = options[:three_d_secure]
379
384
 
380
- authentication_data = {}
381
- authentication_data[:acsTransactionId] = threeds_2_options[:acs_transaction_id] if threeds_2_options[:acs_transaction_id]
382
- authentication_data[:cavv] = threeds_2_options[:cavv] if threeds_2_options[:cavv]
383
- authentication_data[:cavvAlgorithm] = threeds_2_options[:cavv_algorithm] if threeds_2_options[:cavv_algorithm]
384
- authentication_data[:directoryServerTransactionId] = threeds_2_options[:ds_transaction_id] if threeds_2_options[:ds_transaction_id]
385
- authentication_data[:eci] = threeds_2_options[:eci] if threeds_2_options[:eci]
386
- authentication_data[:threeDSecureVersion] = threeds_2_options[:version] if threeds_2_options[:version]
387
- authentication_data[:validationResult] = threeds_2_options[:authentication_response_status] if threeds_2_options[:authentication_response_status]
388
- authentication_data[:xid] = threeds_2_options[:xid] if threeds_2_options[:xid]
385
+ authentication_data = {
386
+ priorThreeDSecureData: { acsTransactionId: threeds_2_options[:acs_transaction_id] }.compact,
387
+ cavv: threeds_2_options[:cavv],
388
+ cavvAlgorithm: threeds_2_options[:cavv_algorithm],
389
+ directoryServerTransactionId: threeds_2_options[:ds_transaction_id],
390
+ eci: threeds_2_options[:eci],
391
+ threeDSecureVersion: threeds_2_options[:version] || options[:three_ds_version],
392
+ validationResult: threeds_2_options[:authentication_response_status],
393
+ xid: threeds_2_options[:xid],
394
+ acsTransactionId: threeds_2_options[:acs_transaction_id],
395
+ flow: threeds_2_options[:flow]
396
+ }.compact
389
397
 
390
398
  post['cardPaymentMethodSpecificInput'] ||= {}
391
399
  post['cardPaymentMethodSpecificInput']['threeDSecure'] ||= {}
400
+ post['cardPaymentMethodSpecificInput']['threeDSecure']['merchantFraudRate'] = threeds_2_options[:merchant_fraud_rate]
401
+ post['cardPaymentMethodSpecificInput']['threeDSecure']['exemptionRequest'] = threeds_2_options[:exemption_request]
402
+ post['cardPaymentMethodSpecificInput']['threeDSecure']['secureCorporatePayment'] = threeds_2_options[:secure_corporate_payment]
392
403
  post['cardPaymentMethodSpecificInput']['threeDSecure']['externalCardholderAuthenticationData'] = authentication_data unless authentication_data.empty?
393
404
  end
394
405
 
@@ -402,17 +413,28 @@ module ActiveMerchant #:nodoc:
402
413
 
403
414
  def url(action, authorization)
404
415
  return preproduction_url + uri(action, authorization) if @options[:url_override].to_s == 'preproduction'
416
+ return ogone_direct_url(action, authorization) if ogone_direct?
405
417
 
406
418
  (test? ? test_url : live_url) + uri(action, authorization)
407
419
  end
408
420
 
421
+ def ogone_direct_url(action, authorization)
422
+ (test? ? ogone_direct_test : ogone_direct_live) + uri(action, authorization)
423
+ end
424
+
425
+ def ogone_direct?
426
+ @options[:url_override].to_s == 'ogone_direct'
427
+ end
428
+
409
429
  def uri(action, authorization)
410
- uri = "/v1/#{@options[:merchant_id]}/"
430
+ version = ogone_direct? ? 'v2' : 'v1'
431
+ uri = "/#{version}/#{@options[:merchant_id]}/"
411
432
  case action
412
433
  when :authorize
413
434
  uri + 'payments'
414
435
  when :capture
415
- uri + "payments/#{authorization}/approve"
436
+ capture_name = ogone_direct? ? 'capture' : 'approve'
437
+ uri + "payments/#{authorization}/#{capture_name}"
416
438
  when :refund
417
439
  uri + "payments/#{authorization}/refund"
418
440
  when :void
@@ -423,7 +445,7 @@ module ActiveMerchant #:nodoc:
423
445
  end
424
446
 
425
447
  def idempotency_key_for_signature(options)
426
- "x-gcs-idempotence-key:#{options[:idempotency_key]}" if options[:idempotency_key]
448
+ "x-gcs-idempotence-key:#{options[:idempotency_key]}" if options[:idempotency_key] && !ogone_direct?
427
449
  end
428
450
 
429
451
  def commit(method, action, post, authorization: nil, options: {})
@@ -461,7 +483,7 @@ module ActiveMerchant #:nodoc:
461
483
  'Date' => date
462
484
  }
463
485
 
464
- headers['X-GCS-Idempotence-Key'] = options[:idempotency_key] if options[:idempotency_key]
486
+ headers['X-GCS-Idempotence-Key'] = options[:idempotency_key] if options[:idempotency_key] && !ogone_direct?
465
487
  headers
466
488
  end
467
489
 
@@ -474,13 +496,13 @@ module ActiveMerchant #:nodoc:
474
496
  #{uri(action, authorization)}
475
497
  REQUEST
476
498
  data = data.each_line.reject { |line| line.strip == '' }.join
477
- digest = OpenSSL::Digest.new('sha256')
499
+ digest = OpenSSL::Digest.new('SHA256')
478
500
  key = @options[:secret_api_key]
479
- "GCS v1HMAC:#{@options[:api_key_id]}:#{Base64.strict_encode64(OpenSSL::HMAC.digest(digest, key, data))}"
501
+ "GCS v1HMAC:#{@options[:api_key_id]}:#{Base64.strict_encode64(OpenSSL::HMAC.digest(digest, key, data)).strip}"
480
502
  end
481
503
 
482
504
  def date
483
- @date ||= Time.now.gmtime.strftime('%a, %d %b %Y %H:%M:%S %Z') # Must be same in digest and HTTP header
505
+ @date ||= Time.now.gmtime.strftime('%a, %d %b %Y %H:%M:%S GMT')
484
506
  end
485
507
 
486
508
  def content_type
@@ -108,6 +108,7 @@ module ActiveMerchant #:nodoc:
108
108
  xml.tag! 'n2:PaymentAction', action
109
109
  xml.tag! 'n2:Token', options[:token]
110
110
  xml.tag! 'n2:PayerID', options[:payer_id]
111
+ xml.tag! 'n2:MsgSubID', options[:idempotency_key] if options[:idempotency_key]
111
112
  add_payment_details(xml, money, currency_code, options)
112
113
  end
113
114
  end
@@ -251,6 +252,7 @@ module ActiveMerchant #:nodoc:
251
252
  add_payment_details(xml, money, currency_code, options)
252
253
  xml.tag! 'n2:IPAddress', options[:ip]
253
254
  xml.tag! 'n2:MerchantSessionId', options[:merchant_session_id] if options[:merchant_session_id].present?
255
+ xml.tag! 'n2:MsgSubID', options[:idempotency_key] if options[:idempotency_key]
254
256
  end
255
257
  end
256
258
  end
@@ -455,7 +455,7 @@ module ActiveMerchant #:nodoc:
455
455
  when 'verify_credentials'
456
456
  response['error'] || 'FAILED'
457
457
  else
458
- response['transactionResponse']['errorCode'] || response['transactionResponse']['responseCode'] if response['transactionResponse']
458
+ response['transactionResponse']['paymentNetworkResponseCode'] || response['transactionResponse']['errorCode'] if response['transactionResponse']
459
459
  end
460
460
  end
461
461
 
@@ -538,6 +538,7 @@ module ActiveMerchant #:nodoc:
538
538
  xml.DS_MERCHANT_COF_INI data[:DS_MERCHANT_COF_INI]
539
539
  xml.DS_MERCHANT_COF_TYPE data[:DS_MERCHANT_COF_TYPE]
540
540
  xml.DS_MERCHANT_COF_TXNID data[:DS_MERCHANT_COF_TXNID] if data[:DS_MERCHANT_COF_TXNID]
541
+ xml.DS_MERCHANT_DIRECTPAYMENT 'false' if options[:stored_credential][:initial_transaction]
541
542
  end
542
543
  end
543
544
  end
@@ -91,7 +91,7 @@ module ActiveMerchant #:nodoc:
91
91
  commit(action, post, options)
92
92
  end
93
93
 
94
- def refund(money, authorization, options = {})
94
+ def refund(money, payment_method, options = {})
95
95
  post = {}
96
96
  action = 'refund'
97
97
 
@@ -99,12 +99,15 @@ module ActiveMerchant #:nodoc:
99
99
  add_invoice(post, money, options)
100
100
  add_clerk(post, options)
101
101
  add_transaction(post, options)
102
- add_card(action, post, get_card_token(authorization), options)
102
+ card_token = payment_method.is_a?(CreditCard) ? get_card_token(payment_method) : payment_method
103
+ add_card(action, post, card_token, options)
103
104
  add_card_present(post, options)
104
105
 
105
106
  commit(action, post, options)
106
107
  end
107
108
 
109
+ alias credit refund
110
+
108
111
  def void(authorization, options = {})
109
112
  options[:invoice] = get_invoice(authorization)
110
113
  commit('invoice', {}, options)
@@ -652,18 +652,19 @@ module ActiveMerchant #:nodoc:
652
652
  end
653
653
  end
654
654
 
655
- def headers(options = {})
656
- key = options[:key] || @api_key
657
- idempotency_key = options[:idempotency_key]
655
+ def key(options = {})
656
+ options[:key] || @api_key
657
+ end
658
658
 
659
+ def headers(options = {})
659
660
  headers = {
660
- 'Authorization' => 'Basic ' + Base64.strict_encode64(key.to_s + ':').strip,
661
+ 'Authorization' => 'Basic ' + Base64.strict_encode64(key(options).to_s + ':').strip,
661
662
  'User-Agent' => "Stripe/v1 ActiveMerchantBindings/#{ActiveMerchant::VERSION}",
662
663
  'Stripe-Version' => api_version(options),
663
664
  'X-Stripe-Client-User-Agent' => stripe_client_user_agent(options),
664
665
  'X-Stripe-Client-User-Metadata' => { ip: options[:ip] }.to_json
665
666
  }
666
- headers['Idempotency-Key'] = idempotency_key if idempotency_key
667
+ headers['Idempotency-Key'] = options[:idempotency_key] if options[:idempotency_key]
667
668
  headers['Stripe-Account'] = options[:stripe_account] if options[:stripe_account]
668
669
  headers
669
670
  end
@@ -694,6 +695,9 @@ module ActiveMerchant #:nodoc:
694
695
 
695
696
  def commit(method, url, parameters = nil, options = {})
696
697
  add_expand_parameters(parameters, options) if parameters
698
+
699
+ return Response.new(false, 'Invalid API Key provided') if test? && !key(options).start_with?('sk_test')
700
+
697
701
  response = api_request(method, url, parameters, options)
698
702
  response['webhook_id'] = options[:webhook_id] if options[:webhook_id]
699
703
  success = success_from(response, options)
@@ -683,7 +683,8 @@ module ActiveMerchant #:nodoc:
683
683
  'year' => format(payment_method.year, :four_digits_year)
684
684
  )
685
685
  end
686
- xml.cardHolderName card_holder_name(payment_method, options)
686
+ name = card_holder_name(payment_method, options)
687
+ xml.cardHolderName name if name.present?
687
688
  xml.cvc payment_method.verification_value
688
689
 
689
690
  add_address(xml, (options[:billing_address] || options[:address]), options)
@@ -995,10 +996,10 @@ module ActiveMerchant #:nodoc:
995
996
  case payment_method
996
997
  when String
997
998
  token_type_and_details(payment_method)
998
- when NetworkTokenizationCreditCard
999
- { payment_type: :network_token }
1000
999
  else
1001
- { payment_type: :credit }
1000
+ type = payment_method.respond_to?(:source) ? :network_token : :credit
1001
+
1002
+ { payment_type: type }
1002
1003
  end
1003
1004
  end
1004
1005
 
@@ -1,3 +1,3 @@
1
1
  module ActiveMerchant
2
- VERSION = '1.129.0'
2
+ VERSION = '1.130.0'
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.129.0
4
+ version: 1.130.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: 2023-05-03 00:00:00.000000000 Z
11
+ date: 2023-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -480,7 +480,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
480
480
  - !ruby/object:Gem::Version
481
481
  version: '0'
482
482
  requirements: []
483
- rubygems_version: 3.4.12
483
+ rubygems_version: 3.4.13
484
484
  signing_key:
485
485
  specification_version: 4
486
486
  summary: Framework and tools for dealing with credit card transactions.