nordea-siirto 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/nordea/siirto.rb +23 -0
- data/lib/nordea/siirto/access_token.rb +70 -0
- data/lib/nordea/siirto/errors.rb +13 -0
- data/lib/nordea/siirto/lookup.rb +37 -0
- data/lib/nordea/siirto/pay.rb +102 -0
- data/lib/nordea/siirto/protocols/base.rb +68 -0
- data/lib/nordea/siirto/protocols/curl.rb +66 -0
- data/lib/nordea/siirto/protocols/net_http.rb +52 -0
- data/lib/nordea/siirto/request.rb +8 -0
- data/lib/nordea/siirto/response.rb +8 -0
- data/lib/nordea/siirto/siirto.rb +132 -0
- data/lib/nordea/siirto/version.rb +5 -0
- metadata +57 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7a303e3afcc99342e66813882aab9976f53b9a8b201cca342226779d0a81bcc9
|
4
|
+
data.tar.gz: '0914494f49ad84ab02fd00231c17b91cdb063920a147b57ae000a8093623f31b'
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c40ad8d7577fe6f02209344a8bf91b509a95cf0cf2543e3c8382fe06451fcba75cbfef69adbb7a88862fc48b6f0d51d12cbae0e390e2c91d53faf7eaf28f099d
|
7
|
+
data.tar.gz: fd2662e9219443cd1d4500f082669be73affaa8b1c9dcac61b8ee126326d56d8bdf6a33ed4d415f907a7ebe0f65ad18e67b962b30e3244f31bf4b3d617803713
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Dependencies
|
2
|
+
require 'net/http'
|
3
|
+
require 'iban'
|
4
|
+
require 'active_support'
|
5
|
+
require 'active_support/core_ext'
|
6
|
+
|
7
|
+
# Intended public interface of the gem
|
8
|
+
require 'nordea/siirto/siirto.rb'
|
9
|
+
|
10
|
+
# Implemented requests
|
11
|
+
require 'nordea/siirto/access_token.rb'
|
12
|
+
require 'nordea/siirto/lookup.rb'
|
13
|
+
require 'nordea/siirto/pay.rb'
|
14
|
+
|
15
|
+
# Implemented protocols
|
16
|
+
require 'nordea/siirto/protocols/base.rb'
|
17
|
+
require 'nordea/siirto/protocols/net_http.rb'
|
18
|
+
require 'nordea/siirto/protocols/curl.rb'
|
19
|
+
|
20
|
+
# Utility classes
|
21
|
+
require 'nordea/siirto/errors.rb'
|
22
|
+
require 'nordea/siirto/request.rb'
|
23
|
+
require 'nordea/siirto/response.rb'
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Nordea
|
2
|
+
module Siirto
|
3
|
+
# Responsible for fetching access token from the server,
|
4
|
+
# and memoizing it.
|
5
|
+
module AccessToken
|
6
|
+
# Store current access token into REDIS
|
7
|
+
KEY = 'Nordea::Siirto::AccessToken'.freeze
|
8
|
+
EXPIRATION_BUFFER = 20 # seconds, arbitrary
|
9
|
+
MUTEX = Mutex.new
|
10
|
+
|
11
|
+
module_function
|
12
|
+
|
13
|
+
# Fetches access token from server if previous token has expired
|
14
|
+
# Memoizes token, and sets expiration time, with some buffer.
|
15
|
+
# @return [String]
|
16
|
+
# rubocop:disable MethodLength
|
17
|
+
def access_token
|
18
|
+
# Synchronization is needed, otherwise race condition may ensue:
|
19
|
+
# Let's assume token has expired, and two threads ask for a new token.
|
20
|
+
# Both proceed to fetch the token from remote server, both return,
|
21
|
+
# but the first token is no longer valid.
|
22
|
+
MUTEX.synchronize do
|
23
|
+
token = Nordea::Siirto.redis.get(KEY)
|
24
|
+
return token if token
|
25
|
+
|
26
|
+
Nordea::Siirto.log('Requesting new access token...')
|
27
|
+
payload = response.body
|
28
|
+
|
29
|
+
token = payload['access_token']
|
30
|
+
expires_in = payload['expires_in'] - EXPIRATION_BUFFER
|
31
|
+
Nordea::Siirto.redis.set(KEY, token)
|
32
|
+
Nordea::Siirto.redis.expire(KEY, expires_in)
|
33
|
+
|
34
|
+
token
|
35
|
+
end
|
36
|
+
end
|
37
|
+
# rubocop:enable MethodLength
|
38
|
+
|
39
|
+
# @return [URI::HTTPS]
|
40
|
+
def uri
|
41
|
+
@uri ||= URI.parse("#{Nordea::Siirto.endpoint}/auth")
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return Nordea::Siirto::Request
|
45
|
+
# rubocop:disable MethodLength
|
46
|
+
def request
|
47
|
+
request = Nordea::Siirto::Request.new
|
48
|
+
request.uri = uri
|
49
|
+
request.method = 'POST'
|
50
|
+
request.headers = {
|
51
|
+
'Accept' => 'application/json',
|
52
|
+
'Content-Type' => 'application/x-www-form-urlencoded'
|
53
|
+
}
|
54
|
+
request.body = {
|
55
|
+
grant_type: 'password',
|
56
|
+
username: Nordea::Siirto.username,
|
57
|
+
password: Nordea::Siirto.api_token,
|
58
|
+
client_id: Nordea::Siirto.username
|
59
|
+
}.to_query
|
60
|
+
request
|
61
|
+
end
|
62
|
+
# rubocop:enable MethodLength
|
63
|
+
|
64
|
+
# @return [Nordea::Siirto::Response]
|
65
|
+
def response
|
66
|
+
Nordea::Siirto.protocol.send!(request)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Nordea
|
2
|
+
# Gem specific errors
|
3
|
+
module Siirto
|
4
|
+
class InitializationError < StandardError; end
|
5
|
+
|
6
|
+
# Errors used by Pay module
|
7
|
+
module Pay
|
8
|
+
class InvalidIBAN < ArgumentError; end
|
9
|
+
class InvalidPayload < ArgumentError; end
|
10
|
+
class MissingLookupId < StandardError; end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Nordea
|
2
|
+
module Siirto
|
3
|
+
# Fetches unique LookupId from Nordea server.
|
4
|
+
# LookupId is required to make a payment request.
|
5
|
+
module Lookup
|
6
|
+
module_function
|
7
|
+
|
8
|
+
# @return [Hash]
|
9
|
+
def lookup
|
10
|
+
response = Nordea::Siirto.protocol.send!(request)
|
11
|
+
response.body
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [URI::HTTPS]
|
15
|
+
def uri
|
16
|
+
@uri ||= URI.parse("#{Nordea::Siirto.endpoint}/lookup/uuid")
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [Nordea::Siirto::Request]
|
20
|
+
def request
|
21
|
+
request = Nordea::Siirto::Request.new
|
22
|
+
request.uri = uri
|
23
|
+
request.method = 'GET'
|
24
|
+
request.headers = {
|
25
|
+
'Accept' => 'application/json',
|
26
|
+
'Authorization' => "Bearer #{AccessToken.access_token}"
|
27
|
+
}
|
28
|
+
request
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [Nordea::Siirto::Response]
|
32
|
+
def response
|
33
|
+
Nordea::Siirto.protocol.send!(request)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module Nordea
|
2
|
+
module Siirto
|
3
|
+
# Implements Nordea Siirto IBAN payments.
|
4
|
+
module Pay
|
5
|
+
# Accepted parameters
|
6
|
+
PARAMS = {
|
7
|
+
required: [:amount, :currency, :bene_account_number],
|
8
|
+
person: [:bene_first_names, :bene_last_name],
|
9
|
+
company: [:bene_company_name],
|
10
|
+
optional: [:fallback_payment, :reference_number, :payment_message,
|
11
|
+
:ultimate_bene_ref_name, :beneficiary_minimum_age,
|
12
|
+
:beneficiary_identifier]
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
module_function
|
16
|
+
|
17
|
+
# @param [Hash] See README
|
18
|
+
# @return [Nordea::Siirto::Response]
|
19
|
+
def pay(params) # :nodoc:
|
20
|
+
raise InvalidPayload, params.inspect unless valid_payload?(params)
|
21
|
+
raise InvalidIBAN, params.inspect unless valid_iban?(params)
|
22
|
+
|
23
|
+
Nordea::Siirto.protocol.send!(request(params))
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [URI::HTTPS]
|
27
|
+
def uri # :nodoc:
|
28
|
+
@uri ||= URI.parse("#{Nordea::Siirto.endpoint}/payment/pay")
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param [Hash]
|
32
|
+
# @return [Nordea::Siirto::Request]
|
33
|
+
# rubocop:disable MethodLength
|
34
|
+
def request(params)
|
35
|
+
request = Nordea::Siirto::Request.new
|
36
|
+
request.uri = uri
|
37
|
+
request.method = 'POST'
|
38
|
+
request.headers = {
|
39
|
+
'Accept' => 'application/json',
|
40
|
+
'Content-type' => 'application/json',
|
41
|
+
'Authorization' => "Bearer #{AccessToken.access_token}"
|
42
|
+
}
|
43
|
+
request.body = format_params(params).to_json
|
44
|
+
Nordea::Siirto.log("Body: #{request.body}")
|
45
|
+
request
|
46
|
+
end
|
47
|
+
# rubocop:enable MethodLength
|
48
|
+
|
49
|
+
# @param [Hash]
|
50
|
+
# @return [Hash]
|
51
|
+
def format_params(params) # :nodoc:
|
52
|
+
hash = params.map do |key, val|
|
53
|
+
# dromedar case required
|
54
|
+
str = key.to_s.camelize
|
55
|
+
str[0] = str[0].downcase
|
56
|
+
{ str => val }
|
57
|
+
end.reduce(&:merge)
|
58
|
+
|
59
|
+
# unique lookupId is needed for each payment request
|
60
|
+
lookup_id = Lookup.lookup.slice('lookupId')
|
61
|
+
raise MissingLookupId unless lookup_id.present?
|
62
|
+
|
63
|
+
hash.merge(lookup_id)
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
# @param [Hash]
|
68
|
+
# @return [Boolean]
|
69
|
+
def valid_iban?(params)
|
70
|
+
# It makes sense to check IBAN validity and bank compatibility before
|
71
|
+
# sending request
|
72
|
+
iban = Iban.new(params[:bene_account_number])
|
73
|
+
return false unless iban.validate
|
74
|
+
|
75
|
+
ALLOWED_BIC.include?(iban.bic)
|
76
|
+
end
|
77
|
+
|
78
|
+
# @param [Hash]
|
79
|
+
# @return [Boolean]
|
80
|
+
# rubocop:disable AbcSize,LineLength
|
81
|
+
def valid_payload?(params)
|
82
|
+
return false unless params.is_a?(Hash)
|
83
|
+
|
84
|
+
# convenience lambda for testing conditions
|
85
|
+
params_present = lambda do |key|
|
86
|
+
(params.keys & PARAMS[key]).size == PARAMS[key].size
|
87
|
+
end
|
88
|
+
|
89
|
+
# required params present
|
90
|
+
return false unless params_present.call(:required)
|
91
|
+
|
92
|
+
# either person or company params present
|
93
|
+
return false if params_present.call(:person) && params_present.call(:company)
|
94
|
+
return false unless params_present.call(:person) || params_present.call(:company)
|
95
|
+
|
96
|
+
# must not contain other params than those listed above
|
97
|
+
(params.keys - PARAMS.values.flatten).size.zero?
|
98
|
+
end
|
99
|
+
# rubocop:enable AbcSize,LineLength
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Nordea
|
2
|
+
module Siirto
|
3
|
+
# NOTE: NOT COVERED BY TEST SET
|
4
|
+
module Protocols
|
5
|
+
# This class may be used as a base class for protocol implementations.
|
6
|
+
# Sub-classes should implement :send_request and :parse_response methods
|
7
|
+
# correctly.
|
8
|
+
#
|
9
|
+
# Gem expects protocol implementation to respond to :send! method, which
|
10
|
+
# takes in a generic Siirto request object, and returns a generic Siirto
|
11
|
+
# response object.
|
12
|
+
class Base
|
13
|
+
# Public interface of protocol implementations
|
14
|
+
# @param [Nordea::Siirto::Request]
|
15
|
+
# @return [Nordea::Siirto::Response]
|
16
|
+
# rubocop:disable MethodLength,AbcSize,LineLength
|
17
|
+
def send!(request)
|
18
|
+
uri = request.uri
|
19
|
+
Nordea::Siirto.log("Sending request to: #{uri}")
|
20
|
+
|
21
|
+
# Send request
|
22
|
+
begin
|
23
|
+
protocol_response = send_request(request)
|
24
|
+
rescue StandardError => e
|
25
|
+
Nordea::Siirto.log("Failed to send request: #{request.inspect} #{e.message}")
|
26
|
+
raise
|
27
|
+
end
|
28
|
+
|
29
|
+
# Parse response
|
30
|
+
begin
|
31
|
+
response = parse_response(protocol_response)
|
32
|
+
rescue StandardError => e
|
33
|
+
Nordea::Siirto.log("Failed to parse response: #{protocol_response.inspect} #{e.message}")
|
34
|
+
raise
|
35
|
+
end
|
36
|
+
|
37
|
+
# Log response
|
38
|
+
message = "Server responds: #{response.message}"
|
39
|
+
message << " #{response.code}"
|
40
|
+
unless response.body['access_token'] # do not log token
|
41
|
+
message << " #{response.body}"
|
42
|
+
end
|
43
|
+
Nordea::Siirto.log(message)
|
44
|
+
|
45
|
+
response
|
46
|
+
end
|
47
|
+
# rubocop:enable MethodLength,AbcSize,LineLength
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# Sub-class must implement
|
52
|
+
# @param [Nordea::Siirto::Request]
|
53
|
+
# @return [Object] Protocol-specific response object
|
54
|
+
def send_request(request)
|
55
|
+
raise NotImplementedError, 'Sub-class must implement'
|
56
|
+
end
|
57
|
+
|
58
|
+
# Sub-class must implement
|
59
|
+
# @params [Object] Protocol-specific response object
|
60
|
+
# @return [Nordea::Siirto::Response]
|
61
|
+
def parse_response(protocol_response)
|
62
|
+
raise NotImplementedError, 'Sub-class must implement'
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Nordea
|
2
|
+
module Siirto
|
3
|
+
# NOTE: NOT COVERED BY TEST SET
|
4
|
+
module Protocols
|
5
|
+
# Implements communication with Nordea server using command line cURL.
|
6
|
+
# Provided as an alternative protocol for net/http, as some Ruby
|
7
|
+
# implementations fail to complete SSL Handshake with Nordea servers.
|
8
|
+
# At least JRuby 1.9.17 falls in this category.
|
9
|
+
#
|
10
|
+
# WARNING: We cannot guarantee what Nordea::Siirto::Response#code
|
11
|
+
# will contain. With legacy JRuby, a better way (next to upgrading)
|
12
|
+
# would be to wrap sufficiently modern and robust Java HTTP library.
|
13
|
+
# That way server responses would be more reliable.
|
14
|
+
class Curl < Base
|
15
|
+
private
|
16
|
+
|
17
|
+
# Parses generic Siirto request and returns curl command string
|
18
|
+
# @param [Nordea::Siirto::Request]
|
19
|
+
# @return [String]
|
20
|
+
def create_request(siirto_request)
|
21
|
+
# i - show information, not just response body
|
22
|
+
# s - hide statusbar, error information
|
23
|
+
request = "curl -X #{siirto_request.method} -is"
|
24
|
+
siirto_request.headers.each do |header, value|
|
25
|
+
request << " --header '#{header}: #{value}'"
|
26
|
+
end
|
27
|
+
if (body = siirto_request.body).present?
|
28
|
+
request << " --data '#{body}'"
|
29
|
+
end
|
30
|
+
request << " #{siirto_request.uri}"
|
31
|
+
request
|
32
|
+
end
|
33
|
+
|
34
|
+
# Makes the actual request
|
35
|
+
# @param [Nordea::Siirto::Request]
|
36
|
+
# @return [Net::HTTPRequest]
|
37
|
+
def send_request(siirto_request)
|
38
|
+
request = create_request(siirto_request)
|
39
|
+
IO.popen(request)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Parses curl response string and returns a generic Siirto response
|
43
|
+
# @params [String]
|
44
|
+
# @return [Nordea::Siirto::Response]
|
45
|
+
def parse_response(curl_response)
|
46
|
+
lines = curl_response.readlines
|
47
|
+
# Absence of network connection
|
48
|
+
raise IOError, 'Curl response empty' if lines.blank?
|
49
|
+
|
50
|
+
code = lines.first.split(' ').last
|
51
|
+
body = JSON.parse(lines.last)
|
52
|
+
|
53
|
+
response = Nordea::Siirto::Response.new
|
54
|
+
response.code = code
|
55
|
+
# Nordea server responds to curl in HTTP/2, and apparently in HTTP/2
|
56
|
+
# there is no standard way to return HTTP status message (e.g. OK, Not
|
57
|
+
# Found), unlike in HTTP/1.1. We would need to either force HTTP/1.1
|
58
|
+
# or map status codes to messages here.
|
59
|
+
response.message = ''
|
60
|
+
response.body = body
|
61
|
+
response
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Nordea
|
2
|
+
module Siirto
|
3
|
+
# NOTE: NOT COVERED BY TEST SET
|
4
|
+
module Protocols
|
5
|
+
# Implements communication with Nordea server using Ruby's standard
|
6
|
+
# net/http library
|
7
|
+
class NetHttp < Base
|
8
|
+
private
|
9
|
+
|
10
|
+
# Creates protocol-specific request from generic Siirto request
|
11
|
+
# @param [Nordea::Siirto::Request]
|
12
|
+
# @return [Net::HTTPRequest]
|
13
|
+
def create_request(siirto_request)
|
14
|
+
# Extract data
|
15
|
+
klass = "Net::HTTP::#{siirto_request.method.capitalize}".constantize
|
16
|
+
uri = siirto_request.uri.request_uri
|
17
|
+
body = siirto_request.body
|
18
|
+
headers = siirto_request.headers
|
19
|
+
|
20
|
+
# Create new Request object
|
21
|
+
request = klass.new(uri)
|
22
|
+
headers.each do |header, value|
|
23
|
+
request[header] = value
|
24
|
+
end
|
25
|
+
request.body = body if body.present?
|
26
|
+
request
|
27
|
+
end
|
28
|
+
|
29
|
+
# Makes the actual request
|
30
|
+
# @param [Nordea::Siirto::Request]
|
31
|
+
# @return [Net::HTTPRequest]
|
32
|
+
def send_request(siirto_request)
|
33
|
+
request = create_request(siirto_request)
|
34
|
+
uri = siirto_request.uri
|
35
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
36
|
+
http.use_ssl = true if uri.port == 443
|
37
|
+
http.request(request)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Parses NET::HTTPResponse into a generic Siirto response
|
41
|
+
# @param [Net::HTTPResponse]
|
42
|
+
# @return [Nordea::Siirto::Response]
|
43
|
+
def parse_response(http_response)
|
44
|
+
response = Nordea::Siirto::Response.new
|
45
|
+
response.code = http_response.code
|
46
|
+
response.body = JSON.parse(http_response.body)
|
47
|
+
response.message = http_response.message
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module Nordea
|
2
|
+
# This module is intended as the sole public API of this gem.
|
3
|
+
#
|
4
|
+
# AccessToken and Lookup requests are needed for actual processing
|
5
|
+
# requests, such as Pay, to work. Client should not need to call them
|
6
|
+
# directly, and therefore they are not directly callable from this module.
|
7
|
+
#
|
8
|
+
# A method handle for each request meant to be called directly by client,
|
9
|
+
# should be included in this API.
|
10
|
+
module Siirto
|
11
|
+
# Nordea endpoints
|
12
|
+
ENDPOINT = {
|
13
|
+
prod: 'https://merchant.mobilewalletservices.nordea.com',
|
14
|
+
test: 'https://merchant.trescomas.express'
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
# Only Nordea and OP supported at the moment
|
18
|
+
ALLOWED_BIC = %w[NDEAFIHH OKOYFIHH].freeze
|
19
|
+
|
20
|
+
# Singleton features implemented as such
|
21
|
+
class << self
|
22
|
+
# Mandatory params: Client must provide these at setup
|
23
|
+
attr_reader :server, :username, :api_token
|
24
|
+
|
25
|
+
# Optional params: Client may provide these at setup
|
26
|
+
attr_reader :logger, :tag, :redis, :protocol
|
27
|
+
|
28
|
+
# Make sure initialization is thread safe
|
29
|
+
MUTEX = Mutex.new
|
30
|
+
|
31
|
+
# Client must initialize Nordea::Siirto module before calling other
|
32
|
+
# methods.
|
33
|
+
#
|
34
|
+
# @params opts [Hash] See README for details
|
35
|
+
# @raise [Nordea::Siirto::InitializationError]
|
36
|
+
# @return [Boolean]
|
37
|
+
# rubocop:disable MethodLength
|
38
|
+
def setup(opts)
|
39
|
+
MUTEX.synchronize do
|
40
|
+
allow_initialize?(opts)
|
41
|
+
|
42
|
+
# Initialize
|
43
|
+
opts.each do |key, val|
|
44
|
+
attr = "@#{key}".to_sym
|
45
|
+
instance_variable_set(attr, val)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Client can inject logger of choice
|
49
|
+
@logger ||= Rails.logger
|
50
|
+
|
51
|
+
# Client can inject logging tag
|
52
|
+
@tag ||= 'Nordea::Siirto --'
|
53
|
+
|
54
|
+
# Client can inject REDIS instance of choice, or adapter.
|
55
|
+
@redis ||= REDIS
|
56
|
+
|
57
|
+
# Client can inject another Protocol
|
58
|
+
@protocol ||= Protocols::NetHttp.new
|
59
|
+
|
60
|
+
# Initialization complete
|
61
|
+
log('Initialized!')
|
62
|
+
true
|
63
|
+
end
|
64
|
+
end
|
65
|
+
# rubocop:enable MethodLength
|
66
|
+
|
67
|
+
# Checks if gem is already initialized with required parameters.
|
68
|
+
# @return [Boolean]
|
69
|
+
def initialized?
|
70
|
+
server.present? && username.present? && api_token.present?
|
71
|
+
end
|
72
|
+
|
73
|
+
# 8.2. Send a payment using IBAN account number
|
74
|
+
# POST /payment/pay
|
75
|
+
#
|
76
|
+
# @param payload [Hash] See README
|
77
|
+
# @raise [Nordea::Siirto::Pay::InvalidIBAN]
|
78
|
+
# @raise [Nordea::Siirto::Pay::InvalidPayload]
|
79
|
+
# @return [Nordea::Siirto::Response]
|
80
|
+
def pay(payload)
|
81
|
+
Pay.pay(payload)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Convenience method for requests
|
85
|
+
# @return [String]
|
86
|
+
def endpoint
|
87
|
+
ENDPOINT[server]
|
88
|
+
end
|
89
|
+
|
90
|
+
# Convenience method for requests
|
91
|
+
# @param msg [String]
|
92
|
+
def log(msg)
|
93
|
+
logger.info("#{tag} #{msg}")
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
# Error messages
|
99
|
+
ERROR = {
|
100
|
+
already_initialized: 'Nordea::Siirto is already initialized.',
|
101
|
+
missing_args: 'Invalid or missing arguments. Client must provide
|
102
|
+
parameter hash with the following keys: :server (either :prod or
|
103
|
+
:test), :username, :api_token.',
|
104
|
+
invalid_logger: 'Logger must respond to :info method.',
|
105
|
+
invalid_protocol: 'Protocol must respond to :send! method'
|
106
|
+
}.freeze
|
107
|
+
|
108
|
+
# Checks that module has not been previously initialized, and
|
109
|
+
# that arguments are more or less acceptable.
|
110
|
+
# @raise [Nordea::Siirto::InitializationError]
|
111
|
+
# rubocop:disable AbcSize,CyclomaticComplexity,GuardClause
|
112
|
+
def allow_initialize?(opts)
|
113
|
+
raise InitializationError, ERROR[:already_initialized] if initialized?
|
114
|
+
raise InitializationError, ERROR[:missing_args] if missing_args?(opts)
|
115
|
+
if opts[:logger] && !opts[:logger].respond_to?(:info)
|
116
|
+
raise InitializationError, ERROR[:invalid_logger]
|
117
|
+
end
|
118
|
+
if opts[:protocol] && !opts[:protocol].respond_to?(:send!)
|
119
|
+
raise InitializationError, ERROR[:invalid_protocol]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
# rubocop:enable AbcSize,CyclomaticComplexity,GuardClause
|
123
|
+
|
124
|
+
# Checks that required parameters are present.
|
125
|
+
# @return [Boolean]
|
126
|
+
def missing_args?(opts)
|
127
|
+
!(opts[:server] && opts[:username] && opts[:api_token] &&
|
128
|
+
ENDPOINT.keys.include?(opts[:server].to_sym))
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nordea-siirto
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matilda Smeds
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-09-16 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |2
|
14
|
+
Nordea::Siirto implements requests according to Nordea Siirto protocol,
|
15
|
+
which enables real time payments for select Finnish bank accounts
|
16
|
+
email: foss@aavasoftware.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/nordea/siirto.rb
|
22
|
+
- lib/nordea/siirto/access_token.rb
|
23
|
+
- lib/nordea/siirto/errors.rb
|
24
|
+
- lib/nordea/siirto/lookup.rb
|
25
|
+
- lib/nordea/siirto/pay.rb
|
26
|
+
- lib/nordea/siirto/protocols/base.rb
|
27
|
+
- lib/nordea/siirto/protocols/curl.rb
|
28
|
+
- lib/nordea/siirto/protocols/net_http.rb
|
29
|
+
- lib/nordea/siirto/request.rb
|
30
|
+
- lib/nordea/siirto/response.rb
|
31
|
+
- lib/nordea/siirto/siirto.rb
|
32
|
+
- lib/nordea/siirto/version.rb
|
33
|
+
homepage:
|
34
|
+
licenses:
|
35
|
+
- MIT
|
36
|
+
metadata: {}
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
requirements: []
|
52
|
+
rubyforge_project:
|
53
|
+
rubygems_version: 2.7.9
|
54
|
+
signing_key:
|
55
|
+
specification_version: 4
|
56
|
+
summary: Nordea Siirto requests
|
57
|
+
test_files: []
|