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,9 @@
1
+ %h3 Has Account?
2
+ %p Enter the personal number to check if any account exists for this customer/company.
3
+
4
+ %form{:action => '/invoicing/has_account'}
5
+ %p
6
+ = field "SSN:", :pno, :text, :size => 10
7
+ *
8
+ %p
9
+ = submit_button "Query"
@@ -0,0 +1,7 @@
1
+ %h2 Has Account?
2
+
3
+ %h3 Result:
4
+ %p
5
+ = @result.inspect
6
+
7
+ = link_to "Back", :root
@@ -0,0 +1,15 @@
1
+ %h3 Return Amount
2
+ %p Enter an invoice number and the amount you will return from the invoice.
3
+
4
+ %form{:action => '/invoicing/return_amount'}
5
+ %p
6
+ = field "Invoice ID:", :invoice_no, :text, :size => 10
7
+ *
8
+ %p
9
+ = field "Amount:", :amount, :text, :size => 6
10
+ *
11
+ %p
12
+ = field "VAT:", :vat, :text, :size => 4, :value => '25,00'
13
+ *
14
+ %p
15
+ = submit_button "Return"
@@ -0,0 +1,7 @@
1
+ %h2 Return Amount
2
+
3
+ %h3 Result:
4
+ %p
5
+ = @result.inspect
6
+
7
+ = link_to "Back", :root
@@ -0,0 +1,9 @@
1
+ %h3 Send Invoice
2
+ %p Enter invoice number of an active invoice you would like to send.
3
+
4
+ %form{:action => '/invoicing/send_invoice'}
5
+ %p
6
+ = field "Invoice ID:", :invoice_no, :text, :size => 10
7
+ *
8
+ %p
9
+ = submit_button "Send"
@@ -0,0 +1,7 @@
1
+ %h2 Send Invoice
2
+
3
+ %h3 Result:
4
+ %p
5
+ = @result.inspect
6
+
7
+ = link_to "Back", :root
@@ -0,0 +1,349 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.require(:default, :development)
4
+ require 'active_support/all'
5
+ require 'sinatra'
6
+ require 'sinatra/mapping'
7
+ require 'haml'
8
+
9
+ require File.expand_path("config/initializer", File.dirname(__FILE__)).to_s
10
+
11
+ # CAUTION: This code haven't been updated to reflect the library - TODO.
12
+
13
+ # == Initialize a Klarna API-client.
14
+
15
+ begin
16
+ @@klarna = ::Klarna::API::Client.new(::Klarna.store_id, ::Klarna.store_secret)
17
+ rescue Klarna::API::Errors::KlarnaCredentialsError => e
18
+ puts e
19
+ rescue ::Klarna::API::Errors::KlarnaServiceError => e
20
+ puts e
21
+ end
22
+
23
+ # == Helpers to DRY up the views.
24
+
25
+ helpers do
26
+ def partial(*args)
27
+ locals = args.last.is_a?(Hash) ? args.pop : {}
28
+ options = args.last.is_a?(Hash) ? args.pop : {}
29
+ options.merge!(:layout => false)
30
+
31
+ template_file = "_#{args.pop}"
32
+ template_path = args.join('/')
33
+ template = [template_path, template_file].join('/')
34
+
35
+ haml(:"#{template}", options, locals)
36
+ end
37
+
38
+ def field(label, name, type, options = {})
39
+ tag, type =
40
+ case type.to_sym
41
+ when :select
42
+ [:select, nil]
43
+ when :textarea
44
+ [:textarea, nil]
45
+ else
46
+ [:input, type]
47
+ end
48
+ capture_haml do
49
+ haml_tag(:label, label, :for => name)
50
+ end <<
51
+ capture_haml do
52
+ haml_tag(tag, options.merge(:type => type, :name => name))
53
+ end
54
+ end
55
+
56
+ def currency_selector(label = "Currency:")
57
+ capture_haml do
58
+ haml_tag(:label, label, :for => :currency)
59
+ end <<
60
+ capture_haml do
61
+ haml_tag(:select, :name => :currency) do
62
+ haml_tag(:option, "Sweden (SEK)", :value => 'SEK')
63
+ haml_tag(:option, "Norway (NOK)", :value => 'NOK')
64
+ haml_tag(:option, "Finland (EUR)", :value => 'EUR')
65
+ haml_tag(:option, "Denmark (DKK)", :value => 'DKK')
66
+ haml_tag(:option, "Germany (EUR)", :value => 'EUR')
67
+ end
68
+ end
69
+ end
70
+
71
+ def country_selector(label = "Country:", options = {})
72
+ prefix = options[:prefix] || ""
73
+ capture_haml do
74
+ haml_tag(:label, label, :for => :country)
75
+ end <<
76
+ capture_haml do
77
+ haml_tag(:select, :name => :"#{prefix}country") do
78
+ haml_tag(:option, "Sweden (SE)", :value => 'SE')
79
+ haml_tag(:option, "Norway (NO)", :value => 'NO')
80
+ haml_tag(:option, "Finland (FI)", :value => 'FI')
81
+ haml_tag(:option, "Denmark (DK)", :value => 'DK')
82
+ haml_tag(:option, "Germany (DE)", :value => 'DE')
83
+ end
84
+ end
85
+ end
86
+
87
+ def ssn_encoding_selector(label = "SSN Encoding:")
88
+ capture_haml do
89
+ haml_tag(:label, label, :for => :pno_encoding)
90
+ end <<
91
+ capture_haml do
92
+ haml_tag(:select, :name => :pno_encoding) do
93
+ haml_tag(:option, "Swedish", :value => 'SV')
94
+ haml_tag(:option, "Norwegian", :value => 'NO')
95
+ haml_tag(:option, "Finnish", :value => 'FI')
96
+ haml_tag(:option, "Danish", :value => 'DA')
97
+ haml_tag(:option, "German", :value => 'DE')
98
+ end
99
+ end
100
+ end
101
+
102
+ def language_selector(label = "Language:")
103
+ capture_haml do
104
+ haml_tag(:label, label, :for => :language)
105
+ end <<
106
+ capture_haml do
107
+ haml_tag(:select, :name => :language) do
108
+ haml_tag(:option, "Swedish (SV)", :value => 'SV')
109
+ haml_tag(:option, "Norwegian (NO)", :value => 'NO')
110
+ haml_tag(:option, "Finnish (FI)", :value => 'FI')
111
+ haml_tag(:option, "Danish (DA)", :value => 'DA')
112
+ haml_tag(:option, "German (DE)", :value => 'DE')
113
+ end
114
+ end
115
+ end
116
+
117
+ def shipment_type_selector(label = "Shipment type:")
118
+ capture_haml do
119
+ haml_tag(:label, label, :for => :shipment_type)
120
+ end <<
121
+ capture_haml do
122
+ haml_tag(:select, :name => :shipment_type) do
123
+ haml_tag(:option, "Standard", :value => ::Klarna::API::SHIPMENT_TYPES[:NORMAL])
124
+ haml_tag(:option, "Express", :value => ::Klarna::API::SHIPMENT_TYPES[:EXPRESS])
125
+ end
126
+ end
127
+ end
128
+
129
+ def submit_button(label = "Submit")
130
+ capture_haml do
131
+ haml_tag(:input, :type => :submit, :value => label)
132
+ end
133
+ end
134
+
135
+ def button(label, link)
136
+ capture_haml do
137
+ haml_tag(:input, :type => 'button', :value => label, :onclick => link)
138
+ end
139
+ end
140
+
141
+ def process_reservation_details(params)
142
+ line_items = []
143
+ line_items << ::Klarna.make_goods(params[:'product[0]_quantity'], params[:'product[0]_article_no]'], params[:'product[0]_title'], params[:'product[0]_price'], params[:'product[0]_vat'], params[:'product[0]_discout'])
144
+ line_items << ::Klarna.make_goods(params[:'product[1]_quantity'], params[:'product[1]_article_no]'], params[:'product[1]_title'], params[:'product[1]_price'], params[:'product[1]_vat'], params[:'product[1]_discout'])
145
+
146
+ delivery_address = ::Klarna::API.make_reservation_address(params[:delivery_first_name], params[:delivery_last_name], params[:delivery_street_address], params[:delivery_postal_code], params[:delivery_city], params[:delivery_country], params[:delivery_house_number])
147
+ invoicing_address = ::Klarna::API.make_reservation_address(params[:invoicing_first_name], params[:invoicing_last_name], params[:invoicing_street_address], params[:invoicing_postal_code], params[:invoicing_city], params[:invoicing_country], params[:delivery_house_number])
148
+
149
+ country = ::Klarna::API.id_for(:country, params[:currency])
150
+ language = ::Klarna::API.id_for(:language, params[:language])
151
+ currency = ::Klarna::API.id_for(:currency, params[:currency])
152
+
153
+ client_ip = @env['REMOTE_ADDR']
154
+ pclass = -1
155
+
156
+ [line_items, delivery_address, invoicing_address, country, language, currency, client_ip, pclass]
157
+ end
158
+ end
159
+
160
+ # == Mappings.
161
+
162
+ map :root, ""
163
+
164
+ # == General.
165
+
166
+ get '/' do
167
+ haml :index
168
+ end
169
+ get '/favicon.ico' do
170
+ nil
171
+ end
172
+ get '/:action' do
173
+ haml params[:action].to_sym
174
+ end
175
+
176
+ # == Essential
177
+
178
+ # FIXME
179
+ get '/essential/calculate_monthly_cost' do
180
+ @result = @@klarna.calculate_monthly_cost(params[:sum] * 100, params[:currency], params[:months], params[:month_fee])
181
+ haml :"essential/calculate_monthly_cost/result"
182
+ end
183
+
184
+ # FIXME: Port to new API.
185
+ get '/essential/get_addresses' do
186
+ @result = @@klarna.get_addresses(
187
+ params[:pno],
188
+ ::Klarna::API::PNO_FORMATS[:SE]
189
+ )
190
+ haml :"essential/get_addresses/result"
191
+ end
192
+
193
+ get '/essential/add_transaction' do
194
+ goods_list = nil # ::Klarna.make_goods(params[:quantity], params[:article_no], t, price, vat, discount)
195
+ address = ::Klarna::API.make_address(params[:care_of], params[:street_address], params[:postal_code], params[:city], params[:country], params[:phone], params[:mobile], params[:email])
196
+ ip = @env['REMOTE_ADDR']
197
+ password = nil
198
+ new_password = nil
199
+ currency = ::Klarna::API.id_for(:currency, params[:currency])
200
+ country = ::Klarna::API.id_for(:country, params[:country])
201
+ language = ::Klarna::API.id_for(:language, params[:language])
202
+
203
+ @result = @@klarna.add_transaction(
204
+ params[:invoicing],
205
+ params[:order_id],
206
+ goods_list,
207
+ params[:shipping_fee],
208
+ params[:shipment_type],
209
+ params[:handling_fee],
210
+ params[:pno],
211
+ params[:first_name],
212
+ params[:last_name],
213
+ address,
214
+ ip,
215
+ currency,
216
+ country,
217
+ language
218
+ )
219
+ haml :"essential/add_transaction/result"
220
+ end
221
+
222
+ # == Invoicing
223
+
224
+ get '/invoicing/has_account' do
225
+ @result = @@klarna.has_account?(params[:pno])
226
+ haml :"essential/send_invoice/result"
227
+ end
228
+
229
+ get '/invoicing/activate_invoice' do
230
+ @result = @@klarna.activate_invoice(params[:invoice_no])
231
+ haml :"essential/activate_invoice/result"
232
+ end
233
+
234
+ get '/invoicing/credit_invoice' do
235
+ @result = @@klarna.credit_invoice(params[:invoice_no], params[:credit_id])
236
+ haml :"essential/credit_invoice/result"
237
+ end
238
+
239
+ get '/invoicing/delete_invoice' do
240
+ @result = @@klarna.delete_invoice(params[:invoice_no])
241
+ haml :"essential/delete_invoice/result"
242
+ end
243
+
244
+ get '/invoicing/return_amount' do
245
+ @result = @@klarna.return_amount(params[:invoice_no], params[:amount], params[:vat])
246
+ haml :"essential/return_amount/result"
247
+ end
248
+
249
+ get '/invoicing/email_invoice' do
250
+ @result = @@klarna.email_invoice(params[:invoice_no])
251
+ haml :"essential/email_invoice/result"
252
+ end
253
+
254
+ get '/invoicing/send_invoice' do
255
+ @result = @@klarna.send_invoice(params[:invoice_no])
256
+ haml :"essential/send_invoice/result"
257
+ end
258
+
259
+ # == Special
260
+
261
+ get '/special/update_charge_amount' do
262
+ @result = @@klarna.update_charge_amount(params[:invoice_no], params[:charge_type], params[:new_amount])
263
+ haml :"special/update_charge_amount/result"
264
+ end
265
+
266
+ get '/special/update_goods_quantity' do
267
+ @result = @@klarna.update_goods_quantity(params[:invoice_no], params[:article_no], params[:quantity])
268
+ haml :"special/update_goods_quantity/result"
269
+ end
270
+
271
+ get '/special/update_order_number' do
272
+ @result = @@klarna.update_order_number(params[:invoice_no], params[:new_order_id])
273
+ haml :"special/update_order_number/result"
274
+ end
275
+
276
+ get '/special/invoice_address' do
277
+ @result = @@klarna.get_invoice_address(params[:invoice_no])
278
+ haml :"special/invoice_address/result"
279
+ end
280
+
281
+ get '/special/invoice_amount' do
282
+ @result = @@klarna.get_invoice_amount(params[:invoice_no])
283
+ haml :"special/invoice_amount/result"
284
+ end
285
+
286
+ get '/special/is_invoice_paid' do
287
+ @result = @@klarna.invoice_paid?(params[:invoice_no])
288
+ haml :"special/is_invoice_paid/result"
289
+ end
290
+
291
+ get '/special/get_pclasses' do
292
+ currency = ::Klarna::API.id_for(:currency, params[:currency])
293
+ @result = @@klarna.get_pclasses(currency)
294
+ haml :"special/get_pclasses/result"
295
+ end
296
+
297
+ # == Reservation
298
+
299
+ get '/reservation/reserve_amount' do
300
+ line_items = []
301
+ line_items << ::Klarna.make_goods(params[:'product[0]_quantity'], params[:'product[0]_article_no]'], params[:'product[0]_title'], params[:'product[0]_price'], params[:'product[0]_vat'], params[:'product[0]_discout'])
302
+ line_items << ::Klarna.make_goods(params[:'product[1]_quantity'], params[:'product[1]_article_no]'], params[:'product[1]_title'], params[:'product[1]_price'], params[:'product[1]_vat'], params[:'product[1]_discout'])
303
+
304
+ delivery_address = ::Klarna::API.make_reservation_address(params[:delivery_first_name], params[:delivery_last_name], params[:delivery_street_address], params[:delivery_postal_code], params[:delivery_city], params[:delivery_country], params[:delivery_house_number])
305
+ invoicing_address = ::Klarna::API.make_reservation_address(params[:invoicing_first_name], params[:invoicing_last_name], params[:invoicing_street_address], params[:invoicing_postal_code], params[:invoicing_city], params[:invoicing_country], params[:delivery_house_number])
306
+
307
+ country = ::Klarna::API.id_for(:country, params[:currency])
308
+ language = ::Klarna::API.id_for(:language, params[:language])
309
+ currency = ::Klarna::API.id_for(:currency, params[:currency])
310
+
311
+ client_ip = @env['REMOTE_ADDR']
312
+ pclass = -1
313
+
314
+ # Q: What is order_id_X?
315
+ @result = @@klarna.reserve_amount(params[:pno], params[:amount], line_items, params[:reference], params[:reference_id], params[:order_id_1], params[:order_id_1],
316
+ client_ip, delivery_address, invoicing_address, params[:email], params[:phone], params[:mobile],
317
+ currency, country, language, params[:pno_encoding], pclass, params[:annual_salary])
318
+ haml :"special/reserve_amount/result"
319
+ end
320
+
321
+ get '/reservation/activate_reservation' do
322
+ # Q: Same as reserve_amount...?
323
+ line_items, delivery_address, invoicing_address, country, language, currency, client_ip, pclass = process_reservation_details(params)
324
+
325
+ @result = @@klarna.activate_reservation(params[:pno], params[:amount], line_items, params[:reference], params[:reference_id], params[:order_id_1], params[:order_id_1],
326
+ client_ip, delivery_address, invoicing_address, params[:email], params[:phone], params[:mobile],
327
+ currency, country, language, params[:pno_encoding], pclass, params[:annual_salary])
328
+ haml :"special/activate_reservation/result"
329
+ end
330
+
331
+ get '/reservation/cancel_reservation' do
332
+ @result = @@klarna.cancel_reservation(params[:reservation_id])
333
+ haml :"special/cancel_reservation/result"
334
+ end
335
+
336
+ get '/reservation/change_reservation' do
337
+ @result = @@klarna.change_reservation(params[:reservation_id], params[:new_amount])
338
+ haml :"special/change_reservation/result"
339
+ end
340
+
341
+ get '/reservation/split_reservation' do
342
+ @result = @@klarna.split_reservation(params[:reservation_id], params[:split_amount], params[:order_id_1], params[:order_id_2])
343
+ haml :"special/split_reservation/result"
344
+ end
345
+
346
+ get '/reservation/reserve_ocr_numbers' do
347
+ @result = @@klarna.reserve_ocr_numbers(params[:ocr_count])
348
+ haml :"special/reserve_ocr_numbers/result"
349
+ end
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'klarna/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "klarna-xmlrpc"
7
+ s.version = Klarna::VERSION.dup
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Jonas Grimfelt","Serg Tyatin"]
10
+ s.email = ["jonas@merchii.com"]
11
+ s.homepage = "http://github.com/2rba/klarna-ruby"
12
+ s.summary = %{A Ruby wrapper for Klarna/Kreditor XML-RPC API.}
13
+ s.description = s.summary
14
+
15
+ s.add_dependency 'activesupport'
16
+ s.add_dependency 'i18n'
17
+
18
+ s.add_development_dependency 'bundler'
19
+ s.add_development_dependency 'rake'
20
+ s.add_development_dependency 'rdoc'
21
+ s.add_development_dependency 'minitest'
22
+ s.add_development_dependency 'mocha'
23
+ s.add_development_dependency 'guard'
24
+ s.add_development_dependency 'guard-bundler'
25
+ s.add_development_dependency 'guard-minitest'
26
+ s.add_development_dependency 'sinatra'
27
+ s.add_development_dependency 'sinatra-mapping'
28
+ s.add_development_dependency 'haml'
29
+
30
+ s.files = `git ls-files`.split("\n")
31
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
32
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
33
+ s.require_paths = ['lib']
34
+ end
@@ -0,0 +1,171 @@
1
+ require 'i18n'
2
+ require 'active_support/all' # TODO: Cherry-pick only what we use.
3
+
4
+ module Klarna
5
+
6
+ autoload :API, 'klarna/api'
7
+ autoload :VERSION, 'klarna/version'
8
+
9
+ module API
10
+ autoload :Client, 'klarna/api/client'
11
+ autoload :Constants, 'klarna/api/constants'
12
+ autoload :Errors, 'klarna/api/errors'
13
+
14
+ module Methods
15
+ autoload :Standard, 'klarna/api/methods/standard'
16
+ autoload :Invoicing, 'klarna/api/methods/invoicing'
17
+ autoload :Reservation, 'klarna/api/methods/reservation'
18
+ autoload :CostCalculations, 'klarna/api/methods/cost_calculations'
19
+ end
20
+ end
21
+
22
+ class KlarnaConfigError < ::StandardError
23
+ end
24
+
25
+ DEFAULT_STORE_CONFIG_FILE = File.join(ENV['HOME'], '.klarna.yml') unless defined?(::Klarna::DEFAULT_STORE_CONFIG_FILE)
26
+ VALID_COUNTRIES = [:SE, :NO, :FI, :DK] unless defined?(::Klarna::VALID_COUNTRIES)
27
+ DEFAULT_COUNTRY = VALID_COUNTRIES.first unless defined?(::Klarna::DEFAULT_COUNTRY)
28
+ DEFAULT_MODE = :test unless defined?(::Klarna::DEFAULT_MODE)
29
+
30
+ # Specifies running mode: +:test+ (alla actions gets virtual) or +:production+ (live)
31
+ # Default: +:test+
32
+ mattr_accessor :mode
33
+ @@mode = :test
34
+
35
+ # Country used to ensure that params sent to Klarna service is correct.
36
+ # Default: +:SE+
37
+ mattr_accessor :country
38
+ @@country = ::Klarna::DEFAULT_COUNTRY
39
+
40
+ # Klarna e-store ID (a.k.a. "eid") used for Klarna API authentication.
41
+ # Default: +nil+
42
+ # NOTE: If +nil+, Klarna will look for credentials in file specified by +Devise.store_config_file+.
43
+ mattr_accessor :store_id
44
+ @@store_id = nil
45
+
46
+ # Klarna e-store shared secret token used for Klarna API authentication.
47
+ # Default: +nil+
48
+ # NOTE: If +nil+, Klarna will look for credentials in file specified by +Devise.credentials_file+.
49
+ mattr_accessor :store_secret
50
+ @@store_secret = nil
51
+
52
+ # Klarna e-store-specific pclasses (a.k.a. campaigns).
53
+ # Default: +nil+
54
+ #
55
+ # NOTE:
56
+ # * Required for campaigns
57
+ # * This should maybe be initialized from database to make more dynamic (e.g. admin inteface).
58
+ #
59
+ mattr_accessor :store_pclasses
60
+ @@store_pclasses = nil
61
+
62
+ # Path to a YAML file containing API credentials - used only if +store_id+ and +store_secret+ are not set.
63
+ # Default: +"~/.klarna.yml"+
64
+ mattr_accessor :store_config_file
65
+ @@store_config_file = ::Klarna::DEFAULT_STORE_CONFIG_FILE
66
+
67
+ # The logger to use in log mode.
68
+ # Default: +::Logger.new(::STDOUT)+
69
+ mattr_accessor :logger
70
+ @@logger = ::Logger.new(::STDOUT)
71
+
72
+ # Sets if activity should be logged or not - for high-level debugging.
73
+ # Default: +false+
74
+ mattr_accessor :logging
75
+ @@logging = false
76
+
77
+ # Sets if Net::HTTP activity should be logged or not - for low-level debugging.
78
+ # Default: +false+
79
+ mattr_accessor :http_logging
80
+ @@http_logging = false
81
+
82
+ class << self
83
+
84
+ # Configuration DSL helper method.
85
+ #
86
+ # == Usage/Example:
87
+ #
88
+ # Klarna::Setup do |config|
89
+ # config.country = :SE
90
+ # # etc.
91
+ # end
92
+ #
93
+ def setup
94
+ yield self
95
+ self.load_credentials_from_file unless self.store_id || self.store_secret
96
+ end
97
+ alias :configure :setup
98
+
99
+ # Reset to defaults - mostly usable in specs.
100
+ #
101
+ def reset!
102
+ self.mode = ::Klarna::DEFAULT_MODE
103
+ self.country = ::Klarna::DEFAULT_COUNTRY
104
+ self.store_id = nil
105
+ self.store_secret = nil
106
+ self.store_pclasses = nil
107
+ self.store_config_file = ::Klarna::DEFAULT_STORE_CONFIG_FILE
108
+ self.logger = ::Logger.new(::STDOUT)
109
+ self.logging = false
110
+ self.http_logging = false
111
+ end
112
+
113
+ # Logging helper for debugging purposes.
114
+ #
115
+ def log(message, level = :info)
116
+ return unless self.logging?
117
+ level = :info if level.blank?
118
+ self.logger ||= ::Logger.new(::STDOUT)
119
+ self.logger.send(level.to_sym, "[klarna:] #{level.to_s.upcase} #{message}")
120
+ end
121
+
122
+ # Logging helper for debugging "log return value"-cases.
123
+ #
124
+ def log_result(label, &block)
125
+ result = block.call
126
+ self.log label % result.inspect
127
+ result
128
+ end
129
+
130
+ # Optional: Try to load credentials from a system file.
131
+ #
132
+ def load_credentials_from_file(force = false)
133
+ begin
134
+ store_config = File.open(self.store_config_file) { |file| YAML.load(file).with_indifferent_access }
135
+ self.store_id = store_config[self.mode][:store_id] if force || self.store_id.nil?
136
+ self.store_secret = store_config[self.mode][:store_secret] if force || self.store_secret.nil?
137
+ self.store_pclasses = store_config[self.mode][:store_pclasses] if force || self.store_pclasses.nil?
138
+ rescue
139
+ raise KlarnaConfigError, "Could not load store details from: #{self.store_config_file.inspect}"
140
+ end
141
+ end
142
+
143
+ def store_id=(value)
144
+ @@store_id = value ? value.to_i : value
145
+ end
146
+
147
+ def store_secret=(value)
148
+ @@store_secret = value ? value.to_s.strip : value
149
+ end
150
+
151
+ def country=(value)
152
+ @@country = value.to_s.upcase.to_sym rescue ::Klarna::DEFAULT_COUNTRY
153
+ end
154
+
155
+ def mode=(value)
156
+ @@mode = value.to_s.downcase.to_sym rescue ::Klarna::DEFAULT_MODE
157
+ end
158
+
159
+ def valid_countries
160
+ ::Klarna::VALID_COUNTRIES
161
+ end
162
+
163
+ def default_country
164
+ ::Klarna::DEFAULT_COUNTRY
165
+ end
166
+
167
+ alias :logging? :logging
168
+ alias :http_logging? :http_logging
169
+ end
170
+
171
+ end