fintecture 0.1.9 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,61 +1,262 @@
1
- require 'json'
2
- require 'faraday'
3
- require 'fintecture/api/endpoints/pis'
4
- require 'fintecture/api/base_url'
5
-
6
- module Fintecture
7
- class Pis
8
- class << self
9
-
10
- # Headers
11
- def prepare_payment(access_token, payload)
12
- url = prepare_payment_endpoint
13
-
14
- Fintecture::Faraday::Authentication::Connection.post(
15
- url: url,
16
- req_body: payload.to_json,
17
- custom_content_type: 'application/json',
18
- bearer: "Bearer #{access_token}",
19
- secure_headers: true
20
- )
21
- end
22
-
23
- # This needs headers
24
- def get_payments(access_token, session_id)
25
- url = payment_endpoint
26
-
27
- Fintecture::Faraday::Authentication::Connection.get(
28
- url: "#{url}/#{session_id}",
29
- custom_content_type: 'application/json',
30
- bearer: "Bearer #{access_token}",
31
- secure_headers: true
32
- )
33
- end
34
-
35
- def get_access_token
36
- response = Fintecture::Authentication.get_access_token
37
-
38
- JSON.parse response.body
39
- end
40
-
41
- private
42
-
43
- def prepare_payment_endpoint
44
- "#{api_base_url}/#{Fintecture::Api::Endpoints::Pis::PREPARE}"
45
- end
46
-
47
- def payment_endpoint
48
- "#{api_base_url}/#{Fintecture::Api::Endpoints::Pis::PAYMENTS}"
49
- end
50
-
51
- def base_url
52
- Fintecture::Api::BaseUrl::FINTECTURE_CONNECT_URL[Fintecture.environment.to_sym]
53
- end
54
-
55
- def api_base_url
56
- Fintecture::Api::BaseUrl::FINTECTURE_API_URL[Fintecture.environment.to_sym]
57
- end
58
-
59
- end
60
- end
1
+ require 'json'
2
+ require 'faraday'
3
+ require 'fintecture/api/endpoints/pis'
4
+ require 'fintecture/api/base_url'
5
+
6
+ module Fintecture
7
+ class Pis
8
+ class << self
9
+
10
+
11
+
12
+
13
+ # ------------ PUBLIC METHODS ------------
14
+ # Connect
15
+ def get_connect(access_token = nil, payment_attrs = nil)
16
+ # Build the request payload
17
+ payload = build_payload_connect(as_json payment_attrs)
18
+ # Do the _get_connect_request request
19
+ _get_connect_request access_token, payload, payment_attrs
20
+ end
21
+
22
+ # Request_to_pay
23
+ def request_to_pay(access_token = nil, payment_attrs = nil)
24
+ # Build the request payload
25
+ payload = build_payload_request_to_pay(as_json payment_attrs)
26
+ # Do the _request_to_pay_request request
27
+ _request_to_pay_request access_token, payload, payment_attrs
28
+ end
29
+
30
+ # Get_payments
31
+ def get_payments(access_token = nil, session_id = nil)
32
+ # Do the get_payments request
33
+ _get_payments_request access_token, session_id
34
+ end
35
+
36
+ # Get_access_token
37
+ def get_access_token
38
+ # Do the get_access_token request
39
+ response = Fintecture::Authentication.get_access_token
40
+ JSON.parse response.body
41
+ end
42
+
43
+
44
+
45
+
46
+ private
47
+ # ------------ REQUESTS ------------
48
+ # Connect
49
+ def _get_connect_request(access_token, payload, payment_attrs)
50
+
51
+ # Get the url request
52
+ url = connect_endpoint
53
+
54
+ # Build uri params
55
+ params = {}
56
+ params['state'] = payment_attrs['state']
57
+ params['redirect_uri'] = payment_attrs['redirect_uri'] if payment_attrs['redirect_uri']
58
+ query_string = "?#{params.map{|key, value| "#{key}=#{value}"}.join('&')}"
59
+
60
+ # Do connect request
61
+ Fintecture::Faraday::Authentication::Connection.post(
62
+ url: url + query_string,
63
+ req_body: payload.to_json,
64
+ custom_content_type: 'application/json',
65
+ bearer: "Bearer #{access_token}",
66
+ secure_headers: true
67
+ )
68
+ end
69
+
70
+ # Request_to_pay
71
+ def _request_to_pay_request(access_token, payload, payment_attrs)
72
+
73
+ # Get the url request
74
+ url = request_to_pay_endpoint
75
+
76
+ additional_headers = {}
77
+ additional_headers['x-language'] = payment_attrs[:x_language]
78
+
79
+ # Do connect request
80
+ Fintecture::Faraday::Authentication::Connection.post(
81
+ url: url,
82
+ req_body: payload.to_json,
83
+ custom_content_type: 'application/json',
84
+ bearer: "Bearer #{access_token}",
85
+ secure_headers: true,
86
+ additional_headers: additional_headers
87
+ )
88
+ end
89
+
90
+ # Get_payments
91
+ def _get_payments_request(access_token, session_id)
92
+ url = payment_endpoint
93
+
94
+ Fintecture::Faraday::Authentication::Connection.get(
95
+ url: "#{url}/#{session_id}",
96
+ custom_content_type: 'application/json',
97
+ bearer: "Bearer #{access_token}",
98
+ secure_headers: true
99
+ )
100
+ end
101
+
102
+
103
+
104
+
105
+ # ------------ BUILD PAYLOADS ------------
106
+ # Connect - Build the payload from payment_attrs
107
+ def build_payload_connect(payment_attrs = nil)
108
+ # Mandatory attributes
109
+ attributes = {
110
+ amount: payment_attrs['amount'].to_s,
111
+ currency: payment_attrs['currency'],
112
+ communication: payment_attrs['communication'],
113
+ end_to_end_id: payment_attrs['end_to_end_id'] || Fintecture::Utils::Crypto.generate_uuid_only_chars
114
+ }
115
+
116
+ # Optionals attributes
117
+ attributes['execution_date'] = payment_attrs['execution_date'] if payment_attrs['execution_date']
118
+ attributes['debited_account_id'] = payment_attrs['debited_account_id'] if payment_attrs['debited_account_id']
119
+ attributes['debited_account_type'] = payment_attrs['debited_account_type'] if payment_attrs['debited_account_type']
120
+ attributes['scheme'] = payment_attrs['scheme'] if payment_attrs['scheme']
121
+
122
+ # Mandatory attributes => beneficiary
123
+ if payment_attrs['beneficiary']
124
+ attributes['beneficiary'] = {
125
+ name: payment_attrs['beneficiary']['name'],
126
+ street: payment_attrs['beneficiary']['street'],
127
+ zip: payment_attrs['beneficiary']['zip'],
128
+ city: payment_attrs['beneficiary']['city'],
129
+ country: payment_attrs['beneficiary']['country'],
130
+ iban: payment_attrs['beneficiary']['iban'],
131
+ swift_bic: payment_attrs['beneficiary']['swift_bic']
132
+ }
133
+
134
+ # Optionals attributes => beneficiary
135
+ attributes['beneficiary']['number'] = payment_attrs['beneficiary']['number'] if payment_attrs['beneficiary']['number']
136
+ attributes['beneficiary']['complement'] = payment_attrs['beneficiary']['complement'] if payment_attrs['beneficiary']['complement']
137
+ attributes['beneficiary']['form'] = payment_attrs['beneficiary']['form'] if payment_attrs['beneficiary']['form']
138
+ attributes['beneficiary']['incorporation'] = payment_attrs['beneficiary']['incorporation'] if payment_attrs['beneficiary']['incorporation']
139
+ end
140
+
141
+ # Mandatory meta data
142
+ meta = {
143
+ psu_name: payment_attrs['customer_full_name'],
144
+ psu_email: payment_attrs['customer_email'],
145
+ psu_phone: payment_attrs['customer_phone']
146
+ }
147
+
148
+ # Optionals meta data
149
+ meta['psu_phone_prefix'] = payment_attrs['customer_phone_prefix'] if payment_attrs['customer_phone_prefix']
150
+ meta['psu_ip'] = payment_attrs['customer_ip'] if payment_attrs['customer_ip']
151
+
152
+ # Mandatory meta => psu_address
153
+ meta['psu_address'] = {
154
+ street: payment_attrs['customer_address']['street'],
155
+ city: payment_attrs['customer_address']['city'],
156
+ zip: payment_attrs['customer_address']['zip'],
157
+ country: payment_attrs['customer_address']['country']
158
+ }
159
+
160
+ # Optionals meta => psu_address
161
+ meta['psu_address']['number'] = payment_attrs['customer_address']['number'] if payment_attrs['customer_address']['number']
162
+ meta['psu_address']['complement'] = payment_attrs['customer_address']['complement'] if payment_attrs['customer_address']['complement']
163
+
164
+ # Return the payload
165
+ {
166
+ meta: meta,
167
+ data: {
168
+ type: 'PIS',
169
+ attributes: attributes,
170
+ }
171
+ }
172
+ end
173
+
174
+ # Request_to_pay - Build the payload from payment_attrs
175
+ def build_payload_request_to_pay(payment_attrs = nil)
176
+ # Mandatory attributes
177
+ attributes = {
178
+ amount: payment_attrs['amount'],
179
+ currency: payment_attrs['currency'],
180
+ communication: payment_attrs['communication']
181
+ }
182
+
183
+ # Mandatory meta data
184
+ meta = {
185
+ psu_name: payment_attrs['customer_full_name'],
186
+ psu_email: payment_attrs['customer_email'],
187
+ psu_phone: payment_attrs['customer_phone'],
188
+ psu_phone_prefix: payment_attrs['customer_phone_prefix']
189
+ }
190
+
191
+ # Optionals meta psu_address
192
+ if payment_attrs['customer_address']
193
+ meta['psu_address'] = {}
194
+ meta['psu_address']['street'] = payment_attrs['customer_address']['street'] if payment_attrs['customer_address']['street']
195
+ meta['psu_address']['number'] = payment_attrs['customer_address']['number'] if payment_attrs['customer_address']['number']
196
+ meta['psu_address']['city'] = payment_attrs['customer_address']['city'] if payment_attrs['customer_address']['city']
197
+ meta['psu_address']['zip'] = payment_attrs['customer_address']['zip'] if payment_attrs['customer_address']['zip']
198
+ meta['psu_address']['country'] = payment_attrs['customer_address']['country'] if payment_attrs['customer_address']['country']
199
+ end
200
+
201
+ # Optionals meta data
202
+ meta['expirary'] = payment_attrs['expirary'] if payment_attrs['expirary']
203
+ meta['cc'] = payment_attrs['cc'] if payment_attrs['cc']
204
+ meta['bcc'] = payment_attrs['bcc'] if payment_attrs['bcc']
205
+
206
+
207
+ # Return the payload
208
+ {
209
+ meta: meta,
210
+ data: {
211
+ type: 'REQUEST_TO_PAY',
212
+ attributes: attributes,
213
+ }
214
+ }
215
+ end
216
+
217
+
218
+
219
+
220
+ # ------------ API ENDPOINTS ------------
221
+ # Request_to_pay
222
+ def request_to_pay_endpoint
223
+ "#{api_base_url}/#{Fintecture::Api::Endpoints::Pis::REQUEST_TO_PAY}"
224
+ end
225
+
226
+ # Payment
227
+ def payment_endpoint
228
+ "#{api_base_url}/#{Fintecture::Api::Endpoints::Pis::PAYMENTS}"
229
+ end
230
+
231
+ # Connect
232
+ def connect_endpoint
233
+ "#{api_base_url}/#{Fintecture::Api::Endpoints::Pis::CONNECT}"
234
+ end
235
+
236
+
237
+
238
+
239
+ # ------------ BASE URL ------------
240
+ def base_url
241
+ Fintecture::Api::BaseUrl::FINTECTURE_CONNECT_URL[Fintecture.environment.to_sym]
242
+ end
243
+
244
+ def api_base_url
245
+ Fintecture::Api::BaseUrl::FINTECTURE_API_URL[Fintecture.environment.to_sym]
246
+ end
247
+
248
+
249
+
250
+ # ------------ TOOLS ------------
251
+ def as_json(element)
252
+ return JSON(element.to_json) if element.is_a? Hash
253
+
254
+ begin
255
+ element.as_json
256
+ rescue NoMethodError
257
+ raise Fintecture::ValidationException.new("invalid parameter format, the parameter should be a Hash or an Object Model instead a #{element.class.name}")
258
+ end
259
+ end
260
+ end
261
+ end
61
262
  end
