cieloz 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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