class EME::Billing

require_relative 'billing/store_item'

Public Class Methods

add_offsite_emp(external_id, emp_amount, opts, conn = connection ) click to toggle source

requires publisher as AMAZON or STEAM.

# File lib/eme/billing.rb, line 293
def self.add_offsite_emp(external_id, emp_amount, opts, conn = connection )
  emp_body = {  "USERNO" => external_id,
                "USERID" => opts[:user_email],
                "PGCODE" => opts[:publisher],
                "PAYAMT" => opts[:pay_amount],
                "TAXAMT" => opts[:tax_amount],
                "CURRENCYCODE" => "USD",
                "CASHAMT" => emp_amount,
                "ORDERTRANSACTIONID" => "#{opts[:publisher]}#{opts[:order_id]}",
                "GAMECODE" => opts[:game_code],
                "COUNTRYCODE" => "USA",
                "IPADDR" => opts[:ip_address],
                "PUBLISHER" => opts[:publisher],
                "DESCRIPTION" => "#{opts[:publisher]} offsite transaction"
  }
  emp_body["CHECKSUM"] = checksum "#{external_id}|#{opts[:user_email]}|#{opts[:publisher]}|USD|#{opts[:pay_amount]}|#{emp_amount}|#{emp_body['GAMECODE']}|#{emp_body['COUNTRYCODE']}|#{emp_body['ORDERTRANSACTIONID']}"
  
  log.debug "EMP_BODY: #{emp_body}"
  res = do_request("/Payment/rest/services/create/v1/EMP", conn, {:method => :post, :body => emp_body.to_json})
  log.debug "RES: #{res}"
  return res["RESPONSE"] if res["RESPONSE"]
  return res
end
billing_info(external_id, conn = connection) click to toggle source
# File lib/eme/billing.rb, line 278
def self.billing_info(external_id, conn = connection)
  res = do_request("/Payment/rest/services/billinginfo/v1/get/#{external_id}", conn)
  return res["RESPONSE"] if res["RESPONSE"]
  return res
end
campaign_hash_map(camp) click to toggle source
# File lib/eme/billing.rb, line 220
def self.campaign_hash_map(camp)
  {
    :tags => (camp["TAGS"] || []).uniq,
    :images => camp["IMAGES"],
    :name => camp["EVENTNAME"],
    :id => camp["EVENTID"],
    :longDescription => camp["HTMLLONGDESCRIPTION"],
    :discount_rate => camp["TOTDISCOUNTRATE"],
    :discount_amount => camp["TOTDISCOUNTAMOUNT"],
    :items => camp["ITEMS"],
    :start_at => camp["STARTDATE"],
    :end_at => camp["ENDDATE"]
  }
end
campaigns(game = nil, lang = 'en', reset_cache = false, conn = connection) click to toggle source
# File lib/eme/billing.rb, line 179
def self.campaigns(game = nil, lang = 'en', reset_cache = false, conn = connection)
  return custom_campaigns("all", game, lang, reset_cache, conn)
end
cash_payment_types(gamecode, reload = false, conn = connection) click to toggle source
# File lib/eme/billing.rb, line 92
def self.cash_payment_types(gamecode, reload = false, conn = connection)
  if settings[:use_memcache] && !reload
    cached = cache.obj_read("payment-type-list-#{gamecode}")
    return cached if cached
  end

  pay_types = []
  request_path = URI.encode("/Payment/rest/services/virtualcurrency/v1/list/#{gamecode}/USD/^/^")
  obj_hash = do_request(request_path, conn)
  obj_hash["LIST"].each do |pt_hash|
    pay_types.push(PaymentType.new(pt_hash))
  end
  pay_types.sort!{|a,b| a.sortno <=> b.sortno }

  if settings[:use_memcache]
    cache.obj_write("payment-type-list-#{gamecode}", pay_types, {:ttl => 300})
  end
  return pay_types
end
checksum(data_string) click to toggle source
# File lib/eme/billing.rb, line 321
def self.checksum(data_string)
  return Digest::SHA1.hexdigest "#{data_string}|#{settings[:api_key]}"