@@ -1,14 +1,14 @@
1
-
2
-
3
-
4
- module Fintecture
5
- module Utils
6
- module Constants
7
-
8
- SIGNEDHEADERPARAMETERLIST = %w[(request-target) Date Digest X-Request-ID];
9
- PSU_TYPES = %w[retail corporate all]
10
- SCOPES = %w[pis ais]
11
-
12
- end
13
- end
1
+
2
+
3
+
4
+ module Fintecture
5
+ module Utils
6
+ module Constants
7
+
8
+ SIGNEDHEADERPARAMETERLIST = %w[(request-target) Date Digest X-Request-ID];
9
+ PSU_TYPES = %w[retail corporate all]
10
+ SCOPES = %w[pis ais]
11
+
12
+ end
13
+ end
14
14
  end
@@ -1,76 +1,78 @@
1
- require 'securerandom'
2
- require 'openssl'
3
- require 'base64'
4
- require 'json'
5
- require 'fintecture/exceptions'
6
- require 'fintecture/utils/constants'
7
- require 'uri'
8
-
9
- module Fintecture
10
- module Utils
11
- class Crypto
12
- class << self
13
-
14
- def generate_uuid
15
- SecureRandom.uuid
16
- end
17
-
18
- def generate_uuid_only_chars
19
- generate_uuid.gsub!('-','')
20
- end
21
-
22
- def sign_payload(payload)
23
- payload = payload.to_json.to_s if payload.is_a? Hash
24
-
25
- digest = OpenSSL::Digest::SHA256.new
26
- private_key = OpenSSL::PKey::RSA.new(Fintecture.private_key)
27
-
28
- begin
29
- signature = private_key.sign(digest, payload)
30
- Base64.strict_encode64(signature)
31
- rescue
32
- raise Fintecture::CryptoException.new('error during signature')
33
- end
34
- end
35
-
36
- def decrypt_private(digest)
37
- digest = URI.unescape digest
38
- encrypted_string = Base64.decode64(digest)
39
- private_key = OpenSSL::PKey::RSA.new(Fintecture.private_key)
40
-
41
- begin
42
- private_key.private_decrypt(encrypted_string, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
43
- rescue OpenSSL::PKey::RSAError => e
44
- raise Fintecture::CryptoException.new("error while decrypt, #{e.message}")
45
- rescue
46
- raise Fintecture::CryptoException.new('error during decryption')
47
- end
48
- end
49
-
50
- def hash_base64(plain_text)
51
- digest = Digest::SHA256.digest plain_text
52
- Base64.strict_encode64(digest)
53
- end
54
-
55
- def create_signature_header(headers)
56
- signing = []
57
- header = []
58
-
59
- Fintecture::Utils::Constants::SIGNEDHEADERPARAMETERLIST.each do |param|
60
- next unless headers[param]
61
-
62
- param_low = param.downcase
63
- signing << "#{param_low}: #{headers[param]}"
64
- header << param_low
65
- end
66
-
67
- # Double quote in join needed. If not we will get two slashes \\n
68
- signature = sign_payload signing.join("\n")
69
-
70
- 'keyId="' + Fintecture.app_id + '",algorithm="rsa-sha256",headers="' + header.join(' ') + '",signature="' + signature + '"'
71
- end
72
-
73
- end
74
- end
75
- end
1
+ require 'securerandom'
2
+ require 'openssl'
3
+ require 'base64'
4
+ require 'json'
5
+ require 'fintecture/exceptions'
6
+ require 'fintecture/utils/constants'
7
+ require 'uri'
8
+
9
+ module Fintecture
10
+ module Utils
11
+ class Crypto
12
+ class << self
13
+
14
+ def generate_uuid
15
+ SecureRandom.uuid
16
+ end
17
+
18
+ def generate_uuid_only_chars
19
+ generate_uuid.gsub!('-','')
20
+ end
21
+
22
+ def sign_payload(payload)
23
+ payload = payload.to_json.to_s if payload.is_a? Hash
24
+ digest = OpenSSL::Digest::SHA256.new
25
+ private_key = OpenSSL::PKey::RSA.new(Fintecture.private_key)
26
+
27
+ begin
28
+ signature = private_key.sign(digest, payload)
29
+ Base64.strict_encode64(signature)
30
+ rescue
31
+ raise Fintecture::CryptoException.new('error during signature')
32
+ end
33
+ end
34
+
35
+ def decrypt_private(digest)
36
+ digest = URI.unescape digest
37
+ encrypted_string = Base64.decode64(digest)
38
+ private_key = OpenSSL::PKey::RSA.new(Fintecture.private_key)
39
+
40
+ begin
41
+ private_key.private_decrypt(encrypted_string, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
42
+ rescue OpenSSL::PKey::RSAError => e
43
+ raise Fintecture::CryptoException.new("error while decrypt, #{e.message}")
44
+ rescue
45
+ raise Fintecture::CryptoException.new('error during decryption')
46
+ end
47
+ end
48
+
49
+ def hash_base64(plain_text)
50
+ digest = Digest::SHA256.digest plain_text
51
+ Base64.strict_encode64(digest)
52
+ end
53
+
54
+ def create_signature_header(headers)
55
+ signing = []
56
+ header = []
57
+
58
+
59
+
60
+ Fintecture::Utils::Constants::SIGNEDHEADERPARAMETERLIST.each do |param|
61
+ next unless headers[param]
62
+
63
+ param_low = param.downcase
64
+ signing << "#{param_low}: #{headers[param]}"
65
+ header << param_low
66
+ end
67
+
68
+
69
+ # Double quote in join needed. If not we will get two slashes \\n
70
+ signature = sign_payload signing.join("\n")
71
+ 'keyId="' + Fintecture.app_id + '",algorithm="rsa-sha256",headers="' + header.join(' ') + '",signature="' + signature + '"'
72
+
73
+ end
74
+
75
+ end
76
+ end
77
+ end
76
78
  end
@@ -1,15 +1,15 @@
1
- require 'time'
2
-
3
- module Fintecture
4
- module Utils
5
- class Date
6
- class << self
7
-
8
- def header_time
9
- Time.now.utc.strftime("%a, %d %b %Y %H:%M:%S GMT")
10
- end
11
-
12
- end
13
- end
14
- end
1
+ require 'time'
2
+
3
+ module Fintecture
4
+ module Utils
5
+ class Date
6
+ class << self
7
+
8
+ def header_time
9
+ Time.now.utc.strftime("%a, %d %b %Y %H:%M:%S GMT")
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
15
  end
@@ -1,26 +1,26 @@
1
- require 'fintecture/exceptions'
2
-
3
- module Fintecture
4
- module Utils
5
- class Validation
6
- class << self
7
-
8
- def raise_if_klass_mismatch(target, klass, param_name = nil)
9
- return if target.is_a? klass
10
-
11
- raise Fintecture::ValidationException.new("invalid #{param_name ? param_name : 'parameter'} format, the parameter should be a #{klass} instead a #{target.class.name}")
12
- end
13
-
14
- def raise_if_invalid_date_format(date)
15
- return unless date
16
- valid_format = date.match(/\d{4}-\d{2}-\d{2}/)
17
- valid_date = ::Date.strptime(date, '%Y-%m-%d') rescue false
18
- return if valid_format && valid_date
19
-
20
- raise Fintecture::ValidationException.new("invalidss #{date} date, the format should be YYYY-MM-DD")
21
- end
22
-
23
- end
24
- end
25
- end
1
+ require 'fintecture/exceptions'
2
+
3
+ module Fintecture
4
+ module Utils
5
+ class Validation
6
+ class << self
7
+
8
+ def raise_if_klass_mismatch(target, klass, param_name = nil)
9
+ return if target.is_a? klass
10
+
11
+ raise Fintecture::ValidationException.new("invalid #{param_name ? param_name : 'parameter'} format, the parameter should be a #{klass} instead a #{target.class.name}")
12
+ end
13
+
14
+ def raise_if_invalid_date_format(date)
15
+ return unless date
16
+ valid_format = date.match(/\d{4}-\d{2}-\d{2}/)
17
+ valid_date = ::Date.strptime(date, '%Y-%m-%d') rescue false
18
+ return if valid_format && valid_date
19
+
20
+ raise Fintecture::ValidationException.new("invalidss #{date} date, the format should be YYYY-MM-DD")
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
26
  end
@@ -1,3 +1,3 @@
1
- module Fintecture
2
- VERSION = '0.1.9'
3
- end
1
+ module Fintecture
2
+ VERSION = '0.2.1'
3
+ end