nitro_pay 0.1.0 → 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.
@@ -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