class ActiveMerchant::Billing::PayuInGateway

Constants

BRAND_MAP
LIVE_INFO_URL
PAYMENT_DIGEST_KEYS
TEST_INFO_URL

Public Class Methods

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

Public Instance Methods

purchase(money, payment, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 24
def purchase(money, payment, options = {})
  requires!(options, :order_id)

  post = {}
  add_invoice(post, money, options)
  add_payment(post, payment)
  add_addresses(post, options)
  add_customer_data(post, options)
  add_auth(post)

  MultiResponse.run do |r|
    r.process { commit(url('purchase'), post) }
    if r.params['enrolled'].to_s == '0'
      r.process { commit(r.params['post_uri'], r.params['form_post_vars']) }
    else
      r.process { handle_3dsecure(r) }
    end
  end
end
refund(money, authorization, options = {}) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 44
def refund(money, authorization, options = {})
  raise ArgumentError, 'Amount is required' unless money

  post = {}

  post[:command] = 'cancel_refund_transaction'
  post[:var1] = authorization
  post[:var2] = generate_unique_id
  post[:var3] = amount(money)

  add_auth(post, :command, :var1)

  commit(url('refund'), post)
end
scrub(transcript) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 63
def scrub(transcript)
  transcript.
    gsub(/(ccnum=)[^&\n"]*(&|\n|"|$)/, '\1[FILTERED]\2').
    gsub(/(ccvv=)[^&\n"]*(&|\n|"|$)/, '\1[FILTERED]\2').
    gsub(/(card_hash=)[^&\n"]*(&|\n|"|$)/, '\1[FILTERED]\2').
    gsub(/(ccnum":")[^"]*(")/, '\1[FILTERED]\2').
    gsub(/(ccvv":")[^"]*(")/, '\1[FILTERED]\2')
end
supports_scrubbing?() click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 59
def supports_scrubbing?
  true
end

Private Instance Methods

add_addresses(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 98
def add_addresses(post, options)
  if options[:billing_address]
    post[:address1] = clean(options[:billing_address][:address1], :text, 100)
    post[:address2] = clean(options[:billing_address][:address2], :text, 100)
    post[:city] = clean(options[:billing_address][:city], :text, 50)
    post[:state] = clean(options[:billing_address][:state], :text, 50)
    post[:country] = clean(options[:billing_address][:country], :text, 50)
    post[:zipcode] = clean(options[:billing_address][:zip], :numeric, 20)
  end

  if options[:shipping_address]
    if options[:shipping_address][:name]
      first, *rest = options[:shipping_address][:name].split(/\s+/)
      post[:shipping_firstname] = clean(first, :name, 60)
      post[:shipping_lastname] = clean(rest.join(' '), :name, 20)
    end
    post[:shipping_address1] = clean(options[:shipping_address][:address1], :text, 100)
    post[:shipping_address2] = clean(options[:shipping_address][:address2], :text, 100)
    post[:shipping_city] = clean(options[:shipping_address][:city], :text, 50)
    post[:shipping_state] = clean(options[:shipping_address][:state], :text, 50)
    post[:shipping_country] = clean(options[:shipping_address][:country], :text, 50)
    post[:shipping_zipcode] = clean(options[:shipping_address][:zip], :numeric, 20)
    post[:shipping_phone] = clean(options[:shipping_address][:phone], :numeric, 50)
  end
end
add_auth(post, *digest_keys) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 79
def add_auth(post, *digest_keys)
  post[:key] = @options[:key]
  post[:txn_s2s_flow] = 1

  digest_keys = PAYMENT_DIGEST_KEYS if digest_keys.empty?
  digest = Digest::SHA2.new(512)
  digest << @options[:key] << '|'
  digest_keys.each do |key|
    digest << (post[key.to_sym] || '') << '|'
  end
  digest << @options[:salt]
  post[:hash] = digest.hexdigest
end
add_customer_data(post, options) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 93
def add_customer_data(post, options)
  post[:email] = clean(options[:email] || 'unknown@example.com', nil, 50)
  post[:phone] = clean((options[:billing_address] && options[:billing_address][:phone]) || '11111111111', :numeric, 50)
end
add_invoice(post, money, options) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 124
def add_invoice(post, money, options)
  post[:amount] = amount(money)

  post[:txnid] = clean(options[:order_id], :alphanumeric, 30)
  post[:productinfo] = clean(options[:description] || 'Purchase', nil, 100)

  post[:surl] = 'http://example.com'
  post[:furl] = 'http://example.com'
end
add_payment(post, payment) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 142
def add_payment(post, payment)
  post[:pg] = 'CC'
  post[:firstname] = clean(payment.first_name, :name, 60)
  post[:lastname] = clean(payment.last_name, :name, 20)

  post[:bankcode] = BRAND_MAP[payment.brand.to_sym]
  post[:ccnum] = payment.number
  post[:ccvv] = payment.verification_value
  post[:ccname] = payment.name
  post[:ccexpmon] = format(payment.month, :two_digits)
  post[:ccexpyr] = format(payment.year, :four_digits)
end
authorization_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 236
def authorization_from(response)
  response['mihpayid']
end
clean(value, format, maxlength) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 155
def clean(value, format, maxlength)
  value ||= ''
  value =
    case format
    when :alphanumeric
      value.gsub(/[^A-Za-z0-9]/, '')
    when :name
      value.gsub(/[^A-Za-z ]/, '')
    when :numeric
      value.gsub(/[^0-9]/, '')
    when :text
      value.gsub(/[^A-Za-z0-9@\-_\/\. ]/, '')
    when nil
      value
    else
      raise "Unknown format #{format} for #{value}"
    end
  value[0...maxlength]
end
commit(url, parameters) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 203
def commit(url, parameters)
  response = parse(ssl_post(url, post_data(parameters), 'Accept-Encoding' => 'identity'))

  Response.new(
    success_from(response),
    message_from(response),
    response,
    authorization: authorization_from(response),
    test: test?
  )
end
handle_3dsecure(response) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 244
def handle_3dsecure(response)
  Response.new(false, '3D-secure enrolled cards are not supported.')
end
message_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 232
def message_from(response)
  (response['error_message'] || response['error'] || response['msg'])
end
parse(body) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 175
def parse(body)
  top = JSON.parse(body)

  if result = top.delete('result')
    result.split('&').inject({}) do |hash, string|
      key, value = string.split('=')
      hash[CGI.unescape(key).downcase] = CGI.unescape(value || '')
      hash
    end.each do |key, value|
      if top[key]
        top["result_#{key}"] = value
      else
        top[key] = value
      end
    end
  end

  if response = top.delete('response')
    top.merge!(response)
  end

  top
rescue JSON::ParserError
  {
    'error' => "Invalid response received from the PayU API. (The raw response was `#{body}`)."
  }
end
post_data(parameters = {}) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 240
def post_data(parameters = {})
  PostData.new.merge!(parameters).to_post_data
end
success_from(response) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 224
def success_from(response)
  if response['result_status']
    (response['status'] == 'success' && response['result_status'] == 'success')
  else
    (response['status'] == 'success' || response['status'].to_s == '1')
  end
end
url(action) click to toggle source
# File lib/active_merchant/billing/gateways/payu_in.rb, line 215
def url(action)
  case action
  when 'purchase'
    (test? ? test_url : live_url)
  else
    (test? ? TEST_INFO_URL : LIVE_INFO_URL)
  end
end