lib/active_merchant/billing/gateways/d_local.rb in activemerchant-1.125.0 vs lib/active_merchant/billing/gateways/d_local.rb in activemerchant-1.126.0

- old
+ new

@@ -17,17 +17,19 @@ end def purchase(money, payment, options = {}) post = {} add_auth_purchase_params(post, money, payment, 'purchase', options) + add_three_ds(post, options) commit('purchase', post, options) end def authorize(money, payment, options = {}) post = {} add_auth_purchase_params(post, money, payment, 'authorize', options) + add_three_ds(post, options) post[:card][:verify] = true if options[:verify].to_s == 'true' commit('authorize', post, options) end @@ -152,17 +154,21 @@ post[:card][:cvv] = card.verification_value post[:card][:descriptor] = options[:dynamic_descriptor] if options[:dynamic_descriptor] post[:card][:capture] = (action == 'purchase') post[:card][:installments] = options[:installments] if options[:installments] post[:card][:installments_id] = options[:installments_id] if options[:installments_id] + post[:card][:force_type] = options[:force_type].to_s.upcase if options[:force_type] end def parse(body) JSON.parse(body) end def commit(action, parameters, options = {}) + three_ds_errors = validate_three_ds_params(parameters[:three_dsecure]) if parameters[:three_dsecure].present? + return three_ds_errors if three_ds_errors + url = url(action, parameters, options) post = post_data(action, parameters) begin raw = ssl_post(url, post, headers(post, options)) response = parse(raw) @@ -246,9 +252,52 @@ "V2-HMAC-SHA256, Signature: #{digest}" end def post_data(action, parameters = {}) parameters.to_json + end + + def xid_or_ds_trans_id(three_d_secure) + if three_d_secure[:version].to_f >= 2 + { ds_transaction_id: three_d_secure[:ds_transaction_id] } + else + { xid: three_d_secure[:xid] } + end + end + + def add_three_ds(post, options) + return unless three_d_secure = options[:three_d_secure] + + post[:three_dsecure] = { + mpi: true, + three_dsecure_version: three_d_secure[:version], + cavv: three_d_secure[:cavv], + eci: three_d_secure[:eci], + enrollment_response: formatted_enrollment(three_d_secure[:enrolled]), + authentication_response: three_d_secure[:authentication_response_status] + }.merge(xid_or_ds_trans_id(three_d_secure)) + end + + def validate_three_ds_params(three_ds) + errors = {} + supported_version = %w{1.0 2.0 2.1.0 2.2.0}.include?(three_ds[:three_dsecure_version]) + supported_enrollment = ['Y', 'N', 'U', nil].include?(three_ds[:enrollment_response]) + supported_auth_response = ['Y', 'N', 'U', nil].include?(three_ds[:authentication_response]) + + errors[:three_ds_version] = 'ThreeDs version not supported' unless supported_version + errors[:enrollment] = 'Enrollment value not supported' unless supported_enrollment + errors[:auth_response] = 'Authentication response value not supported' unless supported_auth_response + errors.compact! + + errors.present? ? Response.new(false, 'ThreeDs data is invalid', errors) : nil + end + + def formatted_enrollment(val) + case val + when 'Y', 'N', 'U' then val + when true, 'true' then 'Y' + when false, 'false' then 'N' + end end end end end