moip 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # A sample Gemfile
2
+ source "http://rubygems.org"
3
+
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ moip (1.0.1)
5
+ activesupport (>= 2.3.2)
6
+ httparty (~> 0.6.1)
7
+ nokogiri (~> 1.4.3)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ activesupport (3.0.1)
13
+ crack (0.1.8)
14
+ diff-lcs (1.1.2)
15
+ httparty (0.6.1)
16
+ crack (= 0.1.8)
17
+ nokogiri (1.4.3.1)
18
+ rspec (2.1.0)
19
+ rspec-core (~> 2.1.0)
20
+ rspec-expectations (~> 2.1.0)
21
+ rspec-mocks (~> 2.1.0)
22
+ rspec-core (2.1.0)
23
+ rspec-expectations (2.1.0)
24
+ diff-lcs (~> 1.1.2)
25
+ rspec-mocks (2.1.0)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ activesupport (>= 2.3.2)
32
+ httparty (~> 0.6.1)
33
+ moip!
34
+ nokogiri (~> 1.4.3)
35
+ rspec (~> 2.1.0)
data/LICENSE CHANGED
File without changes
data/README.markdown CHANGED
@@ -7,7 +7,7 @@ Esta Gem permite utilizar a API do MoIP, gateway de pagamentos do IG.
7
7
  O Pagamento Direto é um recurso que a MoIP disponibiliza para aqueles clientes que necessitam de uma flexibilidade maior do que a Integração HTML pode oferecer.
8
8
 
9
9
  Diferentemente de como é feito com a Integração HTML, seu cliente não precisa ser redirecionado para o site da MoIP para concluir a compra: tudo é feito dentro do ambiente do seu site, dando ao cliente uma maior segurança e confiança no processo.
10
-
10
+
11
11
  As formas de pagamento disponibilizadas pela Gem são:
12
12
 
13
13
  * Boleto
@@ -17,63 +17,70 @@ As formas de pagamento disponibilizadas pela Gem são:
17
17
  ## Instalação
18
18
 
19
19
  Instale a Gem
20
- gem install moip
20
+ gem install moip
21
21
 
22
22
  Adicione a Gem ao Gemfile
23
- gem "moip"
23
+ gem "moip"
24
24
 
25
25
  ## Utilização
26
26
 
27
- O MoIP possui uma SandBox de testes que permite a simulação de pagamentos. Para utilizar a Gem com o SandBox, crie o arquivo moip.yml na pasta Rails.root/config e adicione o token e chave do MoIP.
28
-
29
- ## moip.yml
27
+ O MoIP possui uma SandBox de testes que permite a simulação de pagamentos. Para utilizar a Gem com o SandBox, adicione a seguinte configuração no arquivo do environment que deseja utilizar.
30
28
 
31
- development:
32
- uri: https://desenvolvedor.moip.com.br/sandbox
33
- token: SEU_TOKEN
34
- key: SUA_KEY
29
+ ### config/environments/development.rb
35
30
 
36
- production:
37
- uri:
38
- token:
39
- key:
31
+ MoIP.setup do |config|
32
+ config.uri = https://desenvolvedor.moip.com.br/sandbox
33
+ config.token = SEU_TOKEN
34
+ config.key = SUA_KEY
35
+ end
40
36
 
41
- Após realizar os testes na SandBox, você poderá fazer a mudança para o ambiente de produção do MoIP de maneira simples. Basta inserir o token e chave de produção no arquivo moip.yml.
37
+ Após realizar os testes na SandBox, você poderá fazer a mudança para o ambiente de produção do MoIP de maneira simples. Basta inserir no arquivo de environment de produção o token e chave que serão utilizados. Por padrão a gem já utiliza a URI de produção do MoIP.
42
38
 
43
39
  ###Crie os dados do pagador
44
40
 
45
- pagador = { :nome => "Luiz Inácio Lula da Silva",
46
- :login_moip => "lula",
47
- :email => "presidente@planalto.gov.br",
48
- :tel_cel => "(61)9999-9999",
49
- :apelido => "Lula",
50
- :identidade => "111.111.111-11",
51
- :logradouro => "Praça dos Três Poderes",
52
- :numero => "0",
53
- :complemento => "Palácio do Planalto",
54
- :bairro => "Zona Cívico-Administrativa",
55
- :cidade => "Brasília",
56
- :estado => "DF",
57
- :pais => "BRA",
58
- :cep => "70100-000",
59
- :tel_fixo => "(61)3211-1221" }
41
+ pagador = { :nome => "Luiz Inácio Lula da Silva",
42
+ :login_moip => "lula",
43
+ :email => "presidente@planalto.gov.br",
44
+ :tel_cel => "(61)9999-9999",
45
+ :apelido => "Lula",
46
+ :identidade => "111.111.111-11",
47
+ :logradouro => "Praça dos Três Poderes",
48
+ :numero => "0",
49
+ :complemento => "Palácio do Planalto",
50
+ :bairro => "Zona Cívico-Administrativa",
51
+ :cidade => "Brasília",
52
+ :estado => "DF",
53
+ :pais => "BRA",
54
+ :cep => "70100-000",
55
+ :tel_fixo => "(61)3211-1221" }
60
56
 
61
57
  ###Dados do boleto
62
58
 
63
- boleto = { :valor => "50",
64
- :id_proprio => "Pag#{rand(1000)}",
65
- :forma => "BoletoBancario",
66
- :dias_expiracao => 5,
67
- :pagador => pagador }
59
+ boleto = { :valor => "50",
60
+ :id_proprio => "Pag#{rand(1000)}",
61
+ :forma => "BoletoBancario",
62
+ :dias_expiracao => 5,
63
+ :pagador => pagador }
68
64
 
69
65
  ###Checkout
70
66
 
