cieloz 0.0.2

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 (57) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +170 -0
  5. data/Rakefile +16 -0
  6. data/cieloz.gemspec +34 -0
  7. data/config/locales/en.yml +11 -0
  8. data/config/locales/pt-BR.yml +11 -0
  9. data/lib/cieloz/bandeiras.rb +22 -0
  10. data/lib/cieloz/builder.rb +71 -0
  11. data/lib/cieloz/configuracao.rb +64 -0
  12. data/lib/cieloz/helpers.rb +35 -0
  13. data/lib/cieloz/homologacao.rb +16 -0
  14. data/lib/cieloz/requisicao/dados_ec.rb +14 -0
  15. data/lib/cieloz/requisicao/resposta/erro.rb +11 -0
  16. data/lib/cieloz/requisicao/resposta/transacao.rb +11 -0
  17. data/lib/cieloz/requisicao/resposta.rb +35 -0
  18. data/lib/cieloz/requisicao.rb +69 -0
  19. data/lib/cieloz/requisicao_tid.rb +23 -0
  20. data/lib/cieloz/requisicao_transacao/dados_pedido.rb +32 -0
  21. data/lib/cieloz/requisicao_transacao/dados_portador.rb +79 -0
  22. data/lib/cieloz/requisicao_transacao/forma_pagamento.rb +94 -0
  23. data/lib/cieloz/requisicao_transacao.rb +126 -0
  24. data/lib/cieloz/version.rb +3 -0
  25. data/lib/cieloz.rb +24 -0
  26. data/readme/cielo_developer_guide_2.0.3.pdf +0 -0
  27. data/readme/cielo_guia_seguranca_ecommerce.pdf +0 -0
  28. data/readme/cielo_payment_states.png +0 -0
  29. data/readme/contrato_de_afiliacao_ao_sistema_cielo.pdf +0 -0
  30. data/readme/credentials.png +0 -0
  31. data/readme/dicas_preventivas_para_vendas_mais_seguras.pdf +0 -0
  32. data/readme/email_cielo.pdf +0 -0
  33. data/readme/lista_de_documentos_necessarios_para_afiliacao_de_vendas_pela_internet_pessoa_juridica.pdf +0 -0
  34. data/readme/mastercard_securecodedemo.swf +0 -0
  35. data/readme/supported_products.png +0 -0
  36. data/readme/termo_de_adesao_de_risco.pdf +0 -0
  37. data/readme/verified_by_visa.png +0 -0
  38. data/test/integration/integration_test.rb +104 -0
  39. data/test/minitest_helper.rb +65 -0
  40. data/test/unit/bandeiras_operacoes_test.rb +25 -0
  41. data/test/unit/builder_test.rb +212 -0
  42. data/test/unit/configuracao_test.rb +85 -0
  43. data/test/unit/requisicao_autorizacao_tid_test.rb +19 -0
  44. data/test/unit/requisicao_cancelamento_test.rb +25 -0
  45. data/test/unit/requisicao_captura_test.rb +25 -0
  46. data/test/unit/requisicao_consulta_test.rb +19 -0
  47. data/test/unit/requisicao_test.rb +84 -0
  48. data/test/unit/requisicao_transacao_test.rb +82 -0
  49. data/test/unit/validations_test.rb +358 -0
  50. data/test/unit/xml/dados-ec.xml +4 -0
  51. data/test/unit/xml/dados-pagamento.xml +5 -0
  52. data/test/unit/xml/dados-pedido.xml +9 -0
  53. data/test/unit/xml/dados-portador.xml +7 -0
  54. data/test/unit/xml/dados-simple_attrs.xml +4 -0
  55. data/test/unit/xml/erro.xml +5 -0
  56. data/test/unit/xml/transacao.xml +19 -0
  57. metadata +280 -0
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in spree_cielo.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012,2013 Fábio Luiz Nery de Miranda <github.com/fabiolnm>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,170 @@
1
+ [<img src="https://secure.travis-ci.org/fabiolnm/cieloz.png"/>](http://travis-ci.org/fabiolnm/cieloz)
2
+
3
+ # Cieloz
4
+
5
+ A utility gem for SpreeCielo Gateway gem.
6
+
7
+ ## Getting Started
8
+
9
+ This is a step-by-step guide to enable Cielo Gateway as a payment method to your e-commerce store.
10
+
11
+ First, you should create your credentials at the following Cielo Page:
12
+
13
+ ![Credentials](https://raw.github.com/fabiolnm/cieloz/master/readme/credentials.png)
14
+
15
+ Then a form will be presented to be filled with Store, Store's Owner, Store's Address* and Banking data.
16
+ * address must be the same as the present at Store CNPJ!
17
+
18
+ After the form is submitted, a receipt number is generated, and generally in one or two business days,
19
+ Cielo sends an e-mail with detailed instructions and manuals:
20
+
21
+ * [Email example](https://raw.github.com/fabiolnm/cieloz/master/readme/email_cielo.pdf)
22
+ * [Security Guide](https://raw.github.com/fabiolnm/cieloz/master/readme/cielo_guia_seguranca_ecommerce.pdf)
23
+ * [Affiliation Contract](https://raw.github.com/fabiolnm/cieloz/master/readme/contrato_de_afiliacao_ao_sistema_cielo.pdf)
24
+ * [Preventive Tips for securing sales](https://raw.github.com/fabiolnm/cieloz/master/readme/dicas_preventivas_para_vendas_mais_seguras.pdf)
25
+ * [Required documents for affiliation](https://raw.github.com/fabiolnm/cieloz/master/readme/lista_de_documentos_necessarios_para_afiliacao_de_vendas_pela_internet_pessoa_juridica.pdf)
26
+ * [Risk Terms](https://raw.github.com/fabiolnm/cieloz/master/readme/termo_de_adesao_de_risco.pdf)
27
+
28
+ ##### NOTE
29
+ These were the documents sent by Cielo at December 21, 2012, and are subject to changes according to the Cielo affiliation processs changes.
30
+ If you notice any document is changed since then, and wants to collaborate on keeping this gem updated, please open an issue
31
+ so our team can update this README.
32
+
33
+ ##### Cielo Developer Kit
34
+ Additionaly, the email provides a link where the Cielo Integration Kit can be downloaded:
35
+
36
+ http://www.cielo.com.br/portal/kit-e-commerce-cielo.html
37
+
38
+ This kit contais the API documentation that served as a basis to developing this gem:
39
+ [Cielo e-commerce Developer Guide v2.0.3](https://raw.github.com/fabiolnm/cieloz/master/readme/cielo_developer_guide_2.0.3.pdf).
40
+
41
+ ### The Test Environment
42
+
43
+ The page 32 of this manual provides information about a Test Environment that can be used as a sandbox
44
+ to test integration with Cielo Web Services:
45
+
46
+ https://qasecommerce.cielo.com.br/servicos/ecommwsec.do
47
+
48
+ It also provides API ID and API Secret that are required to be sent within every request sent
49
+ to Cielo Web Services, and valid test credit card numbers to be used at this environment.
50
+
51
+ ### The Cielo Payment Workflow
52
+
53
+ #### Hosted Buy Page versus Store Buy Page
54
+
55
+ Credit Card data can be provided directly to a Store BuyPage, but this requires the Store
56
+ Owner to handle with security issues.
57
+
58
+ The simplest alternative to get started is using an environment provided by the Cielo
59
+ infrastructure. When the user is required to type his credit card data, he is redirected
60
+ to a Cielo Hosted Buy Page. When the user submits his data, he's redirected back to
61
+ a Callback URL provided by the store.
62
+
63
+
64
+ #### Supported CreditCard operations
65
+
66
+ The following diagram was extracted from Cielo Developer Guide v2.0.3, page 5.
67
+
68
+ ![Payment States](https://raw.github.com/fabiolnm/cieloz/master/readme/supported_products.png)
69
+
70
+ #### TransactionRequest (RequisicaoTransacao)
71
+
72
+ Every payment starts with a TransactionRequest. In the Hosted Mode, its main data are:
73
+ * Order Data (DadosPedido)
74
+ * PaymentMethod (FormaPagamento)
75
+ * Authorization Mode (whether it supports Authentication Programs)
76
+ * Capture Mode (can be util for fraud prevention)
77
+
78
+ In Store Mode, it also should include Credit Card Data (DadosPortador).
79
+
80
+ ##### Authorization Modes
81
+
82
+ Visa and Mastercard supports Authentication Programs. This means additional security, as the
83
+ user is required to provide additional security credentials with his bank to be able to
84
+ have a transaction authorized for online payments:
85
+
86
+ * [Verified by Visa](https://raw.github.com/fabiolnm/cieloz/master/readme/verified_by_visa.png),
87
+ from this [source](http://www.verifiedbyvisa.com.br/aspx/funciona/comofunciona.aspx)
88
+ * [MasterCard Secure Code](https://raw.github.com/fabiolnm/cieloz/master/readme/mastercard_securecodedemo.swf),
89
+ from this [source](https://www.mycardsecure.com/vpas/certegy_mc/i18n/en_US/securecodedemo.swf)
90
+
91
+ Additionaly, a specific authorization mode is available to enable recurrent payments, in the
92
+ case they are supported by the Credit Card operator.
93
+
94
+ #### Transaction States and Web Service Operations
95
+
96
+ The following diagram was extracted from Cielo Developer Guide v2.0.3, page 9.
97
+
98
+ ![Payment States](https://raw.github.com/fabiolnm/cieloz/master/readme/cielo_payment_states.png)
99
+
100
+ When a TransactionRequest succeeds, it responds with a Transaction (Transacao) with Status 0 - CREATED.
101
+ This response contains the Transaction ID (TID), and an Authentication URL (url-autenticacao)
102
+ where the user must be redirected to start the Authorization flow.
103
+
104
+ When the user visits this URL, the transaction assumes Status 1 - IN_PROGRESS.
105
+ When the user submits its Credit Card data, the transaction can assume Authentication States,
106
+ if supported by the selected credit card (Verified by Visa or MasterCard Secure Code programs).
107
+
108
+ After authentication/authorization flow, if the user has available credit, the
109
+ transaction assumes Status 4 - AUTHORIZED (Autorizada).
110
+
111
+ When the transaction is at AUTHORIZED state, the Store Owner must capture this payment in the
112
+ next five days. This can be done with a CaptureRequest (RequisicaoCaptura)
113
+
114
+ The Store Owner also has the option to request automatic payment capture, bypassing AUTHORIZED state.
115
+ After capture, the transaction assumes Status 6 - CAPTURED (Capturada).
116
+
117
+ * Manual Capture can be useful for fraud prevention, but it requires aditional Admin efforts.
118
+
119
+ In the 90 days that follows the Authorization or Capture, the transaction can be fully or
120
+ partially cancelled, assuming state 9 - CANCELLED (Cancelada). This can be done with a
121
+ CancelRequest (RequisicaoCancelamento).
122
+
123
+ * At any time, a pending request can be expired at Cielo Gateway, that puts the transaction in CANCELLED state.
124
+ * Each state has its own expire time, see the Developer Guide for detailed information.
125
+
126
+ At any time, a QueryRequest (RequisicaoConsulta) can be made for a specific transaction
127
+ (identified by its TID) to query about the state of the transaction.
128
+
129
+ ### What is this gem about?
130
+
131
+ This gem provides a Ruby integration solution that consumes Cielo Web Services.
132
+
133
+ A developer just instantiates one of the available operations:
134
+
135
+ * RequisicaoTransacao
136
+ * RequisicaoConsulta
137
+ * RequisicaoCaptura
138
+ * RequisicaoCancelamento
139
+
140
+ Then populates them with appropriate data. This gem validates these request objects according to
141
+ Cielo Specifications present at Developer Guide (pages 10, 11, 26, 28 and 30), so it makes error
142
+ handling easier, before the request is sent to Cielo Web Service.
143
+
144
+ If the operation is valid, this gem serializes them as XML and submits to Cielo, parsing the
145
+ response as a Transaction (Transacao) or Error (Erro) objects. Both keeps the original XML response
146
+ as a xml attribute, so it can be logged.
147
+
148
+ ## Installation
149
+
150
+ Add this line to your application's Gemfile:
151
+
152
+ gem 'cieloz'
153
+
154
+ And then execute:
155
+
156
+ $ bundle
157
+
158
+ Or install it yourself as:
159
+
160
+ $ gem install cieloz
161
+
162
+ ## Usage
163
+
164
+ ## Contributing
165
+
166
+ 1. Fork it
167
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
168
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
169
+ 4. Push to the branch (`git push origin my-new-feature`)
170
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs.push "lib"
6
+ t.pattern = 'test/{minitest_helper,unit/**/*}.rb'
7
+ t.verbose = true
8
+ end
9
+
10
+ Rake::TestTask.new("test:integration") do |t|
11
+ t.libs.push "lib"
12
+ t.pattern = 'test/integration/**/*.rb'
13
+ t.verbose = true
14
+ end
15
+
16
+ task default: :test
data/cieloz.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cieloz/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "cieloz"
8
+ gem.version = Cieloz::VERSION
9
+ gem.authors = ["Fábio Luiz Nery de Miranda"]
10
+ gem.email = ["fabio@miranti.net.br"]
11
+ gem.description = %q{A utility gem for Cielo Integration}
12
+ gem.summary = %q{}
13
+ gem.homepage = "https://github.com/fabiolnm/cieloz"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency "nokogiri"
21
+ gem.add_dependency "activesupport"
22
+ gem.add_dependency "activemodel"
23
+
24
+ gem.add_development_dependency "rake"
25
+ gem.add_development_dependency "turn"
26
+ gem.add_development_dependency "fakeweb"
27
+ gem.add_development_dependency "debugger"
28
+
29
+ # see https://github.com/thoughtbot/shoulda-matchers/issues/235
30
+ gem.add_development_dependency "bourne", "1.3.0"
31
+
32
+ gem.add_development_dependency "shoulda-matchers"
33
+ gem.add_development_dependency "minitest-matchers"
34
+ end
@@ -0,0 +1,11 @@
1
+ en:
2
+ activemodel:
3
+ errors:
4
+ models:
5
+ cieloz/requisicao_transacao:
6
+ attributes:
7
+ autorizar:
8
+ authentication_not_supported: Authentication not supported
9
+ direct_auth_available_for_credit_only: Direct auth available for credit only
10
+ forma_pagamento:
11
+ minimum_installment_not_satisfied: Installment should be greater than or equal to R$ 5,00
@@ -0,0 +1,11 @@
1
+ pt-BR:
2
+ activemodel:
3
+ errors:
4
+ models:
5
+ cieloz/requisicao_transacao:
6
+ attributes:
7
+ autorizar:
8
+ authentication_not_supported: Bandeira não possui programa de autenticação
9
+ direct_auth_available_for_credit_only: Autorização Direta disponível apenas em operações de crédito
10
+ forma_pagamento:
11
+ minimum_installment_not_satisfied: O valor mínimo da parcela deve ser R$ 5,00
@@ -0,0 +1,22 @@
1
+ module Cieloz
2
+ module Bandeiras
3
+ ALL = %w(amex diners discover elo mastercard visa)
4
+ AMEX, DINERS, DISCOVER, ELO, MASTERCARD, VISA = ALL
5
+
6
+ def self.operacao produto
7
+ case produto.to_sym
8
+ when :mastercard_securecode
9
+ [MASTERCARD, :autorizar_somente_autenticada]
10
+ when :verified_by_visa
11
+ [VISA, :autorizar_somente_autenticada]
12
+ else
13
+ produto = produto.to_s
14
+ if ALL.include? produto
15
+ [produto, :autorizacao_direta]
16
+ else
17
+ raise "product_not_supported"
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,71 @@
1
+ module Cieloz
2
+ module Builder
3
+ def portador source, opts={}
4
+ num, val, cod, nome = attrs_from source, opts,
5
+ :numero, :validade, :codigo_seguranca, :nome_portador
6
+
7
+ RequisicaoTransacao::DadosPortador.new numero: num,
8
+ validade: val, codigo_seguranca: cod, nome_portador: nome
9
+ end
10
+
11
+ def pedido source, opts={}
12
+ mappings = attrs_from source, opts, :numero, :valor,
13
+ :descricao, :data_hora, :moeda, :idioma, :soft_descriptor
14
+
15
+ num, val, desc, time, cur, lang, soft = mappings
16
+ val = (val * 100).round unless val.nil? or val.integer?
17
+
18
+ time ||= Time.now
19
+ cur ||= Cieloz::Configuracao.moeda
20
+ lang ||= Cieloz::Configuracao.idioma
21
+ soft ||= Cieloz::Configuracao.soft_descriptor
22
+
23
+ RequisicaoTransacao::DadosPedido.new data_hora: time,
24
+ numero: num, valor: val, moeda: cur, idioma: lang,
25
+ descricao: desc, soft_descriptor: soft
26
+ end
27
+
28
+ def pagamento source, opts={}
29
+ opr, parcelas = attrs_from source, opts, :operacao, :parcelas
30
+ RequisicaoTransacao::FormaPagamento.new.operacao opr, parcelas
31
+ end
32
+
33
+ def transacao source, opts={}
34
+ portador, pedido, pagamento, url, capturar, campo_livre =
35
+ attrs_from source, opts, :dados_portador, :dados_pedido,
36
+ :forma_pagamento, :url_retorno, :capturar, :campo_livre
37
+
38
+ url ||= Cieloz::Configuracao.url_retorno
39
+
40
+ txn = RequisicaoTransacao.new dados_portador: portador,
41
+ dados_pedido: pedido, forma_pagamento: pagamento,
42
+ campo_livre: campo_livre, url_retorno: url,
43
+ dados_ec: Cieloz::Configuracao.credenciais
44
+
45
+ capturar ||= Cieloz::Configuracao.captura_automatica
46
+
47
+ case capturar.to_s
48
+ when 'true' then txn.capturar_automaticamente
49
+ else txn.nao_capturar_automaticamente
50
+ end
51
+
52
+ txn.send pagamento.metodo_autorizacao
53
+
54
+ txn
55
+ end
56
+
57
+ private
58
+ def attrs_from source, opts, *keys
59
+ keys.map { |k|
60
+ value_or_attr_name = opts[k] || k
61
+ if value_or_attr_name.is_a? Symbol
62
+ source.send value_or_attr_name if source.respond_to? value_or_attr_name
63
+ else
64
+ value_or_attr_name
65
+ end
66
+ }
67
+ end
68
+ end
69
+
70
+ extend Builder
71
+ end
@@ -0,0 +1,64 @@
1
+ module Cieloz
2
+ module Configuracao
3
+ HOST = "ecommerce.cielo.com.br"
4
+ WS_PATH = "/servicos/ecommwsec.do"
5
+
6
+ @@mode = :cielo
7
+ @@moeda = 986 # ISO 4217 - Manual Cielo, p 11
8
+ @@idioma = "PT"
9
+ @@max_parcelas = 3
10
+ @@max_adm_parcelas = 10
11
+ @@captura_automatica = false
12
+ @@credenciais = nil
13
+ @@dados_ec = nil
14
+
15
+ mattr_writer :credenciais, :captura_automatica
16
+ mattr_accessor :url_retorno, :soft_descriptor
17
+ mattr_accessor :max_parcelas, :max_adm_parcelas, :moeda, :idioma
18
+
19
+ def self.reset!
20
+ cielo_mode!
21
+ @@credenciais = nil
22
+ end
23
+
24
+ def self.store_mode!
25
+ @@mode = :store
26
+ end
27
+
28
+ def self.store_mode?
29
+ @@mode == :store
30
+ end
31
+
32
+ def self.cielo_mode!
33
+ @@mode = :cielo
34
+ end
35
+
36
+ def self.cielo_mode?
37
+ @@mode == :cielo
38
+ end
39
+
40
+ def self.credenciais
41
+ return @@dados_ec if @@dados_ec
42
+ return (@@dados_ec = Requisicao::DadosEc.new @@credenciais) if @@credenciais
43
+
44
+ mode = store_mode? ? :LOJA : :CIELO
45
+ Homologacao::Credenciais.const_get mode
46
+ end
47
+
48
+ def self.host
49
+ @@credenciais ? HOST : Homologacao::HOST
50
+ end
51
+
52
+ def self.path
53
+ WS_PATH
54
+ end
55
+
56
+ def self.url
57
+ "https://#{host}#{WS_PATH}"
58
+ end
59
+
60
+ def self.captura_automatica
61
+ !!@@captura_automatica
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,35 @@
1
+ module Cieloz
2
+ module Helpers
3
+ module ClassMethods
4
+ def hattr_writer *attrs
5
+ attrs.each { |attr|
6
+ define_method "#{attr}=" do |value|
7
+ if value.is_a? Hash
8
+ name = attr.to_s.camelize
9
+ cls = self.class.const_get name
10
+ value = cls.new(value)
11
+ end
12
+ instance_variable_set "@#{attr}", value
13
+ yield(value) if block_given?
14
+ end
15
+ }
16
+ end
17
+ end
18
+
19
+ def self.included base
20
+ base.extend ClassMethods
21
+ base.send :include, ActiveModel::Validations
22
+ end
23
+
24
+ def initialize attrs={}
25
+ self.attributes = attrs
26
+ end
27
+
28
+ def attributes= attrs
29
+ attrs.each {|k,v|
30
+ m = "#{k}="
31
+ send(m, v) if respond_to? m
32
+ }
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,16 @@
1
+ module Cieloz
2
+ module Homologacao
3
+ HOST = "qasecommerce.cielo.com.br"
4
+
5
+ module Credenciais
6
+ CIELO = {
7
+ numero: "1001734898",
8
+ chave: "e84827130b9837473681c2787007da5914d6359947015a5cdb2b8843db0fa832"
9
+ }
10
+ LOJA = {
11
+ numero: "1006993069",
12
+ chave: "25fbb99741c739dd84d7b06ec78c9bac718838630f30b112d033ce2e621b34f3"
13
+ }
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ module Cieloz
2
+ class Requisicao
3
+ class DadosEc
4
+ include Helpers
5
+
6
+ attr_accessor :numero, :chave
7
+ validates :numero, :chave, presence: true
8
+
9
+ def attributes
10
+ { numero: @numero, chave: @chave }
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,11 @@
1
+ module Cieloz
2
+ class Requisicao
3
+ class Erro < Resposta
4
+ attr_accessor :codigo, :mensagem
5
+
6
+ def success?
7
+ false
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Cieloz
2
+ class Requisicao
3
+ class Transacao < Resposta
4
+ attr_accessor :tid, :status, :url_autenticacao
5
+
6
+ def success?
7
+ true
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,35 @@
1
+ module Cieloz
2
+ class Requisicao
3
+ class Resposta
4
+ include ActiveModel::Serializers::Xml
5
+ include Helpers
6
+
7
+ STATUSES = {
8
+ "0" => :criada,
9
+ "1" => :em_andamento,
10
+ "2" => :autenticada,
11
+ "3" => :nao_autenticada,
12
+ "4" => :autorizada,
13
+ "5" => :nao_autorizada,
14
+ "6" => :capturada,
15
+ "9" => :cancelada,
16
+ "10" => :em_autenticacao,
17
+ "12" => :em_cancelamento
18
+ }
19
+
20
+ attr_reader :xml
21
+
22
+ def self.from xml
23
+ obj = new.from_xml xml
24
+ obj.instance_variable_set :@xml, xml
25
+ obj
26
+ end
27
+
28
+ STATUSES.each do |_, status_type|
29
+ define_method "#{status_type}?" do
30
+ success? and STATUSES[status] == status_type
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,69 @@
1
+ require 'net/http'
2
+ require 'builder'
3
+
4
+ class Cieloz::Requisicao
5
+ include Cieloz::Helpers
6
+
7
+ attr_accessor :id, :versao
8
+ attr_reader :dados_ec
9
+ hattr_writer :dados_ec
10
+
11
+ validates :id, :versao, :dados_ec, presence: true
12
+
13
+ def attributes
14
+ { dados_ec: @dados_ec }
15
+ end
16
+
17
+ def to_xml
18
+ x = Builder::XmlMarkup.new
19
+ x.instruct!
20
+ name = self.class.name.demodulize
21
+ x.tag! name.underscore.dasherize, id: id, versao: versao do
22
+ attributes.each { |attr, value|
23
+ next if value.nil?
24
+
25
+ unless value.respond_to? :attributes
26
+ x.tag! dash(attr), value
27
+ else
28
+ x.tag! dash(attr) do
29
+ value.attributes.each do |attr, value|
30
+ x.tag!(dash(attr), value) unless value.blank?
31
+ end
32
+ end
33
+ end
34
+ }
35
+ end
36
+ end
37
+
38
+ def submit
39
+ @id = SecureRandom.uuid if id.blank?
40
+ @versao = "1.2.0" if versao.blank?
41
+
42
+ if valid?
43
+ http = Net::HTTP.new Cieloz::Configuracao.host, 443
44
+ http.use_ssl = true
45
+ http.open_timeout = 5 * 1000
46
+ http.read_timeout = 30 * 1000
47
+ http.ssl_version = :SSLv3 #http://stackoverflow.com/questions/11321403/openssl-trouble-with-ruby-1-9-3
48
+
49
+ parse http.post Cieloz::Configuracao.path, "mensagem=#{to_xml}"
50
+ end
51
+ end
52
+
53
+ def parse res
54
+ body = res.body.force_encoding("ISO-8859-1").encode "UTF-8"
55
+ return Erro.new(codigo: res.code, mensagem: body) if res.code != "200"
56
+
57
+ root = Nokogiri::XML(body).root
58
+ response_class = case root.name
59
+ when 'erro' then Erro
60
+ when 'transacao' then Transacao
61
+ end
62
+ response_class.from body
63
+ end
64
+
65
+ private
66
+ def dash value
67
+ value.to_s.gsub("@", "").dasherize
68
+ end
69
+ end
@@ -0,0 +1,23 @@
1
+ module Cieloz
2
+ class RequisicaoTid < Requisicao
3
+ attr_accessor :tid
4
+
5
+ def attributes
6
+ { tid: @tid, dados_ec: @dados_ec }
7
+ end
8
+ end
9
+
10
+ class RequisicaoTidValor < RequisicaoTid
11
+ attr_accessor :valor
12
+
13
+ def attributes
14
+ { tid: @tid, dados_ec: @dados_ec, valor: @valor }
15
+ end
16
+ end
17
+
18
+ class RequisicaoConsulta < RequisicaoTid ; end
19
+ class RequisicaoAutorizacaoTid < RequisicaoTid ; end
20
+
21
+ class RequisicaoCaptura < RequisicaoTidValor ; end
22
+ class RequisicaoCancelamento < RequisicaoTidValor ; end
23
+ end