Skip to content

Commit

Permalink
Changed PagSeguro notification URL. Send ISO-8859-1 data when confirm…
Browse files Browse the repository at this point in the history
…ing notification.
  • Loading branch information
fnando committed May 26, 2011
1 parent 8ddccac commit 17c8f08
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 70 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
source :rubygems
source "http://gems.simplesideias.com.br"
gemspec
68 changes: 34 additions & 34 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,37 @@ PATH
pagseguro (0.1.10)

GEM
remote: http://rubygems.org/
remote: http://gems.simplesideias.com.br/
specs:
abstract (1.0.0)
actionmailer (3.0.5)
actionpack (= 3.0.5)
actionmailer (3.0.7)
actionpack (= 3.0.7)
mail (~> 2.2.15)
actionpack (3.0.5)
activemodel (= 3.0.5)
activesupport (= 3.0.5)
actionpack (3.0.7)
activemodel (= 3.0.7)
activesupport (= 3.0.7)
builder (~> 2.1.2)
erubis (~> 2.6.6)
i18n (~> 0.4)
i18n (~> 0.5.0)
rack (~> 1.2.1)
rack-mount (~> 0.6.13)
rack-mount (~> 0.6.14)
rack-test (~> 0.5.7)
tzinfo (~> 0.3.23)
activemodel (3.0.5)
activesupport (= 3.0.5)
activemodel (3.0.7)
activesupport (= 3.0.7)
builder (~> 2.1.2)
i18n (~> 0.4)
activerecord (3.0.5)
activemodel (= 3.0.5)
activesupport (= 3.0.5)
i18n (~> 0.5.0)
activerecord (3.0.7)
activemodel (= 3.0.7)
activesupport (= 3.0.7)
arel (~> 2.0.2)
tzinfo (~> 0.3.23)
activeresource (3.0.5)
activemodel (= 3.0.5)
activesupport (= 3.0.5)
activesupport (3.0.5)
activeresource (3.0.7)
activemodel (= 3.0.7)
activesupport (= 3.0.7)
activesupport (3.0.7)
archive-tar-minitar (0.5.2)
arel (2.0.9)
arel (2.0.10)
builder (2.1.2)
columnize (0.3.2)
diff-lcs (1.1.2)
Expand All @@ -44,38 +44,38 @@ GEM
i18n (0.5.0)
linecache19 (0.5.12)
ruby_core_source (>= 0.1.4)
mail (2.2.15)
mail (2.2.19)
activesupport (>= 2.3.6)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.16)
nokogiri (1.4.4)
polyglot (0.3.1)
rack (1.2.2)
rack (1.2.3)
rack-mount (0.6.14)
rack (>= 1.0.0)
rack-test (0.5.7)
rack (>= 1.0)
rails (3.0.5)
actionmailer (= 3.0.5)
actionpack (= 3.0.5)
activerecord (= 3.0.5)
activeresource (= 3.0.5)
activesupport (= 3.0.5)
rails (3.0.7)
actionmailer (= 3.0.7)
actionpack (= 3.0.7)
activerecord (= 3.0.7)
activeresource (= 3.0.7)
activesupport (= 3.0.7)
bundler (~> 1.0)
railties (= 3.0.5)
railties (3.0.5)
actionpack (= 3.0.5)
activesupport (= 3.0.5)
railties (= 3.0.7)
railties (3.0.7)
actionpack (= 3.0.7)
activesupport (= 3.0.7)
rake (>= 0.8.7)
thor (~> 0.14.4)
rake (0.8.7)
rspec (2.5.0)
rspec-core (~> 2.5.0)
rspec-expectations (~> 2.5.0)
rspec-mocks (~> 2.5.0)
rspec-core (2.5.1)
rspec-core (2.5.2)
rspec-expectations (2.5.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.5.0)
Expand All @@ -100,7 +100,7 @@ GEM
thor (0.14.6)
treetop (1.4.9)
polyglot (>= 0.3.1)
tzinfo (0.3.26)
tzinfo (0.3.27)

PLATFORMS
ruby
Expand All @@ -109,7 +109,7 @@ DEPENDENCIES
fakeweb (~> 1.3.0)
nokogiri (~> 1.4.4)
pagseguro!
rails (~> 3.0.5)
rails (~> 3.0)
rspec-rails (~> 2.5.0)
ruby-debug19
sqlite3-ruby (~> 1.3.3)
2 changes: 1 addition & 1 deletion lib/pagseguro/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module PagSeguro

