edools_mymoip 0.8.1

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.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.gitignore +15 -0
  4. data/.travis.yml +4 -0
  5. data/CHANGELOG.md +128 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +20 -0
  8. data/README.md +3 -0
  9. data/Rakefile +10 -0
  10. data/lib/mymoip.rb +57 -0
  11. data/lib/mymoip/bank_debit.rb +22 -0
  12. data/lib/mymoip/commission.rb +54 -0
  13. data/lib/mymoip/credit_card.rb +73 -0
  14. data/lib/mymoip/exceptions.rb +15 -0
  15. data/lib/mymoip/formatter.rb +23 -0
  16. data/lib/mymoip/instruction.rb +134 -0
  17. data/lib/mymoip/json_parser.rb +11 -0
  18. data/lib/mymoip/payer.rb +75 -0
  19. data/lib/mymoip/payment.rb +10 -0
  20. data/lib/mymoip/payment_methods.rb +46 -0
  21. data/lib/mymoip/payment_slip.rb +74 -0
  22. data/lib/mymoip/payments/bank_debit_payment.rb +27 -0
  23. data/lib/mymoip/payments/credit_card_payment.rb +53 -0
  24. data/lib/mymoip/payments/payment_slip_payment.rb +12 -0
  25. data/lib/mymoip/purchase.rb +40 -0
  26. data/lib/mymoip/request.rb +34 -0
  27. data/lib/mymoip/requests/payment_request.rb +53 -0
  28. data/lib/mymoip/requests/transparent_request.rb +36 -0
  29. data/lib/mymoip/validators.rb +12 -0
  30. data/lib/mymoip/version.rb +3 -0
  31. data/mymoip.gemspec +30 -0
  32. data/test/fixtures/fixture.rb +73 -0
  33. data/test/fixtures/vcr_cassettes/payment_request.yml +37 -0
  34. data/test/fixtures/vcr_cassettes/payment_request_with_payment_slip.yml +32 -0
  35. data/test/fixtures/vcr_cassettes/transparent_request.yml +34 -0
  36. data/test/fixtures/vcr_cassettes/transparent_request_with_commissions.yml +35 -0
  37. data/test/lib/test_bank_debit.rb +36 -0
  38. data/test/lib/test_bank_debit_payment.rb +32 -0
  39. data/test/lib/test_commission.rb +121 -0
  40. data/test/lib/test_credit_card_payment.rb +107 -0
  41. data/test/lib/test_creditcard.rb +206 -0
  42. data/test/lib/test_formatter.rb +49 -0
  43. data/test/lib/test_instruction.rb +243 -0
  44. data/test/lib/test_mymoip.rb +79 -0
  45. data/test/lib/test_payer.rb +249 -0
  46. data/test/lib/test_payment.rb +15 -0
  47. data/test/lib/test_payment_methods.rb +54 -0
  48. data/test/lib/test_payment_request.rb +120 -0
  49. data/test/lib/test_payment_slip.rb +78 -0
  50. data/test/lib/test_payment_slip_payment.rb +8 -0
  51. data/test/lib/test_purchase.rb +109 -0
  52. data/test/lib/test_request.rb +88 -0
  53. data/test/lib/test_transparent_request.rb +71 -0
  54. data/test/lib/test_validators.rb +13 -0
  55. data/test/live_test.rb +4 -0
  56. data/test/test_helper.rb +17 -0
  57. metadata +251 -0
