akatus 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -16
- data/.rspec +2 -0
- data/LICENSE +1 -1
- data/Rakefile +6 -1
- data/akatus.gemspec +18 -11
- data/config/i18n.rb +3 -0
- data/lib/akatus.rb +34 -4
- data/lib/akatus/address.rb +11 -0
- data/lib/akatus/configuration.rb +43 -0
- data/lib/akatus/errors.rb +4 -0
- data/lib/akatus/formatters.rb +22 -0
- data/lib/akatus/installment.rb +6 -0
- data/lib/akatus/installment_options.rb +24 -0
- data/lib/akatus/item.rb +24 -0
- data/lib/akatus/payer.rb +35 -0
- data/lib/akatus/payment.rb +61 -0
- data/lib/akatus/payment_option.rb +6 -0
- data/lib/akatus/payment_types.rb +37 -0
- data/lib/akatus/phone.rb +6 -0
- data/lib/akatus/receiver.rb +6 -0
- data/lib/akatus/service.rb +34 -0
- data/lib/akatus/services/installments.rb +54 -0
- data/lib/akatus/services/payment_options.rb +95 -0
- data/lib/akatus/services/transaction.rb +50 -0
- data/lib/akatus/split_fee.rb +6 -0
- data/lib/akatus/transferrable.rb +58 -0
- data/lib/akatus/version.rb +1 -1
- data/locales/pt-BR.yml +69 -0
- data/spec/address_spec.rb +38 -0
- data/spec/factories/address_factories.rb +18 -0
- data/spec/factories/item_factories.rb +35 -0
- data/spec/factories/payer_factories.rb +8 -0
- data/spec/factories/phone_factories.rb +6 -0
- data/spec/item_spec.rb +42 -0
- data/spec/payer_spec.rb +31 -0
- data/spec/phone_spec.rb +23 -0
- data/spec/services/installments_spec.rb +36 -0
- data/spec/services/payment_options_spec.rb +22 -0
- data/spec/services/transaction_spec.rb +80 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/support/configuration.rb +7 -0
- data/spec/support/shared_examples/transferrable_example.rb +22 -0
- metadata +142 -12
- data/LICENSE.txt +0 -22
- data/lib/akatus/configuracao.rb +0 -40
- data/lib/akatus/formatadores.rb +0 -7
@@ -0,0 +1,34 @@
|
|
1
|
+
module Akatus
|
2
|
+
|
3
|
+
class Service
|
4
|
+
|
5
|
+
def send_request
|
6
|
+
|
7
|
+
path = self.class::PATH
|
8
|
+
method = self.class::METHOD
|
9
|
+
|
10
|
+
url = Akatus.config.api_url + path + ".json"
|
11
|
+
payload = self.to_payload
|
12
|
+
|
13
|
+
begin
|
14
|
+
|
15
|
+
if method == :post
|
16
|
+
data = RestClient.post(url, payload.to_json, :content_type => :json, :accept => :json)
|
17
|
+
elsif method == :get
|
18
|
+
data = RestClient.get(url, { :params => payload })
|
19
|
+
else
|
20
|
+
raise "Invalid method: #{method}"
|
21
|
+
end
|
22
|
+
|
23
|
+
JSON.parse(data)['resposta']
|
24
|
+
|
25
|
+
rescue RestClient::UnprocessableEntity => exc
|
26
|
+
message = JSON.load(exc.response)['resposta']['descricao']
|
27
|
+
raise Akatus::UnprocessableEntityError.new(message)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Akatus
|
2
|
+
|
3
|
+
module Services
|
4
|
+
|
5
|
+
class Installments < Akatus::Service
|
6
|
+
|
7
|
+
PATH = 'parcelamento/simulacao'
|
8
|
+
METHOD = :get
|
9
|
+
|
10
|
+
def self.calculate(payment)
|
11
|
+
self.new.calculate(payment)
|
12
|
+
end
|
13
|
+
|
14
|
+
def calculate(payment)
|
15
|
+
|
16
|
+
@payment = payment
|
17
|
+
|
18
|
+
unless payment.payment_method.is_a?(CreditCard)
|
19
|
+
return InstallmentOptions.blank(payment)
|
20
|
+
end
|
21
|
+
|
22
|
+
data = send_request
|
23
|
+
|
24
|
+
options = InstallmentOptions.new
|
25
|
+
|
26
|
+
options.description = data['descricao']
|
27
|
+
options.taken_installments = data['parcelas_assumidas']
|
28
|
+
|
29
|
+
options.installments = data['parcelas'].map do |parcela|
|
30
|
+
Installment.new({
|
31
|
+
:quantity => parcela['quantidade'],
|
32
|
+
:unitary_amount => BigDecimal.new(parcela['valor']),
|
33
|
+
:total_amount => BigDecimal.new(parcela['total'])
|
34
|
+
})
|
35
|
+
end
|
36
|
+
|
37
|
+
options
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_payload
|
42
|
+
{
|
43
|
+
:email => @payment.receiver.email,
|
44
|
+
:amount => @payment.total_amount,
|
45
|
+
:payment_method => @payment.payment_method.brand,
|
46
|
+
:api_key => @payment.receiver.api_key
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Akatus
|
4
|
+
|
5
|
+
module Services
|
6
|
+
|
7
|
+
class PaymentOptions < Akatus::Service
|
8
|
+
|
9
|
+
PATH = 'meios-de-pagamento'
|
10
|
+
METHOD = :post
|
11
|
+
|
12
|
+
def self.available
|
13
|
+
self.new.available
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.available_with_installments(*args)
|
17
|
+
self.new.available_with_installments(*args)
|
18
|
+
end
|
19
|
+
|
20
|
+
def available
|
21
|
+
data = send_request
|
22
|
+
result = {}
|
23
|
+
|
24
|
+
data['meios_de_pagamento'].each do |payment_type|
|
25
|
+
|
26
|
+
key = payment_description_to_type(payment_type['descricao'])
|
27
|
+
|
28
|
+
options = payment_type['bandeiras'].map do |payment_option|
|
29
|
+
PaymentOption.new({
|
30
|
+
:code => payment_option['codigo'],
|
31
|
+
:description => payment_option['descricao'],
|
32
|
+
:installments => payment_option['parcelas']
|
33
|
+
})
|
34
|
+
end
|
35
|
+
|
36
|
+
result[key] = {
|
37
|
+
:name => payment_type['descricao'],
|
38
|
+
:options => options
|
39
|
+
}
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
result
|
44
|
+
end
|
45
|
+
|
46
|
+
def available_with_installments(transaction)
|
47
|
+
|
48
|
+
result = available()
|
49
|
+
|
50
|
+
result.each do |type, group|
|
51
|
+
group[:options].each do |option|
|
52
|
+
transaction.payment_method = payment_type_to_class(type).new({ :brand => option.code })
|
53
|
+
option.installments = Installments.calculate(transaction)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
result
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
def payment_description_to_type(group)
|
62
|
+
case group
|
63
|
+
when 'Boleto Bancário' then :boleto
|
64
|
+
when 'Cartão de Crédito' then :credit_card
|
65
|
+
when 'TEF' then :eft
|
66
|
+
else raise "Unknown payment group: #{group}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def payment_type_to_class(type)
|
71
|
+
case type
|
72
|
+
when :boleto then Akatus::BoletoBancario
|
73
|
+
when :credit_card then Akatus::CreditCard
|
74
|
+
when :eft then Akatus::ElectronicFundsTransfer
|
75
|
+
else raise "Unknown payment group: #{group}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
def to_payload
|
81
|
+
{
|
82
|
+
:meios_de_pagamento => {
|
83
|
+
:correntista => {
|
84
|
+
:email => Akatus.config.email,
|
85
|
+
:api_key => Akatus.config.api_key
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Akatus
|
2
|
+
|
3
|
+
module Services
|
4
|
+
|
5
|
+
class Transaction < Akatus::Service
|
6
|
+
|
7
|
+
PATH = 'carrinho'
|
8
|
+
METHOD = :post
|
9
|
+
|
10
|
+
def self.form_url
|
11
|
+
Akatus.config.base_url + PATH
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.create(*args)
|
15
|
+
self.new.create(*args)
|
16
|
+
end
|
17
|
+
|
18
|
+
def create(payment)
|
19
|
+
|
20
|
+
@payment = payment
|
21
|
+
|
22
|
+
data = send_request
|
23
|
+
|
24
|
+
@payment.id = data['carrinho']
|
25
|
+
|
26
|
+
# TODO: improve; use constants?
|
27
|
+
@payment.status = data['status']
|
28
|
+
@payment.transaction_id = data['transacao']
|
29
|
+
|
30
|
+
if data['url_retorno']
|
31
|
+
@payment.url = data['url_retorno'].sub("https://www.akatus.com/", Akatus.config.base_url)
|
32
|
+
end
|
33
|
+
|
34
|
+
@payment
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
def status
|
39
|
+
# TODO: implement.
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_payload
|
43
|
+
@payment.to_payload
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Akatus
|
2
|
+
|
3
|
+
module Transferrable
|
4
|
+
|
5
|
+
def self.included(klass)
|
6
|
+
klass.send(:extend, ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(attrs = {})
|
10
|
+
attrs.each { |attr, val| send("#{attr}=", val) }
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_payload(include_root = true)
|
14
|
+
class_key = self.class.name.demodulize.underscore
|
15
|
+
|
16
|
+
payload = Hash[(self.class.attributes || []).map do |attr|
|
17
|
+
|
18
|
+
attr_value = send(attr)
|
19
|
+
|
20
|
+
next if attr_value.nil?
|
21
|
+
|
22
|
+
if attr_value.respond_to?(:to_payload)
|
23
|
+
attr_value = attr_value.to_payload(false)
|
24
|
+
end
|
25
|
+
|
26
|
+
if NUMERIC_FIELDS.include?(attr)
|
27
|
+
attr_value = Akatus.format_number(attr_value)
|
28
|
+
end
|
29
|
+
|
30
|
+
if (INTEGER_FIELDS + STRING_FIELDS).include?(attr)
|
31
|
+
attr_value = attr_value.to_s
|
32
|
+
end
|
33
|
+
|
34
|
+
[ I18n.t(attr, :locale => "pt-BR", :scope => [:payload, :attributes, class_key]), attr_value ]
|
35
|
+
end]
|
36
|
+
|
37
|
+
if include_root
|
38
|
+
{ I18n.t(class_key, :locale => "pt-BR", :scope => [:payload]) => payload }
|
39
|
+
else
|
40
|
+
payload
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
module ClassMethods
|
46
|
+
def attributes
|
47
|
+
@attributes
|
48
|
+
end
|
49
|
+
|
50
|
+
def transferrable_attrs(*args)
|
51
|
+
@attributes = *args
|
52
|
+
attr_accessor(*args)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
data/lib/akatus/version.rb
CHANGED
data/locales/pt-BR.yml
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
"pt-BR":
|
4
|
+
|
5
|
+
payload:
|
6
|
+
|
7
|
+
address: endereco
|
8
|
+
credit_card: cartao_de_credito
|
9
|
+
item: produto
|
10
|
+
payer: pagador
|
11
|
+
phone: telefone
|
12
|
+
receiver: recebedor
|
13
|
+
split_fee: comissionamento
|
14
|
+
transaction: carrinho
|
15
|
+
|
16
|
+
attributes:
|
17
|
+
|
18
|
+
address:
|
19
|
+
additional_details: complemento
|
20
|
+
city: cidade
|
21
|
+
country: pais
|
22
|
+
neighborhood: bairro
|
23
|
+
number: numero
|
24
|
+
postal_code: cep
|
25
|
+
reference: referencia
|
26
|
+
state: estado
|
27
|
+
street: logradouro
|
28
|
+
type: tipo
|
29
|
+
|
30
|
+
credit_card:
|
31
|
+
brand: meio_de_pagamento
|
32
|
+
expiration: expiracao
|
33
|
+
installments: parcelas
|
34
|
+
number: numero
|
35
|
+
security_code: codigo_de_seguranca
|
36
|
+
|
37
|
+
electronic_funds_transfer:
|
38
|
+
brand: meio_de_pagamento
|
39
|
+
|
40
|
+
item:
|
41
|
+
description: descricao
|
42
|
+
discount: desconto
|
43
|
+
price: preco
|
44
|
+
quantity: quantidade
|
45
|
+
reference: codigo
|
46
|
+
shipping_cost: frete
|
47
|
+
split_fee: comissionamento
|
48
|
+
weight: peso
|
49
|
+
|
50
|
+
payer:
|
51
|
+
name: nome
|
52
|
+
email: email
|
53
|
+
|
54
|
+
phone:
|
55
|
+
type: tipo
|
56
|
+
number: numero
|
57
|
+
|
58
|
+
receiver:
|
59
|
+
api_key: api_key
|
60
|
+
email: email
|
61
|
+
|
62
|
+
split_fee:
|
63
|
+
amount: valor
|
64
|
+
receiver: recebedor
|
65
|
+
type: tipo
|
66
|
+
|
67
|
+
transaction:
|
68
|
+
payer: pagador
|
69
|
+
receiver: recebedor
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe Akatus::Address do
|
4
|
+
|
5
|
+
let(:attrs) {
|
6
|
+
{
|
7
|
+
:type => 'entrega',
|
8
|
+
:street => 'Rua Labib Marrar',
|
9
|
+
:number => '129',
|
10
|
+
:neighborhood => 'Jardim Santa Cruz',
|
11
|
+
:city => 'São Paulo',
|
12
|
+
:state => 'SP',
|
13
|
+
:country => 'BRA',
|
14
|
+
:postal_code => '04182040',
|
15
|
+
:additional_details => 'Apto. 33',
|
16
|
+
:reference => 'Perto da padaria do Seu Zé'
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
let(:payload) {
|
21
|
+
{
|
22
|
+
'endereco' => {
|
23
|
+
'tipo' => 'entrega',
|
24
|
+
'logradouro' => 'Rua Labib Marrar',
|
25
|
+
'numero' => '129',
|
26
|
+
'bairro' => 'Jardim Santa Cruz',
|
27
|
+
'complemento' => 'Apto. 33',
|
28
|
+
'cidade' => 'São Paulo',
|
29
|
+
'estado' => 'SP',
|
30
|
+
'pais' => 'BRA',
|
31
|
+
'cep' => '04182040'
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
it_behaves_like Akatus::Transferrable
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
FactoryGirl.define do
|
4
|
+
|
5
|
+
factory :address, :class => Akatus::Address do
|
6
|
+
type 'entrega'
|
7
|
+
street 'Rua Labib Marrar'
|
8
|
+
number '129'
|
9
|
+
neighborhood 'Jardim Santa Cruz'
|
10
|
+
city 'São Paulo'
|
11
|
+
state 'SP'
|
12
|
+
country 'BRA'
|
13
|
+
postal_code '04182040'
|
14
|
+
additional_details 'Apto. 33'
|
15
|
+
reference 'Perto da padaria do Seu Zé'
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|