# PagSeguro receives all invoices in this URL. If developer mode is enabled,
# then the URL will be /pagseguro_developer/invoice
GATEWAY_URL = "https://pagseguro.uol.com.br/security/webpagamentos/webpagto.aspx"
GATEWAY_URL = "https://pagseguro.uol.com.br/pagseguro-ws/checkout/NPI.jhtml"

# Hold the config/pagseguro.yml contents
@@config = nil
Expand Down
62 changes: 44 additions & 18 deletions lib/pagseguro/notification.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ module PagSeguro
class Notification
API_URL = "https://pagseguro.uol.com.br/Security/NPI/Default.aspx"

# Map all the attributes from PagSeguro
# Map all the attributes from PagSeguro.
#
MAPPING = {
:payment_method => "TipoPagamento",
:order_id => "Referencia",
Expand All @@ -15,7 +16,8 @@ class Notification
:notes => "Anotacao"
}

# Map order status from PagSeguro
# Map order status from PagSeguro.
#
STATUS = {
"Completo" => :completed,
"Aguardando Pagto" => :pending,
Expand All @@ -25,33 +27,48 @@ class Notification
"Devolvido" => :refunded
}

# Map payment method from PagSeguro
# Map payment method from PagSeguro.
#
PAYMENT_METHOD = {
"Cartão de Crédito" => :credit_card,
"Boleto" => :invoice,
"Pagamento" => :pagseguro,
"Pagamento online" => :online_transfer
}

# The Rails params hash
# The Rails params hash.
#
attr_accessor :params

# Expects the params object from the current request
# Expects the params object from the current request.
# PagSeguro will send POST with ISO-8859-1 encoded data,
# so we need to normalize it to UTF-8.
#
def initialize(params, token = nil)
@token = token
@params = PagSeguro.developer? ? params : normalize(params)
end

# Normalize the specified hash converting all data to UTF-8
# Normalize the specified hash converting all data to UTF-8.
#
def normalize(hash)
each_value(hash) do |value|
Utils.to_utf8(value)
end
end

# Denormalize the specified hash converting all data to ISO-8859-1.
#
def denormalize(hash)
each_value(hash) do |value|
Utils.to_iso8859(value)
end
end

# Return a list of products sent by PagSeguro.
# The values will be normalized
# (e.g. currencies will be converted to cents, quantity will be an integer)
#
def products
@products ||= begin
items = []
Expand All @@ -71,33 +88,38 @@ def products
end
end

# Return the shipping fee
# Will be converted to a float number
# Return the shipping fee.
# Will be converted to a float number.
#
def shipping
to_price mapping_for(:shipping)
end

# Return the order status
# Will be mapped to the STATUS constant
# Return the order status.
# Will be mapped to the STATUS constant.
#
def status
@status ||= STATUS[mapping_for(:status)]
end

# Return the payment method
# Will be mapped to the PAYMENT_METHOD constant
# Return the payment method.
# Will be mapped to the PAYMENT_METHOD constant.
#
def payment_method
@payment_method ||= PAYMENT_METHOD[mapping_for(:payment_method)]
end

# Parse the processing date to a Ruby object
# Parse the processing date to a Ruby object.
#
def processed_at
@processed_at ||= begin
groups = *mapping_for(:processed_at).match(/(\d{2})\/(\d{2})\/(\d{4}) ([\d:]+)/sm)
Time.parse("#{groups[3]}-#{groups[2]}-#{groups[1]} #{groups[4]}")
end
end

