akatus 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -16
  3. data/.rspec +2 -0
  4. data/LICENSE +1 -1
  5. data/Rakefile +6 -1
  6. data/akatus.gemspec +18 -11
  7. data/config/i18n.rb +3 -0
  8. data/lib/akatus.rb +34 -4
  9. data/lib/akatus/address.rb +11 -0
  10. data/lib/akatus/configuration.rb +43 -0
  11. data/lib/akatus/errors.rb +4 -0
  12. data/lib/akatus/formatters.rb +22 -0
  13. data/lib/akatus/installment.rb +6 -0
  14. data/lib/akatus/installment_options.rb +24 -0
  15. data/lib/akatus/item.rb +24 -0
  16. data/lib/akatus/payer.rb +35 -0
  17. data/lib/akatus/payment.rb +61 -0
  18. data/lib/akatus/payment_option.rb +6 -0
  19. data/lib/akatus/payment_types.rb +37 -0
  20. data/lib/akatus/phone.rb +6 -0
  21. data/lib/akatus/receiver.rb +6 -0
  22. data/lib/akatus/service.rb +34 -0
  23. data/lib/akatus/services/installments.rb +54 -0
  24. data/lib/akatus/services/payment_options.rb +95 -0
  25. data/lib/akatus/services/transaction.rb +50 -0
  26. data/lib/akatus/split_fee.rb +6 -0
  27. data/lib/akatus/transferrable.rb +58 -0
  28. data/lib/akatus/version.rb +1 -1
  29. data/locales/pt-BR.yml +69 -0
  30. data/spec/address_spec.rb +38 -0
  31. data/spec/factories/address_factories.rb +18 -0
  32. data/spec/factories/item_factories.rb +35 -0
  33. data/spec/factories/payer_factories.rb +8 -0
  34. data/spec/factories/phone_factories.rb +6 -0
  35. data/spec/item_spec.rb +42 -0
  36. data/spec/payer_spec.rb +31 -0
  37. data/spec/phone_spec.rb +23 -0
  38. data/spec/services/installments_spec.rb +36 -0
  39. data/spec/services/payment_options_spec.rb +22 -0
  40. data/spec/services/transaction_spec.rb +80 -0
  41. data/spec/spec_helper.rb +31 -0
  42. data/spec/support/configuration.rb +7 -0
  43. data/spec/support/shared_examples/transferrable_example.rb +22 -0
  44. metadata +142 -12
  45. data/LICENSE.txt +0 -22
  46. data/lib/akatus/configuracao.rb +0 -40
  47. data/lib/akatus/formatadores.rb +0 -7
@@ -0,0 +1,6 @@
1
+ module Akatus
2
+ class Receiver
3
+ include Transferrable
4
+ transferrable_attrs :email, :api_key
5
+ end
6
+ end
@@ -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,6 @@
1
+ module Akatus
2
+ class SplitFee
3
+ include Transferrable
4
+ transferrable_attrs :receiver, :type, :amount
5
+ end
6
+ 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
@@ -1,3 +1,3 @@
1
1
  module Akatus
2
- VERSION = "0.1.0"
2
+ VERSION = "1.0.0"
3
3
  end
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