pagseguro-oficial 2.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.rspec +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +4 -0
- data/LICENSE-2.0.txt +177 -0
- data/README.md +320 -0
- data/Rakefile +5 -0
- data/examples/abandoned_transactions.rb +26 -0
- data/examples/boot.rb +9 -0
- data/examples/invalid_transaction_by_notification_code.rb +9 -0
- data/examples/payment_request.rb +49 -0
- data/examples/transaction_by_notification_code.rb +5 -0
- data/examples/transactions_by_date.rb +23 -0
- data/lib/pagseguro/address.rb +40 -0
- data/lib/pagseguro/errors.rb +28 -0
- data/lib/pagseguro/exceptions.rb +3 -0
- data/lib/pagseguro/extensions/ensure_type.rb +9 -0
- data/lib/pagseguro/extensions/mass_assignment.rb +11 -0
- data/lib/pagseguro/item.rb +30 -0
- data/lib/pagseguro/items.rb +27 -0
- data/lib/pagseguro/notification.rb +21 -0
- data/lib/pagseguro/payment_method.rb +38 -0
- data/lib/pagseguro/payment_request/response.rb +30 -0
- data/lib/pagseguro/payment_request/serializer.rb +91 -0
- data/lib/pagseguro/payment_request.rb +96 -0
- data/lib/pagseguro/payment_status.rb +33 -0
- data/lib/pagseguro/phone.rb +12 -0
- data/lib/pagseguro/report.rb +124 -0
- data/lib/pagseguro/request.rb +78 -0
- data/lib/pagseguro/sender.rb +23 -0
- data/lib/pagseguro/shipping.rb +57 -0
- data/lib/pagseguro/transaction/response.rb +12 -0
- data/lib/pagseguro/transaction/serializer.rb +115 -0
- data/lib/pagseguro/transaction.rb +167 -0
- data/lib/pagseguro/version.rb +3 -0
- data/lib/pagseguro-oficial.rb +1 -0
- data/lib/pagseguro.rb +94 -0
- data/locales/pt-BR.yml +115 -0
- data/pagseguro-oficial.gemspec +32 -0
- data/spec/fixtures/by_date/success.xml +85 -0
- data/spec/fixtures/invalid_code.xml +7 -0
- data/spec/fixtures/payment_request/failure.xml +7 -0
- data/spec/fixtures/payment_request/success.xml +5 -0
- data/spec/fixtures/transactions/additional.xml +53 -0
- data/spec/fixtures/transactions/success.xml +53 -0
- data/spec/pagseguro/address_spec.rb +17 -0
- data/spec/pagseguro/errors_spec.rb +91 -0
- data/spec/pagseguro/item_spec.rb +20 -0
- data/spec/pagseguro/items_spec.rb +56 -0
- data/spec/pagseguro/notification_spec.rb +18 -0
- data/spec/pagseguro/pagseguro_spec.rb +54 -0
- data/spec/pagseguro/payment_method_spec.rb +41 -0
- data/spec/pagseguro/payment_request/response_spec.rb +24 -0
- data/spec/pagseguro/payment_request/serializer_spec.rb +142 -0
- data/spec/pagseguro/payment_request_spec.rb +107 -0
- data/spec/pagseguro/payment_status_spec.rb +24 -0
- data/spec/pagseguro/phone_spec.rb +6 -0
- data/spec/pagseguro/request_spec.rb +75 -0
- data/spec/pagseguro/sender_spec.rb +9 -0
- data/spec/pagseguro/shipping_spec.rb +40 -0
- data/spec/pagseguro/transaction/serializer_spec.rb +61 -0
- data/spec/pagseguro/transaction_spec.rb +118 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/ensure_type_macro.rb +17 -0
- data/spec/support/mass_assignment_macro.rb +11 -0
- metadata +289 -0
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative "boot"
|
2
|
+
require "active_support/all"
|
3
|
+
|
4
|
+
report = PagSeguro::Transaction.find_abandoned(
|
5
|
+
starts_at: 30.days.ago,
|
6
|
+
size: 1
|
7
|
+
)
|
8
|
+
|
9
|
+
while report.next_page?
|
10
|
+
report.next_page!
|
11
|
+
puts "=> Fetching page #{report.page}"
|
12
|
+
|
13
|
+
abort "=> Errors: #{report.errors.join("\n")}" unless report.valid?
|
14
|
+
|
15
|
+
puts "=> Report was created at: #{report.created_at}"
|
16
|
+
puts
|
17
|
+
|
18
|
+
report.transactions.each do |transaction|
|
19
|
+
puts "=> Abandoned transaction"
|
20
|
+
puts " created at: #{transaction.created_at}"
|
21
|
+
puts " code: #{transaction.code}"
|
22
|
+
puts " type_id: #{transaction.type_id}"
|
23
|
+
puts " gross amount: #{transaction.gross_amount}"
|
24
|
+
puts
|
25
|
+
end
|
26
|
+
end
|
data/examples/boot.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require_relative "boot"
|
3
|
+
|
4
|
+
payment = PagSeguro::PaymentRequest.new
|
5
|
+
payment.abandon_url = "http://dev.simplesideias.com.br/?abandoned"
|
6
|
+
payment.notification_url = "http://dev.simplesideias.com.br/?notification"
|
7
|
+
payment.redirect_url = "http://dev.simplesideias.com.br/?redirect"
|
8
|
+
|
9
|
+
payment.items << {
|
10
|
+
id: 1234,
|
11
|
+
description: %[Televisão 19" Sony],
|
12
|
+
amount: 459.50,
|
13
|
+
weight: 0
|
14
|
+
}
|
15
|
+
|
16
|
+
payment.reference = "REF1234"
|
17
|
+
payment.sender = {
|
18
|
+
name: "Nando Vieira",
|
19
|
+
email: "fnando.vieira@gmail.com",
|
20
|
+
cpf: "21639716866",
|
21
|
+
phone: {
|
22
|
+
area_code: 11,
|
23
|
+
number: "12345678"
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
payment.shipping = {
|
28
|
+
type_name: "sedex",
|
29
|
+
address: {
|
30
|
+
street: "R. Vergueiro",
|
31
|
+
number: 1421,
|
32
|
+
complement: "Sala 213",
|
33
|
+
city: "São Paulo",
|
34
|
+
state: "SP",
|
35
|
+
district: "Vila Mariana"
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
puts "=> REQUEST"
|
40
|
+
puts PagSeguro::PaymentRequest::Serializer.new(payment).to_params
|
41
|
+
|
42
|
+
response = payment.register
|
43
|
+
|
44
|
+
puts
|
45
|
+
puts "=> RESPONSE"
|
46
|
+
puts response.url
|
47
|
+
puts response.code
|
48
|
+
puts response.created_at
|
49
|
+
puts response.errors.to_a
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative "boot"
|
2
|
+
require "active_support/all"
|
3
|
+
|
4
|
+
report = PagSeguro::Transaction.find_by_date(starts_at: 29.days.ago, per_page: 1)
|
5
|
+
|
6
|
+
while report.next_page?
|
7
|
+
report.next_page!
|
8
|
+
puts "== Page #{report.page}"
|
9
|
+
abort "=> Errors: #{report.errors.join("\n")}" unless report.valid?
|
10
|
+
puts "Report created on #{report.created_at}"
|
11
|
+
puts
|
12
|
+
|
13
|
+
report.transactions.each do |transaction|
|
14
|
+
puts "=> Transaction"
|
15
|
+
puts " created_at: #{transaction.created_at}"
|
16
|
+
puts " code: #{transaction.code}"
|
17
|
+
puts " cancellation_source: #{transaction.cancellation_source}"
|
18
|
+
puts " payment method: #{transaction.payment_method.type}"
|
19
|
+
puts " gross amount: #{transaction.gross_amount}"
|
20
|
+
puts " updated at: #{transaction.updated_at}"
|
21
|
+
puts
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module PagSeguro
|
2
|
+
# Set the shipping address information.
|
3
|
+
class Address
|
4
|
+
include Extensions::MassAssignment
|
5
|
+
|
6
|
+
# Set the street name.
|
7
|
+
attr_accessor :street
|
8
|
+
|
9
|
+
# Set the house/building number.
|
10
|
+
attr_accessor :number
|
11
|
+
|
12
|
+
# Set the address complement.
|
13
|
+
# Can be the apartment, suite number or any other qualifier after
|
14
|
+
# the street/number pair.
|
15
|
+
attr_accessor :complement
|
16
|
+
|
17
|
+
# Set the district.
|
18
|
+
# Can be the district, county or neighborhood, if applicable.
|
19
|
+
attr_accessor :district
|
20
|
+
|
21
|
+
# Set the city name.
|
22
|
+
attr_accessor :city
|
23
|
+
|
24
|
+
# Set the state or province.
|
25
|
+
attr_accessor :state
|
26
|
+
|
27
|
+
# Set the postal code.
|
28
|
+
# Must contain 8 numbers.
|
29
|
+
attr_accessor :postal_code
|
30
|
+
|
31
|
+
# Set the country code.
|
32
|
+
# Defaults to +BRA+.
|
33
|
+
attr_accessor :country
|
34
|
+
|
35
|
+
private
|
36
|
+
def before_initialize
|
37
|
+
self.country = "BRA"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module PagSeguro
|
2
|
+
class Errors
|
3
|
+
extend Forwardable
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
def_delegators :@messages, :each, :empty?, :any?, :join, :include?
|
7
|
+
|
8
|
+
def initialize(response = nil)
|
9
|
+
@response = response
|
10
|
+
@messages = []
|
11
|
+
|
12
|
+
process_response if response
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def process_response
|
17
|
+
@messages << error_message(:unauthorized, "Unauthorized") if @response.unauthorized?
|
18
|
+
|
19
|
+
@response.data.css("errors > error").each do |error|
|
20
|
+
@messages << error_message(error.css("code").text, error.css("message").text)
|
21
|
+
end if @response.bad_request?
|
22
|
+
end
|
23
|
+
|
24
|
+
def error_message(code, message)
|
25
|
+
I18n.t(code, scope: "pagseguro.errors", default: message)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module PagSeguro
|
2
|
+
module Extensions
|
3
|
+
module MassAssignment
|
4
|
+
def initialize(options = {})
|
5
|
+
before_initialize if respond_to?(:before_initialize, true)
|
6
|
+
options.each {|name, value| public_send("#{name}=", value) }
|
7
|
+
after_initialize if respond_to?(:after_initialize, true)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module PagSeguro
|
2
|
+
class Item
|
3
|
+
include Extensions::MassAssignment
|
4
|
+
|
5
|
+
# Set the product identifier, such as SKU.
|
6
|
+
attr_accessor :id
|
7
|
+
|
8
|
+
# Set the product description.
|
9
|
+
attr_accessor :description
|
10
|
+
|
11
|
+
# Set the quantity.
|
12
|
+
# Defaults to 1.
|
13
|
+
attr_accessor :quantity
|
14
|
+
|
15
|
+
# Set the amount per unit.
|
16
|
+
attr_accessor :amount
|
17
|
+
|
18
|
+
# Set the weight per unit, in grams.
|
19
|
+
attr_accessor :weight
|
20
|
+
|
21
|
+
# Set the shipping cost per unit.
|
22
|
+
attr_accessor :shipping_cost
|
23
|
+
|
24
|
+
private
|
25
|
+
def before_initialize
|
26
|
+
self.quantity = 1
|
27
|
+
self.weight = 0
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module PagSeguro
|
2
|
+
class Items
|
3
|
+
extend Forwardable
|
4
|
+
include Enumerable
|
5
|
+
include Extensions::EnsureType
|
6
|
+
|
7
|
+
def_delegators :@store, :size, :clear, :empty?, :any?, :each
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@store = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def <<(item)
|
14
|
+
item = ensure_type(Item, item)
|
15
|
+
|
16
|
+
if include?(item)
|
17
|
+
item.quantity += 1
|
18
|
+
else
|
19
|
+
@store << item
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def include?(item)
|
24
|
+
@store.find {|stored_item| stored_item.id == ensure_type(Item, item).id }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module PagSeguro
|
2
|
+
class Notification
|
3
|
+
include PagSeguro::Extensions::MassAssignment
|
4
|
+
|
5
|
+
# The notification code sent by PagSeguro.
|
6
|
+
attr_accessor :code
|
7
|
+
|
8
|
+
# The notification type sent by PagSeguro.
|
9
|
+
attr_accessor :type
|
10
|
+
|
11
|
+
# Detect if the notification is from a transaction.
|
12
|
+
def transaction?
|
13
|
+
type == "transaction"
|
14
|
+
end
|
15
|
+
|
16
|
+
# Fetch the transaction by its notificationCode.
|
17
|
+
def transaction
|
18
|
+
Transaction.find_by_notification_code(code)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module PagSeguro
|
3
|
+
class PaymentMethod
|
4
|
+
include Extensions::MassAssignment
|
5
|
+
|
6
|
+
TYPES = {
|
7
|
+
"1" => :credit_card,
|
8
|
+
"2" => :boleto,
|
9
|
+
"3" => :online_transfer,
|
10
|
+
"4" => :balance,
|
11
|
+
"5" => :oi_paggo,
|
12
|
+
"7" => :direct_deposit
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
# The payment method code.
|
16
|
+
attr_accessor :code
|
17
|
+
|
18
|
+
# The payment method type.
|
19
|
+
attr_accessor :type_id
|
20
|
+
|
21
|
+
# Define shortcuts dynamically.
|
22
|
+
TYPES.each do |id, type|
|
23
|
+
define_method "#{type}?" do
|
24
|
+
type_id.to_s == id
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Return the type in a readable manner.
|
29
|
+
def type
|
30
|
+
TYPES.fetch(type_id.to_s) { raise "PagSeguro::PaymentMethod#type_id isn't mapped" }
|
31
|
+
end
|
32
|
+
|
33
|
+
# Return the payment method's description.
|
34
|
+
def description
|
35
|
+
I18n.t(code, scope: "pagseguro.payment_methods")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module PagSeguro
|
2
|
+
class PaymentRequest
|
3
|
+
class Response
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
def_delegators :response, :success?
|
7
|
+
attr_reader :response
|
8
|
+
|
9
|
+
def initialize(response)
|
10
|
+
@response = response
|
11
|
+
end
|
12
|
+
|
13
|
+
def errors
|
14
|
+
@errors ||= Errors.new(response)
|
15
|
+
end
|
16
|
+
|
17
|
+
def url
|
18
|
+
PagSeguro.site_url("checkout/payment.html?code=#{code}") if code
|
19
|
+
end
|
20
|
+
|
21
|
+
def code
|
22
|
+
@code ||= response.data.css("checkout > code").text if success?
|
23
|
+
end
|
24
|
+
|
25
|
+
def created_at
|
26
|
+
@created_at ||= Time.parse(response.data.css("checkout > date").text) if success?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module PagSeguro
|
2
|
+
class PaymentRequest
|
3
|
+
class Serializer
|
4
|
+
# The payment request that will be serialized.
|
5
|
+
attr_reader :payment_request
|
6
|
+
|
7
|
+
def initialize(payment_request)
|
8
|
+
@payment_request = payment_request
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_params
|
12
|
+
params[:receiverEmail] = PagSeguro.receiver_email
|
13
|
+
params[:currency] = payment_request.currency
|
14
|
+
params[:reference] = payment_request.reference
|
15
|
+
params[:extraAmount] = to_amount(payment_request.extra_amount)
|
16
|
+
params[:redirectURL] = payment_request.redirect_url
|
17
|
+
params[:notificationURL] = payment_request.notification_url
|
18
|
+
params[:abandonURL] = payment_request.abandon_url
|
19
|
+
params[:maxUses] = payment_request.max_uses
|
20
|
+
params[:maxAge] = payment_request.max_age
|
21
|
+
payment_request.items.each.with_index(1) do |item, index|
|
22
|
+
serialize_item(item, index)
|
23
|
+
end
|
24
|
+
|
25
|
+
serialize_sender(payment_request.sender)
|
26
|
+
serialize_shipping(payment_request.shipping)
|
27
|
+
|
28
|
+
params.delete_if {|key, value| value.nil? }
|
29
|
+
|
30
|
+
params
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def params
|
35
|
+
@params ||= {}
|
36
|
+
end
|
37
|
+
|
38
|
+
def serialize_item(item, index)
|
39
|
+
params["itemId#{index}"] = item.id
|
40
|
+
params["itemDescription#{index}"] = item.description
|
41
|
+
params["itemAmount#{index}"] = to_amount(item.amount)
|
42
|
+
params["itemQuantity#{index}"] = item.quantity
|
43
|
+
params["itemShippingCost#{index}"] = to_amount(item.shipping_cost)
|
44
|
+
params["itemWeight#{index}"] = item.weight if item.weight
|
45
|
+
end
|
46
|
+
|
47
|
+
def serialize_sender(sender)
|
48
|
+
return unless sender
|
49
|
+
|
50
|
+
params[:senderEmail] = sender.email
|
51
|
+
params[:senderName] = sender.name
|
52
|
+
params[:senderCPF] = sender.cpf
|
53
|
+
|
54
|
+
serialize_phone(sender.phone)
|
55
|
+
end
|
56
|
+
|
57
|
+
def serialize_phone(phone)
|
58
|
+
return unless phone
|
59
|
+
|
60
|
+
params[:senderAreaCode] = phone.area_code
|
61
|
+
params[:senderPhone] = phone.number
|
62
|
+
end
|
63
|
+
|
64
|
+
def serialize_shipping(shipping)
|
65
|
+
return unless shipping
|
66
|
+
|
67
|
+
params[:shippingType] = shipping.type_id
|
68
|
+
params[:shippingCost] = to_amount(shipping.cost)
|
69
|
+
|
70
|
+
serialize_address(shipping.address)
|
71
|
+
end
|
72
|
+
|
73
|
+
def serialize_address(address)
|
74
|
+
return unless address
|
75
|
+
|
76
|
+
params[:shippingAddressCountry] = address.country
|
77
|
+
params[:shippingAddressState] = address.state
|
78
|
+
params[:shippingAddressCity] = address.city
|
79
|
+
params[:shippingAddressPostalCode] = address.postal_code
|
80
|
+
params[:shippingAddressDistrict] = address.district
|
81
|
+
params[:shippingAddressStreet] = address.street
|
82
|
+
params[:shippingAddressNumber] = address.number
|
83
|
+
params[:shippingAddressComplement] = address.complement
|
84
|
+
end
|
85
|
+
|
86
|
+
def to_amount(amount)
|
87
|
+
"%.2f" % BigDecimal(amount.to_s).round(2).to_s("F") if amount
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|