# Return the buyer info
# Return the buyer info.
#
def buyer
@buyer ||= {
:name => params["CliNome"],
Expand Down Expand Up @@ -129,7 +151,8 @@ def respond_to?(method, include_private = false)
end

# A wrapper to the params hash,
# sanitizing the return to symbols
# sanitizing the return to symbols.
#
def mapping_for(name)
params[MAPPING[name]]
end
Expand All @@ -139,14 +162,15 @@ def mapping_for(name)
#
# invoice.valid?
# invoice.valid?(:nocache)
#
def valid?(force=false)
@valid = nil if force
@valid = validates? if @valid.nil?
@valid
end

private
def each_value(hash, &blk)
def each_value(hash, &blk) # :nodoc:
hash.each do |key, value|
if value.kind_of?(Hash)
hash[key] = each_value(value, &blk)
Expand All @@ -158,7 +182,8 @@ def each_value(hash, &blk)
hash
end

# Convert amount format to float
# Convert amount format to float.
#
def to_price(amount)
amount = "0#{amount}" if amount =~ /^\,/
amount.to_s.gsub(/[^\d]/, "").gsub(/^(\d+)(\d{2})$/, '\1.\2').to_f
Expand All @@ -167,6 +192,7 @@ def to_price(amount)
# Check if the provided data is valid by requesting the
# confirmation API url. The request will always be valid while running in
# developer mode.
#
def validates?
return true if PagSeguro.developer?

Expand All @@ -184,7 +210,7 @@ def validates?
http.ca_file = File.dirname(__FILE__) + "/cacert.pem"

request = Net::HTTP::Post.new(uri.path)
request.set_form_data request_params
request.form_data = denormalize(request_params)
response = http.start {|r| r.request request }
(response.body =~ /VERIFICADO/) != nil
end
Expand Down
4 changes: 2 additions & 2 deletions lib/pagseguro/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ module Utils
extend self

def to_utf8(string)
string.to_s.unpack('C*').pack('U*')
string.to_s.unpack("C*").pack("U*")
end

def to_iso8859(string)
string.to_s.unpack('U*').pack('C*')
string.to_s.unpack("U*").pack("C*")
end
end
end
2 changes: 1 addition & 1 deletion pagseguro.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Gem::Specification.new do |s|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]

s.add_development_dependency "rails" , "~> 3.0.5"
s.add_development_dependency "rails" , "~> 3.0"
s.add_development_dependency "fakeweb" , "~> 1.3.0"
s.add_development_dependency "rspec-rails" , "~> 2.5.0"
s.add_development_dependency "nokogiri" , "~> 1.4.4"
Expand Down
16 changes: 8 additions & 8 deletions spec/pagseguro/notification_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
end

it "should not request the confirmation url when running developer mode" do
PagSeguro.stub!(:developer?).and_return(true)
PagSeguro.stub :developer? => true
Net::HTTP.should_not_receive(:new)
@notification.should be_valid
end
Expand Down Expand Up @@ -217,9 +217,9 @@

describe "confirmation" do
before do
PagSeguro.stub!(:developer?).and_return(false)
PagSeguro.stub :developer? => false
@url = PagSeguro::Notification::API_URL
@notification.stub!(:api_url).and_return(@url)
@notification.stub :api_url => @url
end

it "should be valid" do
Expand All @@ -245,7 +245,7 @@
notification = PagSeguro::Notification.new(@the_params, 'ABCDEF')

post = mock("post").as_null_object
post.should_receive(:set_form_data).with({:Comando => "validar", :Token => "ABCDEF"})
post.should_receive(:form_data=).with({:Comando => "validar", :Token => "ABCDEF"})

Net::HTTP.should_receive(:new).and_return(mock("http").as_null_object)
Net::HTTP::Post.should_receive(:new).and_return(post)
Expand All @@ -254,10 +254,10 @@
end

it "should set the authenticity token from the configuration" do
PagSeguro.stub!(:config).and_return("authenticity_token" => "ABCDEF")
PagSeguro.stub :config => {"authenticity_token" => "ABCDEF"}

post = mock("post").as_null_object
post.should_receive(:set_form_data).with({:Comando => "validar", :Token => "ABCDEF"})
post.should_receive(:form_data=).with({:Comando => "validar", :Token => "ABCDEF"})

Net::HTTP.should_receive(:new).and_return(mock("http").as_null_object)
Net::HTTP::Post.should_receive(:new).and_return(post)
Expand All @@ -268,10 +268,10 @@
it "should propagate params" do
param!("VendedorEmail", "john@doe.com")
param!("NumItens", "14")
PagSeguro.stub!(:config).and_return("authenticity_token" => "ABCDEF")
PagSeguro.stub :config => {"authenticity_token" => "ABCDEF"}

post = mock("post").as_null_object
post.should_receive(:set_form_data).with({
post.should_receive(:form_data=).with({
:Comando => "validar",
:Token => "ABCDEF",
"VendedorEmail" => "john@doe.com",
Expand Down
Loading

0 comments on commit 17c8f08

Please sign in to comment.