end
currencies(gamecode, types = [], reload = false, conn = connection) click to toggle source
# File lib/eme/billing.rb, line 55
def self.currencies(gamecode, types = [], reload = false, conn = connection)
  fetch_currencies(gamecode, "EMP", types, reload, conn)
end
currency_by_id(gamecode, id) click to toggle source
# File lib/eme/billing.rb, line 82
def self.currency_by_id(gamecode, id)
  currs = currencies(gamecode)
  return currs.currencies.select{|x| x.id == id }[0]
end
custom_campaigns(tag = "all", game = nil, lang = 'en', reset_cache = false, conn = connection) click to toggle source
# File lib/eme/billing.rb, line 183
def self.custom_campaigns(tag = "all", game = nil, lang = 'en', reset_cache = false, conn = connection)
  raise RuntimeError, "game required" unless game
  if !reset_cache && settings[:use_memcache]
    cached = cache.read("#{game.downcase}-campaigns-#{tag}-#{lang}")
    return cached if cached
  end

  local_campaigns = []
  cur_page = 1
  camps_per_request = 100

  cur_camps = []
  while(cur_page == 1 || cur_camps.length == camps_per_request)
    base_campaign_api_request = URI.encode("/Item/rest/services/#{game}/promotion/v1/page/#{camps_per_request}/#{cur_page}/true")
    cur_camps = []

    # store in memcache here
    obj_array = do_request(base_campaign_api_request, conn)
    obj_array["LIST"] = [] if obj_array["LIST"].nil?
    obj_array["LIST"].each do |obj|
      cur_camps << Campaign.new(campaign_hash_map(obj))
    end

    cur_page += 1
    local_campaigns += cur_camps
  end
  elite_campaigns = local_campaigns.select{|x| x.tags.include?("promo_tag:elite") }
  sale_campaigns = local_campaigns.select{|x| x.tags.include?("promo_tag:sale") }

  # save to memcache
  if settings[:use_memcache]
    cache.write("#{game.downcase}-campaigns-#{tag}-#{lang}", [elite_campaigns, sale_campaigns], {:ttl => 3600})
  end

  return [elite_campaigns, sale_campaigns]
end
custom_offers(tag = "all", game = nil, lang = nil, reset_cache = false, conn = connection) click to toggle source
# File lib/eme/billing.rb, line 134
def self.custom_offers(tag = "all", game = nil, lang = nil, reset_cache = false, conn = connection)
raise RuntimeError, "game required" unless game
if !reset_cache && settings[:use_memcache]
   cached = cache.obj_read("#{game.downcase}-all-#{tag}-#{lang}")
   return cached if cached
 end

 local_offers = []
 cur_page = 1
 offers_per_req = 100  #250 when that is release

 tag_data = tag == "all" ? "^" : "&attributes=#{tag}"

 tag_data = URI.escape(tag_data)
 cur_offers = []
 while(cur_page == 1 || cur_offers.length == offers_per_req)
   base_offer_api_request = URI.encode("/Item/rest/services/#{game}/gameitem/v1/page/#{offers_per_req}/#{cur_page}/^/true")
   #puts base_offer_api_request

   cur_offers = []

   begin
     obj_array = do_request(base_offer_api_request, conn)
     obj_array["LIST"] = [] if obj_array["LIST"].nil?
     obj_array["LIST"].each do |obj|
       cur_offers << Offer.new(obj)
     end
   rescue RuntimeError => exception
     puts exception.backtrace
     obj_array = {"message" => "Error contacting store."}
     return [] # No offer found
   end

   cur_page += 1
   local_offers += cur_offers
 end

 # save to memcache
 if settings[:use_memcache]
   cache.obj_write("#{game.downcase}-all-#{tag}-#{lang}", local_offers, {:ttl => 3600})
 end

 local_offers
