nitro_pay 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,76 @@
1
+ module NitroPay
2
+ # Currency Obj, useful methods to work with many different countries
3
+ class Currency
4
+ # Receive it amount in Decimal and convert to operator str, like 10,00 or 10.00 to 1000
5
+ def self.to_operator_str(amount)
6
+ # Check invalid entry
7
+ return nil if amount.nil?
8
+ return amount.to_s if amount.is_a?Integer
9
+ amount = format('%.2f', amount) if amount.to_s.float?
10
+ return amount if amount.is_a?(String) && amount.index('.').nil? && amount.index(',').nil?
11
+
12
+ if amount.is_a?String
13
+ return amount if amount.index('.').nil? && amount.index(',').nil?
14
+
15
+ amount = amount.remove('.')
16
+ amount = amount.remove(',')
17
+
18
+ return amount
19
+ end
20
+
21
+ # Convert from BigDecimal
22
+ if amount.is_a?BigDecimal
23
+ aux_amount_str = amount.to_s('F')
24
+ cents = aux_amount_str[aux_amount_str.index('.'), aux_amount_str.length]
25
+
26
+ # Check if there is a bug because the Decimal didn't recognize the second 0
27
+ aux_amount_str = "#{aux_amount_str}0"if cents.index('.')
28
+
29
+ return aux_amount_str.remove('.')
30
+ end
31
+
32
+ # Create the amount as String
33
+ amount.is_a?(String) ? amount_str = amount : amount_str = amount.to_s
34
+ amount_str_not_formatted = amount_str.remove('.').remove(',')
35
+
36
+ # Create the full value
37
+ cents_value = amount_str_not_formatted[amount_str_not_formatted.length-2, amount_str_not_formatted.length-1]
38
+ integer_value = amount_str_not_formatted[0, amount_str_not_formatted.length-2]
39
+
40
+ # The return constraint
41
+ "#{integer_value}#{cents_value}"
42
+ end
43
+
44
+ # Receive it amount in Integer String (like 1000 that means 10,00 or 10.00) and convert to Decimal value
45
+ def self.to_decimal(amount)
46
+ # If it was passed a BigDecimal it must be passed to operator format
47
+ amount = Currency.to_operator_str(amount) if amount.is_a?BigDecimal
48
+
49
+ # Base vars
50
+ aux_amount = amount
51
+ cents_chars_counter = 2
52
+
53
+ # Building the currency str like BigDecimal understands
54
+ cents_str = aux_amount[aux_amount.length-cents_chars_counter..aux_amount.length]
55
+ integer_str = aux_amount[0, aux_amount.length-cents_chars_counter]
56
+ new_amount = "#{integer_str}.#{cents_str}"
57
+
58
+ BigDecimal.new new_amount
59
+ end
60
+
61
+ # Get it cents from operator amount formatted
62
+ def self.get_cents(amount)
63
+ aux = amount.to_s
64
+ cents_length = 2
65
+ aux[aux.length-cents_length, aux.length]
66
+ end
67
+
68
+ # Receive a numeric form operator format & retrieve it
69
+ def self.have_cents?(amount)
70
+ aux = "#{amount.to_f/100}" if amount.is_a?(String) || amount.is_a?(Integer)
71
+ aux = amount.to_s if amount.is_a?Float
72
+ cents = aux[aux.index('.')+1, aux.length]
73
+ cents.length == 2 ? true : false
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,55 @@
1
+ # Override ruby Hash Obj
2
+ class Hash
3
+ # Attr to be external accessible
4
+ attr_accessor :get_url_params
5
+
6
+ # Convert string keys to symbol keys
7
+ def it_keys_to_sym
8
+ self.keys.each do |key|
9
+ self[key].it_keys_to_sym if self[key].is_a?(Hash)
10
+ self[(key.to_sym rescue key) || key] = self.delete(key)
11
+ end
12
+
13
+ return self
14
+ end
15
+
16
+ # Convert it keys to get params
17
+ def it_keys_to_get_param
18
+ self.it_keys_to_sym
19
+ self.get_url_params = '?' if self.get_url_params.nil?
20
+
21
+ self.keys.each do |key|
22
+ self.get_url_params = self.get_url_params+'&' unless self.get_url_params.length == 1
23
+
24
+ # Nested obj_attrs
25
+ if self[key].is_a?(Hash)
26
+ hash_name = key
27
+ hash_obj = self[key]
28
+
29
+ # Hash to GET URL
30
+ param = to_nested_get_param hash_name, hash_obj
31
+ end
32
+
33
+ self.get_url_params = self.get_url_params+param
34
+ end
35
+
36
+ # Remove the last char: &
37
+ return self.get_url_params[0..self.get_url_params.length-2]
38
+ end
39
+
40
+ # SetUp a hash to hash URL GET
41
+ def to_nested_get_param(hash_name, hash_obj)
42
+ # initial value
43
+ get_nested_params = ''
44
+
45
+ # foreach keys to mount the URL_PARAM
46
+ hash_obj.keys.each do |key|
47
+ key_param = hash_obj[key].to_nested_get_param key, hash_obj[key] if hash_obj[key].is_a?(Hash)
48
+ key_param = "#{hash_name}[#{key}]=#{hash_obj[key]}&" unless hash_obj[key].is_a?(Hash)
49
+ get_nested_params = get_nested_params+key_param
50
+ end
51
+
52
+ # return
53
+ get_nested_params
54
+ end
55
+ end
@@ -0,0 +1,29 @@
1
+ module NitroPay
2
+ class Status < NitroPay::Connection
3
+ # Attrs
4
+ attr_accessor :message # API response message
5
+ attr_accessor :http_code # HTTP Code for the request
6
+ attr_accessor :api_code # Internal system response code
7
+ attr_accessor :response # the JSON retrieved
8
+
9
+ # Constructor
10
+ def initialize(params = {})
11
+ super # call it super initialize
12
+ self.path = 'status'
13
+ check_it
14
+ end
15
+
16
+ # Check it status and 'setup' it attrs
17
+ def check_it
18
+ self.path = 'status'
19
+ resp = get_request
20
+ hash_resp = JSON.parse(resp).it_keys_to_sym
21
+ self.http_code = resp.code
22
+ self.message = "EndPoint not response(connection error): #{self.url_requested}" if self.http_code != 200
23
+ self.message = hash_resp[:message] if self.http_code == 200
24
+ self.api_code = hash_resp[:api_code]
25
+ self.response = hash_resp
26
+ self
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,17 @@
1
+ class String
2
+ def remove(pattern)
3
+ gsub pattern, ''
4
+ end
5
+
6
+ def integer?
7
+ self.to_i.to_s == self
8
+ end
9
+
10
+ def float?
11
+ self.to_f.to_s == self
12
+ end
13
+
14
+ def equals?(str)
15
+ self == str
16
+ end
17
+ end
@@ -0,0 +1,123 @@
1
+ module NitroPay
2
+ # Transaction Obj, but can Abstract nested objs like Costumer
3
+ class Transaction < NitroPay::Connection
4
+ attr_accessor :resp
5
+ attr_accessor :status # can be API Status: self.status = NitroPay::Status.new OR/AND Transaction Status
6
+ attr_accessor :sold_items
7
+
8
+ # Constructor
9
+ def initialize(params = {})
10
+ super # super init call
11
+ # Base redirect_link if test_env is set (so the redirect is just appended)
12
+ self.redirect_link = "#{self.end_point_versioned}/transactions" if params[:test_env]
13
+ end
14
+
15
+ # Return it RID easily
16
+ def rid
17
+ self.resp[:rid]
18
+ end
19
+
20
+ # Return it Purchase URL, to pay on the OperatorPage
21
+ def purchase_url
22
+ self.resp[:purchase_url]
23
+ end
24
+
25
+ # GET /api/transactions/:rid by it attr
26
+ def verify
27
+ auth_hash = {}
28
+ auth_hash[:auth] = self.request_params[:auth]
29
+ if self.rid.nil? then return {error:'RID not received'} else self.path = "transactions/#{self.rid}/#{auth_hash.it_keys_to_get_param}" end
30
+ return self.get_json_request
31
+ end
32
+
33
+ # POST /api/transactions/page return operator page URL, like the Cielo Page
34
+ def charge_page(full_resp=false)
35
+ custom_http_params
36
+ # SetUp redirect dynamic if is test
37
+ self.request_params[:transaction][:redirect_link] = "#{self.redirect_link}" if self.request_params[:transaction][:test_env]
38
+
39
+ # dynamic path (it is written when a specific method use it)
40
+ self.path = 'transactions/page'
41
+
42
+ # using json_request because need only the answer (do not use something like it HTTP Code)
43
+ self.resp = self.post_json_request unless full_resp
44
+ self.resp = self.post_request if full_resp
45
+ self.resp
46
+ end
47
+
48
+ # POST /api/transactions
49
+ def charge_store(full_resp=false)
50
+ custom_http_params
51
+
52
+ # dynamic path (it is written when a specific method use it)
53
+ self.path = 'transactions/store'
54
+
55
+ # using json_request because need only the answer (do not use something like it HTTP Code)
56
+ full_resp ? self.resp = self.post_request : self.resp = self.post_json_request
57
+
58
+ # return it received resp
59
+ self.resp
60
+ end
61
+
62
+ # Update the recurrence amount
63
+ def update_subscription(rid=nil, full_resp=false)
64
+ # SetUp
65
+ self.recurrent_rid = rid if rid
66
+ self.path = "transactions/#{self.recurrent_rid}/subscription"
67
+
68
+ # Perform the request
69
+ full_resp ? self.resp = self.put_request : self.resp = self.put_json_request
70
+
71
+ # return it received resp
72
+ self.resp
73
+ end
74
+
75
+ # Stop a recurrence based on it transaction rid
76
+ def unsubscribe(rid=nil, full_resp=false)
77
+ # SetUp
78
+ self.recurrent_rid = rid if rid
79
+ self.path = "transactions/#{self.recurrent_rid}/subscription/unsubscribe"
80
+
81
+ # Perform the request
82
+ full_resp ? self.resp = self.delete_request : self.resp = self.delete_json_request
83
+
84
+ # return it received resp
85
+ self.resp
86
+ end
87
+
88
+ # Return the payments executed for the purchase passed
89
+ def payment_history(rid=nil, full_resp=false)
90
+ # SetUp
91
+ self.recurrent_rid = rid if rid
92
+ self.path = "transactions/#{self.recurrent_rid}/subscription/payment_history"
93
+ self.path = "#{self.path}#{self.request_params.it_keys_to_get_param}"
94
+
95
+ # Perform the request
96
+ full_resp ? self.resp = self.get_request : self.resp = self.get_json_request
97
+
98
+ # return it received resp
99
+ self.resp
100
+ end
101
+
102
+ # Check if a subscription is up-to-date or have any pending
103
+ def up_to_date(rid=nil, full_resp=false)
104
+ # SetUp
105
+ self.recurrent_rid = rid if rid
106
+
107
+ # Create/customize the path & add the auth as param
108
+ self.path = "transactions/#{self.recurrent_rid}/subscription/up-to-date"
109
+ self.path = "#{self.path}#{self.request_params.it_keys_to_get_param}"
110
+
111
+ # Perform the request
112
+ full_resp ? self.resp = self.get_request : self.resp = self.get_json_request
113
+
114
+ # return it received resp
115
+ self.resp
116
+ end
117
+
118
+ # ================ STATIC methods ================
119
+ # GET /api/transactions/:rid by the rid passed
120
+ def self.find(rid)
121
+ end
122
+ end
123
+ end
@@ -1,3 +1,6 @@
1
1
  module NitroPay
