aprova_facil 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +279 -0
- data/Rakefile +11 -0
- data/aprova_facil.gemspec +21 -0
- data/lib/aprova_facil/aprova_facil.rb +147 -0
- data/lib/aprova_facil/cartao_credito.rb +102 -0
- data/lib/aprova_facil/version.rb +3 -0
- data/lib/aprova_facil.rb +26 -0
- data/test/aprova_facil_test.rb +113 -0
- data/test/cartao_credito_test.rb +128 -0
- data/test/test_helper.rb +9 -0
- metadata +71 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 [name of plugin creator]
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,279 @@
|
|
1
|
+
Aprova Fácil
|
2
|
+
------------
|
3
|
+
|
4
|
+
Gem para integração com Gateway Aprova Fácil da [Cobrebem](https://www.cobrebemx.com.br).
|
5
|
+
|
6
|
+
COMO USAR
|
7
|
+
---------
|
8
|
+
|
9
|
+
### Configuração
|
10
|
+
|
11
|
+
O primeiro passo é instalar a gem.
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem install aprova_facil
|
15
|
+
```
|
16
|
+
|
17
|
+
Depois de instalar, você precisará informar seus dados.
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
AprovaFacil::Config.usuario = '<usuario>' # usuário fornecido pela Cobrebem
|
21
|
+
```
|
22
|
+
|
23
|
+
No caso de um abiente de teste ou desenvolvimento também é possível passar o parâmetro
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
AprovaFacil::Config.teste = true
|
27
|
+
```
|
28
|
+
|
29
|
+
Efetuando uma aprovação
|
30
|
+
-----------------------
|
31
|
+
|
32
|
+
Para efetuar uma compra é necessário preencher uma instância da classe CartaoCredito,
|
33
|
+
segue abaixo os dados básicos para uma aprovação.
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
cartao = AprovaFacil::CartaoCredito.new(
|
37
|
+
:valor => 25.00,
|
38
|
+
:numero_cartao => '4073020000000002',
|
39
|
+
:codigo_seguranca => '123',
|
40
|
+
:mes_validade => '10',
|
41
|
+
:ano_validade => '14',
|
42
|
+
:bandeira => AprovaFacil::CartaoCredito::Bandeira::VISA
|
43
|
+
:ip_comprador => '192.168.1.1',
|
44
|
+
:nome_portador => 'Ford Prefect'
|
45
|
+
)
|
46
|
+
```
|
47
|
+
|
48
|
+
### Outros atributos disponíveis
|
49
|
+
|
50
|
+
<table>
|
51
|
+
<tr>
|
52
|
+
<th>Atributo</th>
|
53
|
+
<th>Descrição</th>
|
54
|
+
<th>Obrigatório?</th>
|
55
|
+
<th>Valor padrão</th>
|
56
|
+
</tr>
|
57
|
+
<tr>
|
58
|
+
<td>:documento</td>
|
59
|
+
<td>Número do documento do sistema</td>
|
60
|
+
<td>Não</td>
|
61
|
+
<td></td>
|
62
|
+
</tr>
|
63
|
+
<tr>
|
64
|
+
<td>:valor</td>
|
65
|
+
<td>Valor da transação</td>
|
66
|
+
<td>Sim</td>
|
67
|
+
<td>0.00</td>
|
68
|
+
</tr>
|
69
|
+
<tr>
|
70
|
+
<td>:numero_cartao</td>
|
71
|
+
<td>Número do cartão</td>
|
72
|
+
<td>Sim</td>
|
73
|
+
<td></td>
|
74
|
+
</tr>
|
75
|
+
<tr>
|
76
|
+
<td>:codigo_seguranca</td>
|
77
|
+
<td>Código de segurança do cartão</td>
|
78
|
+
<td>Sim</td>
|
79
|
+
<td></td>
|
80
|
+
</tr>
|
81
|
+
<tr>
|
82
|
+
<td>:mes_validade</td>
|
83
|
+
<td>Mês de validade do cartão</td>
|
84
|
+
<td>Sim</td>
|
85
|
+
<td></td>
|
86
|
+
</tr>
|
87
|
+
<tr>
|
88
|
+
<td>:ano_validade</td>
|
89
|
+
<td>Ano de validade do cartão</td>
|
90
|
+
<td>Sim</td>
|
91
|
+
<td></td>
|
92
|
+
</tr>
|
93
|
+
<tr>
|
94
|
+
<td>:ip_comprador</td>
|
95
|
+
<td>Ip do comprador</td>
|
96
|
+
<td>Sim</td>
|
97
|
+
<td></td>
|
98
|
+
</tr>
|
99
|
+
<tr>
|
100
|
+
<td>:parcelas</td>
|
101
|
+
<td>Quantidade de parcelas</td>
|
102
|
+
<td>Não</td>
|
103
|
+
<td>01</td>
|
104
|
+
</tr>
|
105
|
+
<tr>
|
106
|
+
<td>:bandeira</td>
|
107
|
+
<td>Bandeira, veja abaixo</td>
|
108
|
+
<td>Não</td>
|
109
|
+
<td>VISA</td>
|
110
|
+
</tr>
|
111
|
+
<tr>
|
112
|
+
<td>:nome_portador</td>
|
113
|
+
<td>Nome do portador do cartão</td>
|
114
|
+
<td>Não</td>
|
115
|
+
<td></td>
|
116
|
+
</tr>
|
117
|
+
<tr>
|
118
|
+
<td>:cpf_portador</td>
|
119
|
+
<td>CPF do portador do cartão</td>
|
120
|
+
<td>Não</td>
|
121
|
+
<td></td>
|
122
|
+
</tr>
|
123
|
+
<tr>
|
124
|
+
<td>:data_nascimento</td>
|
125
|
+
<td>Data de nascimento do portador do cartão</td>
|
126
|
+
<td>Não</td>
|
127
|
+
<td></td>
|
128
|
+
</tr>
|
129
|
+
<tr>
|
130
|
+
<td>:nome_mae</td>
|
131
|
+
<td>Nome da mão do portador do cartão</td>
|
132
|
+
<td>Não</td>
|
133
|
+
<td></td>
|
134
|
+
</tr>
|
135
|
+
<tr>
|
136
|
+
<td>:parcelamento_administradora</td>
|
137
|
+
<td>Informa se será parcelado pela loja ou pela adminsitrador</td>
|
138
|
+
<td>Não</td>
|
139
|
+
<td>True</td>
|
140
|
+
</tr>
|
141
|
+
</table>
|
142
|
+
|
143
|
+
### Bandeiras
|
144
|
+
|
145
|
+
```ruby
|
146
|
+
AprovaFacil::CartaoCredito::Bandeira::VISA
|
147
|
+
AprovaFacil::CartaoCredito::Bandeira::MASTERCARD
|
148
|
+
AprovaFacil::CartaoCredito::Bandeira::DINERS
|
149
|
+
AprovaFacil::CartaoCredito::Bandeira::AMEX
|
150
|
+
AprovaFacil::CartaoCredito::Bandeira::HIPERCARD
|
151
|
+
AprovaFacil::CartaoCredito::Bandeira::JCB
|
152
|
+
AprovaFacil::CartaoCredito::Bandeira::SOROCRED
|
153
|
+
AprovaFacil::CartaoCredito::Bandeira::AURA
|
154
|
+
```
|
155
|
+
|
156
|
+
Após criar o cartão deve ser solicidade uma aprovação.
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
aprova_facil = AprovaFacil.new
|
160
|
+
resultado = aprova_facil.aprovar(cartao)
|
161
|
+
```
|
162
|
+
|
163
|
+
### Resultados
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
:aprovada # True ou false
|
167
|
+
:resultado # Descrição do resultado do pedido
|
168
|
+
:codigo_autorizacao # Código de autorização retornado pela administradora do cartão.
|
169
|
+
:transacao # ID da transação do Aprova Fácil.
|
170
|
+
:cartao_mascarado # Número do cartão de crédito mascarado. Eg. 444433******1111
|
171
|
+
:numero_documento # ID do pedido.
|
172
|
+
```
|
173
|
+
|
174
|
+
Captura
|
175
|
+
-------
|
176
|
+
|
177
|
+
Entendese por captura o processo de confirmação de uma transação, o que caracteriza a venda
|
178
|
+
efetivada, sendo realizado assim, o débito no cartão de crédito do cliente.
|
179
|
+
De acordo com os padrões ISO 8583, todas as transações aprovadas pelas Administradoras de
|
180
|
+
Cartões de Crédito devem ser capturadas (confirmadas) pela aplicação do Lojista.
|
181
|
+
Caso a transação não seja capturada (confirmada) pela aplicação do Lojista, no prazo estipulado
|
182
|
+
pelas Administradoras de Cartões Crédito, a mesma será automaticamente desfeita, não havendo assim o
|
183
|
+
débito efetivo no cartão de crédito do cliente, essa informação será exibida no campo
|
184
|
+
“Data Hora Cancelamento”do Extrato do Aprova Fácil.
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
aprova_facil = AprovaFacil.new
|
188
|
+
resultado = aprova_facil.capturar('123123123') # Numero da transação
|
189
|
+
```
|
190
|
+
|
191
|
+
### Resultados
|
192
|
+
|
193
|
+
```ruby
|
194
|
+
:capturado # True ou false
|
195
|
+
:resultado # Descrição da captura
|
196
|
+
```
|
197
|
+
|
198
|
+
Cancelamento
|
199
|
+
------------
|
200
|
+
|
201
|
+
O cancelamento de uma transação somente poderá ser realizado quando a mesma for aprovada pela
|
202
|
+
Administradora e confirmada pelo lojista. Por isso, para que o Aprova Fácil possa realizar o
|
203
|
+
cancelamento, este deve ser solicitado no mesmo dia em que a transação foi processada,
|
204
|
+
ou seja, foi confirmada pela Administradora.
|
205
|
+
|
206
|
+
```ruby
|
207
|
+
aprova_facil = AprovaFacil.new
|
208
|
+
resultado = aprova_facil.cancelar('123123') # Numero da transação
|
209
|
+
```
|
210
|
+
|
211
|
+
### Resultados
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
:cancelado # true ou false
|
215
|
+
:resultado # Descrição do cancelamento
|
216
|
+
:nsu_Cancelamento # Número de cancelamento da Administradora
|
217
|
+
```
|
218
|
+
|
219
|
+
Recorrencia
|
220
|
+
-----------
|
221
|
+
|
222
|
+
A recorrência de transações é utilizada, quando se deseja efetuar novos débitos em um cartão de
|
223
|
+
crédito, seja esta de qualquer periodicidade; é possível alterar o valor do débito a cada cobrança, se
|
224
|
+
necessário.
|
225
|
+
O processo de "recobrança" em uma recorrência, se difere do processo de "recobrança" em um
|
226
|
+
agendamento. A recobrança em uma recorrência é comandada pela aplicação do lojista, nesse caso, deve
|
227
|
+
ser informado apenas o número que identifica a última transação aprovada e confirmada, sendo este,
|
228
|
+
representado pelo parâmetro "Transacao".
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
aprova_facil = AprovaFacil.new
|
232
|
+
resultado = aprova_facil.recobrar('123123', 25.00)
|
233
|
+
```
|
234
|
+
|
235
|
+
Assinatura do método de recobrança.
|
236
|
+
|
237
|
+
```ruby
|
238
|
+
def recobrar(transacao, valor, parcelas = '01', parcelamento_admin = true )
|
239
|
+
```
|
240
|
+
|
241
|
+
### Resultados
|
242
|
+
|
243
|
+
```ruby
|
244
|
+
:aprovada # True ou false
|
245
|
+
:resultado # Descrição da aprovação do resultado do pedido
|
246
|
+
:codigo_autorizacao # Código de autorização retornado pela Administradora do cartão de crédito
|
247
|
+
:transacao # ID da transação Aprova Fáci
|
248
|
+
:cartao_mascarado # Número mascarado do Cartão de Crédito Eg. 444433******1111
|
249
|
+
:numero_documento # ID do pedido da companhia
|
250
|
+
```
|
251
|
+
|
252
|
+
AUTOR:
|
253
|
+
------
|
254
|
+
|
255
|
+
Bruno Frank Silva Cordeiro bfscordeiro (at) gmail (dot) com
|
256
|
+
|
257
|
+
LICENÇA:
|
258
|
+
--------
|
259
|
+
|
260
|
+
(The MIT License)
|
261
|
+
|
262
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
263
|
+
a copy of this software and associated documentation files (the
|
264
|
+
'Software'), to deal in the Software without restriction, including
|
265
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
266
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
267
|
+
permit persons to whom the Software is furnished to do so, subject to
|
268
|
+
the following conditions:
|
269
|
+
|
270
|
+
The above copyright notice and this permission notice shall be
|
271
|
+
included in all copies or substantial portions of the Software.
|
272
|
+
|
273
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
274
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
275
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
276
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
277
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
278
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
279
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require 'aprova_facil/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "aprova_facil"
|
7
|
+
s.version = AprovaFacil::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Bruno Frank"]
|
10
|
+
s.email = ["bfscordeiro@gmail.com"]
|
11
|
+
s.homepage = "https://github.com/brunofrank/aprova_facil"
|
12
|
+
s.summary = %q{Gem para integração de aplicação Ruby com o gateway de pagamento Aprova Fácil da Cobre Bem.}
|
13
|
+
s.description = %q{Gem para integração de aplicação Ruby com o gateway de pagamento Aprova Fácil da Cobre Bem.}
|
14
|
+
|
15
|
+
s.rubyforge_project = "aprova_facil"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
class AprovaFacil
|
4
|
+
class MissingEnvironmentException < StandardError; end
|
5
|
+
class MissingConfigurationException < StandardError; end
|
6
|
+
|
7
|
+
URL = 'https://www.aprovafacil.com/cgi-bin/APFW/'
|
8
|
+
URL_TEST = 'https://teste.aprovafacil.com/cgi-bin/APFW/'
|
9
|
+
|
10
|
+
COMPRAR = 'APC'
|
11
|
+
CAPTURAR = 'CAP'
|
12
|
+
CANCELAR = 'CAN'
|
13
|
+
|
14
|
+
# Método usado para efetuar cobraças recorrentes
|
15
|
+
def recobrar(transacao, valor, parcelas = '01', parcelamento_admin = true )
|
16
|
+
request_url = url(COMPRAR)
|
17
|
+
request_params = {
|
18
|
+
'TransacaoAnterior' => transacao,
|
19
|
+
'ValorDocumento' => valor,
|
20
|
+
'QuantidadeParcelas' => '%02d' % parcelas,
|
21
|
+
'ParcelamentoAdministrador' => parcelamento_admin ? 'S' : 'N'
|
22
|
+
}
|
23
|
+
xml_response = commit(request_url, request_params)
|
24
|
+
treat_apc_response(xml_response)
|
25
|
+
end
|
26
|
+
|
27
|
+
def aprovar(cartao_credito)
|
28
|
+
if cartao_credito.valid?
|
29
|
+
request_url = url(COMPRAR)
|
30
|
+
request_params = cartao_credito.to_params
|
31
|
+
xml_response = commit(request_url, request_params)
|
32
|
+
treat_apc_response(xml_response)
|
33
|
+
else
|
34
|
+
{:aprovada => false, :resultado => cartao_credito.errors.join('\\n')}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def capturar(transacao)
|
39
|
+
request_url = url(CAPTURAR)
|
40
|
+
request_params = {'Transacao' => transacao}
|
41
|
+
xml_response = commit(request_url, request_params)
|
42
|
+
request_result = {}
|
43
|
+
if xml_response
|
44
|
+
response = REXML::Document.new(xml_response)
|
45
|
+
response.elements.each 'ResultadoCAP' do |resultado|
|
46
|
+
resultado.elements.each 'ResultadoSolicitacaoConfirmacao' do |resultado|
|
47
|
+
request_result[:capturado] = !resultado.text.match(/Confirmado/).nil?
|
48
|
+
request_result[:resultado] = resultado.text
|
49
|
+
end
|
50
|
+
end
|
51
|
+
else
|
52
|
+
request_result[:capturado] = false
|
53
|
+
request_result[:resultado] = 'Erro Erro desconhecido'
|
54
|
+
end
|
55
|
+
|
56
|
+
request_result
|
57
|
+
end
|
58
|
+
|
59
|
+
def cancelar(transacao)
|
60
|
+
request_url = url(CANCELAR)
|
61
|
+
request_params = {'Transacao' => transacao}
|
62
|
+
xml_response = commit(request_url, request_params)
|
63
|
+
request_result = {}
|
64
|
+
if xml_response
|
65
|
+
response = REXML::Document.new(xml_response)
|
66
|
+
response.elements.each 'ResultadoCAN' do |resultado|
|
67
|
+
resultado.elements.each 'ResultadoSolicitacaoCancelamento' do |resultado|
|
68
|
+
request_result[:cancelado] = !resultado.text.match(/Cancelado/).nil? or !resultado.text.match(/Cancelamento/).nil?
|
69
|
+
request_result[:resultado] = resultado.text
|
70
|
+
end
|
71
|
+
|
72
|
+
resultado.elements.each 'NSUCancelamento' do |nsu_Cancelamento|
|
73
|
+
request_result[:nsu_Cancelamento] = !nsu_Cancelamento.text
|
74
|
+
end
|
75
|
+
end
|
76
|
+
else
|
77
|
+
request_result[:cancelado] = false
|
78
|
+
request_result[:resultado] = 'Erro Erro desconhecido'
|
79
|
+
end
|
80
|
+
|
81
|
+
request_result
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def url(metodo)
|
87
|
+
url = AprovaFacil::Config.teste? ? URL_TEST.clone : URL.clone
|
88
|
+
url << AprovaFacil::Config.usuario
|
89
|
+
url << '/'
|
90
|
+
url << metodo
|
91
|
+
end
|
92
|
+
|
93
|
+
def commit(url, request_params)
|
94
|
+
request_params.merge!({
|
95
|
+
'ResponderEmUTF8' => 'S'
|
96
|
+
})
|
97
|
+
|
98
|
+
uri = URI.parse(url)
|
99
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
100
|
+
http.use_ssl = true
|
101
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
102
|
+
|
103
|
+
request = Net::HTTP::Post.new(uri.path)
|
104
|
+
request.form_data = request_params
|
105
|
+
response = http.start {|r| r.request request }
|
106
|
+
response.body
|
107
|
+
rescue Exception
|
108
|
+
nil
|
109
|
+
end
|
110
|
+
|
111
|
+
def treat_apc_response(xml_response)
|
112
|
+
request_result = {}
|
113
|
+
if xml_response
|
114
|
+
response = REXML::Document.new(xml_response)
|
115
|
+
response.elements.each 'ResultadoAPC' do |resultado|
|
116
|
+
resultado.elements.each 'TransacaoAprovada' do |aprovada|
|
117
|
+
request_result[:aprovada] = aprovada.text == 'True' ? true : false
|
118
|
+
end
|
119
|
+
|
120
|
+
resultado.elements.each 'ResultadoSolicitacaoAprovacao' do |resultado|
|
121
|
+
request_result[:resultado] = resultado.text
|
122
|
+
end
|
123
|
+
|
124
|
+
resultado.elements.each 'CodigoAutorizacao' do |codigo_autorizacao|
|
125
|
+
request_result[:codigo_autorizacao] = codigo_autorizacao.text
|
126
|
+
end
|
127
|
+
|
128
|
+
resultado.elements.each 'Transacao' do |transacao|
|
129
|
+
request_result[:transacao] = transacao.text
|
130
|
+
end
|
131
|
+
|
132
|
+
resultado.elements.each 'CartaoMascarado' do |cartao_mascarado|
|
133
|
+
request_result[:cartao_mascarado] = cartao_mascarado.text
|
134
|
+
end
|
135
|
+
|
136
|
+
resultado.elements.each 'NumeroDocumento' do |numero_documento|
|
137
|
+
request_result[:numero_documento] = numero_documento.text
|
138
|
+
end
|
139
|
+
end
|
140
|
+
else
|
141
|
+
request_result[:aprovada] = false
|
142
|
+
request_result[:resultado] = 'Erro Erro desconhecido'
|
143
|
+
end
|
144
|
+
|
145
|
+
request_result
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
class AprovaFacil
|
4
|
+
|
5
|
+
class CartaoCredito
|
6
|
+
|
7
|
+
module Bandeira
|
8
|
+
VISA = 'VISA'
|
9
|
+
MASTERCARD = 'MASTERCARD'
|
10
|
+
DINERS = 'DINERS'
|
11
|
+
AMEX = 'AMEX'
|
12
|
+
HIPERCARD = 'HIPERCARD'
|
13
|
+
JCB = 'JCB'
|
14
|
+
SOROCRED = 'SOROCRED'
|
15
|
+
AURA = 'AURA'
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_accessor :documento, :valor, :parcelas, :numero_cartao, :codigo_seguranca,
|
19
|
+
:mes_validade, :ano_validade, :pre_autorizacao, :ip_comprador,
|
20
|
+
:nome_portador, :bandeira, :cpf_portador, :data_nascimento,
|
21
|
+
:nome_mae, :parcelamento_administradora, :errors
|
22
|
+
|
23
|
+
def initialize(options={})
|
24
|
+
@documento = options[:documento]
|
25
|
+
@valor = options[:valor]
|
26
|
+
@parcelas = options[:parcelas] || 1
|
27
|
+
@numero_cartao = options[:numero_cartao]
|
28
|
+
@codigo_seguranca = options[:codigo_seguranca]
|
29
|
+
@mes_validade = options[:mes_validade]
|
30
|
+
@ano_validade = options[:ano_validade]
|
31
|
+
@pre_autorizacao = options[:pre_autorizacao] || false
|
32
|
+
@ip_comprador = options[:ip_comprador]
|
33
|
+
@nome_portador = options[:nome_portador]
|
34
|
+
@bandeira = options[:bandeira] || Bandeira::VISA
|
35
|
+
@cpf_portador = options[:cpf_portador]
|
36
|
+
@data_nascimento = options[:data_nascimento]
|
37
|
+
@nome_mae = options[:nome_mae]
|
38
|
+
@parcelamento_administradora = options[:parcelamento_administradora] || true
|
39
|
+
@transacao_anterior = options[:transacao_anterior]
|
40
|
+
|
41
|
+
@errors = []
|
42
|
+
end
|
43
|
+
|
44
|
+
def valid?
|
45
|
+
errors.clear
|
46
|
+
errors << {:valor => 'deve ser informado'} if valor.nil? or !valor.kind_of?(Float) or valor == 0
|
47
|
+
|
48
|
+
if parcelas.nil? or (parcelas.kind_of?(Integer) and parcelas == 0)
|
49
|
+
errors << {:parcelas => 'deve ser informado'}
|
50
|
+
end
|
51
|
+
|
52
|
+
errors << {:numero_cartao => 'deve ser informado'} if numero_cartao.nil? or numero_cartao.empty?
|
53
|
+
|
54
|
+
if mes_validade.nil? or mes_validade.empty?
|
55
|
+
errors << {:mes_validade => 'deve ser informado'}
|
56
|
+
elsif mes_validade.size != 2 or mes_validade.match(/\D/)
|
57
|
+
errors << {:mes_validade => 'deve ser informado'}
|
58
|
+
end
|
59
|
+
|
60
|
+
if ano_validade.nil? or ano_validade.empty?
|
61
|
+
errors << {:ano_validade => 'deve ser informado'}
|
62
|
+
elsif ano_validade.size != 2 or ano_validade.match(/\D/)
|
63
|
+
errors << {:ano_validade => 'deve ter 2 dígitos numéricos'}
|
64
|
+
end
|
65
|
+
|
66
|
+
if codigo_seguranca.nil? or codigo_seguranca.empty?
|
67
|
+
errors << {:codigo_seguranca => 'deve ser informado'}
|
68
|
+
elsif codigo_seguranca.match(/\D/)
|
69
|
+
errors << {:codigo_seguranca => 'deve até apenas dígitos numéricos'}
|
70
|
+
end
|
71
|
+
|
72
|
+
if ip_comprador.nil? or ip_comprador.empty?
|
73
|
+
errors << {:ip_comprador => 'deve ser informado'}
|
74
|
+
elsif !ip_comprador.match(/\d+\.\d+\.\d+\.\d+/)
|
75
|
+
errors << {:ip_comprador => 'Dese Tem que ser no formato 000.000.000.000'}
|
76
|
+
end
|
77
|
+
|
78
|
+
errors.size == 0
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_params
|
82
|
+
params = {}
|
83
|
+
params['NumeroDocumento'] = documento[0, 50] if self.documento
|
84
|
+
params['ValorDocumento'] = valor
|
85
|
+
params['QuantidadeParcelas'] = '%02d' % parcelas
|
86
|
+
params['NumeroCartao'] = numero_cartao
|
87
|
+
params['MesValidade'] = '%02d' % mes_validade
|
88
|
+
params['AnoValidade'] = '%02d' % ano_validade
|
89
|
+
params['CodigoSeguranc'] = codigo_seguranca
|
90
|
+
params['PreAutorizacao'] = pre_autorizacao ? 'S' : 'N'
|
91
|
+
params['EnderecoIPComprado'] = ip_comprador
|
92
|
+
params['NomePortadorCarta'] = nome_portador if nome_portador
|
93
|
+
params['Bandeira'] = bandeira
|
94
|
+
params['CPFPortadorCartao'] = cpf_portador.gsub /\D/, '' if cpf_portador
|
95
|
+
params['DataNascimentoPortadorCartao'] = data_nascimento.strftime('%Y%m%d') if data_nascimento and data_nascimento.kind_of?(Date)
|
96
|
+
params['NomeMaePortadorCarta'] = nome_mae if nome_mae
|
97
|
+
params['ParcelamentoAdministrador'] = parcelamento_administradora ? 'S' : 'N'
|
98
|
+
|
99
|
+
params
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/lib/aprova_facil.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require "net/https"
|
2
|
+
require "uri"
|
3
|
+
require 'aprova_facil/cartao_credito'
|
4
|
+
require 'aprova_facil/aprova_facil'
|
5
|
+
require "rexml/document"
|
6
|
+
$, = '-' # mudando o separador padrão
|
7
|
+
|
8
|
+
class AprovaFacil
|
9
|
+
class Config
|
10
|
+
def self.usuario
|
11
|
+
@usuario
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.usuario=(usuario)
|
15
|
+
@usuario = usuario
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.teste?
|
19
|
+
@test || false
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.teste=(test)
|
23
|
+
@test = test
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'digest/sha1'
|
3
|
+
|
4
|
+
class AprovaFacilTest < TestHelper
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@aprova_facil = AprovaFacil.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_aprovar
|
11
|
+
resultado = nil
|
12
|
+
3.times.each do
|
13
|
+
resultado = @aprova_facil.aprovar cartao
|
14
|
+
break if resultado[:aprovada]
|
15
|
+
end
|
16
|
+
|
17
|
+
assert_equal true, resultado[:aprovada]
|
18
|
+
assert_not_nil resultado[:resultado]
|
19
|
+
assert_not_nil resultado[:codigo_autorizacao]
|
20
|
+
assert_not_nil resultado[:transacao]
|
21
|
+
assert_equal @cartao_mascarado, resultado[:cartao_mascarado]
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_aprovar_cartao_invalido
|
25
|
+
cartao_invalido = cartao('502')
|
26
|
+
resultado = nil
|
27
|
+
3.times.each do
|
28
|
+
resultado = @aprova_facil.aprovar cartao_invalido
|
29
|
+
break if !resultado[:aprovada]
|
30
|
+
end
|
31
|
+
|
32
|
+
assert_equal false, resultado[:aprovada]
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_recobrar
|
36
|
+
resultado = nil
|
37
|
+
3.times.each do
|
38
|
+
resultado = @aprova_facil.aprovar cartao
|
39
|
+
break if resultado[:aprovada]
|
40
|
+
end
|
41
|
+
assert_equal true, resultado[:aprovada]
|
42
|
+
|
43
|
+
resultado = @aprova_facil.capturar resultado[:transacao]
|
44
|
+
assert_equal true, resultado[:capturado]
|
45
|
+
|
46
|
+
3.times.each do
|
47
|
+
resultado = @aprova_facil.recobrar resultado[:transacao], 25.00
|
48
|
+
break if resultado[:aprovada]
|
49
|
+
end
|
50
|
+
|
51
|
+
assert_equal true, resultado[:aprovada]
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_recobrar_transacao_invalida
|
55
|
+
resultado = @aprova_facil.recobrar '123123', 25.00
|
56
|
+
|
57
|
+
assert_equal false, resultado[:aprovada]
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_capturar
|
61
|
+
resultado = @aprova_facil.capturar '123123123123'
|
62
|
+
|
63
|
+
assert_equal true, resultado[:capturado]
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_cancelar
|
67
|
+
resultado = @aprova_facil.cancelar '123123123123'
|
68
|
+
|
69
|
+
assert_equal true, resultado[:cancelado]
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_get_url
|
73
|
+
metodo = AprovaFacil::COMPRAR
|
74
|
+
expected_url = AprovaFacil::URL_TEST.clone
|
75
|
+
expected_url << AprovaFacil::Config.usuario + '/'
|
76
|
+
|
77
|
+
url = @aprova_facil.send(:url, metodo)
|
78
|
+
assert_equal url, expected_url + metodo
|
79
|
+
|
80
|
+
metodo = AprovaFacil::CAPTURAR
|
81
|
+
url = @aprova_facil.send(:url, metodo)
|
82
|
+
assert_equal url, expected_url + metodo
|
83
|
+
|
84
|
+
metodo = AprovaFacil::CANCELAR
|
85
|
+
url = @aprova_facil.send(:url, metodo)
|
86
|
+
assert_equal url, expected_url + metodo
|
87
|
+
end
|
88
|
+
|
89
|
+
private
|
90
|
+
def cartao(codigo_seguranca = '123')
|
91
|
+
numero_cartao = '4073020000000002'
|
92
|
+
@cartao_mascarado = mascara_cartao(numero_cartao.clone)
|
93
|
+
AprovaFacil::CartaoCredito.new(
|
94
|
+
:valor => 25.00,
|
95
|
+
:numero_cartao => numero_cartao,
|
96
|
+
:codigo_seguranca => codigo_seguranca,
|
97
|
+
:mes_validade => '10',
|
98
|
+
:ano_validade => '14',
|
99
|
+
:ip_comprador => '192.168.1.1',
|
100
|
+
:nome_portador => 'Bruno Frank Silva Cordeiro'
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
def mascara_cartao(cartao)
|
105
|
+
cartao[6] = '*'
|
106
|
+
cartao[7] = '*'
|
107
|
+
cartao[8] = '*'
|
108
|
+
cartao[9] = '*'
|
109
|
+
cartao[10] = '*'
|
110
|
+
cartao[11] = '*'
|
111
|
+
cartao
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CartaoCreditoTest < TestHelper
|
4
|
+
|
5
|
+
def setup
|
6
|
+
@cartao = AprovaFacil::CartaoCredito.new(
|
7
|
+
:valor => 25.00,
|
8
|
+
:numero_cartao => '4073020000000002',
|
9
|
+
:codigo_seguranca => '123',
|
10
|
+
:mes_validade => '10',
|
11
|
+
:ano_validade => '14',
|
12
|
+
:ip_comprador => '192.168.1.1',
|
13
|
+
:nome_portador => 'Bruno Frank Silva'
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_order_create
|
18
|
+
assert_not_nil @cartao
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_validations
|
22
|
+
assert @cartao.valid?
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_validation_valor
|
26
|
+
cartao = @cartao.clone
|
27
|
+
|
28
|
+
cartao.valor = 0
|
29
|
+
assert_equal false, cartao.valid?
|
30
|
+
|
31
|
+
cartao.valor = nil
|
32
|
+
assert_equal false, cartao.valid?
|
33
|
+
|
34
|
+
cartao.valor = 25.00
|
35
|
+
assert cartao.valid?
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_validation_parcelas
|
39
|
+
cartao = @cartao.clone
|
40
|
+
|
41
|
+
cartao.parcelas = nil
|
42
|
+
assert_equal false, cartao.valid?
|
43
|
+
|
44
|
+
cartao.parcelas = 0
|
45
|
+
assert_equal false, cartao.valid?
|
46
|
+
|
47
|
+
cartao.parcelas = 1
|
48
|
+
assert cartao.valid?
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_validation_numero_cartao
|
52
|
+
cartao = @cartao.clone
|
53
|
+
|
54
|
+
cartao.numero_cartao = nil
|
55
|
+
assert_equal false, cartao.valid?
|
56
|
+
|
57
|
+
# Numero Cartão em branco
|
58
|
+
cartao.numero_cartao = ''
|
59
|
+
assert_equal false, cartao.valid?
|
60
|
+
|
61
|
+
cartao.numero_cartao = '4073020000000002'
|
62
|
+
assert cartao.valid?
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_validation_mes_validade
|
66
|
+
cartao = @cartao.clone
|
67
|
+
|
68
|
+
cartao.mes_validade = nil
|
69
|
+
assert_equal false, cartao.valid?
|
70
|
+
|
71
|
+
cartao.mes_validade = '1'
|
72
|
+
assert_equal false, cartao.valid?
|
73
|
+
|
74
|
+
cartao.mes_validade = '123'
|
75
|
+
assert_equal false, cartao.valid?
|
76
|
+
|
77
|
+
cartao.mes_validade = 'aa'
|
78
|
+
assert_equal false, cartao.valid?
|
79
|
+
|
80
|
+
cartao.mes_validade = '10'
|
81
|
+
assert cartao.valid?
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_validation_ano_validade
|
85
|
+
cartao = @cartao.clone
|
86
|
+
|
87
|
+
cartao.ano_validade = nil
|
88
|
+
assert_equal false, cartao.valid?
|
89
|
+
|
90
|
+
cartao.ano_validade = '1'
|
91
|
+
assert_equal false, cartao.valid?
|
92
|
+
|
93
|
+
cartao.ano_validade = '123'
|
94
|
+
assert_equal false, cartao.valid?
|
95
|
+
|
96
|
+
cartao.ano_validade = 'aa'
|
97
|
+
assert_equal false, cartao.valid?
|
98
|
+
|
99
|
+
cartao.ano_validade = '14'
|
100
|
+
assert cartao.valid?
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_validation_codigo_seguranca
|
104
|
+
cartao = @cartao.clone
|
105
|
+
|
106
|
+
cartao.codigo_seguranca = nil
|
107
|
+
assert_equal false, cartao.valid?
|
108
|
+
|
109
|
+
cartao.codigo_seguranca = 'aaa'
|
110
|
+
assert_equal false, cartao.valid?
|
111
|
+
|
112
|
+
cartao.codigo_seguranca = '123'
|
113
|
+
assert cartao.valid?
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_validation_ip_comprador
|
117
|
+
cartao = @cartao.clone
|
118
|
+
|
119
|
+
cartao.ip_comprador = nil
|
120
|
+
assert_equal false, cartao.valid?
|
121
|
+
|
122
|
+
cartao.ip_comprador = '123'
|
123
|
+
assert_equal false, cartao.valid?
|
124
|
+
|
125
|
+
cartao.ip_comprador = '192.168.1.1'
|
126
|
+
assert cartao.valid?
|
127
|
+
end
|
128
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aprova_facil
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 1.0.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Bruno Frank
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-07-16 00:00:00 -03:00
|
14
|
+
default_executable:
|
15
|
+
dependencies: []
|
16
|
+
|
17
|
+
description: "Gem para integra\xC3\xA7\xC3\xA3o de aplica\xC3\xA7\xC3\xA3o Ruby com o gateway de pagamento Aprova F\xC3\xA1cil da Cobre Bem."
|
18
|
+
email:
|
19
|
+
- bfscordeiro@gmail.com
|
20
|
+
executables: []
|
21
|
+
|
22
|
+
extensions: []
|
23
|
+
|
24
|
+
extra_rdoc_files: []
|
25
|
+
|
26
|
+
files:
|
27
|
+
- .gitignore
|
28
|
+
- Gemfile
|
29
|
+
- MIT-LICENSE
|
30
|
+
- README.markdown
|
31
|
+
- Rakefile
|
32
|
+
- aprova_facil.gemspec
|
33
|
+
- lib/aprova_facil.rb
|
34
|
+
- lib/aprova_facil/aprova_facil.rb
|
35
|
+
- lib/aprova_facil/cartao_credito.rb
|
36
|
+
- lib/aprova_facil/version.rb
|
37
|
+
- test/aprova_facil_test.rb
|
38
|
+
- test/cartao_credito_test.rb
|
39
|
+
- test/test_helper.rb
|
40
|
+
has_rdoc: true
|
41
|
+
homepage: https://github.com/brunofrank/aprova_facil
|
42
|
+
licenses: []
|
43
|
+
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
|
47
|
+
require_paths:
|
48
|
+
- lib
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: "0"
|
61
|
+
requirements: []
|
62
|
+
|
63
|
+
rubyforge_project: aprova_facil
|
64
|
+
rubygems_version: 1.6.2
|
65
|
+
signing_key:
|
66
|
+
specification_version: 3
|
67
|
+
summary: "Gem para integra\xC3\xA7\xC3\xA3o de aplica\xC3\xA7\xC3\xA3o Ruby com o gateway de pagamento Aprova F\xC3\xA1cil da Cobre Bem."
|
68
|
+
test_files:
|
69
|
+
- test/aprova_facil_test.rb
|
70
|
+
- test/cartao_credito_test.rb
|
71
|
+
- test/test_helper.rb
|