end
fetch_currencies(gamecode, kind="EMP", types = [], invisible = false, reload = false, conn = connection) click to toggle source
# File lib/eme/billing.rb, line 63
def self.fetch_currencies(gamecode, kind="EMP", types = [], invisible = false, reload = false, conn = connection)
  cache_key = "currency-list-#{gamecode}-kind#{kind}-#{types.sort.join('-')}-#{'invs' if invisible}".downcase
  if settings[:use_memcache] && !reload
    cached = cache.obj_read(cache_key)
    return cached if cached
  end

  currs = nil
  request_path = URI.encode("/Payment/rest/services/virtualcurrency/v1/list/#{gamecode}/#{kind}/^/^#{'/^' if invisible}")
  obj_hash = do_request(request_path, conn)
  
  currs = CurrencyCollection.new(obj_hash["LIST"], types)
  # save to memcache
  if settings[:use_memcache]
    cache.obj_write(cache_key, currs, {:ttl => 300})
  end
  currs
end
find_item(item_id, game=nil, reset_cache = false) click to toggle source
# File lib/eme/billing.rb, line 128
def self.find_item(item_id, game=nil, reset_cache = false)
  game = game || settings[:game]
  request_url = URI.encode("/Item/rest/services/#{game}/gameitem/v1/get/#{item_id}")
  return do_request(request_url, connection(:normal), {:key => "#{game}-single-item-#{item_id}", :ttl => 60})
end
get_wallet(external_id, currency = "EMP", opts = {}, conn = connection, reload=false) click to toggle source
# File lib/eme/billing.rb, line 25
def self.get_wallet(external_id, currency = "EMP", opts = {}, conn = connection, reload=false)
  if settings[:use_memcache] && !reload
    cached = cache.read("wallet-balance-#{external_id}-#{currency}")
    return cached if cached
    backup_cache = cache.read("wallet-balance-#{external_id}-#{currency}-bkup")
    if backup_cache  # Start ASYNC refresh here
      RefreshWalletWorker.new.async.perform(external_id, currency, opts)
      return backup_cache
    end
  end
  gamecode = opts[:game_code] || "TERA"
  wallet = nil
  request_path = "/Payment/rest/services/balance/v1/get/#{external_id}/#{gamecode}/#{currency}/"

  obj_hash = do_request(request_path, conn)

  if obj_hash["RESPONSE"]
    wallet = EME::Billing::Wallet.new(obj_hash["RESPONSE"])
  else
    wallet = EME::Billing::Wallet.new({"TOTREMAINAMT" => 0})
  end

  # save to memcache
  if settings[:use_memcache]
    cache.write("wallet-balance-#{external_id}-#{currency}", wallet, {:ttl => 300})
    cache.write("wallet-balance-#{external_id}-#{currency}-bkup", wallet, {:ttl => 3600})
  end
  wallet
end
items() click to toggle source
# File lib/eme/billing.rb, line 493
def self.items
  @@items
end
offers(game=nil, lang = nil, reset_cache = false, conn = connection) click to toggle source

Fetch the array of all offers. Will cache the results for 5 minutes if settings is true

Attributes

none

Options

none

Examples

EME::Billing.offers()

# File lib/eme/billing.rb, line 124
def self.offers(game=nil, lang = nil, reset_cache = false, conn = connection)
  custom_offers("all", game, lang, reset_cache, conn)