2
- VERSION = "0.1.0"
3
- end
2
+ MAJOR = 1
3
+ MINOR = 0
4
+ PATCH = 0
5
+ VERSION = "#{MAJOR}.#{MINOR}.#{PATCH}"
6
+ end
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,11 @@
1
+ BANDEIRA | Autenticação | Número Cartão | Validade | Cod. Segurança
2
+ VISA | OK | 4012001037141112 | 05/2018 | 123
3
+ MASTER | OK | 5453010000066167 | 05/2018 | 123
4
+ VISA | NO | 4012001038443335 | 05/2018 | 123
5
+ MASTER | NO | 5453010000066167 | 05/2018 | 123
6
+ AMERICAN EXP| NO | 376449047333005 | 05/2018 | 1234
7
+ ELO | NO | 6362970000457013 | 05/2018 | 123
8
+ DINNERS | NO | 36490102462661 | 05/2018 | 123
9
+ DISCOVER | NO | 6011020000245045 | 05/2018 | 123
10
+ JCB | NO | 3566007770004971 | 05/2018 | 123
11
+ AURA | NO |5078601912345600019| 05/2018 | 123
@@ -0,0 +1,3 @@
1
+ Type | Membership number | Access Key
2
+ Store | 1006993069 | 25fbb99741c739dd84d7b06ec78c9bac718838630f30b112d033ce2e621b34f3
3
+ Cielo | 1001734898 | e84827130b9837473681c2787007da5914d6359947015a5cdb2b8843db0fa832
@@ -0,0 +1,42 @@
1
+ module Helpers
2
+ def comment_proxy_yml
3
+ process_file :comment
4
+ end
5
+
6
+ def uncomment_proxy_yml
7
+ process_file :uncomment
8
+ end
9
+
10
+ def process_file action
11
+ file_path = './lib/nitro_pay/config/proxy.yml'
12
+ file = File.open(file_path, 'r+')
13
+ old_lines = file.readlines
14
+ new_lines = []
15
+
16
+ # Create the new lines
17
+ if action == :comment
18
+ old_lines.each do |old_line|
19
+ unless old_line[0] == '#'
20
+ old_line = '#' + old_line
21
+ end
22
+
23
+ new_lines << old_line
24
+ end
25
+ elsif action == :uncomment
26
+ old_lines.each do |old_line|
27
+ new_lines << old_line.remove('#')
28
+ end
29
+ end
30
+
31
+ write_lines file_path, new_lines
32
+ end
33
+
34
+ # Write the new lines
35
+ def write_lines file_path, new_lines
36
+ File.open(file_path, 'w') do |file|
37
+ new_lines.each do |new_line|
38
+ file.puts new_line
39
+ end
40
+ end
41
+ end
42
+ end
data/spec/helpers.rb ADDED
@@ -0,0 +1,56 @@
1
+ require 'file_helper'
2
+ module Helpers
3
+ def http_success
4
+ 200
5
+ end
6
+
7
+ def accessible? url
8
+ RestClient.proxy = NitroPay.proxy
9
+ resp = RestClient.get url
10
+ RestClient.proxy = nil
11
+ resp.code == 200 ? true : false
12
+ end
13
+
14
+ def fake_sold_items
15
+ sold_items = []
16
+
17
+ count = 0
18
+ items_amount = 3
19
+
20
+ until count == items_amount do
21
+ count = count+1
22
+ rand_count_departments = Random.new.rand(1..10)
23
+ sold_item = {
24
+ remote_id: Faker::Number.number(count),
25
+ name: Faker::Commerce.product_name,
26
+ description: Faker::Commerce.department(rand_count_departments, rand_count_departments==2)
27
+ }
28
+
29
+ sold_items << sold_item
30
+ end
31
+
32
+ sold_items
33
+ end
34
+
35
+ def get_json url
36
+ resp = RestClient.get url
37
+ JSON.parse(resp).it_keys_to_sym
38
+ end
39
+
40
+ def page_transaction_mock(card_brand, amount, redir_link)
41
+ page = {}
42
+ page[:transaction] = NitroPay::Transaction.new({
43
+ card:{brand: card_brand},
44
+ clients:{name:Faker::Name.name, email:Faker::Internet.free_email, legal_id:CPF.generate},
45
+ amount: amount, # The last 2 numbers are the cents
46
+ redirect_link: redir_link # (* optional) used only for CieloPage
47
+ })
48
+
49
+ # Fake SoldItems added
50
+ page[:transaction].sold_items = fake_sold_items
51
+
52
+ # Perform BuyPage
53
+ page[:resp] = page[:transaction].charge_page
54
+ page
55
+ end
56
+ end