class ActiveMerchant::Billing::PaymillGateway

Constants

RESPONSE_CODES

Public Class Methods

new(options = {}) click to toggle source
Calls superclass method ActiveMerchant::Billing::Gateway::new
# File lib/active_merchant/billing/gateways/paymill.rb, line 15
def initialize(options = {})
  requires!(options, :public_key, :private_key)
  super
end

Public Instance Methods

authorize(money, payment_method, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 24
def authorize(money, payment_method, options = {})
  action_with_token(:authorize, money, payment_method, options)
end
capture(money, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 28
def capture(money, authorization, options = {})
  post = {}

  add_amount(post, money, options)
  post[:preauthorization] = preauth(authorization)
  post[:description] = options[:order_id]
  post[:source] = 'active_merchant'
  commit(:post, 'transactions', post)
end
purchase(money, payment_method, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 20
def purchase(money, payment_method, options = {})
  action_with_token(:purchase, money, payment_method, options)
end
refund(money, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 38
def refund(money, authorization, options = {})
  post = {}

  post[:amount] = amount(money)
  post[:description] = options[:order_id]
  commit(:post, "refunds/#{transaction_id(authorization)}", post)
end
scrub(transcript) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 63
def scrub(transcript)
  transcript.
    gsub(%r((Authorization: Basic )\w+), '\1[FILTERED]').
    gsub(/(account.number=)(\d*)/, '\1[FILTERED]').
    gsub(/(account.verification=)(\d*)/, '\1[FILTERED]')
end
store(credit_card, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 50
def store(credit_card, options = {})
  # The store request requires a currency and amount of at least $1 USD.
  # This is used for an authorization that is handled internally by Paymill.
  options[:currency] = 'USD'
  options[:money] = 100

  save_card(credit_card, options)
end
supports_scrubbing() click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 59
def supports_scrubbing
  true
end
verify_credentials() click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 70
def verify_credentials
  begin
    ssl_get(live_url + 'transactions/nonexistent', headers)
  rescue ResponseError => e
    return false if e.response.code.to_i == 401
  end

  true
end
void(authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 46
def void(authorization, options = {})
  commit(:delete, "preauthorizations/#{preauth(authorization)}")
end

Private Instance Methods

action_with_token(action, money, payment_method, options) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 133
def action_with_token(action, money, payment_method, options)
  options[:money] = money
  case payment_method
  when String
    self.send("#{action}_with_token", money, payment_method, options)
  else
    MultiResponse.run do |r|
      r.process { save_card(payment_method, options) }
      r.process { self.send("#{action}_with_token", money, r.authorization, options) }
    end
  end
end
add_amount(post, money, options) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 205
def add_amount(post, money, options)
  post[:amount] = amount(money)
  post[:currency] = (options[:currency] || currency(money))
end
add_credit_card(post, credit_card, options) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 82
def add_credit_card(post, credit_card, options)
  post['account.holder'] = (credit_card.try(:name) || '')
  post['account.number'] = credit_card.number
  post['account.expiry.month'] = sprintf('%.2i', credit_card.month)
  post['account.expiry.year'] = sprintf('%.4i', credit_card.year)
  post['account.verification'] = credit_card.verification_value
  post['account.email'] = (options[:email] || nil)
  post['presentation.amount3D'] = (options[:money] || nil)
  post['presentation.currency3D'] = (options[:currency] || currency(options[:money]))
end
authorization_from(parsed_response) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 123
def authorization_from(parsed_response)
  parsed_data = parsed_response['data']
  return '' unless parsed_data.kind_of?(Hash)

  [
    parsed_data['id'],
    parsed_data['preauthorization'].try(:[], 'id')
  ].join(';')
end
authorize_with_token(money, card_token, options) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 156
def authorize_with_token(money, card_token, options)
  post = {}

  add_amount(post, money, options)
  post[:token] = card_token
  post[:description] = options[:order_id]
  post[:source] = 'active_merchant'
  commit(:post, 'preauthorizations', post)
end
commit(method, action, parameters = nil) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 97
def commit(method, action, parameters = nil)
  begin
    raw_response = ssl_request(method, live_url + action, post_data(parameters), headers)
  rescue ResponseError => e
    begin
      parsed = JSON.parse(e.response.body)
    rescue JSON::ParserError
      return Response.new(false, "Unable to parse error response: '#{e.response.body}'")
    end
    return Response.new(false, response_message(parsed), parsed, {})
  end

  response_from(raw_response)
end
headers() click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 93
def headers
  { 'Authorization' => ('Basic ' + Base64.strict_encode64("#{@options[:private_key]}:X").chomp) }
end
parse_reponse(response) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 190
def parse_reponse(response)
  JSON.parse(response.sub(/jsonPFunction\(/, '').sub(/\)\z/, ''))
end
post_data(params) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 198
def post_data(params)
  return nil unless params

  no_blanks = params.reject { |_key, value| value.blank? }
  no_blanks.map { |key, value| "#{key}=#{CGI.escape(value.to_s)}" }.join('&')
end
preauth(authorization) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 210
def preauth(authorization)
  authorization.split(';').last
end
purchase_with_token(money, card_token, options) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 146
def purchase_with_token(money, card_token, options)
  post = {}

  add_amount(post, money, options)
  post[:token] = card_token
  post[:description] = options[:order_id]
  post[:source] = 'active_merchant'
  commit(:post, 'transactions', post)
end
response_for_save_from(raw_response) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 183
def response_for_save_from(raw_response)
  options = { test: test? }

  parser = ResponseParser.new(raw_response, options)
  parser.generate_response
end
response_from(raw_response) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 112
def response_from(raw_response)
  parsed = JSON.parse(raw_response)
  options = {
    authorization: authorization_from(parsed),
    test: (parsed['mode'] == 'test')
  }

  succeeded = (parsed['data'] == []) || (parsed['data']['response_code'].to_i == 20000)
  Response.new(succeeded, response_message(parsed), parsed, options)
end
response_message(parsed_response) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 320
def response_message(parsed_response)
  return parsed_response['error'] if parsed_response['error']
  return 'Transaction approved.' if parsed_response['data'] == []

  code = parsed_response['data']['response_code'].to_i
  RESPONSE_CODES[code] || code.to_s
end
save_card(credit_card, options) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 166
def save_card(credit_card, options)
  post = {}

  add_credit_card(post, credit_card, options)
  post['channel.id'] = @options[:public_key]
  post['jsonPFunction'] = 'jsonPFunction'
  post['transaction.mode'] = (test? ? 'CONNECTOR_TEST' : 'LIVE')

  begin
    raw_response = ssl_request(:get, "#{save_card_url}?#{post_data(post)}", nil, {})
  rescue ResponseError => e
    return Response.new(false, e.response.body)
  end

  response_for_save_from(raw_response)
end
save_card_url() click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 194
def save_card_url
  (test? ? 'https://test-token.paymill.com' : 'https://token-v2.paymill.de')
end
transaction_id(authorization) click to toggle source
# File lib/active_merchant/billing/gateways/paymill.rb, line 214
def transaction_id(authorization)
  authorization.split(';').first
end