moip-ruby 0.1.0

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/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
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 ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Guilherme Nascimento
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,86 @@
1
+ # MoIP
2
+
3
+ Esta Gem permite utilizar a API do MoIP, gateway de pagamentos do IG.
4
+
5
+ ## Pagamento direto
6
+
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
+
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
+
11
+ As formas de pagamento disponibilizadas pela Gem são:
12
+
13
+ * Boleto
14
+ * Débito
15
+ * Cartão de Crédito
16
+
17
+ ## Instalação
18
+
19
+ Instale a Gem
20
+ gem install moip
21
+
22
+ Adicione a Gem ao Gemfile
23
+ gem "moip"
24
+
25
+ ## Utilização
26
+
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.
28
+
29
+ ### config/environments/development.rb
30
+
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
36
+
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.
38
+
39
+ ###Crie os dados do pagador
40
+
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" }
56
+
57
+ ###Dados do boleto
58
+
59
+ boleto = { :valor => "50",
60
+ :id_proprio => "Pag#{rand(1000)}",
61
+ :forma => "BoletoBancario",
62
+ :dias_expiracao => 5,
63
+ :pagador => pagador }
64
+
65
+ ###Checkout
66
+
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
81
+
82
+ * Pagamento Simples
83
+ * Pagamento Recorrente
84
+
85
+
86
+ Baseado no projeto do [Daniel Lopes](http://github.com/danielvlopes/moip_usage).
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+ require 'rubygems'
3
+ require 'rake'
4
+
5
+ require 'rspec/core/rake_task'
6
+
7
+ begin
8
+ require 'jeweler'
9
+ Jeweler::Tasks.new do |gem|
10
+ gem.name = "moip-ruby"
11
+ gem.summary = "Gem para utilização da API MoIP"
12
+ gem.description = "Gem para utilização da API MoIP"
13
+ gem.email = "guilherme.ruby@gmail.com"
14
+ gem.homepage = "http://github.com/guinascimento/moip"
15
+ gem.authors = ["Guilherme Nascimento"]
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'
20
+ end
21
+ Jeweler::GemcutterTasks.new
22
+ rescue LoadError
23
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
24
+ end
25
+
26
+ task :default => :spec
27
+ RSpec::Core::RakeTask.new
28
+
29
+ require 'rake/rdoctask'
30
+ Rake::RDocTask.new do |rdoc|
31
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
32
+
33
+ rdoc.rdoc_dir = 'rdoc'
34
+ rdoc.title = "moip #{version}"
35
+ rdoc.rdoc_files.include('README*')
36
+ rdoc.rdoc_files.include('lib/**/*.rb')
37
+ end
38
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/lib/moip.rb ADDED
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+ require "rubygems"
3
+ require 'active_support/core_ext/module/attribute_accessors'
4
+ require 'active_support/deprecation'
5
+
6
+ module MoIP
7
+ autoload :DirectPayment, 'moip/direct_payment'
8
+ autoload :Client, 'moip/client'
9
+
10
+ # URI para acessar o serviço
11
+ mattr_accessor :uri
12
+ @@uri = 'https://www.moip.com.br'
13
+
14
+ # Token de autenticação
15
+ mattr_accessor :token
16
+
17
+ # Chave de acesso ao serviço
18
+ mattr_accessor :key
19
+
20
+ def self.setup
21
+ yield self
22
+ end
23
+
24
+ STATUS = {1 => "authorized", 2 => "started", 3 => "printed", 4 => "completed", 5 => "canceled", 6 => "analysing"}
25
+
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
31
+
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
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)
40
+ end
41
+
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
@@ -0,0 +1,146 @@
1
+ # encoding: utf-8
2
+ require "nokogiri"
3
+
4
+ module MoIP
5
+
6
+ class MissingPaymentTypeError < StandardError ; end
7
+ class MissingPayerError < StandardError ; end
8
+
9
+ class DirectPayment
10
+
11
+ class << self
12
+
13
+ # Cria uma instrução de pagamento direto
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
+
18
+ builder = Nokogiri::XML::Builder.new(:encoding => "UTF-8") do |xml|
19
+
20
+ # Identificador do tipo de instrução
21
+ xml.EnviarInstrucao {
22
+ xml.InstrucaoUnica {
23
+
24
+ # Dados da transação
25
+ xml.Razao {
26
+ xml.text attributes[:razao]
27
+ }
28
+ xml.Valores {
29
+ xml.Valor(:moeda => "BRL") {
30
+ xml.text attributes[:valor]
31
+ }
32
+ }
33
+ xml.IdProprio {
34
+ xml.text attributes[:id_proprio]
35
+ }
36
+
37
+ # Definindo o pagamento direto
38
+ xml.PagamentoDireto {
39
+ xml.Forma {
40
+ xml.text attributes[:forma]
41
+ }
42
+
43
+ # Débito Bancário
44
+ if attributes[:forma] == "DebitoBancario"
45
+ xml.Instituicao {
46
+ xml.text attributes[:instituicao]
47
+ }
48
+ end
49
+
50
+ # Cartão de Crédito
51
+ if attributes[:forma] == "CartaoCredito"
52
+ xml.Instituicao {
53
+ xml.text attributes[:instituicao]
54
+ }
55
+ xml.CartaoCredito {
56
+ xml.Numero {
57
+ xml.text attributes[:numero]
58
+ }
59
+ xml.Expiracao {
60
+ xml.text attributes[:expiracao]
61
+ }
62
+ xml.CodigoSeguranca {
63
+ xml.text attributes[:codigo_seguranca]
64
+ }
65
+ xml.Portador {
66
+ xml.Nome {
67
+ xml.text attributes[:nome]
68
+ }
69
+ xml.Identidade(:Tipo => "CPF") {
70
+ xml.text attributes[:identidade]
71
+ }
72
+ xml.Telefone {
73
+ xml.text attributes[:telefone]
74
+ }
75
+ xml.DataNascimento {
76
+ xml.text attributes[:data_nascimento]
77
+ }
78
+ }
79
+ }
80
+ xml.Parcelamento {
81
+ xml.Parcelas {
82
+ xml.text attributes[:parcelas]
83
+ }
84
+ xml.Recebimento {
85
+ xml.text attributes[:recebimento]
86
+ }
87
+ }
88
+ end
89
+ }
90
+
91
+ # Dados do pagador
92
+ xml.Pagador {
93
+ xml.Nome { xml.text attributes[:pagador][:nome] }
94
+ xml.LoginMoIP { xml.text attributes[:pagador][:login_moip] }
95
+ xml.Email { xml.text attributes[:pagador][:email] }
96
+ xml.TelefoneCelular { xml.text attributes[:pagador][:tel_cel] }
97
+ xml.Apelido { xml.text attributes[:pagador][:apelido] }
98
+ xml.Identidade { xml.text attributes[:pagador][:identidade] }
99
+ xml.EnderecoCobranca {
100
+ xml.Logradouro { xml.text attributes[:pagador][:logradouro] }
101
+ xml.Numero { xml.text attributes[:pagador][:numero] }
102
+ xml.Complemento { xml.text attributes[:pagador][:complemento] }
103
+ xml.Bairro { xml.text attributes[:pagador][:bairro] }
104
+ xml.Cidade { xml.text attributes[:pagador][:cidade] }
105
+ xml.Estado { xml.text attributes[:pagador][:estado] }
106
+ xml.Pais { xml.text attributes[:pagador][:pais] }
107
+ xml.CEP { xml.text attributes[:pagador][:cep] }
108
+ xml.TelefoneFixo { xml.text attributes[:pagador][:tel_fixo] }
109
+ }
110
+ }
111
+
112
+ # Boleto Bancario
113
+ if attributes[:forma] == "BoletoBancario"
114
+ # Dados extras
115
+ xml.Boleto {
116
+ xml.DiasExpiracao(:Tipo => "Corridos") {
117
+ xml.text attributes[:dias_expiracao]
118
+ }
119
+ xml.Instrucao1 {
120
+ xml.text attributes[:instrucao_1]
121
+ }
122
+ xml.URLLogo {
123
+ xml.text attributes[:url_logo]
124
+ }
125
+ }
126
+ end
127
+
128
+ if attributes[:url_retorno]
129
+ # URL de retorno
130
+ xml.URLRetorno {
131
+ xml.text attributes[:url_retorno]
132
+ }
133
+ end
134
+
135
+ }
136
+ }
137
+ end
138
+
139
+ builder.to_xml
140
+ end
141
+
142
+ end
143
+
144
+ end
145
+
146
+ end
data/moip.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.name = %q{moip-ruby}
5
+
6
+
7
+ gem.authors = ["Guilherme Nascimento"]
8
+ gem.date = %q{2010-11-10}
9
+ gem.description = %q{Gem para utilização da API MoIP}
10
+ gem.email = %q{guilherme.ruby@gmail.com}
11
+ gem.summary = %q{Gem para utilização da API MoIP}
12
+
13
+ gem.files = `git ls-files`.split("\n")
14
+ gem.test_files = `git ls-files -- spec/*.rb`.split("\n")
15
+
16
+ gem.homepage = %q{http://github.com/moiplabs/moip-ruby}
17
+ gem.require_paths = ["lib"]
18
+
19
+ gem.rdoc_options = ["--charset=UTF-8"]
20
+ gem.extra_rdoc_files = [ "LICENSE", "README.markdown"]
21
+
22
+ gem.add_development_dependency(%q<rspec>, ["~> 2.1.0"])
23
+
24
+ gem.add_runtime_dependency(%q<nokogiri>, ["~> 1.4.2"])
25
+ gem.add_runtime_dependency(%q<httparty>, ["~> 0.8.1"])
26
+ gem.add_runtime_dependency(%q<activesupport>, [">= 2.3.2"])
27
+ end
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 ADDED
@@ -0,0 +1,164 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: moip-ruby
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ segments_generated: true
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Guilherme Nascimento
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-04-29 00:00:00 -03:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ type: :runtime
24
+ name: moip-ruby
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
109
+ description: "Gem para utiliza\xC3\xA7\xC3\xA3o da API MoIP"
110
+ email: guilherme.ruby@gmail.com
111
+ executables: []
112
+
113
+ extensions: []
114
+
115
+ extra_rdoc_files:
116
+ - LICENSE
117
+ - README.markdown
118
+ files:
119
+ - .document
120
+ - Gemfile
121
+ - Gemfile.lock
122
+ - LICENSE
123
+ - README.markdown
124
+ - Rakefile
125
+ - VERSION
126
+ - lib/moip.rb
127
+ - lib/moip/client.rb
128
+ - lib/moip/direct_payment.rb
129
+ - moip.gemspec
130
+ - spec/moip_spec.rb
131
+ has_rdoc: true
132
+ homepage: http://github.com/guinascimento/moip
133
+ licenses: []
134
+
135
+ post_install_message:
136
+ rdoc_options: []
137
+
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ segments:
145
+ - 0
146
+ segments_generated: true
147
+ version: "0"
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ segments:
153
+ - 0
154
+ segments_generated: true
155
+ version: "0"
156
+ requirements: []
157
+
158
+ rubyforge_project:
159
+ rubygems_version: 1.3.6
160
+ signing_key:
161
+ specification_version: 3
162
+ summary: "Gem para utiliza\xC3\xA7\xC3\xA3o da API MoIP"
163
+ test_files: []
164
+