allorails 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest ADDED
@@ -0,0 +1,16 @@
1
+ README.md
2
+ Rakefile
3
+ allorails.gemspec
4
+ init.rb
5
+ lib/allorails.rb
6
+ lib/allorails/api/api.rb
7
+ lib/allorails/core.rb
8
+ lib/allorails/errors/errors.rb
9
+ lib/allorails/rails.rb
10
+ lib/allorails/request/request.rb
11
+ lib/allorails/response/model.rb
12
+ lib/allorails/response/response.rb
13
+ test/allorails_spec.rb
14
+ test/test-conf-sample.yml
15
+ test/test-conf.yml
16
+ Manifest
data/README.md ADDED
@@ -0,0 +1,7 @@
1
+ *IMPORTANT:* Allorails is still being developed and tested. Use at your own risk ;)
2
+
3
+ ## Allorails
4
+
5
+ Allorails is a Ruby gem which allows to interact with Allopass's online payment REST API.
6
+
7
+ It is a Ruby port of the Allopass ApiKit for Python written by Pierre Geoffroy and available [here](http://developer.allopass.com/apidoc/kit/python3.1/index.html).
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('allorails', '0.3.1') do |p|
6
+ p.description = "Ruby client for the Allopass online payment REST API"
7
+ p.url = "http://github.com/davb/allorails"
8
+ p.author = "Davide Bonapersona"
9
+ p.email = "davide@feeligo.com"
10
+ p.ignore_pattern = ["tmp/*", "script/*"]
11
+ p.development_dependencies = []
12
+ end
13
+
14
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
data/allorails.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "allorails"
5
+ s.version = "0.3.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Davide Bonapersona"]
9
+ s.date = "2012-05-08"
10
+ s.description = "Ruby client for the Allopass online payment REST API"
11
+ s.email = "davide@feeligo.com"
12
+ s.extra_rdoc_files = ["README.md", "lib/allorails.rb", "lib/allorails/api/api.rb", "lib/allorails/core.rb", "lib/allorails/errors/errors.rb", "lib/allorails/rails.rb", "lib/allorails/request/request.rb", "lib/allorails/response/model.rb", "lib/allorails/response/response.rb"]
13
+ s.files = ["README.md", "Rakefile", "allorails.gemspec", "init.rb", "lib/allorails.rb", "lib/allorails/api/api.rb", "lib/allorails/core.rb", "lib/allorails/errors/errors.rb", "lib/allorails/rails.rb", "lib/allorails/request/request.rb", "lib/allorails/response/model.rb", "lib/allorails/response/response.rb", "test/allorails_spec.rb", "test/test-conf-sample.yml", "test/test-conf.yml", "Manifest"]
14
+ s.homepage = "http://github.com/davb/allorails"
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Allorails", "--main", "README.md"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = "allorails"
18
+ s.rubygems_version = "1.8.21"
19
+ s.summary = "Ruby client for the Allopass online payment REST API"
20
+
21
+ if s.respond_to? :specification_version then
22
+ s.specification_version = 3
23
+
24
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
25
+ else
26
+ end
27
+ else
28
+ end
29
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'allorails'
@@ -0,0 +1,203 @@
1
+ module Allorails
2
+
3
+ class Api
4
+
5
+ attr_accessor :email
6
+
7
+ ## Constructor
8
+ #
9
+ # @param configuration_email_account (string) Email of the configurated account
10
+ # If email is null, the first account is considered
11
+ def initialize(email = nil)
12
+ self.email = email
13
+ end
14
+
15
+ ## Method performing a onetime pricing request
16
+ #
17
+ # @param parameters (Hash) Query string parameters of the API call
18
+ # @param mapping (boolean) Should the response be an object mapping or a plain response
19
+ #
20
+ # @return (ApiResponse) The API call response
21
+ # Will be a OnetimePricingResponse instance if mapping is true, an ApiResponse if not
22
+ #
23
+ # @code
24
+ # # Make sure the apikit is in your search path
25
+ # import allopass_apikit.api
26
+ # api = allopass_apikit.api.AllopassAPI()
27
+ # response = api.getOnetimePricing({'site_id': 127042, 'country': 'FR'})
28
+ # print("{}\n-----".format(response.getWebsite().getName()))
29
+ # for country in response.getCountries()
30
+ # print("{}\n-----".format(country.getCode()))
31
+ # print("{}\n-----".format(country.getName()))
32
+ # @endcode
33
+ def get_onetime_pricing(parameters, mapping = true)
34
+ Allorails::Request::OnetimePricingRequest.new(parameters, mapping, self.email).call
35
+ end
36
+
37
+ ## Method performing a onetime discrete pricing request
38
+ #
39
+ # @param parameters (array) Query string parameters of the API call
40
+ # @param mapping (boolean) Should the response be an object mapping or a plain response
41
+ #
42
+ # @return (ApiResponse) The API call response
43
+ # Will be a OnetimePricingResponse instance if mapping is true, an ApiResponse if not
44
+ #
45
+ # @code
46
+ # # Make sure the apikit is in your search path
47
+ # import allopass_apikit.api
48
+ # api = allopass_apikit.api.AllopassAPI()
49
+ # response = api.getOnetimeDiscretePricing({'site_id': 127042, 'country': 'FR', 'amount': 12})
50
+ # print("{}\n-----".format(response.getWebsite().getName()))
51
+ # for country in response.getCountries()
52
+ # print("{}\n-----".format(country.getCode()))
53
+ # print("{}\n-----".format(country.getName()))
54
+ # @endcode
55
+ def get_onetime_discrete_pricing(parameters, mapping = true)
56
+ Allorails::Request::OnetimeDiscretePricingRequest.new(parameters, mapping, self.email).call
57
+ end
58
+
59
+ ## Method performing a onetime validate codes request
60
+ #
61
+ # @param parameters (array) Query string parameters of the API call
62
+ # @param mapping (boolean) Should the response be an object mapping or a plain response
63
+ #
64
+ # @return (ApiResponse) The API call response
65
+ # Will be a OnetimeValidateCodesResponse instance if mapping is true, an ApiResponse if not
66
+ #
67
+ # @code
68
+ # # Make sure the apikit is in your search path
69
+ # import allopass_apikit.api
70
+ # api = allopass_apikit.api.AllopassAPI()
71
+ # response = api.validateCodes({'site_id': 127042, 'product_id': 354926, 'code': ('9M7QU457',)})
72
+ # print("{}\n-----".format(response->getStatus()))
73
+ # print("{}\n-----".format(response->getStatusDescription()))
74
+ # @endcode
75
+ def validate_codes(parameters, mapping = true)
76
+ Allorails::Request::OnetimeValidateCodesRequest.new(parameters, mapping, self.email).call
77
+ end
78
+
79
+ ## Method performing a onetime button request
80
+ #
81
+ # @param parameters (array) Query string parameters of the API call
82
+ # @param mapping (boolean) Should the response be an object mapping or a plain response
83
+ #
84
+ # @return (ApiResponse) The API call response
85
+ # Will be a OnetimeButtonResponse instance if mapping is true, an ApiResponse if not
86
+ #
87
+ # @code
88
+ # # Make sure the apikit is in your search path
89
+ # import allopass_apikit.api
90
+ # api = allopass_apikit.api.AllopassAPI()
91
+ # response = api.createButton({'site_id': 127042, 'amount': 12.3, 'reference_currency': 'EUR', 'price_mode': 'price', 'price_policy': 'high-only', 'product_name': 'premium sms access', 'forward_url': 'http://product-page.com'})
92
+ # print("{}\n-----".format(response.getButtonId()))
93
+ # print("{}\n-----".format(response.getBuyUrl()))
94
+ # @endcode
95
+ def create_button(parameters = {}, mapping = true)
96
+ Allorails::Request::OnetimeButtonRequest.new(parameters, mapping, self.email).call
97
+ end
98
+
99
+ ## Method performing a onetime discrete button request
100
+ #
101
+ # @param parameters (array) Query string parameters of the API call
102
+ # @param mapping (boolean) Should the response be an object mapping or a plain response
103
+ #
104
+ # @return (ApiResponse) The API call response
105
+ # Will be a OnetimeButtonResponse instance if mapping is true, an ApiResponse if not
106
+ #
107
+ # @code
108
+ # # Make sure the apikit is in your search path
109
+ # import allopass_apikit.api
110
+ # api = allopass_apikit.api.AllopassAPI()
111
+ # response = api.createDiscreteButton({'site_id': 127042, 'amount': 1.1, 'reference_currency': 'EUR', 'price_mode': 'price', 'price_policy': 'high-only', 'product_name': 'premium sms access', 'forward_url': 'http://product-page.com'})
112
+ # print("{}\n-----".format(response.getButtonId()))
113
+ # print("{}\n-----".format(response.getBuyUrl()))
114
+ # @endcode
115
+ def create_discrete_button(parameters = {}, mapping = true)
116
+ Allorails::Request::OnetimeDiscreteButtonRequest.new(parameters, mapping, self.email).call
117
+ end
118
+
119
+ ## Method performing a product detail request
120
+ #
121
+ # @param id (integer) The product id
122
+ # @param parameters (array) Query string parameters of the API call
123
+ # @param mapping (boolean) Should the response be an object mapping or a plain response
124
+ #
125
+ # @return (ApiResponse) The API call response
126
+ # Will be a ProductDetailResponse instance if mapping is true, an ApiResponse if not
127
+ #
128
+ # @code
129
+ # # Make sure the apikit is in your search path
130
+ # import allopass_apikit.api
131
+ # api = allopass_apikit.api.AllopassAPI()
132
+ # response = api.getProduct(354926)
133
+ # print({}"\n-----".format(response.getName()))
134
+ # @endcode
135
+ def get_product(id, parameters = {}, mapping = true)
136
+ Allorails::Request::ProductDetailRequest.new(parameters.merge({'id'=>id}), mapping, self.email).call
137
+ end
138
+
139
+ ## Method performing a transaction prepare request
140
+ #
141
+ # @param parameters (array) Query string parameters of the API call
142
+ # @param mapping (boolean) Should the response be an object mapping or a plain response
143
+ #
144
+ # @return (ApiResponse) The API call response
145
+ # Will be a TransactionPrepareResponse instance if mapping is true, an ApiResponse if not
146
+ #
147
+ # @code
148
+ # # Make sure the apikit is in your search path
149
+ # import allopass_apikit.api
150
+ # api = allopass_apikit.api.AllopassAPI()
151
+ # response = api.prepareTransaction({'site_id': 127042, 'pricepoint_id': 2, 'product_name': 'premium calling product', 'forward_url': 'http://product-page.com', 'amount': 15})
152
+ # print("{}\n-----".format(response.getBuyUrl()))
153
+ # print("{}\n-----".format(response.getCheckoutButton()))
154
+ # @endcode
155
+ def prepareTransaction(parameters, mapping = true)
156
+ Allorails::Request::TransactionPrepareRequest.new(parameters, mapping, self.email).call
157
+ end
158
+
159
+ ## Method performing a transaction detail request based on the transaction id
160
+ #
161
+ # @param id (string) The transaction id
162
+ # @param parameters (array) Query string parameters of the API call
163
+ # @param mapping (boolean) Should the response be an object mapping or a plain response
164
+ #
165
+ # @return (ApiResponse) The API call response
166
+ # Will be a TransactionDetailResponse instance if mapping is true, an ApiResponse if not
167
+ #
168
+ # @code
169
+ # # Make sure the apikit is in your search path
170
+ # import allopass_apikit.api
171
+ # api = allopass_apikit.api.AllopassAPI()
172
+ # response = api.getTransaction('3f5506ac-5345-45e4-babb-96570aafdf6a');
173
+ # print("{}\n-----".format(response.getPaid().getCurrency()))
174
+ # print("{}\n-----".format(response.getPaid().getAmount()))
175
+ # @endcode
176
+ def getTransaction(id, parameters = {}, mapping = true)
177
+ Allorails::Request::TransactionDetailRequest.new(parameters.merge({'id'=>id}), mapping, self.email).call
178
+ end
179
+
180
+ ## Method performing a transaction detail request based on the merchant transaction id
181
+ #
182
+ # @param id (string) The merchant transaction id
183
+ # @param parameters (array) Query string parameters of the API call
184
+ # @param mapping (boolean) Should the response be an object mapping or a plain response
185
+ #
186
+ # @return (ApiResponse) The API call response
187
+ # Will be a TransactionDetailResponse instance if mapping is true, an ApiResponse if not
188
+ #
189
+ # @code
190
+ # # Make sure the apikit is in your search path
191
+ # import allopass_apikit.api
192
+ # api = allopass_apikit.api.AllopassAPI()
193
+ # response = api.getTransactionMerchant('TRX20091112134569B8');
194
+ # print("{}\n-----".format(response.getPaid().getCurrency()))
195
+ # print("{}\n-----".format(response.getPaid().getAmount()))
196
+ # @endcode
197
+ def getTransactionMerchant(id, parameters = {}, mapping = true)
198
+ Allorails::Request::TransactionMerchantRequest.new(parameters.merge({'id'=>id}), mapping, self.email).call
199
+ end
200
+
201
+ end
202
+
203
+ end
@@ -0,0 +1,147 @@
1
+ require 'set'
2
+
3
+ module Allorails
4
+
5
+ module Core
6
+
7
+ # Holds the configuration options for Allorails
8
+ #
9
+ class Configuration
10
+
11
+ # creates a new Configuration object
12
+ # @param options
13
+ # @option options
14
+ def initialize options = {}
15
+ options.each_pair do |opt_name, value|
16
+ opt_name = opt_name.to_sym
17
+ if self.class.accepted_options.include?(opt_name)
18
+ supplied[opt_name] = value
19
+ end
20
+ end
21
+ end
22
+
23
+ # creates a new Configuration object with the given modifications
24
+ # does not modify the current object
25
+ def with options = {}
26
+ # symbolize option keys
27
+ options = symbolize_keys options
28
+ values = supplied.merge(options)
29
+
30
+ if supplied == values
31
+ self # no changes
32
+ else
33
+ self.class.new(values)
34
+ end
35
+ end
36
+
37
+ # API key and secret key depend on the account
38
+ def api_key email = nil
39
+ account(email)[:api_key]
40
+ end
41
+
42
+ def private_key email = nil
43
+ account(email)[:private_key]
44
+ end
45
+
46
+
47
+ protected
48
+
49
+ # symbolize Hash keys
50
+ def symbolize_keys hash
51
+ hash.inject({}) {|h, (k,v)| h[k.to_sym] = v.is_a?(Hash) ? symbolize_keys(v) : v; h }
52
+ end
53
+
54
+
55
+ # Returns the account matching a given email
56
+ #
57
+ # @param email (string) The email identifying the account
58
+ # If email is null, the first account is considered
59
+ #
60
+ # @return (xml.etree.ElementTree.ElementTree) Object representation of the account
61
+ #
62
+ # @throws ApiConfAccountNotFoundError If an email is provided but can't be found
63
+ #
64
+ def account(email = nil)
65
+ if accounts.length == 0
66
+ raise Allorails::ApiConfAccountNotFoundError, "No account found in config. You must configure at least one account."
67
+ else
68
+ # if email is null, the first account is considered
69
+ return accounts[accounts.keys.first] if email.nil?
70
+ # find the account corresponding to the email
71
+ return accounts[email] if accounts.has_key?(email)
72
+ end
73
+ # raise ApiConfAccountNotFoundError if email is provided but can't be found
74
+ raise Allorails::ApiConfAccountNotFoundError, "Missing configuration for account `#{email}`"
75
+ end
76
+
77
+ # supplied options
78
+ def supplied
79
+ @supplied ||= {}
80
+ end
81
+
82
+ # class methods
83
+ class << self
84
+
85
+ # accepted options
86
+ def accepted_options
87
+ @options ||= Set.new
88
+ end
89
+
90
+ # used internally to register a configuration option
91
+ def add_option name, default_value = nil
92
+ # marks the option as accepted
93
+ accepted_options << name
94
+ # defines an accessor method for the option
95
+ define_method(name) do
96
+ if supplied.has_key?(name)
97
+ supplied[name]
98
+ else
99
+ default_value
100
+ end
101
+ end
102
+ end
103
+
104
+
105
+
106
+ end #-- end class << self
107
+
108
+ # registers configuration options
109
+ add_option :accounts, {}
110
+ add_option :default_hash, 'sha1'
111
+ add_option :default_format, 'json'
112
+ add_option :network_timeout, 20
113
+ add_option :network_protocol, 'http'
114
+ add_option :network_port, 80
115
+ add_option :host, 'api.allopass.com'
116
+
117
+ end #-- end class Configuration
118
+
119
+ end #-- end module Core
120
+
121
+ class << self
122
+
123
+ @@config = nil
124
+
125
+ # The global configuration for Allorails
126
+ # generally you would set your configuration options once, after
127
+ # loading the allorails gem.
128
+ #
129
+ # Allorails.config({
130
+ # :accounts => {
131
+ # :your@email.com => {
132
+ # :api_key => 'API_KEY',
133
+ # :private_key => 'PRIVATE_KEY'
134
+ # }
135
+ # },
136
+ # :network_port => PORT
137
+ # })
138
+ #
139
+ def config options = {}
140
+ @@config ||= Core::Configuration.new
141
+ @@config = @@config.with(options) unless options.empty?
142
+ @@config
143
+ end
144
+
145
+ end
146
+
147
+ end
@@ -0,0 +1,28 @@
1
+ module Allorails
2
+
3
+
4
+ class AllopassApikitError < StandardError
5
+ end
6
+
7
+ class ApiConfAccountNotFoundError < StandardError
8
+ end
9
+ class ApiConfFileCorruptedError < StandardError
10
+ end
11
+ class ApiConfFileMissingError < StandardError
12
+ end
13
+ class ApiConfFileMissingSectionError < StandardError
14
+ end
15
+ class ApiFalseResponseSignatureError < StandardError
16
+ end
17
+
18
+ class ApiMissingHashFeatureError < StandardError
19
+ end
20
+ class ApiRemoteErrorError < StandardError
21
+ end
22
+
23
+ class ApiUnavailableResourceError < StandardError
24
+ end
25
+ class ApiWrongFormatResponseError < StandardError
26
+ end
27
+
28
+ end
@@ -0,0 +1,75 @@
1
+ require 'yaml'
2
+
3
+ module Allorails
4
+
5
+ if Object.const_defined?(:Rails) and Rails.const_defined?(:Railtie)
6
+
7
+ class Railtie < Rails::Railtie
8
+
9
+ initializer "allorails.initialize" do |app|
10
+ Allorails::Rails.setup
11
+ end
12
+
13
+ end
14
+
15
+ end
16
+
17
+
18
+ module Rails
19
+
20
+ def self.setup
21
+ load_yaml_config
22
+ #log_to_rails_logger
23
+ nil
24
+ end
25
+
26
+ # Loads Allorails configuration from +RAILS_ROOT/config/allorails.yml+
27
+ #
28
+ # TODO: this configuration file is optional, you can instead use Ruby
29
+ # to configure Allorails inside an initializer
30
+ # (e.g. +RAILS_ROOT/config/initializers/allorails.rb)
31
+ #
32
+ # If you use the yaml configuration file, it should include one section for
33
+ # each Rails environment:
34
+ #
35
+ # development:
36
+ # api_key: YOUR_API_KEY
37
+ # secret_key: YOUR_SECRET_KEY
38
+ #
39
+ # production:
40
+ # api_key: YOUR_API_KEY
41
+ # secret_key: YOUR_SECRET_KEY
42
+ #
43
+ # ERB tags are allowed inside the yaml file: you can do things like
44
+ # api_key: <%= read_from_somewhere_else %>
45
+ #
46
+ def self.load_yaml_config
47
+ path = Pathname.new("#{rails_root}/config/allorails.yml")
48
+ if File.exists?(path)
49
+ cfg = YAML::load(ERB.new(File.read(path)).result)
50
+ unless cfg[rails_env]
51
+ raise "config/allorails.yml is missing a section for `#{rails_env}`"
52
+ end
53
+ Allorails.config(cfg[rails_env])
54
+ end
55
+ end
56
+
57
+ protected
58
+
59
+ def self.rails_env
60
+ ::Rails.respond_to?(:env) ? ::Rails.env : RAILS_ENV
61
+ end
62
+
63
+ # @private
64
+ def self.rails_root
65
+ ::Rails.respond_to?(:root) ? ::Rails.root.to_s : RAILS_ROOT
66
+ end
67
+
68
+ # @private
69
+ def self.rails_logger
70
+ ::Rails.respond_to?(:logger) ? ::Rails.logger : ::RAILS_DEFAULT_LOGGER
71
+ end
72
+
73
+ end
74
+
75
+ end