allorails 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,448 @@
1
+ require 'net/http'
2
+ require 'json'
3
+
4
+ module Allorails
5
+ module Response
6
+
7
+ class ApiResponse
8
+
9
+ ##
10
+ # Constructor
11
+ # @param signature (string) Expected response signature
12
+ # @param headers (list) Response HTTP headers
13
+ # @param body (string) Raw response data
14
+ def initialize(signature, headers, body)
15
+ @_signature = signature
16
+ @_headers = headers
17
+ @_body = body
18
+ end
19
+
20
+ ##
21
+ # Internal method checking the response
22
+ # @throws ApiFalseResponseSignature If the expected signature is not found among response headers
23
+ def _verify
24
+ raise Allorails::ApiFalseResponseSignatureError unless @_headers['x-allopass-response-signature'].include?(@_signature)
25
+ end
26
+
27
+ ## Custom print result
28
+ def to_s
29
+ @_body
30
+ end
31
+
32
+ end # -- end class ApiResponse
33
+
34
+
35
+ class JsonNode
36
+
37
+ attr_reader :children
38
+ attr_reader :attributes
39
+
40
+ def initialize(json_obj)
41
+ @attributes = json_obj.delete('@attributes') || {}
42
+ @children = {}
43
+ json_obj.each_pair do |k, v|
44
+ @children[k] = v.is_a?(Hash) ? JsonNode.new(v) : (v.is_a?(Array) ? v.map{|el| JsonNode.new(el)} : v)
45
+ end
46
+ end
47
+
48
+ def method_missing(m, *args, &block)
49
+ m = m.to_s
50
+ return attributes[m] if attributes.has_key?(m)
51
+ return children[m] if children.has_key?(m)
52
+ return nil
53
+ end
54
+
55
+ end
56
+
57
+
58
+ class ApiMappingResponse < ApiResponse
59
+
60
+ attr_reader :json
61
+
62
+ ##
63
+ # Constructor
64
+ # @param signature (string) Expected response signature
65
+ # @param headers (list) Response HTTP headers
66
+ # @param body (string) Raw response data
67
+ def initialize(signature, headers, body)
68
+ super(signature, headers, body)
69
+ begin
70
+ @json = JsonNode.new(JSON.parse(body)['response'] || {})
71
+ rescue JSON::ParserError => e
72
+ raise Allorails::ApiWrongFormatResponseError
73
+ end
74
+ _verify
75
+ end
76
+
77
+ ##
78
+ # Internal method checking the response
79
+ # @throws ApiFalseResponseSignature If the expected signature is not found among response headers
80
+ def _verify
81
+ if json.code.nil? || json.code.to_i != 0
82
+ raise Allorails::ApiRemoteErrorError
83
+ end
84
+ super
85
+ end
86
+
87
+ ##
88
+ # Internal method allowing easy reading of JSON nodes
89
+ # @param (sym) name of the (top-level) node that needs to be read
90
+ # @param (Class) type to which the result should be cast
91
+ def self.node_reader(node_name, type = String)
92
+ # define a Proc to cast the node's text to the specified type
93
+ cast = case true
94
+ when type == String then Proc.new{|x| x.to_s}
95
+ when type == Integer then Proc.new{|x| x.to_i}
96
+ when type == Float then Proc.new{|x| to_f}
97
+ when type == DateTime then Proc.new{|x| x.date.nil? ? (x.timestamp.nil? ? nil : DateTime.strptime(x.timestamp, "%s")) : DateTime.strptime(x.date)}
98
+ else Proc.new{|x| type.new x}
99
+ end
100
+ # add a method accessing the node and casting the text
101
+ send :define_method, node_name do
102
+ result = json.send(node_name)
103
+ return cast.call(result) unless result.nil?
104
+ end
105
+ end
106
+
107
+ end
108
+
109
+
110
+ class OnetimePricingResponse < ApiMappingResponse
111
+
112
+ ## Provides the creation date
113
+ # @return (DateTime) Creation date
114
+ node_reader :creation_date, DateTime
115
+
116
+ ## Provides the customer ip
117
+ # @return (string) customer ip
118
+ node_reader :customer_ip
119
+
120
+ ## Provides the customer country
121
+ # @return (string) customer country
122
+ node_reader :customer_country
123
+
124
+ ## Provides the website
125
+ # @return (Website) website
126
+ node_reader :website
127
+
128
+ ## Provides the pricepoints by countries
129
+ # @return (Array) available countries (list of Country object)
130
+ def countries
131
+ countries = []
132
+ json.countries.children.values.each{|r| countries += r.children.values.map{|c| ::Allorails::Country.new(c)}}
133
+ countries
134
+ end
135
+
136
+ ## Provides the pricepoints by region
137
+ # @return (Array) available regions (list of Regions object)
138
+ def regions
139
+ json.countries.children.values.map{|r| ::Allorails::Region.new(r)}
140
+ end
141
+
142
+ ## Provides the pricepoints by markets
143
+ # @return (list) available markets (list of Market object)
144
+ def markets
145
+ json.markets.children.values.map{|m| ::Allorails::Market.new(m)}
146
+ end
147
+
148
+ end
149
+
150
+
151
+ ## Class defining a onetime validate-codes request's response
152
+ class OnetimeValidateCodesResponse < ApiMappingResponse
153
+ ## The validation is successful
154
+ VALIDATESCODES_SUCCESS = 0
155
+
156
+ ## The validation failed
157
+ VALIDATESCODES_FAILED = 1
158
+
159
+ ## Provides the validation status
160
+ # @return (int) validation status
161
+ node_reader :status, Integer
162
+
163
+ ## Provides the validation status description
164
+ # @return (string) validation status description
165
+ node_reader :status_description
166
+
167
+ ## Provides access type
168
+ # @return (string) access type
169
+ node_reader :access_type
170
+
171
+ ## Provides the transaction id
172
+ # @return (string) transaction id
173
+ node_reader :transaction_id
174
+
175
+ ## Provides price information
176
+ # @return (Price) price information
177
+ node_reader :price, ::Allorails::Price
178
+
179
+ ## Provides paid price information
180
+ # @return (Price) paid price information
181
+ node_reader :paid, ::Allorails::Price
182
+
183
+ ## Provides the validation date
184
+ # @return (datetime.datetime) validation date
185
+ node_reader :validation_date, DateTime
186
+
187
+ ## Provides the product name
188
+ # @return (string) product name
189
+ node_reader :product_name
190
+
191
+ ## Provides the website
192
+ # @return (Website) website
193
+ node_reader :website
194
+
195
+ ## Provides the customer ip
196
+ # @return (string) customer ip
197
+ node_reader :customer_ip
198
+
199
+ ## Provides the customer country
200
+ # @return (string) customer country
201
+ node_reader :customer_country
202
+
203
+ ## Provides the expected number of codes
204
+ # @return (int) expected number of codes
205
+ node_reader :expected_number_of_codes, Integer
206
+
207
+ ## Provides the codes you tried to validate
208
+ # @return (Array) list of Code objects
209
+ def codes
210
+ json.codes.children.values.map{|c| ::Allorails::Code.new(c)}
211
+ end
212
+
213
+ ## Provides the merchant transaction id
214
+ # @return (string) merchant transaction id
215
+ node_reader :merchant_transaction_id
216
+
217
+ ## Provides the client data
218
+ # @return (string) client data
219
+ node_reader :data
220
+
221
+ ## Provides the affiliation code
222
+ # @return (string) affiliation code
223
+ node_reader :affiliate
224
+
225
+ ## Provides information about the associated partners
226
+ # @return (list) partners information (list of Partner objects)
227
+ def partners
228
+ json.partners.children.values.map{|c| ::Allorails::Partner.new(c)}
229
+ end
230
+
231
+ end
232
+
233
+
234
+ ## Class defining a product detail request's response
235
+ class ProductDetailResponse < ApiMappingResponse
236
+
237
+ ## Provides the product id
238
+ # @return (int) product id
239
+ node_reader :id, Integer
240
+
241
+ ## Provides the product key
242
+ # @return (string) product key
243
+ node_reader :key
244
+
245
+ ## Provides access type
246
+ # @return (string) access type
247
+ node_reader :access_type
248
+
249
+ ## Provides the creation date
250
+ # @return (datetime.datetime) Creation date
251
+ node_reader :creation_date, DateTime
252
+
253
+ ## Provides the product name
254
+ # @return (string) product name
255
+ node_reader :name
256
+
257
+ ## Provides the website
258
+ # @return (Website) website
259
+ node_reader :website
260
+
261
+ ## Provides the expected number of codes
262
+ # @return (int) expected number of codes
263
+ node_reader :expected_number_of_codes, Integer
264
+
265
+ ## Provides the purchase url
266
+ # @return (string) purchase url
267
+ node_reader :purchase_url
268
+
269
+ ## Provides the forward url
270
+ # @return (string) forward url
271
+ node_reader :forward_url
272
+
273
+ ## Provides the error url
274
+ # @return (string) error url
275
+ node_reader :error_url
276
+
277
+ ## Provides the notification url
278
+ # @return (string) notification url
279
+ node_reader :notification_url
280
+
281
+ end
282
+
283
+
284
+ ## Class defining a transaction prepare request's response
285
+ class TransactionPrepareResponse < ApiMappingResponse
286
+
287
+ ## Provides access type
288
+ # @return (string) access type
289
+ node_reader :access_type
290
+
291
+ ## Provides the transaction id
292
+ # @return (string) transaction id
293
+ node_reader :transaction_id
294
+
295
+ ## Provides the creation date
296
+ # @return (datetime.datetime) Creation date
297
+ node_reader :creation_date, DateTime
298
+
299
+ ## Provides price information
300
+ # @return (Price) price information
301
+ node_reader :price, ::Allorails::Price
302
+
303
+ ## Provides information about the pricepoint
304
+ # @return (Pricepoint) pricepoint information
305
+ node_reader :pricepoint, ::Allorails::Pricepoint
306
+
307
+ ## Provides the website
308
+ # @return (Website) website
309
+ node_reader :website
310
+
311
+ ## Provides the buy url
312
+ # @return (string) buy url
313
+ node_reader :buy_url
314
+
315
+ ## Provides the checkout button
316
+ # @return (string) checkout button (html code)
317
+ node_reader :checkout_button
318
+
319
+ end
320
+
321
+
322
+ ## Class defining a transaction detail request's response
323
+ class TransactionDetailResponse < ApiMappingResponse
324
+
325
+ ## The transaction is at first step : initialization
326
+ INIT = -1
327
+
328
+ ## The transaction is successful
329
+ SUCCESS = 0
330
+
331
+ ## The transaction failed due to insufficient funds
332
+ INSUFFICIENT_FUNDS = 1
333
+
334
+ ## The transaction timeouted
335
+ TIMEOUT = 2
336
+
337
+ ## The transaction has been cancelled by user
338
+ CANCELLED = 3
339
+
340
+ ## The transaction has been blocked due to fraud suspicions
341
+ ANTI_FRAUD = 4
342
+
343
+ ## Provides the transaction status
344
+ # @return (int) transaction status
345
+ node_reader :status, Integer
346
+
347
+ ## Provides the validation status description
348
+ # @return (string) validation status description
349
+ node_reader :status_description
350
+
351
+ ## Provides access type
352
+ # @return (string) access type
353
+ node_reader :access_type
354
+
355
+ ## Provides the tansaction id
356
+ # @return (string) transaction id
357
+ node_reader :transaction_id
358
+
359
+ ## Provides price information
360
+ # @return (Price) price information
361
+ node_reader :price, ::Allorails::Price
362
+
363
+ ## Provides paid price information
364
+ # @return (Price) paid price information
365
+ node_reader :paid, ::Allorails::Price
366
+
367
+ ## Provides the creation date
368
+ # @return (datetime.datetime) Creation date
369
+ node_reader :creation_date, DateTime
370
+
371
+ ## Provides the end date
372
+ # @return (datetime.datetime) end date
373
+ node_reader :end_date, DateTime
374
+
375
+ ## Provides the product name
376
+ # @return (string) product name
377
+ node_reader :product_name
378
+
379
+ ## Provides the customer ip
380
+ # @return (string) customer ip
381
+ node_reader :customer_ip
382
+
383
+ ## Provides the customer country
384
+ # @return (string) customer country
385
+ node_reader :customer_country
386
+
387
+ ## Provides the expected number of codes
388
+ # @return (int) expected number of codes
389
+ node_reader :expected_number_of_codes, Integer
390
+
391
+ ## Provides the codes associated with the transaction
392
+ # @return (list) list of codes (list of string)
393
+ def codes
394
+ json.codes.children.values.map{|c| ::Allorails::Code.new(c)}
395
+ end
396
+
397
+ ## Provides the merchant transaction id
398
+ # @return (string) merchant transaction id
399
+ node_reader :merchant_transaction_id
400
+
401
+ ## Provides the client data
402
+ # @return (string) client data
403
+ node_reader :data
404
+
405
+ ## Provides the affiliation code
406
+ # @return (string) affiliation code
407
+ node_reader :affiliate
408
+
409
+ ## Provides information about the associated partners
410
+ # @return (list) partners information (list of Partner objects)
411
+ def partners
412
+ json.partners.children.values.map{|c| ::Allorails::Partner.new(c)}
413
+ end
414
+
415
+ end
416
+
417
+
418
+ ## Class defining a onetime button request's response
419
+ class OnetimeButtonResponse < ApiMappingResponse
420
+
421
+ ## Provides access type
422
+ # @return (string) access type
423
+ node_reader :access_type
424
+
425
+ ## Provides the button id
426
+ # @return (string) button id
427
+ node_reader :button_id
428
+
429
+ ## Provides the creation date
430
+ # @return (datetime.datetime) Creation date
431
+ node_reader :creation_date, DateTime
432
+
433
+ ## Provides the website
434
+ # @return (Website) website
435
+ node_reader :website, Website
436
+
437
+ ## Provides the buy url
438
+ # @return (string) buy url
439
+ node_reader :buy_url
440
+
441
+ ## Provides the checkout button
442
+ # @return (string) checkout button (html code)
443
+ node_reader :checkout_button
444
+
445
+ end
446
+
447
+ end #-- end module Allorails::Response
448
+ end #-- end module Allorails
data/lib/allorails.rb ADDED
@@ -0,0 +1,51 @@
1
+ require 'allorails/core'
2
+
3
+ require 'allorails/errors/errors'
4
+
5
+ module Allorails
6
+
7
+ #autoload :Conf, 'allorails/conf'
8
+ autoload :Api, 'allorails/api/api'
9
+
10
+ #def self.Conf
11
+ # Allorails::Conf.instance
12
+ #end
13
+
14
+ autoload :Website, 'allorails/response/model'
15
+ autoload :Country, 'allorails/response/model'
16
+ autoload :Region, 'allorails/response/model'
17
+ autoload :Market, 'allorails/response/model'
18
+ autoload :Pricepoint, 'allorails/response/model'
19
+ autoload :Price, 'allorails/response/model'
20
+ autoload :Payout, 'allorails/response/model'
21
+ autoload :PhoneNumber, 'allorails/response/model'
22
+ autoload :Keyword, 'allorails/response/model'
23
+ autoload :Partner, 'allorails/response/model'
24
+ autoload :Code, 'allorails/response/model'
25
+
26
+ module Request
27
+ autoload :ApiRequest, 'allorails/request/request'
28
+ autoload :OnetimePricingRequest, 'allorails/request/request'
29
+ autoload :OnetimeDiscretePricingRequest, 'allorails/request/request'
30
+ autoload :OnetimeValidateCodesRequest, 'allorails/request/request'
31
+ autoload :ProductDetailRequest, 'allorails/request/request'
32
+ autoload :TransactionPrepareRequest, 'allorails/request/request'
33
+ autoload :TransactionDetailRequest, 'allorails/request/request'
34
+ autoload :TransactionMerchantRequest, 'allorails/request/request'
35
+ autoload :OnetimeButtonRequest, 'allorails/request/request'
36
+ autoload :OnetimeDiscreteButtonRequest, 'allorails/request/request'
37
+ end
38
+
39
+ module Response
40
+ autoload :ApiResponse, 'allorails/response/response'
41
+ autoload :OnetimePricingResponse, 'allorails/response/response'
42
+ autoload :OnetimeValidateCodesResponse, 'allorails/response/response'
43
+ autoload :ProductDetailResponse, 'allorails/response/response'
44
+ autoload :TransactionPrepareResponse, 'allorails/response/response'
45
+ autoload :TransactionDetailResponse, 'allorails/response/response'
46
+ autoload :OnetimeButtonResponse, 'allorails/response/response'
47
+ end
48
+
49
+ end
50
+
51
+ require 'allorails/rails'
@@ -0,0 +1,69 @@
1
+ require 'allorails'
2
+ require 'yaml'
3
+
4
+ # load Allorails configuration options for testing
5
+ #
6
+ # to be able to run these tests, create a test/test-conf.yml file,
7
+ # based on test/test-conf-sample.yml
8
+ # but using your own API credentials
9
+ Allorails.config(YAML.load File.read(File.join(File.dirname(__FILE__), 'test-conf.yml')))
10
+
11
+
12
+ # some additional parameters for the tests
13
+ YOUR_SITE_ID = 281629
14
+ TEST_COUNTRY_CODE = 'UK'
15
+
16
+
17
+ # run the tests
18
+
19
+ describe Allorails::Request::ApiRequest, "#init" do
20
+ it "starts" do
21
+ req = Allorails::Request::ApiRequest.new(params = {}, mapping = true, email_account = nil)
22
+ req.should_not be_nil
23
+ end
24
+ end
25
+
26
+ describe Allorails::Api, "#init" do
27
+ it "initializes with email=nil" do
28
+ api = Allorails::Api.new
29
+ end
30
+ end
31
+
32
+ describe Allorails::Api, "#get_onetime_pricing" do
33
+ api = Allorails::Api.new
34
+ resp = api.get_onetime_pricing({'site_id' => YOUR_SITE_ID, 'country' => TEST_COUNTRY_CODE})
35
+ it "returns a valid response" do
36
+ resp.to_s.should_not be_nil
37
+ resp.creation_date.is_a?(DateTime).should be_true
38
+ resp.regions.is_a?(Array).should be_true
39
+ resp.regions.each do |reg|
40
+ reg.is_a?(Allorails::Region).should be_true
41
+ reg.countries.is_a?(Array).should be_true
42
+ reg.countries.each do |ctry|
43
+ ctry.is_a?(Allorails::Country).should be_true
44
+ (ctry.code.length > 0).should be_true
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ describe Allorails::Api, "#create_discrete_button" do
51
+ api = Allorails::Api.new
52
+ resp = api.create_discrete_button({
53
+ 'site_id' => YOUR_SITE_ID,
54
+ 'product_name' => 'TEST-DISCRETE-BUTTON',
55
+ 'forward_url' => 'http://any-test.url/is?good',
56
+ 'price_mode' => 'price',
57
+ 'amount' => 0.99,
58
+ 'price_policy' => 'high-preferred',
59
+ 'reference_currency' => 'EUR'
60
+ })
61
+ it "returns a valid response" do
62
+ resp.to_s.should_not be_nil
63
+ resp.is_a?(Allorails::Response::OnetimeButtonResponse).should be_true
64
+ (resp.json).should_not be_nil
65
+ # puts resp.json.inspect #DEBUG
66
+ resp.button_id.should_not be_nil
67
+ resp.website.is_a?(Allorails::Website).should be_true
68
+ end
69
+ end
@@ -0,0 +1,11 @@
1
+ accounts:
2
+ your@email.com:
3
+ api_key: 9696ba35ebb3dc6c11c964c269f262a6
4
+ private_key: 50372be654ecacf9dbb1b431535f21d0
5
+
6
+ default_hash: sha1
7
+ default_format: json
8
+ network_timeout: 20
9
+ network_protocol: http
10
+ network_port: 80
11
+ host: pgeoffroy.api.payment.allopass.dev
@@ -0,0 +1,12 @@
1
+ accounts:
2
+ jonathan@feeligo.com:
3
+ api_key: d33102f78bea414ed098e5cd0bf17632
4
+ private_key: 2670c0094d163a718ea44f5459114301
5
+
6
+
7
+ default_hash: sha1
8
+ default_format: json
9
+ network_timeout: 20
10
+ network_protocol: http
11
+ network_port: 80
12
+ host: api.allopass.com
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: allorails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Davide Bonapersona
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-08 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Ruby client for the Allopass online payment REST API
15
+ email: davide@feeligo.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files:
19
+ - README.md
20
+ - lib/allorails.rb
21
+ - lib/allorails/api/api.rb
22
+ - lib/allorails/core.rb
23
+ - lib/allorails/errors/errors.rb
24
+ - lib/allorails/rails.rb
25
+ - lib/allorails/request/request.rb
26
+ - lib/allorails/response/model.rb
27
+ - lib/allorails/response/response.rb
28
+ files:
29
+ - README.md
30
+ - Rakefile
31
+ - allorails.gemspec
32
+ - init.rb
33
+ - lib/allorails.rb
34
+ - lib/allorails/api/api.rb
35
+ - lib/allorails/core.rb
36
+ - lib/allorails/errors/errors.rb
37
+ - lib/allorails/rails.rb
38
+ - lib/allorails/request/request.rb
39
+ - lib/allorails/response/model.rb
40
+ - lib/allorails/response/response.rb
41
+ - test/allorails_spec.rb
42
+ - test/test-conf-sample.yml
43
+ - test/test-conf.yml
44
+ - Manifest
45
+ homepage: http://github.com/davb/allorails
46
+ licenses: []
47
+ post_install_message:
48
+ rdoc_options:
49
+ - --line-numbers
50
+ - --inline-source
51
+ - --title
52
+ - Allorails
53
+ - --main
54
+ - README.md
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '1.2'
69
+ requirements: []
70
+ rubyforge_project: allorails
71
+ rubygems_version: 1.8.21
72
+ signing_key:
73
+ specification_version: 3
74
+ summary: Ruby client for the Allopass online payment REST API
75
+ test_files: []