class ActiveMerchant::Billing::Shift4Gateway
Constants
- DISALLOWED_ENTRY_MODE_ACTIONS
- RECURRING_TYPE_TRANSACTIONS
- SUCCESS_TRANSACTION_STATUS
- TRANSACTIONS_WITHOUT_RESPONSE_CODE
- URL_POSTFIX_MAPPING
Public Class Methods
new(options = {})
click to toggle source
Calls superclass method
ActiveMerchant::Billing::Gateway::new
# File lib/active_merchant/billing/gateways/shift4.rb, line 24 def initialize(options = {}) requires!(options, :client_guid, :auth_token) @client_guid = options[:client_guid] @auth_token = options[:auth_token] @access_token = options[:access_token] super end
Public Instance Methods
capture(money, authorization, options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 64 def capture(money, authorization, options = {}) post = {} action = 'capture' options[:invoice] = get_invoice(authorization) add_datetime(post, options) add_invoice(post, money, options) add_clerk(post, options) add_transaction(post, options) add_card(action, post, get_card_token(authorization), options) commit(action, post, options) end
purchase(money, payment_method, options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 32 def purchase(money, payment_method, options = {}) post = {} action = 'sale' payment_method = get_card_token(payment_method) if payment_method.is_a?(String) add_datetime(post, options) add_invoice(post, money, options) add_clerk(post, options) add_transaction(post, options) add_card(action, post, payment_method, options) add_card_present(post, options) add_customer(post, payment_method, options) commit(action, post, options) end
refund(money, payment_method, options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 78 def refund(money, payment_method, options = {}) post = {} action = 'refund' add_datetime(post, options) add_invoice(post, money, options) add_clerk(post, options) add_transaction(post, options) card_token = payment_method.is_a?(CreditCard) ? get_card_token(payment_method) : payment_method add_card(action, post, card_token, options) add_card_present(post, options) commit(action, post, options) end
Also aliased as: credit
scrub(transcript)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 128 def scrub(transcript) transcript. gsub(%r(("Number\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]'). gsub(%r(("expirationDate\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]'). gsub(%r(("FirstName\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]'). gsub(%r(("LastName\\?"\s*:\s*\\?")[^"]*)i, '\1[FILTERED]'). gsub(%r(("securityCode\\?":{\\?"\w+\\?":\d+,\\?"value\\?":\\?")\d*)i, '\1[FILTERED]') end
setup_access_token()
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 137 def setup_access_token post = {} add_credentials(post, options) add_datetime(post, options) response = commit('accesstoken', post, request_headers('accesstoken', options)) raise OAuthResponseError.new(response, response.params.fetch('result', [{}]).first.dig('error', 'longText')) unless response.success? response.params['result'].first['credential']['accessToken'] end
store(credit_card, options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 113 def store(credit_card, options = {}) post = {} action = 'add' add_datetime(post, options) add_card(action, post, credit_card, options) add_customer(post, credit_card, options) commit(action, post, options) end
supports_scrubbing?()
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 124 def supports_scrubbing? true end
verify(credit_card, options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 100 def verify(credit_card, options = {}) post = {} action = 'verify' post[:transaction] = {} add_datetime(post, options) add_card(action, post, credit_card, options) add_customer(post, credit_card, options) add_card_on_file(post[:transaction], options) commit(action, post, options) end
void(authorization, options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 95 def void(authorization, options = {}) options[:invoice] = get_invoice(authorization) commit('invoice', {}, options) end
Private Instance Methods
add_card(action, post, payment_method, options)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 181 def add_card(action, post, payment_method, options) post[:card] = {} post[:card][:entryMode] = options[:entry_mode] || 'M' unless DISALLOWED_ENTRY_MODE_ACTIONS.include?(action) if payment_method.is_a?(CreditCard) post[:card][:expirationDate] = "#{format(payment_method.month, :two_digits)}#{format(payment_method.year, :two_digits)}" post[:card][:number] = payment_method.number post[:card][:securityCode] = {} post[:card][:securityCode][:indicator] = 1 post[:card][:securityCode][:value] = payment_method.verification_value else post[:card] = {} if post[:card].nil? post[:card][:token] = {} post[:card][:token][:value] = payment_method post[:card][:expirationDate] = options[:expiration_date] if options[:expiration_date] end end
add_card_on_file(post, options)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 225 def add_card_on_file(post, options) return unless options[:stored_credential] || options[:usage_indicator] || options[:indicator] || options[:scheduled_indicator] || options[:transaction_id] stored_credential = options[:stored_credential] || {} post[:cardOnFile] = {} post[:cardOnFile][:usageIndicator] = options[:usage_indicator] || (stored_credential[:initial_transaction] ? '01' : '02') post[:cardOnFile][:indicator] = options[:indicator] || '01' post[:cardOnFile][:scheduledIndicator] = options[:scheduled_indicator] || (RECURRING_TYPE_TRANSACTIONS.include?(stored_credential[:reason_type]) ? '01' : '02') post[:cardOnFile][:transactionId] = options[:transaction_id] || stored_credential[:network_transaction_id] if options[:transaction_id] || stored_credential[:network_transaction_id] end
add_card_present(post, options)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 198 def add_card_present(post, options) post[:card] = {} unless post[:card].present? post[:card][:present] = options[:card_present] || 'N' end
add_clerk(post, options)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 156 def add_clerk(post, options) post[:clerk] = {} post[:clerk][:numericId] = options[:clerk_id] || '1' end
add_credentials(post, options)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 150 def add_credentials(post, options) post[:credential] = {} post[:credential][:clientGuid] = @client_guid post[:credential][:authToken] = @auth_token end
add_customer(post, card, options)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 204 def add_customer(post, card, options) address = options[:billing_address] || {} post[:customer] = {} post[:customer][:addressLine1] = address[:address1] if address[:address1] post[:customer][:postalCode] = address[:zip] if address[:zip] && !address[:zip]&.to_s&.empty? post[:customer][:firstName] = card.first_name if card.is_a?(CreditCard) && card.first_name post[:customer][:lastName] = card.last_name if card.is_a?(CreditCard) && card.last_name post[:customer][:emailAddress] = options[:email] if options[:email] post[:customer][:ipAddress] = options[:ip] if options[:ip] end
add_datetime(post, options)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 167 def add_datetime(post, options) post[:dateTime] = options[:date_time] || current_date_time(options) end
add_invoice(post, money, options)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 161 def add_invoice(post, money, options) post[:amount] = {} post[:amount][:total] = amount(money.to_f) post[:amount][:tax] = options[:tax].to_f || 0.0 end
add_purchase_card(post, options)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 216 def add_purchase_card(post, options) return unless options[:customer_reference] || options[:destination_postal_code] || options[:product_descriptors] post[:purchaseCard] = {} post[:purchaseCard][:customerReference] = options[:customer_reference] if options[:customer_reference] post[:purchaseCard][:destinationPostalCode] = options[:destination_postal_code] if options[:destination_postal_code] post[:purchaseCard][:productDescriptors] = options[:product_descriptors] if options[:product_descriptors] end
add_transaction(post, options)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 171 def add_transaction(post, options) post[:transaction] = {} post[:transaction][:invoice] = options[:invoice] || Time.new.to_i.to_s[1..3] + rand.to_s[2..7] post[:transaction][:notes] = options[:notes] if options[:notes].present? post[:transaction][:vendorReference] = options[:order_id] add_purchase_card(post[:transaction], options) add_card_on_file(post[:transaction], options) end
avs_result_from(response)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 289 def avs_result_from(response) AVSResult.new(code: response['result'].first&.dig('transaction', 'avs', 'result')) if response['result'].first&.dig('transaction', 'avs') end
commit(action, parameters, option)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 236 def commit(action, parameters, option) url_postfix = URL_POSTFIX_MAPPING[action] || 'transactions' url = (test? ? "#{test_url}#{url_postfix}/#{action}" : "#{live_url}#{url_postfix}/#{action}") if action == 'invoice' response = parse(ssl_request(:delete, url, parameters.to_json, request_headers(action, option))) else response = parse(ssl_post(url, parameters.to_json, request_headers(action, option))) end Response.new( success_from(action, response), message_from(action, response), response, authorization: authorization_from(action, response), avs_result: avs_result_from(response), test: test?, error_code: error_code_from(action, response) ) end
current_date_time(options = {})
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 333 def current_date_time(options = {}) time_zone = options[:merchant_time_zone] || 'Pacific Time (US & Canada)' time = Time.now.in_time_zone(time_zone) offset = Time.now.in_time_zone(time_zone).formatted_offset time.strftime('%Y-%m-%dT%H:%M:%S.%3N') + offset end
error(response)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 328 def error(response) server_error = { 'longText' => response['error'] } if response['error'] server_error || response['result'].first['error'] end
error_code_from(action, response)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 275 def error_code_from(action, response) code = response['result'].first&.dig('transaction', 'responseCode') primary_code = response['result'].first['error'].present? return unless code == 'D' || primary_code == true || success_from(action, response) if response['result'].first&.dig('transaction', 'hostResponse') response['result'].first&.dig('transaction', 'hostResponse', 'reasonCode') elsif response['result'].first['error'] response['result'].first&.dig('error', 'primaryCode') else response['result'].first&.dig('transaction', 'responseCode') end end
get_card_token(authorization)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 302 def get_card_token(authorization) authorization.is_a?(CreditCard) ? authorization : authorization.split('|')[0] end
get_invoice(authorization)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 306 def get_invoice(authorization) authorization.is_a?(CreditCard) ? authorization : authorization.split('|')[1] end
handle_response(response)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 256 def handle_response(response) case response.code.to_i when 200...300, 400, 401, 500 response.body else raise ResponseError.new(response) end end
message_from(action, response)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 271 def message_from(action, response) success_from(action, response) ? 'Transaction successful' : (error(response)&.dig('longText') || response['result'].first&.dig('transaction', 'hostResponse', 'reasonDescription') || 'Transaction declined') end
parse(body)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 265 def parse(body) return {} if body == '' JSON.parse(body) end
request_headers(action, options)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 310 def request_headers(action, options) headers = { 'Content-Type' => 'application/json' } headers['AccessToken'] = @access_token headers['Invoice'] = options[:invoice] if action != 'capture' && options[:invoice].present? headers['InterfaceVersion'] = '1' headers['InterfaceName'] = 'Spreedly' headers['CompanyName'] = 'Spreedly' headers end
success_from(action, response)
click to toggle source
# File lib/active_merchant/billing/gateways/shift4.rb, line 322 def success_from(action, response) success = error(response).nil? success &&= SUCCESS_TRANSACTION_STATUS.include?(response['result'].first['transaction']['responseCode']) unless TRANSACTIONS_WITHOUT_RESPONSE_CODE.include?(action) success end