klarna-xmlrpc 0.2.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.
Files changed (95) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +13 -0
  3. data/Gemfile +14 -0
  4. data/Guardfile +16 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.textile +139 -0
  7. data/Rakefile +22 -0
  8. data/TODO +30 -0
  9. data/examples/Gemfile +8 -0
  10. data/examples/config/initializer.rb +15 -0
  11. data/examples/console.rb +71 -0
  12. data/examples/public/images/klarna.png +0 -0
  13. data/examples/public/images/ruby.png +0 -0
  14. data/examples/views/_address.haml +22 -0
  15. data/examples/views/_articles.haml +21 -0
  16. data/examples/views/checkout_page_example.haml +2 -0
  17. data/examples/views/essential/add_transaction/_form.haml +32 -0
  18. data/examples/views/essential/add_transaction/result.haml +7 -0
  19. data/examples/views/essential/calculate_monthly_cost/_form.haml +16 -0
  20. data/examples/views/essential/calculate_monthly_cost/result.haml +7 -0
  21. data/examples/views/essential/get_addresses/_form.haml +9 -0
  22. data/examples/views/essential/get_addresses/result.haml +8 -0
  23. data/examples/views/index.haml +296 -0
  24. data/examples/views/layout.haml +48 -0
  25. data/examples/views/payment_terms_example.haml +102 -0
  26. data/examples/views/product_page_example.haml +2 -0
  27. data/examples/views/reservation/activate_reservation/_form.haml +54 -0
  28. data/examples/views/reservation/activate_reservation/result.haml +7 -0
  29. data/examples/views/reservation/cancel_reservation/_form.haml +8 -0
  30. data/examples/views/reservation/cancel_reservation/result.haml +7 -0
  31. data/examples/views/reservation/change_reservation/_form.haml +10 -0
  32. data/examples/views/reservation/change_reservation/result.haml +7 -0
  33. data/examples/views/reservation/reserve_amount/_form.haml +58 -0
  34. data/examples/views/reservation/reserve_amount/result.haml +7 -0
  35. data/examples/views/reservation/reserve_ocr_numbers/_form.haml +8 -0
  36. data/examples/views/reservation/reserve_ocr_numbers/result.haml +7 -0
  37. data/examples/views/reservation/split_reservation/_form.haml +14 -0
  38. data/examples/views/reservation/split_reservation/result.haml +7 -0
  39. data/examples/views/special/get_pclasses/_form.haml +8 -0
  40. data/examples/views/special/get_pclasses/result.haml +7 -0
  41. data/examples/views/special/invoice_address/_form.haml +8 -0
  42. data/examples/views/special/invoice_address/result.haml +7 -0
  43. data/examples/views/special/invoice_amount/_form.haml +8 -0
  44. data/examples/views/special/invoice_amount/result.haml +7 -0
  45. data/examples/views/special/is_invoice_paid/_form.haml +8 -0
  46. data/examples/views/special/is_invoice_paid/result.haml +7 -0
  47. data/examples/views/special/update_charge_amount/_form.haml +15 -0
  48. data/examples/views/special/update_charge_amount/result.haml +7 -0
  49. data/examples/views/special/update_goods_quantity/_form.haml +17 -0
  50. data/examples/views/special/update_goods_quantity/result.haml +7 -0
  51. data/examples/views/special/update_order_number/_form.haml +10 -0
  52. data/examples/views/special/update_order_number/result.haml +7 -0
  53. data/examples/views/useful/activate_invoice/_form.haml +9 -0
  54. data/examples/views/useful/activate_invoice/result.haml +7 -0
  55. data/examples/views/useful/credit_invoice/_form.haml +11 -0
  56. data/examples/views/useful/credit_invoice/result.haml +7 -0
  57. data/examples/views/useful/delete_invoice/_form.haml +9 -0
  58. data/examples/views/useful/delete_invoice/result.haml +7 -0
  59. data/examples/views/useful/email_invoice/_form.haml +9 -0
  60. data/examples/views/useful/email_invoice/result.haml +7 -0
  61. data/examples/views/useful/has_account/_form.haml +9 -0
  62. data/examples/views/useful/has_account/result.haml +7 -0
  63. data/examples/views/useful/return_amount/_form.haml +15 -0
  64. data/examples/views/useful/return_amount/result.haml +7 -0
  65. data/examples/views/useful/send_invoice/_form.haml +9 -0
  66. data/examples/views/useful/send_invoice/result.haml +7 -0
  67. data/examples/web.rb +349 -0
  68. data/klarna.gemspec +34 -0
  69. data/lib/klarna.rb +171 -0
  70. data/lib/klarna/api.rb +187 -0
  71. data/lib/klarna/api/client.rb +126 -0
  72. data/lib/klarna/api/constants.rb +647 -0
  73. data/lib/klarna/api/errors.rb +154 -0
  74. data/lib/klarna/api/methods.rb +16 -0
  75. data/lib/klarna/api/methods/cost_calculations.rb +134 -0
  76. data/lib/klarna/api/methods/invoicing.rb +304 -0
  77. data/lib/klarna/api/methods/reservation.rb +188 -0
  78. data/lib/klarna/api/methods/standard.rb +126 -0
  79. data/lib/klarna/version.rb +5 -0
  80. data/test/fixtures/api/companies.yml +97 -0
  81. data/test/fixtures/api/pclasses.yml +37 -0
  82. data/test/fixtures/api/persons.yml +144 -0
  83. data/test/fixtures/api/stores.yml +6 -0
  84. data/test/fixtures/klarna.yml +10 -0
  85. data/test/klarna/api/client_test.rb +288 -0
  86. data/test/klarna/api/errors_test.rb +34 -0
  87. data/test/klarna/api/methods/cost_calculations_test.rb +78 -0
  88. data/test/klarna/api/methods/invoicing_test.rb +409 -0
  89. data/test/klarna/api/methods/reservation_test.rb +66 -0
  90. data/test/klarna/api/methods/standard_test.rb +244 -0
  91. data/test/klarna/api_test.rb +184 -0
  92. data/test/klarna_test.rb +204 -0
  93. data/test/support/assertions_helper.rb +40 -0
  94. data/test/test_helper.rb +55 -0
  95. metadata +335 -0
