class ActiveMerchant::Billing::AdyenGateway
Constants
- API_VERSION
- AVS_MAPPING
- CVC_MAPPING
- NETWORK_TOKENIZATION_CARD_SOURCE
- STANDARD_ERROR_CODE_MAPPING
Public Class Methods
new(options={})
click to toggle source
Calls superclass method
ActiveMerchant::Billing::Gateway::new
# File lib/active_merchant/billing/gateways/adyen.rb, line 32 def initialize(options={}) requires!(options, :username, :password, :merchant_account) @username, @password, @merchant_account = options.values_at(:username, :password, :merchant_account) super end
Public Instance Methods
adjust(money, authorization, options={})
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 83 def adjust(money, authorization, options={}) post = init_post(options) add_invoice_for_modification(post, money, options) add_reference(post, authorization, options) add_extra_data(post, nil, options) commit('adjustAuthorisation', post, options) end
capture(money, authorization, options={})
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 63 def capture(money, authorization, options={}) post = init_post(options) add_invoice_for_modification(post, money, options) add_reference(post, authorization, options) commit('capture', post, options) end
purchase(money, payment, options={})
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 38 def purchase(money, payment, options={}) if options[:execute_threed] || options[:threed_dynamic] authorize(money, payment, options) else MultiResponse.run do |r| r.process { authorize(money, payment, options) } r.process { capture(money, r.authorization, capture_options(options)) } end end end
refund(money, authorization, options={})
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 70 def refund(money, authorization, options={}) post = init_post(options) add_invoice_for_modification(post, money, options) add_original_reference(post, authorization, options) commit('refund', post, options) end
scrub(transcript)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 115 def scrub(transcript) transcript. gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]'). gsub(%r(("number\\?":\\?")[^"]*)i, '\1[FILTERED]'). gsub(%r(("cvc\\?":\\?")[^"]*)i, '\1[FILTERED]'). gsub(%r(("cavv\\?":\\?")[^"]*)i, '\1[FILTERED]') end
store(credit_card, options={})
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 91 def store(credit_card, options={}) requires!(options, :order_id) post = init_post(options) add_invoice(post, 0, options) add_payment(post, credit_card) add_extra_data(post, credit_card, options) add_stored_credentials(post, credit_card, options) add_recurring_contract(post, options) add_address(post, options) commit('authorise', post, options) end
supports_scrubbing?()
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 111 def supports_scrubbing? true end
verify(credit_card, options={})
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 103 def verify(credit_card, options={}) MultiResponse.run(:use_first_response) do |r| r.process { authorize(0, credit_card, options) } options[:idempotency_key] = nil r.process(:ignore_result) { void(r.authorization, options) } end end
void(authorization, options={})
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 77 def void(authorization, options={}) post = init_post(options) add_reference(post, authorization, options) commit('cancel', post, options) end
Private Instance Methods
add_3ds(post, options)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 330 def add_3ds(post, options) if three_ds_2_options = options[:three_ds_2] device_channel = three_ds_2_options[:channel] if device_channel == 'app' post[:threeDS2RequestData] = { deviceChannel: device_channel } else add_browser_info(three_ds_2_options[:browser_info], post) post[:threeDS2RequestData] = { deviceChannel: device_channel, notificationURL: three_ds_2_options[:notification_url] } end else return unless options[:execute_threed] || options[:threed_dynamic] post[:browserInfo] = { userAgent: options[:user_agent], acceptHeader: options[:accept_header] } post[:additionalData] = { executeThreeD: 'true' } if options[:execute_threed] end end
add_3ds1_authenticated_data(post, options)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 354 def add_3ds1_authenticated_data(post, options) three_d_secure_options = options[:three_d_secure] post[:mpiData] = { cavv: three_d_secure_options[:cavv], cavvAlgorithm: three_d_secure_options[:cavv_algorithm], eci: three_d_secure_options[:eci], xid: three_d_secure_options[:xid], directoryResponse: three_d_secure_options[:directory_response_status], authenticationResponse: three_d_secure_options[:authentication_response_status] } end
add_3ds2_authenticated_data(post, options)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 366 def add_3ds2_authenticated_data(post, options) three_d_secure_options = options[:three_d_secure] # If the transaction was authenticated in a frictionless flow, send the transStatus from the ARes. if(three_d_secure_options[:authentication_response_status].nil?) authentication_response = three_d_secure_options[:directory_response_status] else authentication_response = three_d_secure_options[:authentication_response_status] end post[:mpiData] = { threeDSVersion: three_d_secure_options[:version], eci: three_d_secure_options[:eci], cavv: three_d_secure_options[:cavv], dsTransID: three_d_secure_options[:ds_transaction_id], directoryResponse: three_d_secure_options[:directory_response_status], authenticationResponse: authentication_response } end
add_3ds_authenticated_data(post, options)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 346 def add_3ds_authenticated_data(post, options) if options[:three_d_secure] && options[:three_d_secure][:eci] && options[:three_d_secure][:xid] add_3ds1_authenticated_data(post, options) elsif options[:three_d_secure] add_3ds2_authenticated_data(post, options) end end
add_address(post, options)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 228 def add_address(post, options) return unless post[:card]&.kind_of?(Hash) if (address = options[:billing_address] || options[:address]) && address[:country] post[:billingAddress] = {} post[:billingAddress][:street] = address[:address1] || 'N/A' post[:billingAddress][:houseNumberOrName] = address[:address2] || 'N/A' post[:billingAddress][:postalCode] = address[:zip] if address[:zip] post[:billingAddress][:city] = address[:city] || 'N/A' post[:billingAddress][:stateOrProvince] = get_state(address) post[:billingAddress][:country] = address[:country] if address[:country] end end
add_browser_info(browser_info, post)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 488 def add_browser_info(browser_info, post) return unless browser_info post[:browserInfo] = { acceptHeader: browser_info[:accept_header], colorDepth: browser_info[:depth], javaEnabled: browser_info[:java], language: browser_info[:language], screenHeight: browser_info[:height], screenWidth: browser_info[:width], timeZoneOffset: browser_info[:timezone], userAgent: browser_info[:user_agent] } end
add_card(post, credit_card)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 274 def add_card(post, credit_card) card = { expiryMonth: credit_card.month, expiryYear: credit_card.year, holderName: credit_card.name, number: credit_card.number, cvc: credit_card.verification_value } card.delete_if { |k, v| v.blank? } card[:holderName] ||= 'Not Provided' if credit_card.is_a?(NetworkTokenizationCreditCard) requires!(card, :expiryMonth, :expiryYear, :holderName, :number) post[:card] = card end
add_extra_data(post, payment, options)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 171 def add_extra_data(post, payment, options) post[:telephoneNumber] = options[:billing_address][:phone] if options.dig(:billing_address, :phone) post[:shopperEmail] = options[:shopper_email] if options[:shopper_email] post[:shopperIP] = options[:shopper_ip] if options[:shopper_ip] post[:shopperReference] = options[:shopper_reference] if options[:shopper_reference] post[:shopperStatement] = options[:shopper_statement] if options[:shopper_statement] post[:fraudOffset] = options[:fraud_offset] if options[:fraud_offset] post[:selectedBrand] = options[:selected_brand] if options[:selected_brand] post[:selectedBrand] ||= NETWORK_TOKENIZATION_CARD_SOURCE[payment.source.to_s] if payment.is_a?(NetworkTokenizationCreditCard) post[:deliveryDate] = options[:delivery_date] if options[:delivery_date] post[:merchantOrderReference] = options[:merchant_order_reference] if options[:merchant_order_reference] post[:additionalData] ||= {} post[:additionalData][:overwriteBrand] = normalize(options[:overwrite_brand]) if options[:overwrite_brand] post[:additionalData][:customRoutingFlag] = options[:custom_routing_flag] if options[:custom_routing_flag] post[:additionalData]['paymentdatasource.type'] = NETWORK_TOKENIZATION_CARD_SOURCE[payment.source.to_s] if payment.is_a?(NetworkTokenizationCreditCard) post[:additionalData][:authorisationType] = options[:authorisation_type] if options[:authorisation_type] post[:additionalData][:adjustAuthorisationData] = options[:adjust_authorisation_data] if options[:adjust_authorisation_data] post[:additionalData][:industryUsage] = options[:industry_usage] if options[:industry_usage] post[:additionalData][:updateShopperStatement] = options[:update_shopper_statement] if options[:update_shopper_statement] post[:additionalData][:RequestedTestAcquirerResponseCode] = options[:requested_test_acquirer_response_code] if options[:requested_test_acquirer_response_code] && test? post[:deviceFingerprint] = options[:device_fingerprint] if options[:device_fingerprint] add_risk_data(post, options) end
add_installments(post, options)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 324 def add_installments(post, options) post[:installments] = { value: options[:installments] } end
add_invoice(post, money, options)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 245 def add_invoice(post, money, options) currency = options[:currency] || currency(money) amount = { value: localized_amount(money, currency), currency: currency } post[:amount] = amount end
add_invoice_for_modification(post, money, options)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 254 def add_invoice_for_modification(post, money, options) currency = options[:currency] || currency(money) amount = { value: localized_amount(money, currency), currency: currency } post[:modificationAmount] = amount end
add_mpi_data_for_network_tokenization_card(post, payment)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 304 def add_mpi_data_for_network_tokenization_card(post, payment) post[:mpiData] = {} post[:mpiData][:authenticationResponse] = 'Y' post[:mpiData][:cavv] = payment.payment_cryptogram post[:mpiData][:directoryResponse] = 'Y' post[:mpiData][:eci] = payment.eci || '07' end
add_original_reference(post, authorization, options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 299 def add_original_reference(post, authorization, options = {}) original_psp_reference, _, _ = authorization.split('#') post[:originalReference] = single_reference(authorization) || original_psp_reference end
add_payment(post, payment)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 263 def add_payment(post, payment) if payment.is_a?(String) _, _, recurring_detail_reference = payment.split('#') post[:selectedRecurringDetailReference] = recurring_detail_reference add_recurring_contract(post, options) else add_mpi_data_for_network_tokenization_card(post, payment) if payment.is_a?(NetworkTokenizationCreditCard) add_card(post, payment) end end
add_recurring_contract(post, options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 316 def add_recurring_contract(post, options = {}) recurring = { contract: 'RECURRING' } post[:recurring] = recurring end
add_recurring_processing_model(post, options)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 217 def add_recurring_processing_model(post, options) return unless options.dig(:stored_credential, :reason_type) || options[:recurring_processing_model] if options.dig(:stored_credential, :reason_type) && options[:stored_credential][:reason_type] == 'unscheduled' recurring_processing_model = 'CardOnFile' else recurring_processing_model = 'Subscription' end post[:recurringProcessingModel] = options[:recurring_processing_model] || recurring_processing_model end
add_reference(post, authorization, options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 294 def add_reference(post, authorization, options = {}) _, psp_reference, _ = authorization.split('#') post[:originalReference] = single_reference(authorization) || psp_reference end
add_risk_data(post, options)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 195 def add_risk_data(post, options) if (risk_data = options[:risk_data]) risk_data = Hash[risk_data.map { |k, v| ["riskdata.#{k}", v] }] post[:additionalData].merge!(risk_data) end end
add_shopper_interaction(post, payment, options={})
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 207 def add_shopper_interaction(post, payment, options={}) if options.dig(:stored_credential, :initial_transaction) || (payment.respond_to?(:verification_value) && payment.verification_value) || payment.is_a?(NetworkTokenizationCreditCard) shopper_interaction = 'Ecommerce' else shopper_interaction = 'ContAuth' end post[:shopperInteraction] = options[:shopper_interaction] || shopper_interaction end
add_stored_credentials(post, payment, options)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 202 def add_stored_credentials(post, payment, options) add_shopper_interaction(post, payment, options) add_recurring_processing_model(post, options) end
avs_code_from(response)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 410 def avs_code_from(response) AVS_MAPPING[response['additionalData']['avsResult'][0..1].strip] if response.dig('additionalData', 'avsResult') end
basic_auth()
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 428 def basic_auth Base64.strict_encode64("#{@username}:#{@password}") end
capture_options(options)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 289 def capture_options(options) return options.merge(idempotency_key: "#{options[:idempotency_key]}-cap") if options[:idempotency_key] options end
commit(action, parameters, options)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 389 def commit(action, parameters, options) begin raw_response = ssl_post("#{url}/#{action}", post_data(action, parameters), request_headers(options)) response = parse(raw_response) rescue ResponseError => e raw_response = e.response.body response = parse(raw_response) end success = success_from(action, response) Response.new( success, message_from(action, response), response, authorization: authorization_from(action, parameters, response), test: test?, error_code: success ? nil : error_code_from(response), avs_result: AVSResult.new(:code => avs_code_from(response)), cvv_result: CVVResult.new(cvv_result_from(response)) ) end
cvv_result_from(response)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 414 def cvv_result_from(response) CVC_MAPPING[response['additionalData']['cvcResult'][0]] if response.dig('additionalData', 'cvcResult') end
error_code_from(response)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 484 def error_code_from(response) STANDARD_ERROR_CODE_MAPPING[response['errorCode']] end
get_state(address)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 241 def get_state(address) address[:state] && !address[:state].blank? ? address[:state] : 'N/A' end
init_post(options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 473 def init_post(options = {}) post = {} post[:merchantAccount] = options[:merchant_account] || @merchant_account post[:reference] = options[:order_id] if options[:order_id] post end
message_from(action, response)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 454 def message_from(action, response) return authorize_message_from(response) if action.to_s == 'authorise' response['response'] || response['message'] end
parse(body)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 384 def parse(body) return {} if body.blank? JSON.parse(body) end
post_data(action, parameters = {})
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 480 def post_data(action, parameters = {}) JSON.generate(parameters) end
request_headers(options)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 432 def request_headers(options) headers = { 'Content-Type' => 'application/json', 'Authorization' => "Basic #{basic_auth}" } headers['Idempotency-Key'] = options[:idempotency_key] if options[:idempotency_key] headers end
single_reference(authorization)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 312 def single_reference(authorization) authorization if !authorization.include?('#') end
success_from(action, response)
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 441 def success_from(action, response) case action.to_s when 'authorise', 'authorise3d' ['Authorised', 'Received', 'RedirectShopper'].include?(response['resultCode']) when 'capture', 'refund', 'cancel' response['response'] == "[#{action}-received]" when 'adjustAuthorisation' response['response'] == 'Authorised' || response['response'] == '[adjustAuthorisation-received]' else false end end
url()
click to toggle source
# File lib/active_merchant/billing/gateways/adyen.rb, line 418 def url if test? "#{test_url}#{API_VERSION}" elsif @options[:subdomain] "https://#{@options[:subdomain]}-pal-live.adyenpayments.com/pal/servlet/Payment/#{API_VERSION}" else "#{live_url}#{API_VERSION}" end end