test_ruby 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/kount.rb +28 -0
- data/lib/kount/cart.rb +36 -0
- data/lib/kount/client.rb +124 -0
- data/lib/kount/payment_types.rb +52 -0
- data/lib/kount/request.rb +41 -0
- data/lib/kount/request/inquiry.rb +85 -0
- data/lib/kount/request/update.rb +28 -0
- data/lib/kount/ris-inquiry.rb +33 -0
- data/lib/kount/security_mash.rb +82 -0
- data/lib/kount/utils/khash.rb +49 -0
- metadata +87 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 24de3c82081a4eb24f4777e696ff181004009a168cb8a88d289829eb2dede6f1
|
4
|
+
data.tar.gz: e186054c1fb43bcd9e9ec663c25b70c08bf62ac2136850ac0298d24364776cc2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 291231e2ff81415cc3e239524677dbd0da31b3a21c1de6af91cdf9111ec71bf11ef50589e23b7a424bbb87704d69a10ffdd900855146da7f9140db01220333ec
|
7
|
+
data.tar.gz: '08082a29bf662c340d13fa4aa6b550787bd37e539fb94d7835c9a83c523b43a73af4bbd828119d0ddb6ea578170b2a977d1fd7337e04584a9ab4677283c146eb'
|
data/lib/kount.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'kount/client'
|
2
|
+
require 'kount/payment_types'
|
3
|
+
|
4
|
+
##
|
5
|
+
# This module is the main entry point to the service wrapper.
|
6
|
+
# Its primary function is to collect the runtime options
|
7
|
+
# and return a Client object, on which all of the runtime
|
8
|
+
# integration takes place.
|
9
|
+
module Kount
|
10
|
+
# Creates the client object
|
11
|
+
#
|
12
|
+
# Expected options include:
|
13
|
+
# options = {
|
14
|
+
# :merchant_id => "MERCHANT_ID" # required (6 digit number)
|
15
|
+
# :ksalt => "KSALT" # required (provided by Kount)
|
16
|
+
# :key => "RIS_KEY" # required (created in the AWC web app)
|
17
|
+
# :endpoint => "RIS_ENDPOINT" # optional (default https://risk.kount.net)
|
18
|
+
# :version => "RIS_VERSION" # optional (defaults "0630")
|
19
|
+
# :is_test => "IS_TEST" # optional (defaults to false)
|
20
|
+
# }
|
21
|
+
# @param options Hash
|
22
|
+
def new(options = {})
|
23
|
+
fail ArgumentError, 'Config options required' if options.empty?
|
24
|
+
Client.new(options)
|
25
|
+
end
|
26
|
+
|
27
|
+
module_function :new
|
28
|
+
end
|
data/lib/kount/cart.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
module Kount
|
2
|
+
##
|
3
|
+
# This class handles cart data until the get_request is ready
|
4
|
+
# to push the data into the form fields
|
5
|
+
class Cart
|
6
|
+
attr_accessor :items
|
7
|
+
|
8
|
+
# Initialize cart object
|
9
|
+
def initialize
|
10
|
+
@items = []
|
11
|
+
end
|
12
|
+
|
13
|
+
# Add cart items
|
14
|
+
#
|
15
|
+
# @param item [String] Cart item name
|
16
|
+
# @param type [String] Cart type name
|
17
|
+
# @param desc [String] Cart item long description
|
18
|
+
# @param quant [String] Cart item quantity
|
19
|
+
# @param price [String] Cart item price in cents
|
20
|
+
def add_item(item, type, desc, quant, price)
|
21
|
+
@items << { TYPE: type,
|
22
|
+
DESC: desc,
|
23
|
+
ITEM: item,
|
24
|
+
QUANT: quant,
|
25
|
+
PRICE: price }
|
26
|
+
end
|
27
|
+
|
28
|
+
# Initialize an Inquiry object
|
29
|
+
#
|
30
|
+
# @param param [String] Param type: :TYPE, :DESC, :ITEM, :PRICE, or :QUANT
|
31
|
+
# @return [Array] Ordered array of the cart contents for each param type
|
32
|
+
def get_item(param)
|
33
|
+
@items.collect { |item| item[param] }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/kount/client.rb
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'kount/security_mash'
|
2
|
+
require 'kount/cart'
|
3
|
+
require 'kount/request'
|
4
|
+
require 'kount/request/update'
|
5
|
+
require 'kount/request/inquiry'
|
6
|
+
require 'rest-client'
|
7
|
+
require 'uri'
|
8
|
+
|
9
|
+
# rubocop:disable Style/ClassVars
|
10
|
+
module Kount
|
11
|
+
##
|
12
|
+
# This class is where the primary interaction with
|
13
|
+
# the merchant integration will take place.
|
14
|
+
class Client
|
15
|
+
# Tells the RIS server to respond in JSON instead of key/value pairs
|
16
|
+
# This cannot be overridden.
|
17
|
+
RESPONSE_FORMAT = 'JSON'
|
18
|
+
|
19
|
+
# RIS Version. Can be overridden my merchant if required.
|
20
|
+
DEFAULT_VERSION = '0630'
|
21
|
+
|
22
|
+
# Default endpoint for production. Used by the DEFAULT_OPTIONS
|
23
|
+
ENDPOINT_PROD = 'https://risk.kount.net'
|
24
|
+
|
25
|
+
# Default endpoint for test. Used by the TEST_DEFAULT_OPTIONS
|
26
|
+
ENDPOINT_TEST = 'https://risk.test.kount.net'
|
27
|
+
|
28
|
+
# Default params for production
|
29
|
+
PROD_DEFAULT_OPTIONS = {
|
30
|
+
endpoint: ENDPOINT_PROD,
|
31
|
+
version: DEFAULT_VERSION,
|
32
|
+
is_test: false
|
33
|
+
}
|
34
|
+
|
35
|
+
# Default params for test if is_test is TRUE
|
36
|
+
TEST_DEFAULT_OPTIONS = {
|
37
|
+
endpoint: ENDPOINT_TEST,
|
38
|
+
version: DEFAULT_VERSION
|
39
|
+
}
|
40
|
+
|
41
|
+
# Initialize a client object
|
42
|
+
#
|
43
|
+
# Example usage
|
44
|
+
# {:merchant_id => "123456", :key => "trhvihsrihsta7ftadk6edkre7y8..."}
|
45
|
+
#
|
46
|
+
# @param params [Hash] Hash with merchant_id, ksalt and key, plus any
|
47
|
+
# other optional params
|
48
|
+
def initialize(params = {})
|
49
|
+
@options = {}
|
50
|
+
if params[:is_test]
|
51
|
+
@options.merge!(TEST_DEFAULT_OPTIONS)
|
52
|
+
else
|
53
|
+
@options.merge!(PROD_DEFAULT_OPTIONS)
|
54
|
+
end
|
55
|
+
@options.merge!(params)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Makes the call to the Kount RIS server
|
59
|
+
#
|
60
|
+
# @param request [Kount::Request] Kount inquiry or update object
|
61
|
+
# @return [Hash] RIS response formatted into a native hash
|
62
|
+
def get_response(request)
|
63
|
+
params = prepare_request_params(request)
|
64
|
+
response = {}
|
65
|
+
begin
|
66
|
+
response = RestClient::Resource.new(
|
67
|
+
endpoint,
|
68
|
+
verify_ssl: verify_ssl_option, timeout: 1).post params, x_kount_api_key: key
|
69
|
+
|
70
|
+
JSON.parse(response)
|
71
|
+
rescue
|
72
|
+
# RIS errors do not come back as JSON, so just pass them along raw.
|
73
|
+
response
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Give the request object what it needs to know to process the params
|
78
|
+
# to send to RIS.
|
79
|
+
def prepare_request_params(request)
|
80
|
+
request.prepare_params(version, merchant_id, RESPONSE_FORMAT, ksalt)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Kount Merchant ID
|
84
|
+
def merchant_id
|
85
|
+
@options[:merchant_id]
|
86
|
+
end
|
87
|
+
|
88
|
+
# RIS Interface Version
|
89
|
+
def version
|
90
|
+
@options[:version]
|
91
|
+
end
|
92
|
+
|
93
|
+
# RIS Endpoint URL
|
94
|
+
def endpoint
|
95
|
+
@options[:endpoint]
|
96
|
+
end
|
97
|
+
|
98
|
+
# Merchant API for RIS acess
|
99
|
+
def key
|
100
|
+
@options[:key]
|
101
|
+
end
|
102
|
+
|
103
|
+
# Secret Kount salt for KHASH
|
104
|
+
def ksalt
|
105
|
+
@options[:ksalt]
|
106
|
+
end
|
107
|
+
|
108
|
+
# Is test or production setting
|
109
|
+
def test?
|
110
|
+
@options[:is_test]
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
# Helper method to turn on/off the SSL cert verify based on is_test config
|
116
|
+
def verify_ssl_option
|
117
|
+
if test?
|
118
|
+
OpenSSL::SSL::VERIFY_NONE
|
119
|
+
else
|
120
|
+
OpenSSL::SSL::VERIFY_PEER
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Kount
|
2
|
+
##
|
3
|
+
# Convenience class to provide a list of PTYP values
|
4
|
+
class PaymentTypes
|
5
|
+
# Credit card (VISA, MasterCard, Amercian Express, etc)
|
6
|
+
CREDIT_CARD = 'CARD'
|
7
|
+
#Generic Token
|
8
|
+
TOKEN = 'TOKEN'
|
9
|
+
# PayPal
|
10
|
+
PAYPAL = 'PYPL'
|
11
|
+
# Check
|
12
|
+
CHECK = 'CHEK'
|
13
|
+
# Merchant issued gift card (not the ones with VISA/MC on them)
|
14
|
+
GIFT_CARD = 'GIFT'
|
15
|
+
# Carte Bleue
|
16
|
+
CARTE_BLEUE = 'CARTE_BLEUE'
|
17
|
+
# Sofort
|
18
|
+
SOFORT = 'SOFORT'
|
19
|
+
# Elv
|
20
|
+
ELV = 'ELV'
|
21
|
+
# Poli
|
22
|
+
POLI = 'POLI'
|
23
|
+
# Neteller
|
24
|
+
NETELLER = 'NETELLER'
|
25
|
+
# Giropay
|
26
|
+
GIROPAY = 'GIROPAY'
|
27
|
+
# BPay
|
28
|
+
BPAY = 'BPAY'
|
29
|
+
# Interac
|
30
|
+
INTERAC = 'INTERAC'
|
31
|
+
# Apple Pay
|
32
|
+
APPLE_PAY = 'APAY'
|
33
|
+
# Skrill
|
34
|
+
SKRILL = 'SKRILL'
|
35
|
+
# Moneybooker (basically another name for Skrill)
|
36
|
+
MONEYBOOKERS = 'SKRILL'
|
37
|
+
# Mercado Pago
|
38
|
+
MERCADO_PAGO = 'MERCADE_PAGO'
|
39
|
+
# Bill Me Later
|
40
|
+
BILL_ME_LATER = 'BLML'
|
41
|
+
# Google Checkout
|
42
|
+
GOOGLE_CHECKOUT = 'GOOG'
|
43
|
+
# Green Dot Money Pack
|
44
|
+
GREEN_DOT_MONEY_PACK = 'GDMP'
|
45
|
+
# Single Euro Payments Area
|
46
|
+
SINGLE_EURO_PAYMENTS_AREA = 'SEPA'
|
47
|
+
# None
|
48
|
+
NONE = 'NONE'
|
49
|
+
# Other
|
50
|
+
OTHER = 'OTHER'
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'kount/security_mash'
|
2
|
+
module Kount
|
3
|
+
##
|
4
|
+
# This class acts as an abstract class for each type of request.
|
5
|
+
class Request
|
6
|
+
attr_accessor :params
|
7
|
+
|
8
|
+
# Initialize a Request object
|
9
|
+
#
|
10
|
+
# Example usage
|
11
|
+
# Not used directly. Use Inquiry or Update instead.
|
12
|
+
#
|
13
|
+
# @param initial_params [Hash] Initial params for request
|
14
|
+
def initialize(initial_params = {})
|
15
|
+
fail "Cannot directly instantiate a #{self.class}." if
|
16
|
+
self.class == Request
|
17
|
+
@params = initial_params
|
18
|
+
end
|
19
|
+
|
20
|
+
# Add params to the current request object
|
21
|
+
# @param hash [Hash] Hash of values to be added
|
22
|
+
def add_params(hash)
|
23
|
+
@params.merge!(hash)
|
24
|
+
end
|
25
|
+
|
26
|
+
# This method creates the final state of the params collection such that
|
27
|
+
# it can be sent to RIS. Items that are specific to either the Inquiry
|
28
|
+
# or Update calls are delegated to the prepare_params method in each
|
29
|
+
# respective class.
|
30
|
+
#
|
31
|
+
# @param version [String] RIS version
|
32
|
+
# @param merchant_id [String] Merchant ID
|
33
|
+
# @param response_format [String] Response format (JSON)
|
34
|
+
# @param _ksalt [String] Kount supplied secret salt for KHASH
|
35
|
+
def prepare_params(version, merchant_id, response_format, _ksalt = '')
|
36
|
+
# The KSALT is not used here, however, it is used in the corresponding
|
37
|
+
# subclass prepare_params methods.
|
38
|
+
params.merge!(VERS: version, MERC: merchant_id, FRMT: response_format)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Kount
|
2
|
+
##
|
3
|
+
# This class extends the Request class.
|
4
|
+
class Inquiry < Request
|
5
|
+
attr_accessor :cart
|
6
|
+
|
7
|
+
# Initialize an Inquiry object
|
8
|
+
#
|
9
|
+
# Example usage
|
10
|
+
# {:MACK => "Y", :AUTH => "A"}
|
11
|
+
#
|
12
|
+
# @param initial_params [Hash] Initial params for request
|
13
|
+
def initialize(initial_params = {})
|
14
|
+
super(initial_params)
|
15
|
+
@cart = Cart.new
|
16
|
+
# We want Request to default to MODE Q unless a different mode has
|
17
|
+
# been passed.
|
18
|
+
add_params(MODE: 'Q') unless initial_params.key?(:MODE)
|
19
|
+
end
|
20
|
+
|
21
|
+
# @param version [String] RIS version
|
22
|
+
# @param merchant_id [String] Merchant ID
|
23
|
+
# @param response_format [String] Response format (JSON)
|
24
|
+
# @param ksalt [String] Kount supplied secret salt for KHASH
|
25
|
+
def prepare_params(version, merchant_id, response_format, ksalt)
|
26
|
+
super(version, merchant_id, response_format, ksalt)
|
27
|
+
begin
|
28
|
+
params.merge! collect_cart_items
|
29
|
+
# The Kount::Request has no knowledge of the KSALT or merchant_id, both
|
30
|
+
# of which are needed for KHASH. Request form params have everything we
|
31
|
+
# need at this point to do the KHASH if needed.
|
32
|
+
fixup_payment_params(ksalt, merchant_id)
|
33
|
+
end
|
34
|
+
params
|
35
|
+
end
|
36
|
+
|
37
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
38
|
+
def fixup_payment_params(ksalt, merchant_id)
|
39
|
+
ptok = params[:PTOK]
|
40
|
+
case params[:PTYP]
|
41
|
+
when 'CARD', 'TOKEN'
|
42
|
+
ptok = Kount::SecurityMash.hash_credit_card(ptok, ksalt)
|
43
|
+
params.merge!(PTOK: ptok, PENC: 'KHASH')
|
44
|
+
when 'GIFT', 'OTHER'
|
45
|
+
ptok = Kount::SecurityMash.hash_gift_card(ptok, ksalt, merchant_id)
|
46
|
+
params.merge!(PTOK: ptok, PENC: 'KHASH')
|
47
|
+
when 'NONE'
|
48
|
+
params.merge!(PTOK: nil, PENC: nil)
|
49
|
+
else
|
50
|
+
params[:PENC] ||= 'NONE'
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Pulls the cart data into the request params hash
|
55
|
+
def collect_cart_items
|
56
|
+
{
|
57
|
+
PROD_TYPE: cart.get_item(:TYPE),
|
58
|
+
PROD_DESC: cart.get_item(:DESC),
|
59
|
+
PROD_ITEM: cart.get_item(:ITEM),
|
60
|
+
PROD_PRICE: cart.get_item(:PRICE),
|
61
|
+
PROD_QUANT: cart.get_item(:QUANT)
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
# Puts the cart object into the request for processing
|
66
|
+
# @param cart [Kount::Cart] Cart object
|
67
|
+
def add_cart(cart)
|
68
|
+
@cart = cart
|
69
|
+
end
|
70
|
+
|
71
|
+
# Add UDF to request
|
72
|
+
# @param name [String] UDF label name
|
73
|
+
# @param value [String] UDF value
|
74
|
+
def add_udf(name, value)
|
75
|
+
@params.merge!("UDF[#{name}]" => value)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Convenience method to create the payment params
|
79
|
+
# @param type [String] Payment type
|
80
|
+
# @param token [String] Payment token
|
81
|
+
def add_payment(type, token = '')
|
82
|
+
add_params(PTYP: type, PTOK: token)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Kount
|
2
|
+
##
|
3
|
+
# This class extends the Request class and is used in the
|
4
|
+
# process of sending updates to an existing transaction
|
5
|
+
# generated by a previous Inquiry request.
|
6
|
+
class Update < Request
|
7
|
+
# Initialize an Update object
|
8
|
+
#
|
9
|
+
# Example usage
|
10
|
+
# {:MACK => "Y", :AUTH => "A"}
|
11
|
+
#
|
12
|
+
# @param initial_params [Hash] Initial params for request
|
13
|
+
def initialize(initial_params = {})
|
14
|
+
super(initial_params)
|
15
|
+
# Default to mode U unless mode X is explicitly set
|
16
|
+
add_params(MODE: 'U') unless initial_params[:MODE] == 'X'
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param version [String] RIS version
|
20
|
+
# @param merchant_id [String] Merchant ID
|
21
|
+
# @param response_format [String] Response format (JSON)
|
22
|
+
# @param ksalt [String] Kount supplied secret salt for KHASH
|
23
|
+
def prepare_params(version, merchant_id, response_format, ksalt)
|
24
|
+
super(version, merchant_id, response_format, ksalt)
|
25
|
+
params
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'kount'
|
2
|
+
|
3
|
+
|
4
|
+
options = {
|
5
|
+
merchant_id: 900431, #required (6 digit number, assigned by Kount)
|
6
|
+
key: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiI5MDA0MzEiLCJhdWQiOiJLb3VudC4xIiwiaWF0IjoxNTU0MjYwMTE5LCJzY3AiOnsia2EiOm51bGwsImtjIjpudWxsLCJhcGkiOnRydWUsInJpcyI6dHJ1ZX19.d0_1SHKePnTjsKsiaE6JJonfbMuT8AlaCgnkFs1PwwA', #required (created in the AWC web app by merchant)
|
7
|
+
ksalt: '1b^jIFD)e1@<ZKuH"A+?Ea`p+ATAo6@:Wee+EM+(FD5Z2/N<' , #required (provided by Kount)
|
8
|
+
endpoint: 'https://risk.test.kount.net',
|
9
|
+
version: '0630',
|
10
|
+
is_test: true #RIS endpoint is set to Kount Test Server setting
|
11
|
+
}
|
12
|
+
client = Kount.new(options)
|
13
|
+
inquiry = Kount::Inquiry.new(
|
14
|
+
SITE: "DEFAULT",
|
15
|
+
MACK: "Y",
|
16
|
+
AUTH: "A",
|
17
|
+
ORDR: "3458",
|
18
|
+
TOTL: "5000",
|
19
|
+
EMAL: "sanjeev.kumar@intimetec.com",
|
20
|
+
MODE:'Q'
|
21
|
+
|
22
|
+
)
|
23
|
+
|
24
|
+
inquiry.add_params(CURR:"USD", IPAD:"49.206.242.238",SESS:"70093SDDFDSFDSSDFS")
|
25
|
+
#inquiry.add_payment(Kount::PaymentTypes::CREDIT_CARD, "4111111111111111")
|
26
|
+
#inquiry.add_payment(Kount::PaymentTypes::GIFT_CARD, "4111111111111111")
|
27
|
+
inquiry.add_payment(Kount::PaymentTypes::CHECK, "01234567811111111111111")
|
28
|
+
|
29
|
+
cart = Kount::Cart.new()
|
30
|
+
cart.add_item('32 inch LCD TV', 'Electronics', 'Television', '44', '1000')
|
31
|
+
inquiry.add_cart(cart)
|
32
|
+
response = client.get_response(inquiry)
|
33
|
+
puts response.to_s()
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
module Kount
|
3
|
+
##
|
4
|
+
# This class implements the Kount KHASH for cards and gift cards.
|
5
|
+
# rubocop:disable Style/Documentation
|
6
|
+
class SecurityMash
|
7
|
+
# @param plain_text [String] String to be hashed
|
8
|
+
# @param ptyp [String] Payment type code: CARD, GIFT, or OTHER
|
9
|
+
# @return [String] KHASH version of string
|
10
|
+
def self.hash_token(plain_text, ptyp, ksalt, merchant_id = '')
|
11
|
+
if ptyp == 'CARD'
|
12
|
+
hash_credit_card(plain_text, ksalt)
|
13
|
+
else
|
14
|
+
hash_gift_card(plain_text, ksalt, merchant_id)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Hash a credit card number.
|
19
|
+
# Preserves first six characters of the input so that hashed cards can be
|
20
|
+
# categorized by Bank Identification Number (BIN).
|
21
|
+
#
|
22
|
+
# Example usage:
|
23
|
+
# hashed = Kount::SecurityMash.hash_credit_card("4111111111111111")
|
24
|
+
# Expect: 411111WMS5YA6FUZA1KC
|
25
|
+
# hashed = Kount::SecurityMash.hash_credit_card("5199185454061655")
|
26
|
+
# Expect: 5199182NOQRXNKTTFL11
|
27
|
+
# hashed = Kount::SecurityMash.hash_credit_card("4259344583883")
|
28
|
+
# Expect: 425934FEXQI1QS6TH2O5
|
29
|
+
#
|
30
|
+
# @param plain_text [String] String to be hashed
|
31
|
+
# @return [String] KHASH version of string
|
32
|
+
def self.hash_credit_card(plain_text, ksalt)
|
33
|
+
return plain_text if khashed?(plain_text)
|
34
|
+
first_six = plain_text[0..5]
|
35
|
+
mashed = mash(plain_text, 14, ksalt)
|
36
|
+
"#{first_six}#{mashed}"
|
37
|
+
end
|
38
|
+
|
39
|
+
# Hash a gift card number.
|
40
|
+
# Use the six characters of the merchant id so that hashed cards can be
|
41
|
+
# unique across the entire domain.
|
42
|
+
#
|
43
|
+
# Example usage:
|
44
|
+
# hashed = Kount::SecurityMash.hash_gift_card("123456", "3245876")
|
45
|
+
# Expect: 1234569HXH32Y5NNJCGB
|
46
|
+
|
47
|
+
# @param plain_text [String] String to be hashed
|
48
|
+
# @return [String] KHASH version of string
|
49
|
+
def self.hash_gift_card(plain_text, ksalt, merchant_id)
|
50
|
+
mashed = mash(plain_text, 14, ksalt)
|
51
|
+
"#{merchant_id}#{mashed}"
|
52
|
+
end
|
53
|
+
|
54
|
+
# Compute a base64 hash of the provided data.
|
55
|
+
#
|
56
|
+
# @param data [String] Data to hash
|
57
|
+
# @param len [int] Length of hash to retain
|
58
|
+
# @return [String] Hashed data
|
59
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
60
|
+
def self.mash(data, len, m)
|
61
|
+
a = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
62
|
+
r = Digest::SHA1.hexdigest("#{data}.#{m}")
|
63
|
+
c = ''
|
64
|
+
len = 17 if len > 17
|
65
|
+
limit = 2 * len
|
66
|
+
i = 0
|
67
|
+
while i < limit
|
68
|
+
c << a[r[i..i + 6].to_i(16) % 36]
|
69
|
+
i += 2
|
70
|
+
end
|
71
|
+
c
|
72
|
+
end
|
73
|
+
|
74
|
+
# end mash
|
75
|
+
|
76
|
+
# @param val [String] Token that may or may not be khashed
|
77
|
+
# @return [Boolean] True if token is already khashed
|
78
|
+
def self.khashed?(val)
|
79
|
+
true if val =~ /(\d{6}[A-Z0-9]{14})/
|
80
|
+
end
|
81
|
+
end # end KountSecurityMash
|
82
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Kount
|
2
|
+
class NewKhash
|
3
|
+
# @param plain_text [String] String to be hashed
|
4
|
+
# @param ptyp [String] Payment type code: CARD, GIFT, or OTHER
|
5
|
+
# @return [String] KHASH version of string
|
6
|
+
def self.hash_token(plain_text, ptyp, ksalt, merchant_id = '')
|
7
|
+
puts ptyp
|
8
|
+
exit
|
9
|
+
if ptyp == 'CARD'
|
10
|
+
HashPaymentToken(plain_text, ksalt)
|
11
|
+
elsif ptyp == 'CHEK'
|
12
|
+
HashCheckPayment(plain_text, ksalt)
|
13
|
+
else
|
14
|
+
HashGiftCard(plain_text, ksalt, merchant_id)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.getKhash(data, len, m)
|
19
|
+
a = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
20
|
+
r = Digest::SHA1.hexdigest("#{data}.#{m}")
|
21
|
+
c = ''
|
22
|
+
len = 17 if len > 17
|
23
|
+
limit = 2 * len
|
24
|
+
i = 0
|
25
|
+
while i < limit
|
26
|
+
c << a[r[i..i + 6].to_i(16) % 36]
|
27
|
+
i += 2
|
28
|
+
end
|
29
|
+
c
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.HashPaymentToken(plain_text, ksalt)
|
33
|
+
first_six = plain_text[0..5]
|
34
|
+
mashed = getKhash(plain_text, 14, ksalt)
|
35
|
+
"#{first_six}#{mashed}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.HashCheckPayment(plain_text, ksalt)
|
39
|
+
first_six = plain_text[0..5]
|
40
|
+
mashed = getKhash(plain_text, 14, ksalt)
|
41
|
+
"#{first_six}#{mashed}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.HashGiftCard(plain_text, ksalt, merchant_id)
|
45
|
+
mashed = getKhash(plain_text, 14, ksalt)
|
46
|
+
"#{merchant_id}#{mashed}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: test_ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- TestRuby
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-06-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.8.0
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.0.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 1.8.0
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 3.0.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rspec
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :development
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
description: A wrapper to facilitate making TEST Rubi calls
|
48
|
+
email: sanjeev@intimetec.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- lib/kount.rb
|
54
|
+
- lib/kount/cart.rb
|
55
|
+
- lib/kount/client.rb
|
56
|
+
- lib/kount/payment_types.rb
|
57
|
+
- lib/kount/request.rb
|
58
|
+
- lib/kount/request/inquiry.rb
|
59
|
+
- lib/kount/request/update.rb
|
60
|
+
- lib/kount/ris-inquiry.rb
|
61
|
+
- lib/kount/security_mash.rb
|
62
|
+
- lib/kount/utils/khash.rb
|
63
|
+
homepage: http://rubygems.org/gems/test_ruby
|
64
|
+
licenses:
|
65
|
+
- MIT
|
66
|
+
metadata: {}
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.9.3
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 1.3.5
|
81
|
+
requirements: []
|
82
|
+
rubyforge_project:
|
83
|
+
rubygems_version: 2.7.6.2
|
84
|
+
signing_key:
|
85
|
+
specification_version: 4
|
86
|
+
summary: Test Ruby Services Wrapper
|
87
|
+
test_files: []
|