centralpos 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6c60cb95f39f536fab9531ac30baa89c5e850f2c
4
+ data.tar.gz: 9125a2ce057a13871f8813747f746c8e3122c6ae
5
+ SHA512:
6
+ metadata.gz: 8c13caae5acf29b9eb4de665aed041ff7dfe68370de3c2b11e4d5b536f29b691259931a4e759280008c8c850c3b848dc561adc1287c6093ecbaf3f9856ba3283
7
+ data.tar.gz: 4cde3a0137c90fd78275d330aeb92ada5060b05f92b5490bc7d1f171a1f055e80a20840c5840c5e6d5a1602f667c5960fca077b127f2e54b9563d72d22bed841
data/.gitignore ADDED
@@ -0,0 +1,23 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+
11
+ # OS generated files #
12
+ ######################
13
+ .DS_Store
14
+ .DS_Store?
15
+ ._*
16
+ .Spotlight-V100
17
+ .Trashes
18
+ ehthumbs.db
19
+ Thumbs.db
20
+ dump.rdb
21
+
22
+ # GS folder for managing the Gemset
23
+ .gs/
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.3
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.1.6
5
+ - 2.2.5
6
+ - 2.3.1
7
+ before_install: gem install bundler -v 1.12.5
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at cavi21@gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in centralpos.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Agustin Cavilliotti
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,147 @@
1
+ # Centralpos
2
+
3
+ ## Installation
4
+
5
+ Add this line to your application's Gemfile:
6
+
7
+ ```ruby
8
+ gem 'centralpos'
9
+ ```
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install centralpos
18
+
19
+ ## Setup
20
+
21
+ You should first configure the WSDL endpoints (Sandbox & Production), by doing:
22
+
23
+ ```ruby
24
+ Centralpos.setup do |config|
25
+ config.sandbox_wsdl_endpoint = 'https://sandbox.example.com?wsdl'
26
+ config.production_wsdl_endpoint = 'https://production.example.com?wsdl'
27
+ end
28
+ ```
29
+
30
+ In a Rails environment make sense to place this in an initializer.
31
+
32
+ ## Usage
33
+
34
+ In order to use this gem you must already have an account in [Centralpos](http://centralpos.com). Once you have it you can do the following:
35
+
36
+ - [Initialize and Account](#initialize-and-account)
37
+ - [Ask about Batches](#ask-about-batches)
38
+ - [Do stuff with an open Batch - Transactions](#do-stuff-with-an-open-batch---transactions)
39
+
40
+ ### Initialize an Account
41
+
42
+ Load the **Account** with the `"username"` and `"password"`, in order to ask for the batches and everything:
43
+
44
+ ```ruby
45
+ account = Centralpos::Account.new("username", "password")
46
+ ```
47
+
48
+ now that you have the `account` you can ensure that the credentials are valid calling,
49
+
50
+ ```ruby
51
+ account.valid?
52
+ ```
53
+
54
+ or ask for the cards that you are able to process with Centralpos,
55
+
56
+ ```ruby
57
+ account.enabled_cards
58
+ ```
59
+
60
+ ### Ask about Batches
61
+
62
+ With an `account` loaded and `valid?` you can now ask about the open batches that this account has at the moment. Remember that this batches are the only one that accept new transactions to be process later on,
63
+
64
+ ```ruby
65
+ open_batches = account.open_batches # returns an Array of Centralpos::Batch instances
66
+ ```
67
+
68
+ Or if you already have the batch **ID** you can ask directly about it,
69
+
70
+ ```ruby
71
+ batch = account.batch(id) # returns a Centralpos::Batch instance
72
+ ```
73
+
74
+ If you want to know all the past batches, that are not open, you can ask them by,
75
+
76
+ ```ruby
77
+ past_batches = account.past_batches # returns an Array of Centralpos::Batch instances
78
+ ```
79
+
80
+
81
+ ### Do stuff with an open Batch - Transactions
82
+
83
+ With an `open_batch` loaded we can start adding, removing or updating transactions to it, in order to process them afterwards. And also check the transactions that are already present in it
84
+
85
+ Let's create a transaction first, for this we have to pass the parameters as arguments to initialize it:
86
+
87
+ ```ruby
88
+ transaction_params = {
89
+ owner_id: "owner_id1",
90
+ cc_number: "4111111111111111",
91
+ amount: 100.0,
92
+ }
93
+ transaction = Centralpos::Transaction.new(transaction_params)
94
+ ```
95
+
96
+ > IMPORTANT: The value of **:owner_id** can only appear once in a **batch** and this value it is the one that is being use to remove a **transaction** from an open **batch**.
97
+
98
+ There are also to optional values that you can pass to the transaction, this are:
99
+
100
+ ```ruby
101
+ transaction_params = transaction_params.merge({
102
+ optional_data_1: "",
103
+ optional_data_2: ""
104
+ })
105
+ ```
106
+
107
+ So now with a `valid` transaction (yes you can call to `transaction.valid?` or `transaction.invalid?`) you can add it to the open batch,
108
+
109
+ ```ruby
110
+ open_batch.add_transaction(transaction)
111
+ ```
112
+
113
+ and maybe because you make a mistake you want to remove a transaction of a open batch, to do it you have to remember that the value that it's used to match the transaction that you want to remove is the **owner_id** in the **transaction** instance, so
114
+
115
+ ```ruby
116
+ open_batch.remove_transaction(transaction)
117
+ ```
118
+
119
+ You can also be able to update a transaction that it's already in the open batch, and as you can imagine you only can update the **cc_number**, **amount**, **optional_data_1** and **optional_data_2** values of the transaction, so
120
+
121
+ ```ruby
122
+ transaction.amount = 250.0
123
+ open_batch.update_transaction(transaction)
124
+ ```
125
+
126
+ on the back what this is doing is removing the transaction from the open batch and adding it again with the new values, that's why you can't change the **owner_id** value of it.
127
+
128
+ ## TO-DOs:
129
+
130
+ - Add tests
131
+ - Add missing methods
132
+
133
+ ## Development
134
+
135
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
136
+
137
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
138
+
139
+ ## Contributing
140
+
141
+ Bug reports and pull requests are welcome on GitHub at https://github.com/donaronline/centralpos. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
142
+
143
+
144
+ ## License
145
+
146
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
147
+
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task default: [:test]
11
+
12
+ task :console do
13
+ require "pry"
14
+ require "./lib/centralpos"
15
+ require "httplog"
16
+
17
+ def reload!
18
+ files = $LOADED_FEATURES.select { |feat| feat =~ %r{lib/centralpos} }
19
+ # Deactivate warning messages.
20
+ original_verbose, $VERBOSE = $VERBOSE, nil
21
+ files.each { |file| load file }
22
+ # Activate warning messages again.
23
+ $VERBOSE = original_verbose
24
+ "Console reloaded!"
25
+ end
26
+
27
+ ARGV.clear
28
+ Pry.start
29
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "centralpos"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'centralpos/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "centralpos"
8
+ spec.version = Centralpos::VERSION
9
+ spec.authors = ["Agustin Cavilliotti"]
10
+ spec.email = ["cavi21@gmail.com"]
11
+
12
+ spec.summary = "Ruby wrapper for the CentralPos WebService"
13
+ spec.description = "Ruby wrapper for the CentralPos WebService"
14
+ spec.homepage = "https://github.com/cavi21/centralpos"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "savon", "~> 2.11"
23
+
24
+ spec.add_development_dependency "pry"
25
+ spec.add_development_dependency "httplog"
26
+ spec.add_development_dependency "bundler", "~> 1.12"
27
+ spec.add_development_dependency "minitest", "~> 5.0"
28
+ spec.add_development_dependency "pry-byebug", "~> 3.2"
29
+ spec.add_development_dependency "rake", "~> 10.4"
30
+ spec.add_development_dependency "vcr", "~> 2.9"
31
+ spec.add_development_dependency "webmock", "~> 1.21"
32
+ end
@@ -0,0 +1,97 @@
1
+ # Allowed Operations:
2
+ # [
3
+ # :add_registro,
4
+ # :del_registro,
5
+ # :get_estado_presentaciones,
6
+ # :get_presentaciones_abiertas,
7
+ # :list_registros,
8
+ # :list_tarjetas_habilitadas,
9
+ # :put_procesa_presentacion
10
+ # ]
11
+ #
12
+ # Deprecated Operations:
13
+ # [
14
+ # :get_respuesta_presentacion,
15
+ # :get_detalles_presentacion_respondida,
16
+ # :put_datos_presentacion_abierta,
17
+ # :get_presentaciones_futuras,
18
+ # :get_presentaciones_respondidas
19
+ # ]
20
+ module Centralpos
21
+ class Account
22
+ include Utils
23
+ attr_reader :username, :error, :gateway
24
+
25
+ def initialize(username, password, mode = :sandbox)
26
+ @username = username
27
+ @gateway = Centralpos::Core::Gateway.new(username, password, mode)
28
+ self
29
+ end
30
+
31
+ def sandbox
32
+ @enabled_cards = nil
33
+ @gateway.sandbox
34
+ end
35
+
36
+ def sandbox?
37
+ @gateway.mode == :sandbox
38
+ end
39
+
40
+ def live
41
+ @enabled_cards = nil
42
+ @gateway.live
43
+ end
44
+
45
+ def live?
46
+ !sandbox?
47
+ end
48
+
49
+ def valid?
50
+ response = enabled_cards
51
+ @error = response[:error]
52
+ @error.nil?
53
+ end
54
+
55
+ def enabled_cards
56
+ @enabled_cards ||= @gateway.call(:list_tarjetas_habilitadas)
57
+ end
58
+
59
+ def open_batches
60
+ response = @gateway.call(:get_presentaciones_abiertas)
61
+ if response[:success] && response[:error].nil?
62
+ return [] unless response[:result][:lista_presentaciones]
63
+
64
+ batches = ensure_array(response[:result][:lista_presentaciones][:presentacion])
65
+ batches.map do |batch_data|
66
+ Centralpos::Batch.new(batch_data.merge(account: self))
67
+ end
68
+ else
69
+ response
70
+ end
71
+ end
72
+
73
+ def batch(id)
74
+ Centralpos::Batch.new({id: id}.merge(account: self))
75
+ end
76
+
77
+ def past_batches
78
+ response = @gateway.call(:get_estado_presentaciones)
79
+ if response[:success] && response[:error].nil?
80
+ return [] unless response[:result][:lista_presentaciones]
81
+
82
+ batches = ensure_array(response[:result][:lista_presentaciones][:presentacion_procesada])
83
+ batches.map do |batch_data|
84
+ Centralpos::Batch.new(batch_data.merge(account: self))
85
+ end
86
+ else
87
+ response
88
+ end
89
+ end
90
+
91
+ private
92
+
93
+ def attr_inspect
94
+ [ :username ]
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,130 @@
1
+ module Centralpos
2
+ class Batch
3
+ include Utils
4
+ attr_reader :id, :card_id, :card, :status_id, :status, :period, :date_since, :date_until, :processed_date, :commerce_number
5
+
6
+ def initialize(account: nil, **params)
7
+ @account = account if account && account.is_a?(Centralpos::Account)
8
+ @id = params.delete(:id) || params.delete(:id_presentacion)
9
+ process_data(params)
10
+ end
11
+
12
+ def transactions
13
+ ensure_account_valid!
14
+
15
+ response = @account.gateway.call(:list_registros, batch_params)
16
+
17
+ if response[:success] && response[:error].nil?
18
+ return [] if response[:result][:lista_registros].nil?
19
+
20
+ entries = ensure_array(response[:result][:lista_registros][:registro])
21
+ entries.map do |entries_data|
22
+ Centralpos::Transaction.load_it(entries_data.merge(batch: self))
23
+ end
24
+ else
25
+ response
26
+ end
27
+ end
28
+
29
+ def add_transaction(transaction)
30
+ ensure_account_valid! && ensure_transaction_valid!(transaction)
31
+
32
+ response = @account.gateway.call(:add_registro, batch_params.merge(transaction.to_add_params))
33
+
34
+ if response[:success] && response[:error].nil?
35
+ { transaction: transaction.to_hash }
36
+ else
37
+ response
38
+ end
39
+ end
40
+
41
+ def remove_transaction(transaction)
42
+ ensure_account_valid! && ensure_transaction_valid!(transaction)
43
+
44
+ response = @account.gateway.call(:del_registro, batch_params.merge(transaction.to_remove_params))
45
+
46
+ if response[:success] && response[:error].nil?
47
+ { transaction: transaction.to_hash }
48
+ else
49
+ response
50
+ end
51
+ end
52
+
53
+ def update_transaction(transaction)
54
+ ensure_account_valid! && ensure_transaction_valid!(transaction)
55
+ remove_transaction(transaction)
56
+ add_transaction(transaction)
57
+ end
58
+
59
+ def has_transaction?(transaction)
60
+ transactions_by_id.key?(transaction.owner_id)
61
+ end
62
+
63
+ def get_transaction(transaction)
64
+ return unless has_transaction?(transaction)
65
+
66
+ { transaction: transactions_by_id.fetch(transaction.owner_id) }
67
+ end
68
+
69
+ def can_process?(date_when = nil)
70
+ date_when = Time.now if date_when.nil? || !date_when.is_a?(DateTime)
71
+ date_when_utc = date_when.utc
72
+
73
+ (@date_since.utc <= date_when_utc) && (date_when_utc <= @date_until.utc)
74
+ end
75
+
76
+ def process
77
+ ensure_account_valid!
78
+
79
+ @account.gateway.call(:put_procesa_presentacion, batch_params)
80
+ end
81
+
82
+ private
83
+
84
+ def batch_params
85
+ {
86
+ "IdPresentacion" => @id
87
+ }
88
+ end
89
+
90
+ def attr_inspect
91
+ [ :id, :card, :period, :date_until ]
92
+ end
93
+
94
+ def process_data(data)
95
+ return if data.nil? || data.blank?
96
+
97
+ @card = data[:tarjeta]
98
+ @card_id = data[:id_tarjeta]
99
+ @period = data[:periodo]
100
+ @date_since = Centralpos::Utils.in_time_zone(data[:fecha_presentacion_desde])
101
+ @date_until = Centralpos::Utils.in_time_zone(data[:fecha_presentacion_hasta])
102
+ @processed_date = Centralpos::Utils.in_time_zone(data[:fecha_de_procesamiento])
103
+ @commerce_number = data[:numero_de_comercio]
104
+ @repetition_number = data[:numero_repeticion]
105
+ @status_id = data[:id_estado]
106
+ @status = data[:estado]
107
+ end
108
+
109
+ def transactions_by_id
110
+ return @transactions_by_id unless @transactions_by_id.nil?
111
+
112
+ @transactions_by_id = transactions.each_with_object({}) do |transaction, _hash|
113
+ _hash[transaction.owner_id] = transaction
114
+ end
115
+ end
116
+
117
+ def ensure_transaction_valid!(transaction)
118
+ unless transaction.is_a?(Centralpos::Transaction) && transaction.valid?
119
+ raise AccountError.new("You should provide a transaction to be added to the batch, and it should be a Centralpos::Transaction instance")
120
+ end
121
+ end
122
+
123
+ def ensure_account_valid!
124
+ unless @account && @account.is_a?(Centralpos::Account)
125
+ raise AccountError.new("You should provide an account for the batch, and it should be a Centralpos::Account instance")
126
+ end
127
+ end
128
+
129
+ end
130
+ end
@@ -0,0 +1,5 @@
1
+ module Centralpos
2
+ module Core
3
+ class ClientError < Centralpos::Error; end
4
+ end
5
+ end
@@ -0,0 +1,111 @@
1
+ module Centralpos
2
+ module Core
3
+ class Gateway
4
+ attr_reader :mode
5
+
6
+ def initialize(username, password, mode = :sandbox)
7
+ @username = username
8
+ @password = password
9
+ @mode = mode
10
+ end
11
+
12
+ def call(method, extra_data = {})
13
+ message = authentication_params.merge(extra_data)
14
+
15
+ response = client.call(method, message: message)
16
+
17
+ parse_result(response, method)
18
+ rescue Savon::Error, Errno::ENETUNREACH => error
19
+ handle_exception(error)
20
+ end
21
+
22
+ def sandbox
23
+ @client = nil
24
+ @mode = :sandbox
25
+ end
26
+
27
+ def live
28
+ @client = nil
29
+ @mode = :live
30
+ end
31
+
32
+ private
33
+
34
+ def client
35
+ @client ||= Savon.client(opts)
36
+ end
37
+
38
+ def opts
39
+ { wsdl: wsdl_endpoint }.merge(Centralpos::Core::Logger.options)
40
+ end
41
+
42
+ def wsdl_endpoint
43
+ case @mode
44
+ when :live then Centralpos.production_wsdl_endpoint
45
+ when :sandbox then Centralpos.sandbox_wsdl_endpoint
46
+ else
47
+ Centralpos.sandbox_wsdl_endpoint
48
+ end
49
+ end
50
+
51
+ def authentication_params
52
+ {
53
+ "Autenticacion" => {
54
+ "Usuario" => @username,
55
+ "Clave" => @password
56
+ }
57
+ }
58
+ end
59
+
60
+ def parse_result(response, method)
61
+ body = parse_body(response, method)
62
+
63
+ successful_response(response).merge(result: body)
64
+ end
65
+
66
+ def parse_body(response, method)
67
+ method_response = "#{method}_response".to_sym
68
+ method_result = "#{method}_result".to_sym
69
+
70
+ response.body[method_response][method_result]
71
+ end
72
+
73
+ def handle_exception(error)
74
+ case error
75
+ when Savon::SOAPFault
76
+ failed_response(error).merge(error: error.to_hash[:fault])
77
+ when Savon::HTTPError
78
+ failed_response(error).merge(error: error.to_hash)
79
+ when Errno::ENETUNREACH
80
+ unable_to_connect(error).merge(error: error.message)
81
+ else
82
+ raise error
83
+ end
84
+ end
85
+
86
+ def successful_response(response)
87
+ {
88
+ response_code: response.http.code,
89
+ success: true,
90
+ error: nil
91
+ }
92
+ end
93
+
94
+ def failed_response(error)
95
+ {
96
+ response_code: error.http.code,
97
+ success: false,
98
+ result: nil
99
+ }
100
+ end
101
+
102
+ def unable_to_connect(error)
103
+ {
104
+ response_code: nil,
105
+ success: false,
106
+ result: nil
107
+ }
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,36 @@
1
+ module Centralpos
2
+ module Core
3
+ class Logger
4
+ attr_accessor :log, :pretty_print_xml, :log_level
5
+
6
+ # Receives a hash with keys `log`, `pretty_print_xml` and `log_level`.
7
+ # `log_level` can be :info, :debug, :warn, :error or :fatal
8
+ #
9
+ # @param opts [Hash]
10
+ # @option opts [Boolean] :log
11
+ # @option opts [Boolean] :pretty_print_xml
12
+ # @option opts [Symbol] :log_level
13
+ def initialize(opts = {})
14
+ @log = opts[:log] || false
15
+ @pretty_print_xml = opts[:pretty_print_xml] || false
16
+ @log_level = opts[:log_level] || :info
17
+ end
18
+
19
+ # Returns a hash with the logging options for Savon.
20
+ #
21
+ # @return [Hash]
22
+ def logger_options
23
+ { log: log, pretty_print_xml: pretty_print_xml, log_level: log_level }
24
+ end
25
+
26
+ def self.options=(opts = {})
27
+ @logger = Centralpos::Core::Logger.new(opts)
28
+ end
29
+
30
+ def self.options
31
+ @logger ||= Centralpos::Core::Logger.new
32
+ @logger.logger_options
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,4 @@
1
+ module Centralpos
2
+ class Error < StandardError; end
3
+ class AccountError < Error; end
4
+ end
@@ -0,0 +1,85 @@
1
+ module Centralpos
2
+ class Transaction
3
+ include Utils
4
+ MD5_DIGEST = OpenSSL::Digest.new("md5").freeze
5
+ UPDATABLE_VALUES = [ :cc_number, :amount, :optional_data_1, :optional_data_2 ].freeze
6
+ attr_reader :id, :owner_id, :amount, :optional_data_1, :optional_data_2, :applied, :message, :card_error_code
7
+
8
+ def self.load_it(data)
9
+ data.merge!({
10
+ owner_id:data[:id_user],
11
+ cc_number:data[:nro_tarjeta],
12
+ amount: data[:importe],
13
+ optional_data_1: data[:dato_opcional],
14
+ optional_data_2: data[:dato_opcional_2],
15
+ applied: data[:aplicado],
16
+ message: data[:observaciones],
17
+ card_error_code: data[:cod_error_tarjeta]
18
+ })
19
+ new(data)
20
+ end
21
+
22
+ def initialize(owner_id:, cc_number:, amount:, optional_data_1: "", optional_data_2: "", applied:, message:, card_error_code:, **extras)
23
+ @id = md5("#{owner_id}-#{cc_number}")
24
+ @owner_id = owner_id.to_i
25
+ @cc_number = cc_number
26
+ @amount = amount.to_s
27
+ @optional_data_1 = optional_data_1
28
+ @optional_data_2 = optional_data_2
29
+ @applied = applied
30
+ @message = message
31
+ @card_error_code = card_error_code
32
+ @extras = extras
33
+ end
34
+ UPDATABLE_VALUES.each do |key|
35
+ define_method("#{key}=") do |value|
36
+ instance_variable_set("@#{key}", value)
37
+ end
38
+ end
39
+
40
+ def valid?
41
+ !invalid?
42
+ end
43
+
44
+ def invalid?
45
+ @owner_id.empty? || @cc_number.empty? || !@amount || @amount <= 0.0
46
+ end
47
+
48
+ def to_hash
49
+ {
50
+ id: id,
51
+ owner_id: owner_id,
52
+ amount: @amount,
53
+ optional_data_1: @optional_data_1,
54
+ optional_data_2: @optional_data_2,
55
+ applied: @applied
56
+ }
57
+ end
58
+
59
+ def to_add_params
60
+ {
61
+ "DatoOpcional1" => @optional_data_1,
62
+ "DatoOpcional2" => @optional_data_2,
63
+ "IdUser" => @owner_id,
64
+ "NroTarjeta" => @cc_number,
65
+ "Importe" => @amount
66
+ }
67
+ end
68
+
69
+ def to_remove_params
70
+ {
71
+ "IdUser" => owner_id
72
+ }
73
+ end
74
+
75
+ private
76
+
77
+ def attr_inspect
78
+ [ :id ]
79
+ end
80
+
81
+ def md5(string)
82
+ MD5_DIGEST.hexdigest(string)
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,28 @@
1
+ module Centralpos
2
+ module Utils
3
+ extend self
4
+
5
+ def inspect
6
+ formatted_attrs = attr_inspect.map do |attr|
7
+ "#{attr}: #{send(attr).inspect}"
8
+ end
9
+ "#<#{self.class.name} #{formatted_attrs.join(", ")}>"
10
+ end
11
+
12
+ def ensure_array(stuff)
13
+ [stuff].flatten(1)
14
+ end
15
+
16
+ def in_time_zone(datetime)
17
+ return datetime unless datetime && Centralpos.override_timezone
18
+
19
+ datetime.change(offset: Centralpos.default_timezone)
20
+ end
21
+
22
+ private
23
+
24
+ def attr_inspect
25
+ []
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,3 @@
1
+ module Centralpos
2
+ VERSION = "0.2.0"
3
+ end
data/lib/centralpos.rb ADDED
@@ -0,0 +1,61 @@
1
+ # SUPPORT LIBS
2
+ require "savon"
3
+ require "erb"
4
+ require "ostruct"
5
+
6
+ require "centralpos/version"
7
+ require "centralpos/errors"
8
+ require "centralpos/utils"
9
+ # CORE
10
+ require "centralpos/core/errors"
11
+ require "centralpos/core/logger"
12
+ require "centralpos/core/gateway"
13
+ # RESOURCES
14
+ require "centralpos/account"
15
+ require "centralpos/batch"
16
+ require "centralpos/transaction"
17
+
18
+ module Centralpos
19
+ @@sandbox_wsdl_endpoint = ''
20
+ @@production_wsdl_endpoint = ''
21
+ @@override_timezone = true
22
+ @@default_timezone = '-0300'
23
+
24
+ class << self
25
+ def sandbox_wsdl_endpoint
26
+ @@sandbox_wsdl_endpoint
27
+ end
28
+
29
+ def production_wsdl_endpoint
30
+ @@production_wsdl_endpoint
31
+ end
32
+
33
+ def override_timezone
34
+ @@override_timezone
35
+ end
36
+
37
+ def default_timezone
38
+ @@default_timezone
39
+ end
40
+
41
+ def setup
42
+ yield self
43
+ end
44
+
45
+ def sandbox_wsdl_endpoint=(url_string)
46
+ @@sandbox_wsdl_endpoint = url_string
47
+ end
48
+
49
+ def production_wsdl_endpoint=(url_string)
50
+ @@production_wsdl_endpoint = url_string
51
+ end
52
+
53
+ def override_timezone=(value)
54
+ @@override_timezone = value.is_a?(Boolean) ? value : true
55
+ end
56
+
57
+ def default_timezone=(value)
58
+ @@default_timezone = value
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,30 @@
1
+ Centralpos.setup do |config|
2
+ config.sandbox_wsdl_endpoint = ''
3
+ config.production_wsdl_endpoint = 'http://acceso.centralpos.com:8096/CentralPosDebAutWS.asmx?wsdl'
4
+ end
5
+
6
+ account = Centralpos::Account.new("maria@reynoldspropiedades.com", "Lichi", :live)
7
+ batch = account.batch('84577')
8
+
9
+ transaction_params = {
10
+ optional_data_1: "41u6vtaxwdy",
11
+ owner_id: "",
12
+ cc_number: "",
13
+ amount: 6000.0,
14
+ }
15
+ transaction = Centralpos::Transaction.new(transaction_params)
16
+ batch.add_transaction(transaction)
17
+ batch.update_transaction(transaction)
18
+
19
+
20
+ transaction_params = {
21
+ owner_id: "79643",
22
+ cc_number: "",
23
+ amount: 1.0
24
+ }
25
+ transaction = Centralpos::Transaction.new(transaction_params)
26
+ batch.remove_transaction(transaction)
27
+
28
+
29
+
30
+ { "KeyDO" => '1e4404983fd3236da010c394e37559a7', "KeyCliente" => '30714740276' }
metadata ADDED
@@ -0,0 +1,192 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: centralpos
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Agustin Cavilliotti
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-10-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: savon
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.11'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: httplog
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.12'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.12'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.2'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.2'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '10.4'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '10.4'
111
+ - !ruby/object:Gem::Dependency
112
+ name: vcr
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '2.9'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '2.9'
125
+ - !ruby/object:Gem::Dependency
126
+ name: webmock
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.21'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.21'
139
+ description: Ruby wrapper for the CentralPos WebService
140
+ email:
141
+ - cavi21@gmail.com
142
+ executables: []
143
+ extensions: []
144
+ extra_rdoc_files: []
145
+ files:
146
+ - ".gitignore"
147
+ - ".ruby-version"
148
+ - ".travis.yml"
149
+ - CODE_OF_CONDUCT.md
150
+ - Gemfile
151
+ - LICENSE.txt
152
+ - README.md
153
+ - Rakefile
154
+ - bin/console
155
+ - bin/setup
156
+ - centralpos.gemspec
157
+ - lib/centralpos.rb
158
+ - lib/centralpos/account.rb
159
+ - lib/centralpos/batch.rb
160
+ - lib/centralpos/core/errors.rb
161
+ - lib/centralpos/core/gateway.rb
162
+ - lib/centralpos/core/logger.rb
163
+ - lib/centralpos/errors.rb
164
+ - lib/centralpos/transaction.rb
165
+ - lib/centralpos/utils.rb
166
+ - lib/centralpos/version.rb
167
+ - update_transaction.rb
168
+ homepage: https://github.com/cavi21/centralpos
169
+ licenses:
170
+ - MIT
171
+ metadata: {}
172
+ post_install_message:
173
+ rdoc_options: []
174
+ require_paths:
175
+ - lib
176
+ required_ruby_version: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
181
+ required_rubygems_version: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ version: '0'
186
+ requirements: []
187
+ rubyforge_project:
188
+ rubygems_version: 2.5.2
189
+ signing_key:
190
+ specification_version: 4
191
+ summary: Ruby wrapper for the CentralPos WebService
192
+ test_files: []