@@ -0,0 +1,134 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/validators.rb')
2
+ module MyMoip
3
+ class Instruction
4
+ include Validators
5
+ include ActiveModel::Validations
6
+
7
+ attr_accessor :id, :payment_reason, :values, :payer,
8
+ :commissions, :fee_payer_login, :payment_receiver_login,
9
+ :payment_receiver_name, :installments,
10
+ :notification_url, :return_url,
11
+ :payment_slip, :payment_methods
12
+
13
+ validates_presence_of :id, :payment_reason, :values, :payer
14
+ validate :commissions_value_must_be_lesser_than_values
15
+ validate :payment_receiver_presence_in_commissions
16
+ validate :url_format_validation
17
+
18
+ def initialize(attrs)
19
+ attrs.each do |attr, value|
20
+ public_send(:"#{attr}=", value)
21
+ end
22
+
23
+ self.commissions ||= []
24
+ end
25
+
26
+ def to_xml(root = nil)
27
+ raise InvalidPayer if payer.invalid?
28
+ raise InvalidPaymentSlip if payment_slip and payment_slip.invalid?
29
+ raise InvalidInstruction if self.invalid?
30
+ if invalid_commission = commissions.detect { |c| c.invalid? }
31
+ raise InvalidComission, invalid_commission
32
+ end
33
+
34
+ xml = ""
35
+ root = Builder::XmlMarkup.new(target: xml)
36
+
37
+ root.EnviarInstrucao do |n1|
38
+ n1.InstrucaoUnica(TipoValidacao: "Transparente") do |n2|
39
+ n2.Razao(@payment_reason)
40
+ n2.Valores do |n3|
41
+ @values.each { |v| n3.Valor("%.2f" % v, moeda: "BRL") }
42
+ end
43
+ n2.IdProprio(@id)
44
+
45
+ if @installments
46
+ n2.Parcelamentos do |n4|
47
+ @installments.each do |installments|
48
+ n4.Parcelamento do |n5|
49
+ n5.MinimoParcelas(installments[:min])
50
+ n5.MaximoParcelas(installments[:max])
51
+ if installments[:forward_taxes]
52
+ n5.Repassar(installments[:forward_taxes])
53
+ end
54
+ if installments[:receive_in_installments]
55
+ n5.Recebimento('Parcelado')
56
+ end
57
+ n5.Juros(installments[:fee])
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ commissions_to_xml(n2) if commissions.any?
64
+ payment_receiver_to_xml(n2) if payment_receiver_login
65
+
66
+ n2.Pagador { |n3| @payer.to_xml(n3) }
67
+
68
+ unless @payment_methods.blank? or @payment_methods.using_all?
69
+ n2.FormasPagamento { |n3| @payment_methods.to_xml(n3) }
70
+ end
71
+ unless @payment_slip.blank?
72
+ n2.Boleto { |n3| @payment_slip.to_xml(n3) }
73
+ end
74
+ unless @notification_url.blank?
75
+ n2.URLNotificacao(@notification_url)
76
+ end
77
+ unless @return_url.blank?
78
+ n2.URLRetorno(@return_url)
79
+ end
80
+ end
81
+ end
82
+
83
+ xml
84
+ end
85
+
86
+ def commissions_sum
87
+ commissions.inject(0) do |sum, commission|
88
+ sum + commission.gross_amount(self)
89
+ end
90
+ end
91
+
92
+ def gross_amount
93
+ values ? values.reduce(0) { |sum, value| sum + value } : 0
94
+ end
95
+
96
+ protected
97
+
98
+ def commissions_value_must_be_lesser_than_values
99
+ if commissions_sum > gross_amount
100
+ errors.add(:commissions, "Commissions value sum is greater than instruction value sum")
101
+ end
102
+ end
103
+
104
+ def payment_receiver_presence_in_commissions
105
+ if commissions.find { |c| c.receiver_login == payment_receiver_login }
106
+ errors.add(:payment_receiver_login, "Payment receiver can't be commissioned")
107
+ end
108
+ end
109
+
110
+ def commissions_to_xml(node)
111
+ node.Comissoes do |n|
112
+ commissions.each { |c| c.to_xml(n) }
113
+ n.PagadorTaxa { |pt| pt.LoginMoIP(fee_payer_login) } if fee_payer_login
114
+ end
115
+ end
116
+
117
+ def payment_receiver_to_xml(node)
118
+ node.Recebedor do |n|
119
+ n.LoginMoIP(payment_receiver_login)
120
+ n.Apelido(payment_receiver_name)
121
+ end
122
+ end
123
+
124
+ def url_format_validation
125
+ if not notification_url.blank? and not valid_url?(notification_url)
126
+ errors.add(:notification_url, 'Invalid URL format')
127
+ end
128
+
129
+ if not return_url.blank? and not valid_url?(return_url)
130
+ errors.add(:return_url, 'Invalid URL format.')
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,11 @@
1
+ module MyMoip
2
+ class JsonParser
3
+ def self.call(body, format)
4
+ if format == :json
5
+ JSON.parse body.match(/\?\((?<valid_json>.+)\)/)[:valid_json]
6
+ else
7
+ body
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,75 @@
1
+ module MyMoip
2
+ class Payer
3
+ include ActiveModel::Validations
4
+
5
+ attr_accessor :id, :name, :email,
6
+ :address_street, :address_street_number,
7
+ :address_street_extra, :address_neighbourhood,
8
+ :address_city, :address_state, :address_country,
9
+ :address_cep, :address_phone
10
+
11
+ validates_presence_of :id, :name, :email, :address_street,
12
+ :address_street_number, :address_neighbourhood,
13
+ :address_city, :address_state, :address_country,
14
+ :address_cep, :address_phone
15
+ validates_length_of :address_state, is: 2
16
+ validates_length_of :address_country, is: 3
17
+ validates_length_of :address_cep, is: 8
18
+ validates_length_of :address_phone, within: 10..11
19
+
20
+ def initialize(attrs)
21
+ attrs.each do |attr, value|
22
+ public_send(:"#{attr}=", value)
23
+ end
24
+ end
25
+
26
+ def address_cep=(value)
27
+ value.gsub!(/\D*/, '') unless value.nil?
28
+ @address_cep = value
29
+ end
30
+
31
+ def address_state=(value)
32
+ value = value.upcase unless value.nil?
33
+ @address_state = value
34
+ end
35
+
36
+ def address_country=(value)
37
+ value = value.upcase unless value.nil?
38
+ @address_country = value
39
+ end
40
+
41
+ def address_phone=(value)
42
+ unless value.nil?
43
+ # Removes non-digits
44
+ value.gsub!(/\D*/, '')
45
+ # Removes zeros in the beginning
46
+ value.gsub!(/\A0*/, '')
47
+ end
48
+ @address_phone = value
49
+ end
50
+
51
+ def to_xml(root = nil, formatter = MyMoip::Formatter)
52
+ if root.nil?
53
+ xml = ""
54
+ root ||= Builder::XmlMarkup.new(target: xml)
55
+ end
56
+
57
+ root.Nome(@name)
58
+ root.Email(@email)
59
+ root.IdPagador(@id)
60
+ root.EnderecoCobranca do |n1|
61
+ n1.Logradouro(@address_street)
62
+ n1.Numero(@address_street_number)
63
+ n1.Complemento(@address_street_extra)
64
+ n1.Bairro(@address_neighbourhood)
65
+ n1.Cidade(@address_city)
66
+ n1.Estado(@address_state)
67
+ n1.Pais(@address_country)
68
+ n1.CEP(formatter.cep(@address_cep))
69
+ n1.TelefoneFixo(formatter.phone(@address_phone))
70
+ end
71
+
72
+ xml
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,10 @@
1
+ module MyMoip
2
+ class Payment
3
+ def self.payment_method
4
+ name.gsub(/^MyMoip::|Payment$/, '').gsub(/([a-z])([A-Z])/,'\1_\2').downcase.to_sym
5
+ end
6
+ end
7
+ end
8
+
9
+ payments = Dir[File.dirname(__FILE__) + "/payments/*.rb"]
10
+ payments.each { |f| require f }
@@ -0,0 +1,46 @@
1
+ module MyMoip
2
+ class PaymentMethods
3
+ include ActiveModel::Validations
4
+
5
+ attr_accessor :payment_slip, :credit_card, :debit, :debit_card, :financing,
6
+ :moip_wallet
7
+
8
+ validates_inclusion_of :payment_slip, :credit_card, :debit, :debit_card,
9
+ :financing, :moip_wallet, in: [true, false]
10
+
11
+ def initialize(attrs = {})
12
+ self.payment_slip = true
13
+ self.credit_card = true
14
+ self.debit = true
15
+ self.debit_card = true
16
+ self.financing = true
17
+ self.moip_wallet = true
18
+
19
+ attrs.each do |attr, value|
20
+ public_send(:"#{attr}=", value)
21
+ end
22
+ end
23
+
24
+ def to_xml(root = nil)
25
+ if root.nil?
26
+ xml = ""
27
+ root ||= Builder::XmlMarkup.new(target: xml)
28
+ end
29
+
30
+ if not using_all?
31
+ root.FormaPagamento('BoletoBancario') if payment_slip
32
+ root.FormaPagamento('CartaoDeCredito') if credit_card
33
+ root.FormaPagamento('DebitoBancario') if debit
34
+ root.FormaPagamento('CartaoDeDebito') if debit_card
35
+ root.FormaPagamento('FinanciamentoBancario') if financing
36
+ root.FormaPagamento('CarteiraMoIP') if moip_wallet
37
+ end
38
+
39
+ xml
40
+ end
41
+
42
+ def using_all?
43
+ payment_slip and credit_card and debit and debit_card and financing and moip_wallet
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,74 @@
1
+ module MyMoip
2
+ class PaymentSlip
3
+ include Validators
4
+ include ActiveModel::Validations
5
+
6
+ attr_accessor :expiration_date, :expiration_days, :expiration_days_type,
7
+ :instruction_line_1, :instruction_line_2,
8
+ :instruction_line_3, :logo_url
9
+
10
+ validates_length_of :instruction_line_1, maximum: 63, allow_nil: true
11
+ validates_length_of :instruction_line_2, maximum: 63, allow_nil: true
12
+ validates_length_of :instruction_line_3, maximum: 63, allow_nil: true
13
+
14
+ validates_numericality_of :expiration_days, less_than_or_equal_to: 99,
15
+ allow_nil: true
16
+ validates_inclusion_of :expiration_days_type,
17
+ in: [:business_day, :calendar_day], allow_nil: true
18
+
19
+ validate :logo_url_format
20
+ validate :expiration_date_format
21
+
22
+ def initialize(attrs)
23
+ attrs.each do |attr, value|
24
+ public_send(:"#{attr}=", value)
25
+ end
26
+ end
27
+
28
+ def to_xml(root = nil)
29
+ raise InvalidPaymentSlip if invalid?
30
+
31
+ if root.nil?
32
+ xml = ""
33
+ root ||= Builder::XmlMarkup.new(target: xml)
34
+ end
35
+
36
+ root.DataVencimento(expiration_date.strftime('%Y-%m-%dT%H:%M:%S.%L%:z')) unless expiration_date.blank?
37
+
38
+ if expiration_days
39
+ type = nil
40
+ if expiration_days_type
41
+ if expiration_days_type == :business_day
42
+ type = {'Tipo' => 'Uteis'}
43
+ elsif expiration_days_type == :calendar_day
44
+ type = {'Tipo' => 'Corridos'}
45
+ end
46
+ end
47
+
48
+ root.DiasExpiracao(expiration_days, type)
49
+ end
50
+
51
+ root.Instrucao1(instruction_line_1) unless instruction_line_1.blank?
52
+ root.Instrucao2(instruction_line_2) unless instruction_line_2.blank?
53
+ root.Instrucao3(instruction_line_3) unless instruction_line_3.blank?
54
+
55
+ root.URLLogo(logo_url) unless logo_url.blank?
56
+
57
+ xml
58
+ end
59
+
60
+ private
61
+
62
+ def logo_url_format
63
+ if not logo_url.blank? and not valid_url?(logo_url)
64
+ errors.add(:logo_url, 'Invalid URL format.')
65
+ end
66
+ end
67
+
68
+ def expiration_date_format
69
+ if not expiration_date.blank? and not expiration_date.instance_of?(DateTime)
70
+ errors.add(:expiration_date, 'Expiration date must be a DateTime object.')
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,27 @@
1
+ module MyMoip
2
+ class BankDebitPayment < Payment
3
+ attr_accessor :bank_debit
4
+
5
+ def initialize(bank_debit)
6
+ @bank_debit = bank_debit
7
+ end
8
+
9
+ def to_json
10
+ raise InvalidBankDebit, "No bank debit information provided." if @bank_debit.nil?
11
+ raise InvalidBankDebit if @bank_debit.invalid?
12
+
13
+ json = {
14
+ Forma: "DebitoBancario",
15
+ }
16
+
17
+ json[:Instituicao] = {
18
+ banco_do_brasil: "BancoDoBrasil",
19
+ bradesco: "Bradesco",
20
+ banrisul: "Banrisul",
21
+ itau: "Itau"
22
+ }.fetch(@bank_debit.bank)
23
+
24
+ json
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,53 @@
1
+ module MyMoip
2
+ class CreditCardPayment < Payment
3
+ attr_accessor :credit_card, :installments
4
+
5
+ def initialize(credit_card, opts = {})
6
+ self.credit_card = credit_card
7
+ self.installments = opts[:installments] || 1
8
+ end
9
+
10
+ def to_json(formatter = MyMoip::Formatter)
11
+ raise InvalidCreditCard, 'No credit card provided.' if credit_card.nil?
12
+ raise InvalidCreditCard if credit_card.invalid?
13
+
14
+ json = {
15
+ Forma: "CartaoCredito",
16
+ Parcelas: @installments,
17
+ CartaoCredito: {
18
+ Numero: credit_card.card_number,
19
+ Expiracao: credit_card.expiration_date,
20
+ CodigoSeguranca: credit_card.security_code
21
+ }
22
+ }
23
+
24
+ json[:CartaoCredito][:Portador] = {
25
+ Nome: credit_card.owner_name,
26
+ DataNascimento: (credit_card.owner_birthday and
27
+ formatter.date(credit_card.owner_birthday)),
28
+ Telefone: (credit_card.owner_phone and
29
+ formatter.phone(credit_card.owner_phone)),
30
+ Identidade: (credit_card.owner_cpf and
31
+ formatter.cpf(credit_card.owner_cpf))
32
+ }
33
+
34
+ json[:Instituicao] = {
35
+ american_express: "AmericanExpress",
36
+ diners: "Diners",
37
+ hipercard: "Hipercard",
38
+ mastercard: "Mastercard",
39
+ visa: "Visa"
40
+ }.fetch(credit_card.logo)
41
+
42
+ if cash?
43
+ json[:Recebimento] = "AVista"
44
+ end
45
+
46
+ json
47
+ end
48
+
49
+ def cash?
50
+ @installments == 1
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,12 @@
1
+ module MyMoip
2
+ class PaymentSlipPayment < Payment
3
+
4
+ def to_json
5
+ json = {
6
+ Forma: 'BoletoBancario'
7
+ }
8
+
9
+ json
10
+ end
11
+ end
12
+ end