71
- def checkout
72
- response = MoIP.checkout(boleto)
67
+ def checkout
68
+ response = MoIP::Client.checkout(boleto)
69
+
70
+ # exibe o boleto para impressão
71
+ redirect_to MoIP::Client.moip_page(response["Token"])
72
+ end
73
+
74
+ ###Erros
75
+
76
+ - MoIP::MissingPaymentTypeError - Quando falta a razão do pagamento na requisição.
77
+ - MoIP::MissingPayerError - Quando falta as informações do pagador na requisição.
78
+ - MoIP::WebServerResponseError - Quando há algum erro ao se enviar a solicitação ao servidor. Normalmente a razão do erro vem como resposta da mensagem.
79
+
80
+ ## Futuras implementações
73
81
 
74
- # exibe o boleto para impressão
75
- redirect_to MoIP.moip_page(response["Token"])
76
- end
82
+ * Pagamento Simples
83
+ * Pagamento Recorrente
77
84
 
78
85
 
79
- Baseado no projeto do [Daniel Lopes](http://github.com/danielvlopes/moip_usage).
86
+ Baseado no projeto do [Daniel Lopes](http://github.com/danielvlopes/moip_usage).
data/Rakefile CHANGED
@@ -1,46 +1,30 @@
1
+ # coding: utf-8
1
2
  require 'rubygems'
2
3
  require 'rake'
3
4
 
5
+ require 'rspec/core/rake_task'
6
+
4
7
  begin
5
8
  require 'jeweler'
6
9
  Jeweler::Tasks.new do |gem|
7
10
  gem.name = "moip"
8
- gem.summary = %Q{Gem para utilização da API MoIP}
9
- gem.description = %Q{Gem para utilização da API MoIP}
11
+ gem.summary = "Gem para utilização da API MoIP"
12
+ gem.description = "Gem para utilização da API MoIP"
10
13
  gem.email = "guilherme.ruby@gmail.com"
11
14
  gem.homepage = "http://github.com/guinascimento/moip"
12
15
  gem.authors = ["Guilherme Nascimento"]
13
- # gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ gem.add_development_dependency "rspec", "~> 2.1.0"
17
+ gem.add_dependency "nokogiri", "~> 1.4.3"
18
+ gem.add_dependency "httparty", "~> 0.8.1"
19
+ gem.add_dependency "activesupport", '>= 2.3.2'
15
20
  end
16
21
  Jeweler::GemcutterTasks.new
17
22
  rescue LoadError
18
23
  puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
24
  end
20
25
 
21
- require 'rake/testtask'
22
- Rake::TestTask.new(:test) do |test|
23
- test.libs << 'lib' << 'test'
24
- test.pattern = 'test/**/test_*.rb'
25
- test.verbose = true
26
- end
27
-
28
- begin
29
- require 'rcov/rcovtask'
30
- Rcov::RcovTask.new do |test|
31
- test.libs << 'test'
32
- test.pattern = 'test/**/test_*.rb'
33
- test.verbose = true
34
- end
35
- rescue LoadError
36
- task :rcov do
37
- abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
- end
39
- end
40
-
41
- task :test => :check_dependencies
42
-
43
- task :default => :test
26
+ task :default => :spec
27
+ RSpec::Core::RakeTask.new
44
28
 
45
29
  require 'rake/rdoctask'
46
30
  Rake::RDocTask.new do |rdoc|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.1
1
+ 1.0.2
data/lib/moip.rb CHANGED
@@ -1,61 +1,47 @@
1
+ # encoding: utf-8
1
2
  require "rubygems"
2
- require 'httparty'
3
- require "nokogiri"
4
-
5
- require "direct_payment"
3
+ require 'active_support/core_ext/module/attribute_accessors'
4
+ require 'active_support/deprecation'
6
5
 
7
6
  module MoIP
8
- include HTTParty
9
-
10
- CONFIG = YAML.load_file("config/moip.yml")["development"]
11
- STATUS = { 1 => "authorized", 2 => "started", 3 => "printed", 4 => "completed", 5 => "canceled", 6 => "analysing"}
12
-
13
- base_uri "#{CONFIG["uri"]}/ws/alpha"
14
- basic_auth CONFIG["token"], CONFIG["key"]
15
-
16
- class << self
17
-
18
- # Envia uma instrução para pagamento único
19
- def checkout(attributes = {})
20
- full_data = post('EnviarInstrucao/Unica', :body => DirectPayment.direct(attributes))
7
+ autoload :DirectPayment, 'moip/direct_payment'
8
+ autoload :Client, 'moip/client'
21
9
 
22
- raise(StandardError, "Ocorreu um erro ao chamar o webservice") if full_data.nil?
10
+ # URI para acessar o serviço
11
+ mattr_accessor :uri
12
+ @@uri = 'https://www.moip.com.br'
23
13
 
24
- response = full_data["ns1:EnviarInstrucaoUnicaResponse"]["Resposta"]
25
- raise(StandardError, response["Erro"]) if response["Status"] == "Falha"
14
+ # Token de autenticação
15
+ mattr_accessor :token
26
16
 
27
- return response
28
- end
17
+ # Chave de acesso ao serviço
18
+ mattr_accessor :key
29
19
 
30
- # Consulta dos dados das autorizações e pagamentos associados à Instrução
31
- def query(token)
32
- full_data = get("ConsultarInstrucao/#{token}")
33
- raise(StandardError, "Ocorreu um erro ao chamar o webservice") if full_data.nil?
20
+ def self.setup
21
+ yield self
22
+ end
34
23
 
35
- response = full_data["ns1:ConsultarTokenResponse"]["RespostaConsultar"]
36
- raise(StandardError, response["Erro"]) if response["Status"] == "Falha"
24
+ STATUS = {1 => "authorized", 2 => "started", 3 => "printed", 4 => "completed", 5 => "canceled", 6 => "analysing"}
37
25
 
38
- return response
39
- end
40
-
41
- # Retorna a URL de acesso ao MoIP
42
- def moip_page(token)
43
- raise(StandardError, "É necessário informar um token para retornar os dados da transação") if token.nil?
44
- "#{CONFIG["uri"]}/Instrucao.do?token=#{token}"
45
- end
26
+ class << self
27
+ def checkout(attributes = {})
28
+ ActiveSupport::Deprecation.warn("MoIP.checkout has been deprecated. Use MoIP::Client.checkout instead", caller)
29
+ MoIP::Client.checkout(attributes)
30
+ end
46
31
 
47
- # Monta o NASP
48
- def notification(params)
49
- notification = {}
50
- notification[:transaction_id] = params["id_transacao"]
51
- notification[:amount] = sprintf("%.2f", params["valor"].to_f / 100).to_d
52
- notification[:status] = STATUS[params["status_pagamento"].to_i]
53
- notification[:code] = params["cod_moip"]
54
- notification[:payment_type] = params["tipo_pagamento"]
55
- notification[:email] = params["email_consumidor"]
56
- notification
57
- end
32
+ def query(token)
33
+ ActiveSupport::Deprecation.warn("MoIP.query has been deprecated. Use MoIP::Client.query instead", caller)
34
+ MoIP::Client.query(token)
35
+ end
58
36
 
37
+ def moip_page(token)
38
+ ActiveSupport::Deprecation.warn("MoIP.moip_page has been deprecated. use MoIP::Client.moip_page instead", caller)
39
+ MoIP::Client.moip_page(token)
59
40
  end
60
41
 
61
- end
42
+ def notification(params)
43
+ ActiveSupport::Deprecation.warn("MoIP.notification has been deprecated. use MoIP::Client.notification instead", caller)
44
+ MoIP::Client.moip_page(token)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,62 @@
1
+ # encoding: utf-8
2
+ require 'httparty'
3
+
4
+ module MoIP
5
+ class WebServerResponseError < StandardError ; end
6
+ class MissingTokenError < StandardError ; end
7
+
8
+ class Client
9
+ include HTTParty
10
+
11
+ base_uri "#{MoIP.uri}/ws/alpha"
12
+ basic_auth MoIP.token, MoIP.key
13
+
14
+ class << self
15
+
16
+ # Envia uma instrução para pagamento único
17
+ def checkout(attributes = {})
18
+ full_data = peform_action!(:post, 'EnviarInstrucao/Unica', :body => DirectPayment.body(attributes))
19
+
20
+ get_response!(full_data["ns1:EnviarInstrucaoUnicaResponse"]["Resposta"])
21
+ end
22
+
23
+ # Consulta dos dados das autorizações e pagamentos associados à Instrução
24
+ def query(token)
25
+ full_data = peform_action!(:get, "ConsultarInstrucao/#{token}")
26
+
27
+ get_response!(full_data["ns1:ConsultarTokenResponse"]["RespostaConsultar"])
28
+ end
29
+
30
+ # Retorna a URL de acesso ao MoIP
31
+ def moip_page(token)
32
+ raise(MissingTokenError, "É necessário informar um token para retornar os dados da transação") if token.nil?
33
+ "#{MoIP.uri}/Instrucao.do?token=#{token}"
34
+ end
35
+
36
+ # Monta o NASP
37
+ def notification(params)
38
+ notification = {}
39
+ notification[:transaction_id] = params["id_transacao"]
40
+ notification[:amount] = params["valor"]
41
+ notification[:status] = MoIP::STATUS[params["status_pagamento"].to_i]
42
+ notification[:code] = params["cod_moip"]
43
+ notification[:payment_type] = params["tipo_pagamento"]
44
+ notification[:email] = params["email_consumidor"]
45
+ notification
46
+ end
47
+
48
+ private
49
+
50
+ def peform_action!(action_name, url, options = {})
51
+ response = self.send(action_name, url, options)
52
+ raise(WebServerResponseError, "Ocorreu um erro ao chamar o webservice") if response.nil?
53
+ response
54
+ end
55
+
56
+ def get_response!(data)
57
+ raise(WebServerResponseError, data["Erro"]) if data["Status"] == "Falha"
58
+ data
59
+ end
60
+ end
61
+ end
62
+ end
@@ -1,19 +1,29 @@
1
+ # encoding: utf-8
2
+ require "nokogiri"
3
+
1
4
  module MoIP
2
5
 
6
+ class MissingPaymentTypeError < StandardError ; end
7
+ class MissingPayerError < StandardError ; end
8
+
3
9
  class DirectPayment
4
10
 
5
11
  class << self
6
12
 
7
13
  # Cria uma instrução de pagamento direto
8
- def direct(attributes = {})
14
+ def body(attributes = {})
15
+ raise(MissinPaymentTypeError, "É necessário informar a razão do pagamento") if attributes[:razao].nil?
16
+ raise(MissingPayerError, "É obrigatório passar as informações do pagador") if attributes[:pagador].nil?
17
+
9
18
  builder = Nokogiri::XML::Builder.new(:encoding => "UTF-8") do |xml|
10
19
 
11
20
  # Identificador do tipo de instrução
12
21
  xml.EnviarInstrucao {
13
22
  xml.InstrucaoUnica {
23
+
14
24
  # Dados da transação
15
25
  xml.Razao {
16
- xml.text "Pagamento"
26
+ xml.text attributes[:razao]
17
27
  }
18
28
  xml.Valores {
19
29
  xml.Valor(:moeda => "BRL") {
@@ -42,7 +52,6 @@ module MoIP
42
52
  xml.Instituicao {
43
53
  xml.text attributes[:instituicao]
44
54
  }
45
-
46
55
  xml.CartaoCredito {
47
56
  xml.Numero {
48
57
  xml.text attributes[:numero]
@@ -80,7 +89,6 @@ module MoIP
80
89
  }
81
90
 
82
91
  # Dados do pagador
83
- raise(StandardError, "É obrigatório passar as informações do pagador") if attributes[:pagador].nil?
84
92
  xml.Pagador {
85
93
  xml.Nome { xml.text attributes[:pagador][:nome] }
86
94
  xml.LoginMoIP { xml.text attributes[:pagador][:login_moip] }
@@ -116,15 +124,23 @@ module MoIP
116
124
  }
117
125
  }
118
126
  end
119
-
127
+
128
+ if attributes[:url_retorno]
129
+ # URL de retorno
130
+ xml.URLRetorno {
131
+ xml.text attributes[:url_retorno]
132
+ }
133
+ end
134
+
120
135
  }
121
136
  }
122
137
  end
138
+
123
139
  builder.to_xml
124
140
  end
125
141
 
126
142
  end
127
143
 
128
144
  end
129
-
130
- end
145
+
146
+ end
data/moip.gemspec CHANGED
@@ -1,51 +1,66 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{moip}
8
- s.version = "1.0.1"
8
+ s.version = "1.0.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Guilherme Nascimento"]
12
- s.date = %q{2010-11-02}
12
+ s.date = %q{2012-04-29}
13
13
  s.description = %q{Gem para utilização da API MoIP}
14
14
  s.email = %q{guilherme.ruby@gmail.com}
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
- "README.markdown"
17
+ "README.markdown"
18
18
  ]
19
19
  s.files = [
20
20
  ".document",
21
- ".gitignore",
22
- "LICENSE",
23
- "README.markdown",
24
- "Rakefile",
25
- "VERSION",
26
- "lib/direct_payment.rb",
27
- "lib/moip.rb",
28
- "moip.gemspec",
29
- "spec/lib/config.yaml",
30
- "spec/lib/moip_spec.rb"
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "LICENSE",
24
+ "README.markdown",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "lib/moip.rb",
28
+ "lib/moip/client.rb",
29
+ "lib/moip/direct_payment.rb",
30
+ "moip.gemspec",
31
+ "spec/moip_spec.rb"
31
32
  ]
32
33
  s.homepage = %q{http://github.com/guinascimento/moip}
33
- s.rdoc_options = ["--charset=UTF-8"]
34
34
  s.require_paths = ["lib"]
35
- s.rubygems_version = %q{1.3.7}
35
+ s.rubygems_version = %q{1.3.6}
36
36
  s.summary = %q{Gem para utilização da API MoIP}
37
- s.test_files = [
38
- "spec/lib/moip_spec.rb"
39
- ]
40
37
 
41
38
  if s.respond_to? :specification_version then
42
39
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
43
40
  s.specification_version = 3
44
41
 
45
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
42
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
43
+ s.add_runtime_dependency(%q<moip>, [">= 0"])
44
+ s.add_development_dependency(%q<rspec>, ["~> 2.1.0"])
45
+ s.add_development_dependency(%q<rspec>, ["~> 2.1.0"])
46
+ s.add_runtime_dependency(%q<nokogiri>, ["~> 1.4.3"])
47
+ s.add_runtime_dependency(%q<httparty>, ["~> 0.8.1"])
48
+ s.add_runtime_dependency(%q<activesupport>, [">= 2.3.2"])
46
49
  else
50
+ s.add_dependency(%q<moip>, [">= 0"])
51
+ s.add_dependency(%q<rspec>, ["~> 2.1.0"])
52
+ s.add_dependency(%q<rspec>, ["~> 2.1.0"])
53
+ s.add_dependency(%q<nokogiri>, ["~> 1.4.3"])
54
+ s.add_dependency(%q<httparty>, ["~> 0.8.1"])
55
+ s.add_dependency(%q<activesupport>, [">= 2.3.2"])
47
56
  end
48
57
  else
58
+ s.add_dependency(%q<moip>, [">= 0"])
59
+ s.add_dependency(%q<rspec>, ["~> 2.1.0"])
60
+ s.add_dependency(%q<rspec>, ["~> 2.1.0"])
61
+ s.add_dependency(%q<nokogiri>, ["~> 1.4.3"])
62
+ s.add_dependency(%q<httparty>, ["~> 0.8.1"])
63
+ s.add_dependency(%q<activesupport>, [">= 2.3.2"])
49
64
  end
50
65
  end
51
66
 
data/spec/moip_spec.rb ADDED
@@ -0,0 +1,289 @@
1
+ # encoding: utf-8
2
+ require "moip"
3
+
4
+ require "digest/sha1"
5
+
6
+ describe "Make payments with the MoIP API" do
7
+
8
+ before :all do
9
+ MoIP.setup do |config|
10
+ config.uri = 'https://desenvolvedor.moip.com.br/sandbox'
11
+ config.token = 'token'
12
+ config.key = 'key'
13
+ end
14
+
15
+ @pagador = { :nome => "Luiz Inácio Lula da Silva",
16
+ :login_moip => "lula",
17
+ :email => "presidente@planalto.gov.br",
18
+ :tel_cel => "(61)9999-9999",
19
+ :apelido => "Lula",
20
+ :identidade => "111.111.111-11",
21
+ :logradouro => "Praça dos Três Poderes",
22
+ :numero => "0",
23
+ :complemento => "Palácio do Planalto",
24
+ :bairro => "Zona Cívico-Administrativa",
25
+ :cidade => "Brasília",
26
+ :estado => "DF",
27
+ :pais => "BRA",
28
+ :cep => "70100-000",
29
+ :tel_fixo => "(61)3211-1221" }
30
+
31
+ @billet_without_razao = { :value => "8.90", :id_proprio => id,
32
+ :forma => "BoletoBancario", :pagador => @pagador}
33
+ @billet = { :value => "8.90", :id_proprio => id,
34
+ :forma => "BoletoBancario", :pagador => @pagador ,
35
+ :razao=> "Pagamento" }
36
+
37
+ @debit = { :value => "8.90", :id_proprio => id, :forma => "DebitoBancario",
38
+ :instituicao => "BancoDoBrasil", :pagador => @pagador,
39
+ :razao => "Pagamento"}
40
+
41
+ @credit = { :value => "8.90", :id_proprio => id, :forma => "CartaoCredito",
42
+ :instituicao => "AmericanExpress",:numero => "345678901234564",
43
+ :expiracao => "08/11", :codigo_seguranca => "1234",
44
+ :nome => "João Silva", :identidade => "134.277.017.00",
45
+ :telefone => "(21)9208-0547", :data_nascimento => "25/10/1980",
46
+ :parcelas => "2", :recebimento => "AVista",
47
+ :pagador => @pagador, :razao => "Pagamento"}
48
+ end
49
+
50
+ context "checkout" do
51
+ before(:each) do
52
+ MoIP::Client.stub!(:post).
53
+ and_return("ns1:EnviarInstrucaoUnicaResponse"=>
54
+ { "Resposta"=>
55
+ { "ID"=>Time.now.strftime("%y%m%d%H%M%S"),
56
+ "Status"=>"Sucesso",
57
+ "Token" => "T2N0L0X8E0S71217U2H3W1T4F4S4G4K731D010V0S0V0S080M010E0Q082X2"
58
+ }
59
+ })
60
+ end
61
+
62
+ it "with old api should be deprecated" do
63
+ deprecations = collect_deprecations{ MoIP.checkout(@billet) }
64
+
65
+ deprecations.should_not be_empty
66
+ deprecations.any? {|w| w =~ /MoIP.checkout has been deprecated/ }.should be_true
67
+ end
68
+
69
+ context "when it is a billet checkout" do
70
+ it "should raise an exception when razao parameter is not passed" do
71
+ error = "É necessário informar a razão do pagamento"
72
+
73
+ lambda { MoIP::Client.checkout(@billet_without_razao) }.should
74
+ raise_error(MoIP::MissingPaymentTypeError,error)
75
+ end
76
+
77
+ it "should have status 'Sucesso'" do
78
+ response = MoIP::Client.checkout(@billet)
79
+ response["Status"].should == "Sucesso"
80
+ end
81
+ end
82
+
83
+ context "when it is a debit checkout" do
84
+ it "should have status 'Sucesso' with valid arguments" do
85
+ response = MoIP::Client.checkout(@debit)
86
+ response["Status"].should == "Sucesso"
87
+ end
88
+
89
+ it "should have status 'Falha' when a instituition is not passed as argument" do
90
+ @incorrect_debit = { :value => "37.90", :id_proprio => id,
91
+ :forma => "DebitoBancario", :pagador => @pagador,
92
+ :razao => "Pagamento"}
93
+
94
+ error = "Pagamento direto não é possível com a instituição de pagamento enviada"
95
+
96
+ MoIP::Client.stub!(:post)
97
+ .and_return("ns1:EnviarInstrucaoUnicaResponse"=>
98
+ { "Resposta"=>
99
+ {
100
+ "Status"=>"Falha",
101
+ "Erro"=>error
102
+ }
103
+ })
104
+ error = "Pagamento direto não é possível com a instituição de pagamento enviada"
105
+ lambda { MoIP::Client.checkout(@incorrect_debit) }.should
106
+ raise_error(MoIP::WebServerResponseError, error)
107
+ end
108
+
109
+ it "should raise an exception if payer informations were not passed" do
110
+ @incorrect_debit = { :value => "37.90", :id_proprio => id,
111
+ :forma => "DebitoBancario",
112
+ :instituicao => "BancoDoBrasil",
113
+ :razao => "Pagamento"
114
+ }
115
+
116
+ lambda { MoIP::Client.checkout(@incorrect_debit) }.should
117
+ raise_error(MoIP::MissingPayerError, "É obrigatório passar as informações do pagador")
118
+ end
119
+ end
120
+
121
+ context "when it is a credit card checkout" do
122
+ it "should have status 'Sucesso' with valid arguments" do
123
+ response = MoIP::Client.checkout(@credit)
124
+ response["Status"].should == "Sucesso"
125
+ end
126
+
127
+ it "should have status 'Falha' when the card informations were not passed as argument" do
128
+ @incorrect_credit = { :value => "8.90", :id_proprio => id,
129
+ :forma => "CartaoCredito", :pagador => @pagador,
130
+ :razao => "Pagamento"
131
+ }
132
+
133
+ error = "Pagamento direto não é possível com a instituição de pagamento enviada"
134
+ MoIP::Client.stub!(:post)
135
+ .and_return("ns1:EnviarInstrucaoUnicaResponse"=>
136
+ {
137
+ "Resposta"=>
138
+ {
139
+ "Status"=>"Falha",
140
+ "Erro"=>error
141
+ }
142
+ })
143
+
144
+ error = "Pagamento direto não é possível com a instituição de pagamento enviada"
145
+ lambda { MoIP::Client.checkout(@incorrect_credit) }.should
146
+ raise_error(MoIP::WebServerResponseError, error)
147
+ end
148
+ end
149
+
150
+ context "in error scenario" do
151
+ it "should raise an exception if response is nil" do
152
+ MoIP::Client.stub!(:post).and_return(nil)
153
+ lambda { MoIP::Client.checkout(@billet) }.should
154
+ raise_error(StandardError,"Ocorreu um erro ao chamar o webservice")
155
+ end
156
+
157
+ it "should raise an exception if status is fail" do
158
+ MoIP::Client.stub!(:post)
159
+ .and_return("ns1:EnviarInstrucaoUnicaResponse"=>
160
+ { "Resposta"=>
161
+ {"Status"=>"Falha",
162
+ "Erro"=>"O status da resposta é Falha"
163
+ }
164
+ })
165
+
166
+ lambda { MoIP::Client.checkout(@billet) }.should raise_error(StandardError, "O status da resposta é Falha")
167
+ end
168
+ end
169
+ end
170
+
171
+ context "query a transaction token" do
172
+ before(:each) do
173
+ MoIP::Client.stub!(:get)
174
+ .and_return("ns1:ConsultarTokenResponse"=>
175
+ { "RespostaConsultar"=>
176
+ {"Status"=>"Sucesso",
177
+ "ID"=>"201010291031001210000000046760"
178
+ }
179
+ })
180
+ end
181
+
182
+ it "with old api should be deprecated" do
183
+ deprecations = collect_deprecations{ MoIP.query(token) }
184
+
185
+ deprecations.should_not be_empty
186
+ deprecations.any? {|w| w =~ /MoIP.query has been deprecated/ }.should be_true
187
+ end
188
+
189
+ it "should retrieve the transaction" do
190
+ response = MoIP::Client.query(token)
191
+ response["Status"].should == "Sucesso"
192
+ end
193
+
194
+ context "in a error scenario" do
195
+ it "should retrieve status 'Falha'" do
196
+ MoIP::Client.stub!(:get)
197
+ .and_return("ns1:ConsultarTokenResponse"=>
198
+ { "RespostaConsultar"=>
199
+ {"Status"=>"Falha",
200
+ "Erro"=>"Instrução não encontrada",
201
+ "ID"=>"201010291102522860000000046768"
202
+ }
203
+ })
204
+ query = "000000000000000000000000000000000000000000000000000000000000"
205
+ lambda { MoIP::Client.query(query) }.should raise_error(StandardError, "Instrução não encontrada")
206
+ end
207
+ end
208
+ end
209
+
210
+ context "build the MoIP URL" do
211
+ it "with old api should be deprecated" do
212
+ deprecations = collect_deprecations{ MoIP.moip_page(token) }
213
+
214
+ deprecations.should_not be_empty
215
+ deprecations.any? {|w| w =~ /MoIP.moip_page has been deprecated/ }.should be_true
216
+ end
217
+
218
+ it "should build the correct URL" do
219
+ page = "https://desenvolvedor.moip.com.br/sandbox/Instrucao.do?token=#{token}"
220
+ MoIP::Client.moip_page(token).should == page
221
+ end
222
+
223
+ it "should raise an error if the token is not informed" do
224
+ error = "É necessário informar um token para retornar os dados da transação"
225
+ lambda { MoIP::Client.moip_page("").should
226
+ raise_error(ArgumentError, error) }
227
+ end
228
+
229
+ it "should raise an error if nil is passed as the token" do
230
+ error = "É necessário informar um token para retornar os dados da transação"
231
+ lambda { MoIP::Client.moip_page(nil).should
232
+ raise_error(ArgumentError, error) }
233
+ end
234
+ end
235
+
236
+ context "when receive notification" do
237
+ before(:each) do
238
+ @params = { "id_transacao" => "Pag62", "valor" => "8.90",
239
+ "status_pagamento" => "3", "cod_moip" => "001",
240
+ "forma_pagamento" => "73", "tipo_pagamento" => "BoletoBancario",
241
+ "email_consumidor" => "presidente@planalto.gov.br" }
242
+ end
243
+
244
+ it "with old api should be deprecated" do
245
+ deprecations = collect_deprecations{ MoIP.notification(@param) }
246
+
247
+ deprecations.should_not be_empty
248
+ deprecations.any? {|w| w =~ /MoIP.notification has been deprecated/ }.should be_true
249
+ end
250
+
251
+ it "should return a hash with the params extracted from NASP" do
252
+ response = { :transaction_id => "Pag62", :amount => "8.90",
253
+ :status => "printed", :code => "001",
254
+ :payment_type => "BoletoBancario",
255
+ :email => "presidente@planalto.gov.br" }
256
+
257
+ MoIP::Client.notification(@params).should == response
258
+ end
259
+
260
+ it "should return valid status based on status code" do
261
+ MoIP::STATUS[1].should == "authorized"
262
+ MoIP::STATUS[2].should == "started"
263
+ MoIP::STATUS[3].should == "printed"
264
+ MoIP::STATUS[4].should == "completed"
265
+ MoIP::STATUS[5].should == "canceled"
266
+ MoIP::STATUS[6].should == "analysing"
267
+ end
268
+ end
269
+
270
+ def id
271
+ "transaction_" + Digest::SHA1.hexdigest([Time.now, rand].join)
272
+ end
273
+
274
+ def token
275
+ "T2X0Q1N021E0B2S9U1P0V3Y0G1F570Y2P4M0P000M0Z0F0J0G0U4N6C7W5T9"
276
+ end
277
+
278
+ def collect_deprecations
279
+ old_behavior = ActiveSupport::Deprecation.behavior
280
+ deprecations = []
281
+ ActiveSupport::Deprecation.behavior = Proc.new do |message, callstack|
282
+ deprecations << message
283
+ end
284
+ result = yield
285
+ deprecations
286
+ ensure
287
+ ActiveSupport::Deprecation.behavior = old_behavior
288
+ end
289
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moip
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
5
4
  prerelease: false
6
5
  segments:
7
6
  - 1
8
7
  - 0
9
- - 1
10
- version: 1.0.1
8
+ - 2
9
+ segments_generated: true
10
+ version: 1.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Guilherme Nascimento
@@ -15,10 +15,97 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-02 00:00:00 -02:00
18
+ date: 2012-04-29 00:00:00 -03:00
19
19
  default_executable:
20
- dependencies: []
21
-
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ type: :runtime
24
+ name: moip
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ segments:
30
+ - 0
31
+ segments_generated: true
32
+ version: "0"
33
+ requirement: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ prerelease: false
36
+ type: :development
37
+ name: rspec
38
+ version_requirements: &id002 !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 2
44
+ - 1
45
+ - 0
46
+ segments_generated: true
47
+ version: 2.1.0
48
+ requirement: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ prerelease: false
51
+ type: :development
52
+ name: rspec
53
+ version_requirements: &id003 !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ~>
56
+ - !ruby/object:Gem::Version
57
+ segments:
58
+ - 2
59
+ - 1
60
+ - 0
61
+ segments_generated: true
62
+ version: 2.1.0
63
+ requirement: *id003
64
+ - !ruby/object:Gem::Dependency
65
+ prerelease: false
66
+ type: :runtime
67
+ name: nokogiri
68
+ version_requirements: &id004 !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ~>
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 1
74
+ - 4
75
+ - 3
76
+ segments_generated: true
77
+ version: 1.4.3
78
+ requirement: *id004
79
+ - !ruby/object:Gem::Dependency
80
+ prerelease: false
81
+ type: :runtime
82
+ name: httparty
83
+ version_requirements: &id005 !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ segments:
88
+ - 0
89
+ - 8
90
+ - 1
91
+ segments_generated: true
92
+ version: 0.8.1
93
+ requirement: *id005
94
+ - !ruby/object:Gem::Dependency
95
+ prerelease: false
96
+ type: :runtime
97
+ name: activesupport
98
+ version_requirements: &id006 !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ segments:
103
+ - 2
104
+ - 3
105
+ - 2
106
+ segments_generated: true
107
+ version: 2.3.2
108
+ requirement: *id006
22
109
  description: "Gem para utiliza\xC3\xA7\xC3\xA3o da API MoIP"
23
110
  email: guilherme.ruby@gmail.com
24
111
  executables: []
@@ -30,49 +117,48 @@ extra_rdoc_files:
30
117
  - README.markdown
31
118
  files:
32
119
  - .document
33
- - .gitignore
120
+ - Gemfile
121
+ - Gemfile.lock
34
122
  - LICENSE
35
123
  - README.markdown
36
124
  - Rakefile
37
125
  - VERSION
38
- - lib/direct_payment.rb
39
126
  - lib/moip.rb
127
+ - lib/moip/client.rb
128
+ - lib/moip/direct_payment.rb
40
129
  - moip.gemspec
41
- - spec/lib/config.yaml
42
- - spec/lib/moip_spec.rb
130
+ - spec/moip_spec.rb
43
131
  has_rdoc: true
44
132
  homepage: http://github.com/guinascimento/moip
45
133
  licenses: []
46
134
 
47
135
  post_install_message:
48
- rdoc_options:
49
- - --charset=UTF-8
136
+ rdoc_options: []
137
+
50
138
  require_paths:
51
139
  - lib
52
140
  required_ruby_version: !ruby/object:Gem::Requirement
53
- none: false
54
141
  requirements:
55
142
  - - ">="
56
143
  - !ruby/object:Gem::Version
57
- hash: 3
58
144
  segments:
59
145
  - 0
146
+ segments_generated: true
60
147
  version: "0"
61
148
  required_rubygems_version: !ruby/object:Gem::Requirement
62
- none: false
63
149
  requirements:
64
150
  - - ">="
65
151
  - !ruby/object:Gem::Version
66
- hash: 3
67
152
  segments:
68
153
  - 0
154
+ segments_generated: true
69
155
  version: "0"
70
156
  requirements: []
71
157
 
72
158
  rubyforge_project:
73
- rubygems_version: 1.3.7
159
+ rubygems_version: 1.3.6
74
160
  signing_key:
75
161
  specification_version: 3
76
162
  summary: "Gem para utiliza\xC3\xA7\xC3\xA3o da API MoIP"
77
- test_files:
78
- - spec/lib/moip_spec.rb
163
+ test_files: []
164
+
data/.gitignore DELETED
@@ -1,24 +0,0 @@
1
- ## MAC OS
2
- .DS_Store
3
-
4
- ## TEXTMATE
5
- *.tmproj
6
- tmtags
7
-
8
- ## EMACS
9
- *~
10
- \#*
11
- .\#*
12
-
13
- ## VIM
14
- *.swp
15
-
16
- ## PROJECT::GENERAL
17
- coverage
18
- rdoc
19
- pkg
20
-
21
- ## PROJECT::SPECIFIC
22
-
23
- lib/main.rb
24
- config.yaml
@@ -1,125 +0,0 @@
1
- require "moip"
2
-
3
- describe "Make payments with the MoIP API" do
4
-
5
- CONFIG_TEST = YAML.load_file("config.yaml")["test"]
6
-
7
- before :all do
8
- @pagador = { :nome => "Luiz Inácio Lula da Silva",
9
- :login_moip => "lula",
10
- :email => "presidente@planalto.gov.br",
11
- :tel_cel => "(61)9999-9999",
12
- :apelido => "Lula",
13
- :identidade => "111.111.111-11",
14
- :logradouro => "Praça dos Três Poderes",
15
- :numero => "0",
16
- :complemento => "Palácio do Planalto",
17
- :bairro => "Zona Cívico-Administrativa",
18
- :cidade => "Brasília",
19
- :estado => "DF",
20
- :pais => "BRA",
21
- :cep => "70100-000",
22
- :tel_fixo => "(61)3211-1221" }
23
-
24
- @billet = { :value => "8.90", :id_proprio => id, :forma => "BoletoBancario", :pagador => @pagador }
25
- @debit = { :value => "8.90", :id_proprio => id, :forma => "DebitoBancario", :instituicao => "BancoDoBrasil", :pagador => @pagador }
26
- @credit = { :value => "8.90", :id_proprio => id, :forma => "CartaoCredito", :instituicao => "AmericanExpress", :numero => "345678901234564", :expiracao => "08/11", :codigo_seguranca => "1234", :nome => "João Silva", :identidade => "134.277.017.00", :telefone => "(21)9208-0547", :data_nascimento => "25/10/1980", :parcelas => "2", :recebimento => "AVista", :pagador => @pagador }
27
- end
28
-
29
- context "make a billet checkout" do
30
- it "should have status Sucesso" do
31
- MoIP.stub!(:post).and_return("ns1:EnviarInstrucaoUnicaResponse"=>{ "Resposta"=>{ "ID"=>Time.now.strftime("%y%m%d%H%M%S"), "Status"=>"Sucesso", "Token" => "T2N0L0X8E0S71217U2H3W1T4F4S4G4K731D010V0S0V0S080M010E0Q082X2" }})
32
- response = MoIP.checkout(@billet)
33
- response["Status"].should == "Sucesso"
34
- end
35
- end
36
-
37
- context "make a debit checkout" do
38
- it "should have status Sucesso" do
39
- MoIP.stub!(:post).and_return("ns1:EnviarInstrucaoUnicaResponse"=>{ "Resposta"=>{ "ID"=>Time.now.strftime("%y%m%d%H%M%S"), "Status"=>"Sucesso", "Token" => "T2N0L0X8E0S71217U2H3W1T4F4S4G4K731D010V0S0V0S080M010E0Q082X2" }})
40
- response = MoIP.checkout(@debit)
41
- response["Status"].should == "Sucesso"
42
- end
43
- end
44
-
45
- context "make a debit checkout without pass a institution" do
46
- it "should have status Falha" do
47
- @incorrect_debit = { :value => "37.90", :id_proprio => id, :forma => "DebitoBancario", :pagador => @pagador }
48
- MoIP.stub!(:post).and_return("ns1:EnviarInstrucaoUnicaResponse"=>{ "Resposta"=>{"Status"=>"Falha", "Erro"=>"Pagamento direto não é possível com a instituição de pagamento enviada" }})
49
- lambda { MoIP.checkout(@incorrect_debit) }.should raise_error(StandardError, "Pagamento direto não é possível com a instituição de pagamento enviada")
50
- end
51
- end
52
-
53
- context "make a debit checkout without pass the payer informations" do
54
- it "should raise an exception" do
55
- @incorrect_debit = { :value => "37.90", :id_proprio => id, :forma => "DebitoBancario", :instituicao => "BancoDoBrasil" }
56
- lambda { MoIP.checkout(@incorrect_debit) }.should raise_error(StandardError, "É obrigatório passar as informações do pagador")
57
- end
58
- end
59
-
60
- context "make a credit card checkout" do
61
- it "should have status Sucesso" do
62
- MoIP.stub!(:post).and_return("ns1:EnviarInstrucaoUnicaResponse"=>{ "Resposta"=>{ "ID"=>Time.now.strftime("%y%m%d%H%M%S"), "Status"=>"Sucesso", "Token" => "T2N0L0X8E0S71217U2H3W1T4F4S4G4K731D010V0S0V0S080M010E0Q082X2" }})
63
- response = MoIP.checkout(@credit)
64
- response["Status"].should == "Sucesso"
65
- end
66
- end
67
-
68
- context "make a credit card checkout without pass card informations" do
69
- it "should have status Falha" do
70
- @incorrect_credit = { :value => "8.90", :id_proprio => id, :forma => "CartaoCredito", :pagador => @pagador }
71
- MoIP.stub!(:post).and_return("ns1:EnviarInstrucaoUnicaResponse"=>{ "Resposta"=>{"Status"=>"Falha", "Erro"=>"Pagamento direto não é possível com a instituição de pagamento enviada" }})
72
- lambda { MoIP.checkout(@incorrect_credit) }.should raise_error(StandardError, "Pagamento direto não é possível com a instituição de pagamento enviada")
73
- end
74
- end
75
-
76
- context "in error scenario" do
77
- it "should raise an exception if response is nil" do
78
- MoIP.stub!(:post).and_return(nil)
79
- lambda { MoIP.checkout(@billet) }.should raise_error(StandardError, "Ocorreu um erro ao chamar o webservice")
80
- end
81
-
82
- it "should raise an exception if status is fail" do
83
- MoIP.stub!(:post).and_return("ns1:EnviarInstrucaoUnicaResponse"=>{ "Resposta"=>{"Status"=>"Falha", "Erro"=>"O status da resposta é Falha" }})
84
- lambda { MoIP.checkout(@billet) }.should raise_error(StandardError, "O status da resposta é Falha")
85
- end
86
- end
87
-
88
- context "query a transaction token" do
89
- it "should retrieve the transaction" do
90
- MoIP.stub!(:get).and_return("ns1:ConsultarTokenResponse"=>{ "RespostaConsultar"=>{"Status"=>"Sucesso", "ID"=>"201010291031001210000000046760" }})
91
- response = MoIP.query(token)
92
- response["Status"].should == "Sucesso"
93
- end
94
- end
95
-
96
- context "query a transaction token in a error scenario" do
97
- it "should retrieve status Falha" do
98
- MoIP.stub!(:get).and_return("ns1:ConsultarTokenResponse"=>{ "RespostaConsultar"=>{"Status"=>"Falha", "Erro"=>"Instrução não encontrada", "ID"=>"201010291102522860000000046768"}})
99
- lambda { MoIP.query("000000000000000000000000000000000000000000000000000000000000") }.should raise_error(StandardError, "Instrução não encontrada")
100
- end
101
- end
102
-
103
- context "build the MoIP URL" do
104
- it "should build the correct URL" do
105
- MoIP.moip_page(token).should == "#{CONFIG_TEST["uri"]}/Instrucao.do?token=#{token}"
106
- end
107
-
108
- it "should raise an error if the token is not informed" do
109
- lambda { MoIP.moip_page("").should raise_error(ArgumentError, "É necessário informar um token para retornar os dados da transação") }
110
- end
111
-
112
- it "should raise an error if nil is passed as the token" do
113
- lambda { MoIP.moip_page(nil).should raise_error(ArgumentError, "É necessário informar um token para retornar os dados da transação") }
114
- end
115
- end
116
-
117
- def id
118
- "transaction_" + Digest::SHA1.hexdigest([Time.now, rand].join)
119
- end
120
-
121
- def token
122
- "T2X0Q1N021E0B2S9U1P0V3Y0G1F570Y2P4M0P000M0Z0F0J0G0U4N6C7W5T9"
123
- end
124
-
125
- end