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.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +170 -0
- data/Rakefile +16 -0
- data/cieloz.gemspec +34 -0
- data/config/locales/en.yml +11 -0
- data/config/locales/pt-BR.yml +11 -0
- data/lib/cieloz/bandeiras.rb +22 -0
- data/lib/cieloz/builder.rb +71 -0
- data/lib/cieloz/configuracao.rb +64 -0
- data/lib/cieloz/helpers.rb +35 -0
- data/lib/cieloz/homologacao.rb +16 -0
- data/lib/cieloz/requisicao/dados_ec.rb +14 -0
- data/lib/cieloz/requisicao/resposta/erro.rb +11 -0
- data/lib/cieloz/requisicao/resposta/transacao.rb +11 -0
- data/lib/cieloz/requisicao/resposta.rb +35 -0
- data/lib/cieloz/requisicao.rb +69 -0
- data/lib/cieloz/requisicao_tid.rb +23 -0
- data/lib/cieloz/requisicao_transacao/dados_pedido.rb +32 -0
- data/lib/cieloz/requisicao_transacao/dados_portador.rb +79 -0
- data/lib/cieloz/requisicao_transacao/forma_pagamento.rb +94 -0
- data/lib/cieloz/requisicao_transacao.rb +126 -0
- data/lib/cieloz/version.rb +3 -0
- data/lib/cieloz.rb +24 -0
- data/readme/cielo_developer_guide_2.0.3.pdf +0 -0
- data/readme/cielo_guia_seguranca_ecommerce.pdf +0 -0
- data/readme/cielo_payment_states.png +0 -0
- data/readme/contrato_de_afiliacao_ao_sistema_cielo.pdf +0 -0
- data/readme/credentials.png +0 -0
- data/readme/dicas_preventivas_para_vendas_mais_seguras.pdf +0 -0
- data/readme/email_cielo.pdf +0 -0
- data/readme/lista_de_documentos_necessarios_para_afiliacao_de_vendas_pela_internet_pessoa_juridica.pdf +0 -0
- data/readme/mastercard_securecodedemo.swf +0 -0
- data/readme/supported_products.png +0 -0
- data/readme/termo_de_adesao_de_risco.pdf +0 -0
- data/readme/verified_by_visa.png +0 -0
- data/test/integration/integration_test.rb +104 -0
- data/test/minitest_helper.rb +65 -0
- data/test/unit/bandeiras_operacoes_test.rb +25 -0
- data/test/unit/builder_test.rb +212 -0
- data/test/unit/configuracao_test.rb +85 -0
- data/test/unit/requisicao_autorizacao_tid_test.rb +19 -0
- data/test/unit/requisicao_cancelamento_test.rb +25 -0
- data/test/unit/requisicao_captura_test.rb +25 -0
- data/test/unit/requisicao_consulta_test.rb +19 -0
- data/test/unit/requisicao_test.rb +84 -0
- data/test/unit/requisicao_transacao_test.rb +82 -0
- data/test/unit/validations_test.rb +358 -0
- data/test/unit/xml/dados-ec.xml +4 -0
- data/test/unit/xml/dados-pagamento.xml +5 -0
- data/test/unit/xml/dados-pedido.xml +9 -0
- data/test/unit/xml/dados-portador.xml +7 -0
- data/test/unit/xml/dados-simple_attrs.xml +4 -0
- data/test/unit/xml/erro.xml +5 -0
- data/test/unit/xml/transacao.xml +19 -0
- metadata +280 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
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
|
+

|
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
|
+

|
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
|
+

|
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,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
|