akatus 0.1.0 → 1.0.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.
- 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
|