@@ -0,0 +1,187 @@
1
+ # encoding: utf-8
2
+ require 'digest/sha2'
3
+ require 'xmlrpc/base64'
4
+
5
+ require 'klarna/api/constants'
6
+ require 'klarna/api/errors'
7
+
8
+ module Klarna
9
+ module API
10
+
11
+ # == Reference:
12
+ #
13
+ # * http://integration.klarna.com/api-functions
14
+ #
15
+ # == Note:
16
+ #
17
+ # All input data strings should be coded in accordance with ISO-8859-1.
18
+ #
19
+ # This implementation is not 1-to-1 implementation of the Klarna API functions.
20
+ # The methods are refactored/cleaned up to meet Ruby code standards; avoid
21
+ # unessecary code-repetition and spaghetti-code like the other implementations.
22
+ # Same functionality can be achieved though; see the RDocs.
23
+ #
24
+ # To obtain pclasses - or download the pclasses file:
25
+ #
26
+ # 1. Log in to Kreditor Online.
27
+ # 2. Click on "Display store"
28
+ # 3. Click on "Click here to view campaigns".
29
+ #
30
+ # ...or use the API-method +::Klarna::API.get_pclasses+.
31
+ #
32
+
33
+ include ::Klarna::API::Constants
34
+ include ::Klarna::API::Errors
35
+
36
+ @@client = nil
37
+
38
+ class << self
39
+
40
+ # Re-use or (re-)initialize a new Klarna XML-RPC API client.
41
+ #
42
+ def client(force_new = false)
43
+ begin
44
+ if force_new || @@client.nil?
45
+ @@client = ::Klarna::API::Client.new
46
+ end
47
+ rescue => e
48
+ ::Klarna.log e, :error
49
+ end
50
+ @@client
51
+ end
52
+
53
+ def key_for(kind, value)
54
+ begin
55
+ kind = validated_kind(kind)
56
+ rescue => e
57
+ raise e
58
+ end
59
+
60
+ begin
61
+ is_correct_format = !(value.to_s =~ /^\d+$/)
62
+ constants = ::Klarna::API.const_get(kind)
63
+ key = is_correct_format ? value : constants.invert[value.to_i] # BUG: Should lookup the value's key.
64
+ rescue
65
+ raise ::Klarna::API::KlarnaArgumentError, "Invalid '#{kind}': #{value.inspect}"
66
+ end
67
+
68
+ if !key
69
+ raise ::Klarna::API::KlarnaStandardError, "Key not found for '#{kind}': #{value.inspect}"
70
+ end
71
+ key.to_sym
72
+ end
73
+
74
+ def id_for(kind, value)
75
+ begin
76
+ kind = validated_kind(kind)
77
+ rescue => e
78
+ raise e
79
+ end
80
+
81
+ begin
82
+ is_correct_format = (value.to_s =~ /^\d+$/)
83
+ constants = ::Klarna::API.const_get(kind)
84
+ id = is_correct_format ? value.to_i : constants[value.to_s.upcase.to_sym]
85
+ rescue
86
+ raise ::Klarna::API::KlarnaArgumentError, "Invalid '#{kind}': #{value.inspect}"
87
+ end
88
+
89
+ if !id
90
+ raise ::Klarna::API::KlarnaStandardError, "Id not found for '#{kind}': #{value.inspect}"
91
+ end
92
+ id.to_i
93
+ end
94
+
95
+ # Validate if specified +kind+ is a valid constant.
96
+ #
97
+ def validated_kind(kind)
98
+ valid_kinds = [:country, :currency, :language, :pno_format, :address_format, :shipment_type, :pclass, :mobile, :invoice, :goods, :monthly_cost]
99
+ valid_kinds.collect! do |valid_kind|
100
+ [valid_kind.to_s.singularize.to_sym, valid_kind.to_s.pluralize.to_sym]
101
+ end
102
+ valid_kinds.flatten!
103
+ kind = kind.to_s.pluralize.to_sym
104
+
105
+ unless kind.is_a?(String) || kind.is_a?(Symbol)
106
+ raise ::Klarna::API::KlarnaArgumentError, "Not a valid kind: #{kind.inspect}. Expects a symbol or a string: #{valid_kinds.join(', ')}"
107
+ end
108
+
109
+ unless valid_kinds.include?(kind.to_s.downcase.to_sym)
110
+ raise ::Klarna::API::KlarnaArgumentError, "Not a valid kind: #{kind.inspect}. Valid kinds: #{valid_kinds.join(', ')}"
111
+ end
112
+
113
+ kind.to_s.upcase.to_sym
114
+ end
115
+
116
+ # Parse, validate, and cast a method argument before RPC-call.
117
+ #
118
+ def validate_arg(value, cast_to, format_expression, strip_expression = nil, &block)
119
+ raise ::Klarna::API::KlarnaArgumentError,
120
+ "Argument cast_to should be Symbol, but was #{cast_to.class.name}." unless cast_to.is_a?(Symbol)
121
+ raise ::Klarna::API::KlarnaArgumentError,
122
+ "Argument regexp should be Regexp, but was #{format_expression.class.name}." unless format_expression.is_a?(Regexp)
123
+ raise ::Klarna::API::KlarnaArgumentError,
124
+ "Argument strip should be Regexp, but was #{strip_expression.class.name}." unless strip_expression.is_a?(Regexp)
125
+
126
+ value = value.to_s.gsub(strip_expression, '') if strip_expression
127
+
128
+ unless value.to_s =~ format_expression
129
+ raise ::Klarna::API::KlarnaArgumentError, "Invalid argument: #{value.inspect}. Expected format: #{format_expression.inspect}"
130
+ end
131
+
132
+ # Pass value to block - for type casting, etc. - if given.
133
+ value = block.call(value) if block_given?
134
+
135
+ value.tap do |v|
136
+ case cast_to
137
+ when :string then v.to_s
138
+ when :integer then v.to_i
139
+ when :decimal then v.to_f # number of decimals?
140
+ when :date then v # TODO
141
+ else
142
+ raise ::Klarna::API::KlarnaArgumentError, "Invalid cast_to value: #{cast_to.inspect}. "
143
+ end
144
+ end
145
+ end
146
+
147
+ def parse_flags(constant_name, flags)
148
+ if flags.is_a?(Hash)
149
+ flags = flags.sum do |k, v|
150
+ v ? ::Klarna::API.const_get(constant_name.to_s.upcase.to_sym)[k.to_s.upcase.to_sym] : 0
151
+ end
152
+ end
153
+ flags.to_i
154
+ end
155
+
156
+ def digest(*args)
157
+ string = args.join(':')
158
+ iso_value = self.encode(string)
159
+
160
+
161
+ hex_md5_digest = [*::Digest::MD5.hexdigest(iso_value)].pack('H*')
162
+ base64_digest = ::XMLRPC::Base64.encode(hex_md5_digest).strip
163
+ hex_sha512_digest = [*Digest::SHA512.hexdigest(iso_value)].pack('H*')
164
+ base64_digest = ::XMLRPC::Base64.encode(hex_sha512_digest).strip
165
+ end
166
+
167
+ def encode(string, from_encoding = 'utf-8')
168
+ if string.respond_to?(:encode)
169
+ string.encode(::Klarna::API::PROTOCOL_ENCODING, from_encoding)
170
+ else
171
+ ::Iconv.conv(::Klarna::API::PROTOCOL_ENCODING, from_encoding, string)
172
+ end
173
+ end
174
+
175
+ def decode(string, from_encoding = ::Klarna::API::PROTOCOL_ENCODING)
176
+ if string.respond_to?(:encode)
177
+ string.encode('utf-8', from_encoding)
178
+ else
179
+ ::Iconv rescue require 'iconv'
180
+ ::Iconv.conv(from_encoding, ::Klarna::API::PROTOCOL_ENCODING, string)
181
+ end
182
+ end
183
+
184
+ end
185
+
186
+ end
187
+ end
@@ -0,0 +1,126 @@
1
+ # encoding: utf-8
2
+ require 'xmlrpc/client'
3
+
4
+ require 'klarna/api/methods'
5
+
6
+ module Klarna
7
+ module API
8
+ class Client < ::XMLRPC::Client
9
+
10
+ include ::Klarna::API::Methods
11
+
12
+ attr_accessor :store_id,
13
+ :store_secret,
14
+ :mode,
15
+ :timeout,
16
+ :last_request_headers,
17
+ :last_request_params,
18
+ :last_response,
19
+ :client_ip,
20
+ :protocol,
21
+ :host,
22
+ :port
23
+
24
+ def initialize(*args)
25
+ self.store_id = args.shift || ::Klarna.store_id
26
+ self.store_secret = args.shift || ::Klarna.store_secret
27
+
28
+ if self.store_id.blank? || self.store_secret.blank?
29
+ raise ::Klarna::API::KlarnaCredentialsError, "Both 'store_id' and 'store_secret' must be set."
30
+ end
31
+
32
+ options = args.extract_options!
33
+ self.client_ip = options[:client_ip].presence || '127.0.0.1'
34
+ self.mode = options.key?(:mode) ? options[:mode] : ::Klarna.mode
35
+ self.timeout = options.key?(:timeout) ? options[:timeout] : 10 # seconds
36
+
37
+ unless ::Klarna::API::END_POINT.keys.include?(self.mode)
38
+ raise "No such mode: #{self.mode.inspect}. " <<
39
+ "Valid modes: #{::Klarna::API::END_POINT.keys.collect(&:inspect).join(', ')}"
40
+ end
41
+
42
+ begin
43
+ ::Klarna.log "Endpoint URI: %s" % self.endpoint_uri.inspect
44
+
45
+ super(self.host, '/', self.port, nil, nil, nil, nil, self.use_ssl?, self.timeout)
46
+
47
+ self.http_header_extra ||= {}
48
+ self.http_header_extra.merge!(self.content_type_headers)
49
+
50
+ self.instance_variable_get(:@http).set_debug_output(::Klarna.logger) if ::Klarna.http_logging?
51
+ rescue ::XMLRPC::FaultException => e
52
+ raise ::Klarna::API::KlarnaServiceError.new(e.faultCode, e.faultString)
53
+ end
54
+ end
55
+
56
+ def call(service_method, *args)
57
+ args.collect! { |arg| arg.is_a?(String) ? ::Klarna::API.decode(arg) : arg }
58
+ ::Klarna.log "Method: #{service_method}"
59
+ ::Klarna.log "Params: %s" % args.inspect #self.add_meta_params(*args).inspect
60
+
61
+ self.last_request_headers = http_header_extra
62
+
63
+ begin
64
+ ::Klarna.log_result("Result: %s") do
65
+ params = args #self.add_meta_params(*args)
66
+ self.last_request_params = params
67
+ self.last_response = super(service_method, *params)
68
+ end
69
+ rescue ::XMLRPC::FaultException => e
70
+ raise ::Klarna::API::KlarnaServiceError.new(e.faultCode, e.faultString)
71
+ end
72
+ end
73
+
74
+ def ssl?
75
+ self.protocol == 'https'
76
+ end
77
+ alias :use_ssl? :ssl?
78
+
79
+ def protocol
80
+ @protocol = ::Klarna::API::END_POINT[self.mode][:protocol]
81
+ end
82
+
83
+ def host
84
+ @host = ::Klarna::API::END_POINT[self.mode][:host]
85
+ end
86
+
87
+ def port
88
+ @port = ::Klarna::API::END_POINT[self.mode][:port]
89
+ end
90
+
91
+ def endpoint_uri
92
+ @endpoint_uri = "#{self.protocol}://#{self.host}:#{self.port}"
93
+ end
94
+
95
+ protected
96
+
97
+ # Request content-type headers.
98
+ #
99
+ def content_type_headers
100
+ {
101
+ :'Accept-Encoding' => 'deflate,gzclient_ip',
102
+ :'Content-Type' => "text/xml;charset=#{::Klarna::API::PROTOCOL_ENCODING}",
103
+ :'Accept-Charset' => 'iso-8859-1', # REVISIT: 'UTF-8,ISO-8859-1,US-ASCII',
104
+ :'Connection' => 'close',
105
+ :'User-Agent' => 'ruby/xmlrpc' # Note: Default "User-Agent" gives 400-error.
106
+ }.with_indifferent_access
107
+ end
108
+
109
+ # Ensure that the required client info params get sent with each Klarna API request.
110
+ # Without these the Klarna API will get a service error response.
111
+ #
112
+ def add_meta_params(*args)
113
+ args.unshift *[::Klarna::API::PROTOCOL_VERSION, ::XMLRPC::Client::USER_AGENT]
114
+ args
115
+ end
116
+
117
+ # Pass additional required digest args to the raw digest method.
118
+ #
119
+ def digest(*args)
120
+ options = args.extract_options!
121
+ ::Klarna::API.digest(*[(self.store_id unless options[:store_id] == false), args, self.store_secret].compact.flatten)
122
+ end
123
+
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,647 @@
1
+ # encoding: utf-8
2
+
3
+ module Klarna
4
+ module API
5
+ module Constants
6
+
7
+ # -----------------------------------------------------------------------
8
+ # API
9
+ # -----------------------------------------------------------------------
10
+ END_POINT = {
11
+ :test => {
12
+ :protocol => 'http',
13
+ :host => 'payment-beta.klarna.com',
14
+ :port => 80
15
+ },
16
+ :production => {
17
+ :protocol => 'https',
18
+ :host => 'payment.klarna.com',
19
+ :port => 443
20
+ }
21
+ }.freeze
22
+
23
+ PROTOCOL_ENCODING = 'iso-8859-1'.freeze # NOTE: New API supports: ['UTF-8', 'ISO-8859-1', 'US-ASCII'].freeze
24
+ PROTOCOL_VERSION = '4.1'.freeze
25
+
26
+ # -----------------------------------------------------------------------
27
+ # General
28
+ # -----------------------------------------------------------------------
29
+ AVERAGE_INTEREST_PERIOD = 45.freeze
30
+ DAYS_IN_A_YEAR = 365.25.freeze
31
+
32
+ # -----------------------------------------------------------------------
33
+ # Mode: Defaults
34
+ # -----------------------------------------------------------------------
35
+ DEFAULTS = {
36
+ :OCR => '',
37
+ :PCLASS => -1,
38
+ :YSALARY => 0
39
+ }.freeze
40
+
41
+ # -----------------------------------------------------------------------
42
+ # Flags: Campaign Type
43
+ # -----------------------------------------------------------------------
44
+ PCLASS = {
45
+ :NONE => -1,
46
+ :ANNUITY => 0,
47
+ :DIVISOR => 1
48
+ }.freeze
49
+
50
+ # -----------------------------------------------------------------------
51
+ # Flags: Mobile
52
+ # -----------------------------------------------------------------------
53
+ MOBILE = {
54
+ :PRESERVE_RESERVATION => 16,
55
+ :PHONE_TRANSACTION => 512,
56
+ :SEND_PHONE_PIN => 1024
57
+ }.freeze
58
+
59
+ # -----------------------------------------------------------------------
60
+ # Flags: Invoice
61
+ # -----------------------------------------------------------------------
62
+ INVOICE = {
63
+ :AUTO_ACTIVATE => 1,
64
+ :TEST_MODE => 2,
65
+ :MANUAL_AUTO_ACTIVATE => 4,
66
+ :PRE_PAY => 8,
67
+ :DELAYED_PAY => 16
68
+ }.freeze
69
+
70
+ # -----------------------------------------------------------------------
71
+ # Flags: Goods
72
+ # -----------------------------------------------------------------------
73
+ GOODS = {
74
+ :PRINT_1000 => 1,
75
+ :PRINT_100 => 2,
76
+ :PRINT_10 => 4,
77
+ :IS_SHIPMENT => 8,
78
+ :IS_HANDLING => 16,
79
+ :INC_VAT => 32
80
+ }.freeze
81
+
82
+ # -----------------------------------------------------------------------
83
+ # Flags: Monthly Cost
84
+ # -----------------------------------------------------------------------
85
+ MONTHLY_COST = {
86
+ :LIMIT => 0,
87
+ :ACTUAL => 1
88
+ }.freeze
89
+
90
+ # -----------------------------------------------------------------------
91
+ # Mode: Shipment Type (add_invoice)
92
+ # -----------------------------------------------------------------------
93
+ SHIPMENT_TYPES = {
94
+ :NORMAL => 1,
95
+ :EXPRESS => 2
96
+ }.freeze
97
+
98
+ # -----------------------------------------------------------------------
99
+ # Mode: Charge Type (update_charge_amount)
100
+ # -----------------------------------------------------------------------
101
+ CHARGE_TYPES = {
102
+ :SHIPMENT => 1,
103
+ :HANDLING => 2
104
+ }.freeze
105
+
106
+ # -----------------------------------------------------------------------
107
+ # Mode: Address Type
108
+ # -----------------------------------------------------------------------
109
+ ADDRESS_FORMATS = {
110
+ :OLD => 1,
111
+ :NEW => 2,
112
+ :GIVEN => 5
113
+ }.freeze
114
+
115
+ # -----------------------------------------------------------------------
116
+ # Mode: Personal Number Encodings (SSN)
117
+ # -----------------------------------------------------------------------
118
+ PNO_FORMATS = {
119
+ :FAKE => 1,
120
+ :SE => 2, # valid: yymmdd-nnnn, yymmddnnnn, yyyymmdd-nnnn, yyyymmddnnnn
121
+ :NO => 3, # valid: ddmmyynnnnn
122
+ :FI => 4, # valid: ddmmyy-nnnn, ddmmyynnnn
123
+ :DK => 5, # valid: ddmmyynnnn
124
+ :DE => 6, # valid: ?
125
+ :NL => 7, # valid: ?
126
+ :CNO => 1000
127
+ }.freeze
128
+
129
+ # -----------------------------------------------------------------------
130
+ # Mode: Currencies
131
+ # -----------------------------------------------------------------------
132
+ CURRENCIES = {
133
+ :SEK => 0,
134
+ :NOK => 1,
135
+ :EUR => 2,
136
+ :DKK => 3
137
+ }.freeze
138
+
139
+ # -----------------------------------------------------------------------
140
+ # Mode: Country (ISO3166)
141
+ # -----------------------------------------------------------------------
142
+ COUNTRIES = {
143
+ :AF => 1, # AFGHANISTAN
144
+ :AX => 2, # ÅLAND ISLANDS
145
+ :AL => 3, # ALBANIA
146
+ :DZ => 4, # ALGERIA
147
+ :AS => 5, # AMERICAN SAMOA
148
+ :AD => 6, # ANDORRA
149
+ :AO => 7, # ANGOLA
150
+ :AI => 8, # ANGUILLA
151
+ :AQ => 9, # ANTARCTICA
152
+ :AG => 10, # ANTIG. A. BARBUDA
153
+ :AR => 11, # ARGENTINA
154
+ :AM => 12, # ARMENIA
155
+ :AW => 13, # ARUBA
156
+ :AU => 14, # AUSTRALIA
157
+ :AT => 15, # AUSTRIA
158
+ :AZ => 16, # AZERBAIJAN
159
+ :BS => 17, # BAHAMAS
160
+ :BH => 18, # BAHRAIN
161
+ :BD => 19, # BANGLADESH
162
+ :BB => 20, # BARBADOS
163
+ :BY => 21, # BELARUS
164
+ :BE => 22, # BELGIUM
165
+ :BZ => 23, # BELIZE
166
+ :BJ => 24, # BENIN
167
+ :BM => 25, # BERMUDA
168
+ :BT => 26, # BHUTAN
169
+ :BO => 27, # BOLIVIA
170
+ :BA => 28, # BOS. A. HERZEGOV.
171
+ :BW => 29, # BOTSWANA
172
+ :BV => 30, # BOUVET ISLAND
173
+ :BR => 31, # BRAZIL
174
+ :IO => 32, # BR. IND. O.T.
175
+ :BN => 33, # BRUNEI DARUSSALAM
176
+ :BG => 34, # BULGARIA
177
+ :BF => 35, # BURKINA FASO
178
+ :BI => 36, # BURUNDI
179
+ :KH => 37, # CAMBODIA
180
+ :CM => 38, # CAMEROON
181
+ :CA => 39, # CANADA
182
+ :CV => 40, # CAPE VERDE
183
+ :KY => 41, # CAYMAN ISLANDS
184
+ :CF => 42, # C.A.R.
185
+ :TD => 43, # CHAD
186
+ :CL => 44, # CHILE
187
+ :CN => 45, # CHINA
188
+ :CX => 46, # CHRISTMAS ISLAND
189
+ :CC => 47, # COCOS ISLANDS
190
+ :CO => 48, # COLOMBIA
191
+ :KM => 49, # COMOROS
192
+ :CG => 50, # CONGO
193
+ :CD => 51, # CONGO
194
+ :CK => 52, # COOK ISLANDS
195
+ :CR => 53, # COSTA RICA
196
+ :CI => 54, # COTE D'IVOIRE
197
+ :HR => 55, # CROATIA
198
+ :CU => 56, # CUBA
199
+ :CY => 57, # CYPRUS
200
+ :CZ => 58, # CZECH REPUBLIC
201
+ :DK => 59, # DENMARK
202
+ :DJ => 60, # DJIBOUTI
203
+ :DM => 61, # DOMINICA
204
+ :DO => 62, # DOMINICAN REPUBLIC
205
+ :EC => 63, # ECUADOR
206
+ :EG => 64, # EGYPT
207
+ :SV => 65, # EL SALVADOR
208
+ :GQ => 66, # EQUATORIAL GUINEA
209
+ :ER => 67, # ERITREA
210
+ :EE => 68, # ESTONIA
211
+ :ET => 69, # ETHIOPIA
212
+ :FK => 70, # FALKLAND ISLANDS
213
+ :FO => 71, # FAROE ISLANDS
214
+ :FJ => 72, # FIJI
215
+ :FI => 73, # FINLAND
216
+ :FR => 74, # FRANCE
217
+ :GF => 75, # FRENCH GUIANA
218
+ :PF => 76, # FRENCH POLYNESIA
219
+ :TF => 77, # FR.S. TERRITORIES
220
+ :GA => 78, # GABON
221
+ :GM => 79, # GAMBIA
222
+ :GE => 80, # GEORGIA
223
+ :DE => 81, # GERMANY
224
+ :GH => 82, # GHANA
225
+ :GI => 83, # GIBRALTAR
226
+ :GR => 84, # GREECE
227
+ :GL => 85, # GREENLAND
228
+ :GD => 86, # GRENADA
229
+ :GP => 87, # GUADELOUPE
230
+ :GU => 88, # GUAM
231
+ :GT => 89, # GUATEMALA
232
+ :GG => 90, # GUERNSEY
233
+ :GN => 91, # GUINEA
234
+ :GW => 92, # GUINEA-BISSAU
235
+ :GY => 93, # GUYANA
236
+ :HT => 94, # HAITI
237
+ :HM => 95, # HEARD A. MCD ISL.
238
+ :VA => 96, # HOLY SEE
239
+ :HN => 97, # HONDURAS
240
+ :HK => 98, # HONG KONG
241
+ :HU => 99, # HUNGARY
242
+ :IS => 100, # ICELAND
243
+ :IN => 101, # INDIA
244
+ :ID => 102, # INDONESIA
245
+ :IR => 103, # IRAN
246
+ :IQ => 104, # IRAQ
247
+ :IE => 105, # IRELAND
248
+ :IM => 106, # ISLE OF MAN
249
+ :IL => 107, # ISRAEL
250
+ :IT => 108, # ITALY
251
+ :JM => 109, # JAMAICA
252
+ :JP => 110, # JAPAN
253
+ :JE => 111, # JERSEY
254
+ :JO => 112, # JORDAN
255
+ :KZ => 113, # KAZAKHSTAN
256
+ :KE => 114, # KENYA
257
+ :KI => 115, # KIRIBATI
258
+ :KP => 116, # KOREA, D.P.R OF
259
+ :KR => 117, # KOREA, R. OF
260
+ :KW => 118, # KUWAIT
261
+ :KG => 119, # KYRGYZSTAN
262
+ :LA => 120, # LAO P.D.R
263
+ :LV => 121, # LATVIA
264
+ :LB => 122, # LEBANON
265
+ :LS => 123, # LESOTHO
266
+ :LR => 124, # LIBERIA
267
+ :LY => 125, # LIBYAN A.J.
268
+ :LI => 126, # LIECHTENSTEIN
269
+ :LT => 127, # LITHUANIA
270
+ :LU => 128, # LUXEMBOURG
271
+ :MO => 129, # MACAO
272
+ :MK => 130, # MACEDONIA
273
+ :MG => 131, # MADAGASCAR
274
+ :MW => 132, # MALAWI
275
+ :MY => 133, # MALAYSIA
276
+ :MV => 134, # MALDIVES
277
+ :ML => 135, # MALI
278
+ :MT => 136, # MALTA
279
+ :MH => 137, # MARSHALL ISLANDS
280
+ :MQ => 138, # MARTINIQUE
281
+ :MR => 139, # MAURITANIA
282
+ :MU => 140, # MAURITIUS
283
+ :YT => 141, # MAYOTTE
284
+ :MX => 142, # MEXICO
285
+ :FM => 143, # MICRONESIA
286
+ :MD => 144, # MOLDOVA
287
+ :MC => 145, # MONACO
288
+ :MN => 146, # MONGOLIA
289
+ :MS => 147, # MONTSERRAT
290
+ :MA => 148, # MOROCCO
291
+ :MZ => 149, # MOZAMBIQUE
292
+ :MM => 150, # MYANMAR
293
+ :NA => 151, # NAMIBIA
294
+ :NR => 152, # NAURU
295
+ :NP => 153, # NEPAL
296
+ :NL => 154, # NETHERLANDS
297
+ :AN => 155, # NETH. ANTILLES
298
+ :NC => 156, # NEW CALEDONIA
299
+ :NZ => 157, # NEW ZEALAND
300
+ :NI => 158, # NICARAGUA
301
+ :NE => 159, # NIGER
302
+ :NG => 160, # NIGERIA
303
+ :NU => 161, # NIUE
304
+ :NF => 162, # NORFOLK ISLAND
305
+ :MP => 163, # N.MARIANA ISLANDS
306
+ :NO => 164, # NORWAY
307
+ :OM => 165, # OMAN
308
+ :PK => 166, # PAKISTAN
309
+ :PW => 167, # PALAU
310
+ :PS => 168, # PALESTINIAN T.O
311
+ :PA => 169, # PANAMA
312
+ :PG => 170, # PAPUA NEW GUINEA
313
+ :PY => 171, # PARAGUAY
314
+ :PE => 172, # PERU
315
+ :PH => 173, # PHILIPPINES
316
+ :PN => 174, # PITCAIRN
317
+ :PL => 175, # POLAND
318
+ :PT => 176, # PORTUGAL
319
+ :PR => 177, # PUERTO RICO
320
+ :QA => 178, # QATAR
321
+ :RE => 179, # REUNION
322
+ :RO => 180, # ROMANIA
323
+ :RU => 181, # RUSSIAN FED.
324
+ :RW => 182, # RWANDA
325
+ :SH => 183, # SAINT HELENA
326
+ :KN => 184, # ST KITTS A. NEVIS
327
+ :LC => 185, # SAINT LUCIA
328
+ :PM => 186, # ST P A MIQUELON
329
+ :VC => 187, # ST V A THE GRENA.
330
+ :WS => 188, # SAMOA
331
+ :SM => 189, # SAN MARINO
332
+ :ST => 190, # S.TOME A PRINCIPE
333
+ :SA => 191, # SAUDI ARABIA
334
+ :SN => 192, # SENEGAL
335
+ :CS => 193, # SERB. A. MONTE.
336
+ :SC => 194, # SEYCHELLES
337
+ :SL => 195, # SIERRA LEONE
338
+ :SG => 196, # SINGAPORE
339
+ :SK => 197, # SLOVAKIA
340
+ :SI => 198, # SLOVENIA
341
+ :SB => 199, # SOLOMON ISLANDS
342
+ :SO => 200, # SOMALIA
343
+ :ZA => 201, # SOUTH AFRICA
344
+ :GS => 202, # S.GEORGIA ATSSI
345
+ :ES => 203, # SPAIN
346
+ :LK => 204, # SRI LANKA
347
+ :SD => 205, # SUDAN
348
+ :SR => 206, # SURINAME
349
+ :SJ => 207, # SVALB. A J.MAYEN
350
+ :SZ => 208, # SWAZILAND
351
+ :SE => 209, # SWEDEN
352
+ :CH => 210, # SWITZERLAND
353
+ :SY => 211, # SYRIAN A.R
354
+ :TW => 212, # TAIWAN P.O. CHINA
355
+ :TJ => 213, # TAJIKISTAN
356
+ :TZ => 214, # TANZANIA
357
+ :TH => 215, # THAILAND
358
+ :TL => 216, # TIMOR-LESTE
359
+ :TG => 217, # TOGO
360
+ :TK => 218, # TOKELAU
361
+ :TO => 219, # TONGA
362
+ :TT => 220, # TR. AND TOBAGO
363
+ :TN => 221, # TUNISIA
364
+ :TR => 222, # TURKEY
365
+ :TM => 223, # TURKMENISTAN
366
+ :TC => 224, # T. A CAICOS ISL.
367
+ :TV => 225, # TUVALU
368
+ :UG => 226, # UGANDA
369
+ :UA => 227, # UKRAINE
370
+ :AE => 228, # U.A.E
371
+ :GB => 229, # UNITED KINGDOM
372
+ :US => 230, # UNITED STATES
373
+ :UM => 231, # US M.O. ISLANDS
374
+ :UY => 232, # URUGUAY
375
+ :UZ => 233, # UZBEKISTAN
376
+ :VU => 234, # VANUATU
377
+ :VE => 235, # VENEZUELA
378
+ :VN => 236, # VIET NAM
379
+ :VG => 237, # VIRGIN ISLANDS BR
380
+ :VI => 238, # VIRGIN ISLANDS US
381
+ :WF => 239, # WALLIS AND FUTUNA
382
+ :EH => 240, # WESTERN SAHARA
383
+ :YE => 241, # YEMEN
384
+ :ZM => 242, # ZAMBIA
385
+ :ZW => 243 # ZIMBABWE
386
+ }.freeze
387
+
388
+ # -----------------------------------------------------------------------
389
+ # Mode: Language (ISO639)
390
+ # -----------------------------------------------------------------------
391
+ LANGUAGES = {
392
+ :AA => 1, # Afar
393
+ :AB => 2, # Abkhazian
394
+ :AE => 3, # Avestan
395
+ :AF => 4, # Afrikaans
396
+ :AM => 5, # Amharic
397
+ :AR => 6, # Arabic
398
+ :AS => 7, # Assamese
399
+ :AY => 8, # Aymara
400
+ :AZ => 9, # Azerbaijani
401
+ :BA => 10, # Bashkir
402
+ :BE => 11, # Belarusian
403
+ :BG => 12, # Bulgarian
404
+ :BH => 13, # Bihari
405
+ :BI => 14, # Bislama
406
+ :BN => 15, # Bengali; Bangla
407
+ :BO => 16, # Tibetan
408
+ :BR => 17, # Breton
409
+ :BS => 18, # Bosnian
410
+ :CA => 19, # Catalan
411
+ :CE => 20, # Chechen
412
+ :CH => 21, # Chamorro
413
+ :CO => 22, # Corsican
414
+ :CS => 23, # Czech
415
+ :CU => 24, # Church Slavic
416
+ :CV => 25, # Chuvash
417
+ :CY => 26, # Welsh
418
+ :DA => 27, # Danish
419
+ :DE => 28, # German
420
+ :DZ => 29, # Dzongkha; Bhutani
421
+ :EL => 30, # Greek
422
+ :EN => 31, # English
423
+ :EO => 32, # Esperanto
424
+ :ES => 33, # Spanish
425
+ :ET => 34, # Estonian
426
+ :EU => 35, # Basque
427
+ :FA => 36, # Persian
428
+ :FI => 37, # Finnish
429
+ :FJ => 38, # Fijian; Fiji
430
+ :FO => 39, # Faroese
431
+ :FR => 40, # French
432
+ :FY => 41, # Frisian
433
+ :GA => 42, # Irish
434
+ :GD => 43, # Scots; Gaelic
435
+ :GL => 44, # Gallegan; Galician
436
+ :GN => 45, # Guarani
437
+ :GU => 46, # Gujarati
438
+ :GV => 47, # Manx
439
+ :HA => 48, # Hausa (?)
440
+ :HE => 49, # Hebrew
441
+ :HI => 50, # Hindi
442
+ :HO => 51, # Hiri Motu
443
+ :HR => 52, # Croatian
444
+ :HU => 53, # Hungarian
445
+ :HY => 54, # Armenian
446
+ :HZ => 55, # Herero
447
+ :IA => 56, # Interlingua
448
+ :ID => 57, # Indonesian
449
+ :IE => 58, # Interlingue
450
+ :IK => 59, # Inupiak
451
+ :IO => 60, # Ido
452
+ :IS => 61, # Icelandic
453
+ :IT => 62, # Italian
454
+ :IU => 63, # Inuktitut
455
+ :JA => 64, # Japanese
456
+ :JV => 65, # Javanese
457
+ :KA => 66, # Georgian
458
+ :KI => 67, # Kikuyu
459
+ :KJ => 68, # Kuanyama
460
+ :KK => 69, # Kazakh
461
+ :KL => 70, # Kalaallisut
462
+ :KM => 71, # Khmer; Cambodian
463
+ :KN => 72, # Kannada
464
+ :KO => 73, # Korean
465
+ :KS => 74, # Kashmiri
466
+ :KU => 75, # Kurdish
467
+ :KV => 76, # Komi
468
+ :KW => 77, # Cornish
469
+ :KY => 78, # Kirghiz
470
+ :LA => 79, # Latin
471
+ :LB => 80, # Letzeburgesch
472
+ :LN => 81, # Lingala
473
+ :LO => 82, # Lao; Laotian
474
+ :LT => 83, # Lithuanian
475
+ :LV => 84, # Latvian; Lettish
476
+ :MG => 85, # Malagasy
477
+ :MH => 86, # Marshall
478
+ :MI => 87, # Maori
479
+ :MK => 88, # Macedonian
480
+ :ML => 89, # Malayalam
481
+ :MN => 90, # Mongolian
482
+ :MO => 91, # Moldavian
483
+ :MR => 92, # Marathi
484
+ :MS => 93, # Malay
485
+ :MT => 94, # Maltese
486
+ :MY => 95, # Burmese
487
+ :NA => 96, # Nauru
488
+ :NB => 97, # Norwegian Bokmål
489
+ :ND => 98, # Ndebele, North
490
+ :NE => 99, # Nepali
491
+ :NG => 100, # Ndonga
492
+ :NL => 101, # Dutch
493
+ :NN => 102, # Norwegian Nynorsk
494
+ :NO => 103, # Norwegian
495
+ :NR => 104, # Ndebele, South
496
+ :NV => 105, # Navajo
497
+ :NY => 106, # Chichewa; Nyanja
498
+ :OC => 107, # Occitan; Provençal
499
+ :OM => 108, # (Afan) Oromo
500
+ :OR => 109, # Oriya
501
+ :OS => 110, # Ossetian; Ossetic
502
+ :PA => 111, # Panjabi; Punjabi
503
+ :PI => 112, # Pali
504
+ :PL => 113, # Polish
505
+ :PS => 114, # Pashto, Pushto
506
+ :PT => 115, # Portuguese
507
+ :QU => 116, # Quechua
508
+ :RM => 117, # Rhaeto-Romance
509
+ :RN => 118, # Rundi; Kirundi
510
+ :RO => 119, # Romanian
511
+ :RU => 120, # Russian
512
+ :RW => 121, # Kinyarwanda
513
+ :SA => 122, # Sanskrit
514
+ :SC => 123, # Sardinian
515
+ :SD => 124, # Sindhi
516
+ :SE => 125, # Northern Sami
517
+ :SG => 126, # Sango; Sangro
518
+ :SI => 127, # Sinhalese
519
+ :SK => 128, # Slovak
520
+ :SL => 129, # Slovenian
521
+ :SM => 130, # Samoan
522
+ :SN => 131, # Shona
523
+ :SO => 132, # Somali
524
+ :SQ => 133, # Albanian
525
+ :SR => 134, # Serbian
526
+ :SS => 135, # Swati; Siswati
527
+ :ST => 136, # Sesotho
528
+ :SU => 137, # Sundanese
529
+ :SV => 138, # Swedish
530
+ :SW => 139, # Swahili
531
+ :TA => 140, # Tamil
532
+ :TE => 141, # Telugu
533
+ :TG => 142, # Tajik
534
+ :TH => 143, # Thai
535
+ :TI => 144, # Tigrinya
536
+ :TK => 145, # Turkmen
537
+ :TL => 146, # Tagalog
538
+ :TN => 147, # Tswana; Setswana
539
+ :TO => 148, # Tonga (?)
540
+ :TR => 149, # Turkish
541
+ :TS => 150, # Tsonga
542
+ :TT => 151, # Tatar
543
+ :TW => 152, # Twi
544
+ :TY => 153, # Tahitian
545
+ :UG => 154, # Uighur
546
+ :UK => 155, # Ukrainian
547
+ :UR => 156, # Urdu
548
+ :UZ => 157, # Uzbek
549
+ :VI => 158, # Vietnamese
550
+ :VO => 159, # Volapuk
551
+ :WA => 160, # Walloon
552
+ :WO => 161, # Wolof
553
+ :XH => 162, # Xhosa
554
+ :YI => 163, # Yiddish
555
+ :YO => 164, # Yoruba
556
+ :ZA => 165, # Zhuang
557
+ :ZH => 166, # Chinese
558
+ :ZU => 167 # Zulu
559
+ }.freeze
560
+
561
+ # -----------------------------------------------------------------------
562
+ # Mode: Interest Rates (TODO: Remove - deprecated?)
563
+ # -----------------------------------------------------------------------
564
+ INTEREST_RATES = {
565
+ :SE => 19.50,
566
+ :NO => 22.00,
567
+ :DK => 21.60,
568
+ :FI => 22.00,
569
+ :DE => 14.95,
570
+ :NL => 14.95
571
+ }.freeze
572
+
573
+ # -----------------------------------------------------------------------
574
+ # Amounts
575
+ # -----------------------------------------------------------------------
576
+
577
+ LOWEST_PAYMENT_BY_COUNTRY = {
578
+ :SE => 5000.00,
579
+ :NO => 9500.00,
580
+ :FI => 895.00,
581
+ :DK => 8900.00,
582
+ :DE => 695.00,
583
+ :NL => 500.00
584
+ }.freeze
585
+
586
+ # TODO: Remove - deprecated?
587
+ LOWEST_PAYMENT_BY_CURRENCY = {
588
+ CURRENCIES[:SEK] => 5000.00,
589
+ CURRENCIES[:NOK] => 9500.00,
590
+ CURRENCIES[:EUR] => 895.00,
591
+ CURRENCIES[:DKK] => 8900.00
592
+ }.freeze
593
+
594
+ # -----------------------------------------------------------------------
595
+ # Genders
596
+ # -----------------------------------------------------------------------
597
+
598
+ GENDERS = {
599
+ :FEMALE => 0,
600
+ :MALE => 1
601
+ }.freeze
602
+
603
+ # -----------------------------------------------------------------------
604
+ # Country defaults
605
+ # -----------------------------------------------------------------------
606
+ COUNTRY_DEFAULTS = {
607
+ :SE => {
608
+ :country => COUNTRIES[:SE],
609
+ :lang => LANGUAGES[:SV],
610
+ :currency => CURRENCIES[:SEK],
611
+ :pno => PNO_FORMATS[:SE]
612
+ },
613
+ :NO => {
614
+ :country => COUNTRIES[:NO],
615
+ :lang => LANGUAGES[:NB],
616
+ :currency => CURRENCIES[:NOK],
617
+ :pno => PNO_FORMATS[:NO]
618
+ },
619
+ :DK => {
620
+ :country => COUNTRIES[:DK],
621
+ :lang => LANGUAGES[:DA],
622
+ :currency => CURRENCIES[:DKK],
623
+ :pno => PNO_FORMATS[:DK]
624
+ },
625
+ :FI => {
626
+ :country => COUNTRIES[:FI],
627
+ :lang => LANGUAGES[:FI],
628
+ :currency => CURRENCIES[:EUR],
629
+ :pno => PNO_FORMATS[:FI]
630
+ },
631
+ :DE => {
632
+ :country => COUNTRIES[:DE],
633
+ :lang => LANGUAGES[:DE],
634
+ :currency => CURRENCIES[:EUR],
635
+ :pno => PNO_FORMATS[:DE]
636
+ },
637
+ :NL => {
638
+ :country => COUNTRIES[:NL],
639
+ :lang => LANGUAGES[:NL],
640
+ :currency => CURRENCIES[:EUR],
641
+ :pno => PNO_FORMATS[:NL]
642
+ }
643
+ }.freeze
644
+
645
+ end
646
+ end
647
+ end