end
purchase(external_id, item, currency = "EMP", opts = {}, conn = connection) click to toggle source
# File lib/eme/billing.rb, line 235
def self.purchase(external_id, item, currency = "EMP", opts = {}, conn = connection)
  purchase_body = {}
  # We need accountID, and gameAccountId!!!
  purchase_body = {
    "USERNO" => external_id,
    "USERID" => opts[:email],
    "GAMEUSERNO" => opts[:game_account_id],
    "QUANTITY" => opts[:quantity ] || 1,
    "GAMECODE" => opts[:game_code],
    "USERSUBSET" => opts[:elite] ? "elite" : "normal",
    "PRICEID" => opts[:price_point_id],
    "COUNTRYCODE" => "SGS", #"USA"  # hard-coded due to bug in FFG system with ip addresses  We are using SGS (South Geargian, and the Sandwich Islands) to denote Web Sales.
    "CHARGEAMT" => opts[:amount],
    "LOCATION" => opts[:location] || "web",
    "ORDERTRANSACTIONID" => "#{external_id}-#{opts[:game_account_id]}-#{Time.now.strftime('%Y%m%d%H%M%S%L')}"
  }
  purchase_body["EVENTID"] = opts[:campaign_id] if opts[:campaign_id]
  purchase_body["CHECKSUM"] = checksum "#{external_id}|#{opts[:email]}|#{opts[:game_account_id]}|#{purchase_body['GAMECODE']}|#{opts[:price_point_id]}|SGS|#{purchase_body['ORDERTRANSACTIONID']}"

  raise RuntimeError, "Account required." if purchase_body["USERNO"].nil?
  raise RuntimeError, "Game Account required." if purchase_body["GAMEUSERNO"].nil?
  raise RuntimeError, "Price required." if purchase_body["PRICEID"].nil? || purchase_body["CHARGEAMT"].nil?
  #raise RuntimeError, "IP Address required." if purchase_body["ipAddress"].nil?
  raise RuntimeError, "Quantity required." if purchase_body["QUANTITY"].nil?

  json = JSON.generate(purchase_body)

  purchase_path = "/Payment/rest/services/purchase/v1/item"

  obj_hash = do_request(purchase_path, conn, {:method => :post, :body => json})
  # PUTS NOT CHECKING CORRECT ERROR MESSAGES YET!!! -CR-
  if(obj_hash["RETCODE"] == 9998)
    puts obj_hash.inspect
    return {"message" => "Server failed to remove your EMP.  Sorry no item for you right now.", "error" => true}
    #return {"message" => "You do not have enough EMP for this purchase.  Please buy EMP and try again.", "error" => true}
  elsif(obj_hash["RETCODE"] == 0)
    return {"transaction_id" => obj_hash["RESPONSE"]["TRANSACTIONID"], "error" => false, "price" => opts[:amount] || item.price }
  else
    puts obj_hash.inspect
    return {"message" => obj_hash["ERRMSG"], "error" => true}
  end
end
reload_wallet(external_id, currency = "EMP", opts = {}, conn = connection) click to toggle source

Fetch the balance of user with external id equal to external_id. Will cache the results for 5 minutes if settings is true

Attributes

  • external_id - master_account_id of the player

  • external_account_id - Game id of the game account you are connecting too (required if multiple game accounts)

Options

none

Examples

EME::Billing.get_wallet(609)

# File lib/eme/billing.rb, line 21
def self.reload_wallet(external_id, currency = "EMP", opts = {}, conn = connection)
  return get_wallet(external_id, currency, opts, conn, true)
end
secret_hash(user_id, game_account_id = 0) click to toggle source
# File lib/eme/billing.rb, line 317
def self.secret_hash(user_id, game_account_id = 0)
  return Digest::SHA1.hexdigest "#{settings[:mystery_key]}#{user_id}#{game_account_id}"
end
subscription_billing_info(external_id, conn = connection) click to toggle source

StoreAPI.do_request(“/Payment/rest/services/billinginfo/v1/get/100001”)

# File lib/eme/billing.rb, line 285
def self.subscription_billing_info(external_id, conn = connection)
  res = do_request("/Payment/rest/services/get/v1/Subscription/#{external_id}", conn)
  return res["RESPONSE"] if res["RESPONSE"]
  return res
end
subscription_by_id(gamecode, id, reload = false, conn = connection) click to toggle source
# File lib/eme/billing.rb, line 87
def self.subscription_by_id(gamecode, id, reload = false, conn = connection)
  subs = subscriptions(gamecode, [], true)
  return subs.currencies.select{|x| x.id == id }[0]
end
subscriptions(gamecode, types = [], invisible = false, reload = false, conn = connection) click to toggle source
# File lib/eme/billing.rb, line 59
def self.subscriptions(gamecode, types = [], invisible = false, reload = false, conn = connection)
  fetch_currencies(gamecode, "SUB", types, invisible, reload, conn)
end