baby-braspag 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,91 @@
1
+ module Braspag
2
+ module Crypto
3
+ class JarWebservice
4
+ def self.encrypt(map)
5
+ crypto_key = Braspag::Connection.instance.crypto_key
6
+ raise Braspag::IncompleteParams if map.nil?
7
+ raise Braspag::IncompleteParams unless map.is_a?(Hash)
8
+
9
+ request = ::HTTPI::Request.new encrypt_uri
10
+
11
+ data = {:key => crypto_key, :fields => map}
12
+
13
+ request.headers["Content-Type"] = "application/json"
14
+
15
+ request.body = data.to_json
16
+
17
+ response = ::HTTPI.post request
18
+
19
+ begin
20
+ response = JSON.parse(response.body)
21
+ rescue Exception => e
22
+ raise UnknownError
23
+ end
24
+
25
+ raise IncompleteParams if (
26
+ response["msg"] == "INVALID FORMAT" ||
27
+ response["msg"] == "INVALID FIELDS"
28
+ )
29
+
30
+ raise InvalidEncryptedKey if response["msg"] == "INVALID ENCRYPTED STRING"
31
+ raise InvalidCryptKey if response["msg"] == "INVALID KEY"
32
+
33
+ response["encrypt"]
34
+ end
35
+
36
+ def self.decrypt(encrypted, fields)
37
+ crypto_key = Braspag::Connection.instance.crypto_key
38
+ raise Braspag::InvalidEncryptedKey if encrypted.nil?
39
+ raise Braspag::InvalidEncryptedKey unless encrypted.is_a?(String)
40
+
41
+ raise Braspag::IncompleteParams if fields.nil?
42
+ raise Braspag::IncompleteParams unless fields.is_a?(Array)
43
+
44
+
45
+ request = ::HTTPI::Request.new decrypt_uri
46
+ request.body = {
47
+ "key" => crypto_key,
48
+ "encrypted" => encrypted,
49
+ "fields" => fields
50
+ }.to_json
51
+
52
+ request.headers["Content-Type"] = "application/json"
53
+
54
+ response = ::HTTPI.post request
55
+
56
+ begin
57
+ response = JSON.parse(response.body)
58
+ rescue Exception => e
59
+ raise UnknownError
60
+ end
61
+
62
+ raise IncompleteParams if (
63
+ response["msg"] == "INVALID FORMAT" ||
64
+ response["msg"] == "INVALID FIELDS"
65
+ )
66
+
67
+ raise InvalidEncryptedKey if response["msg"] == "INVALID ENCRYPTED STRING"
68
+
69
+ raise InvalidCryptKey if response["msg"] == "INVALID KEY"
70
+
71
+ map = {}
72
+ response["fields"].each do |key,value|
73
+ map[key.downcase.to_sym] = value
74
+ end
75
+ map
76
+ end
77
+
78
+ protected
79
+ def self.encrypt_uri
80
+ connection_uri = Braspag::Connection.instance.crypto_url
81
+ "#{connection_uri}/v1/encrypt.json"
82
+ end
83
+
84
+ def self.decrypt_uri
85
+ connection_uri = Braspag::Connection.instance.crypto_url
86
+ "#{connection_uri}/v1/decrypt.json"
87
+ end
88
+
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,100 @@
1
+ module Braspag
2
+ module Crypto
3
+ class Webservice
4
+ def self.encrypt(map)
5
+ connection = Braspag::Connection.instance
6
+ raise Braspag::IncompleteParams if map.nil?
7
+ raise Braspag::IncompleteParams unless map.is_a?(Hash)
8
+
9
+ request = ::HTTPI::Request.new self.uri
10
+
11
+ fields = "\n"
12
+ map.each do |key, value|
13
+ fields.concat(" <tns:string>#{key}=#{value}</tns:string>\n")
14
+ end
15
+
16
+ request.body = <<-STRING
17
+ <?xml version="1.0" encoding="utf-8"?>
18
+ <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
19
+ <env:Header />
20
+ <env:Body>
21
+ <tns:EncryptRequest xmlns:tns="https://www.pagador.com.br/webservice/BraspagGeneralService">
22
+ <tns:merchantId>#{connection.merchant_id}</tns:merchantId>
23
+ <tns:request>
24
+ #{fields}
25
+ </tns:request>
26
+ </tns:EncryptRequest>
27
+ </env:Body>
28
+ </env:Envelope>
29
+ STRING
30
+
31
+ request.headers["Content-Type"] = "text/xml"
32
+
33
+ response = ::HTTPI.post request
34
+
35
+ document = Nokogiri::XML(response.body)
36
+
37
+ raise Braspag::UnknownError if document.children.empty?
38
+
39
+ #melhorar este parser cof cof
40
+ response = document.children.children.children.children.children.to_s
41
+
42
+ raise Braspag::InvalidMerchantId if (response == 'Erro BP 011' || response == 'Erro BP 012')
43
+ raise Braspag::InvalidIP if (response == 'Erro BP 067' || response == 'Erro BP 068')
44
+
45
+ response
46
+ end
47
+
48
+ def self.decrypt(encripted_text)
49
+ connection = Braspag::Connection.instance
50
+
51
+ raise Braspag::IncompleteParams if encripted_text.nil?
52
+ raise Braspag::IncompleteParams unless encripted_text.is_a?(String)
53
+
54
+ request = ::HTTPI::Request.new self.uri
55
+
56
+ request.body = <<-STRING
57
+ <?xml version="1.0" encoding="utf-8"?>
58
+ <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
59
+ <env:Header />
60
+ <env:Body>
61
+ <tns:DecryptRequest xmlns:tns="https://www.pagador.com.br/webservice/BraspagGeneralService">
62
+ <tns:merchantId>#{connection.merchant_id}</tns:merchantId>
63
+ <tns:cryptString>#{encripted_text}</tns:cryptString>
64
+ </tns:DecryptRequest>
65
+ </env:Body>
66
+ </env:Envelope>
67
+ STRING
68
+
69
+ request.headers["Content-Type"] = "text/xml"
70
+
71
+ response = ::HTTPI.post request
72
+
73
+ document = Nokogiri::XML(response.body)
74
+ raise Braspag::UnknownError if document.children.empty?
75
+
76
+ result_error = document.children.children.children.children.children.first.content.to_s
77
+
78
+ raise Braspag::InvalidMerchantId if (result_error == 'Erro BP 011' || result_error == 'Erro BP 012')
79
+ raise Braspag::InvalidIP if (result_error == 'Erro BP 067' || result_error == 'Erro BP 068')
80
+
81
+ self.convert_request_to_map document
82
+ end
83
+
84
+ protected
85
+ def self.uri
86
+ connection = Braspag::Connection.instance
87
+ "#{connection.braspag_url}/BraspagGeneralService/BraspagGeneralService.asmx"
88
+ end
89
+
90
+ def self.convert_request_to_map(document)
91
+ map = {}
92
+ document.children.children.children.children.children.each do |n|
93
+ values = n.content.to_s.split("=")
94
+ map[values[0].downcase.to_sym] = values[1]
95
+ end
96
+ map
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,90 @@
1
+ module Braspag
2
+ class Eft < PaymentMethod
3
+
4
+ PAYMENT_METHODS = {
5
+ :bradesco => 11,
6
+ :itau => 12,
7
+ :banco_do_brasil => 15,
8
+ :banco_real => 16,
9
+ :banrisul => 30,
10
+ :unibanco => 31
11
+ }
12
+
13
+ MAPPING = {
14
+ :merchant_id => "Id_Loja",
15
+ :order_id => "VENDAID",
16
+ :customer_name => "nome",
17
+ :customer_id => "CPF",
18
+ :amount => "VALOR",
19
+ :payment_method => "CODPAGAMENTO",
20
+ :installments => "PARCELAS",
21
+ :has_interest => "TIPOPARCELADO"
22
+ }
23
+
24
+ ACTION_URI = "/pagador/passthru.asp"
25
+
26
+ def self.generate(params, crypto_strategy = nil)
27
+ connection = Braspag::Connection.instance
28
+ params[:merchant_id] = connection.merchant_id
29
+
30
+ params = self.normalize_params(params)
31
+ self.check_params(params)
32
+
33
+ data = {}
34
+
35
+ MAPPING.each do |k, v|
36
+ case k
37
+ when :payment_method
38
+ data[v] = PAYMENT_METHODS[params[:payment_method]]
39
+ when :amount
40
+ data[v] = Utils.convert_decimal_to_string(params[:amount])
41
+ else
42
+ data[v] = params[k] || ""
43
+ end
44
+ end
45
+
46
+ html = "<form id=\"form_tef_#{params[:order_id]}\" name=\"form_tef_#{params[:order_id]}\" action=\"#{self.action_url}\" method=\"post\">"
47
+
48
+ if crypto_strategy.nil?
49
+ data.each do |key, value|
50
+ html << "<input type=\"text\" name=\"#{key}\" value=\"#{value}\" />"
51
+ end
52
+ else
53
+ data.delete("Id_Loja")
54
+ html << "<input type=\"text\" name=\"Id_Loja\" value=\"#{params[:merchant_id]}\" />"
55
+ html << "<input type=\"text\" name=\"crypt\" value=\"#{crypto_strategy.encrypt(data)}\" />"
56
+ end
57
+
58
+ html << "</form><script type=\"text/javascript\" charset=\"utf-8\">document.forms[\"form_tef_#{params[:order_id]}\"].submit();</script>"
59
+
60
+ html
61
+ end
62
+
63
+ def self.normalize_params(params)
64
+ params = super
65
+
66
+ params[:installments] = params[:installments].to_i unless params[:installments].nil?
67
+ params[:installments] ||= 1
68
+
69
+ params[:has_interest] = params[:has_interest] == true ? "1" : "0"
70
+
71
+ params
72
+ end
73
+
74
+ def self.check_params(params)
75
+ super
76
+
77
+ if params[:installments]
78
+ raise InvalidInstallments if params[:installments].to_i < 1 || params[:installments].to_i > 99
79
+ end
80
+
81
+ if params[:has_interest]
82
+ raise InvalidHasInterest if params[:has_interest] != "1" && params[:has_interest] != "0"
83
+ end
84
+ end
85
+
86
+ def self.action_url
87
+ Braspag::Connection.instance.braspag_url + ACTION_URI
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,39 @@
1
+ module Braspag
2
+ class InvalidConnection < Exception ; end
3
+ class InvalidMerchantId < Exception ; end
4
+ class InvalidConnection < Exception ; end
5
+ class IncompleteParams < Exception ; end
6
+ class InvalidOrderId < Exception ; end
7
+ class InvalidCustomerName < Exception ; end
8
+ class InvalidCustomerId < Exception ; end
9
+ class InvalidNumber < Exception ; end
10
+ class InvalidInstructions < Exception ; end
11
+ class InvalidExpirationDate < Exception ; end
12
+ class InvalidStringFormat < Exception ; end
13
+ class InvalidPost < Exception ; end
14
+ class InvalidPaymentMethod < Exception ; end
15
+ class InvalidAmount < Exception ; end
16
+ class InvalidInstallments < Exception ; end
17
+ class InvalidHasInterest < Exception ; end
18
+ class InvalidIP < Exception; end
19
+ class InvalidCryptKey < Exception; end
20
+ class InvalidEncryptedKey < Exception; end
21
+ class InvalidHolder < Exception ; end
22
+ class InvalidExpirationDate < Exception ; end
23
+ class InvalidSecurityCode < Exception ; end
24
+ class InvalidType < Exception ; end
25
+ class InvalidNumberPayments < Exception ; end
26
+ class InvalidNumberInstallments < Exception ; end
27
+ class InvalidJustClickKey < Exception ; end
28
+ class UnknownError < Exception ; end
29
+
30
+ class Connection
31
+ class InvalidMerchantId < Exception ; end
32
+ class InvalidEnv < Exception ; end
33
+ class InvalidBraspagUrl < Exception ; end
34
+ end
35
+
36
+ class Order
37
+ class InvalidData < Exception; end
38
+ end
39
+ end
@@ -0,0 +1,42 @@
1
+ module Braspag
2
+ class Order
3
+ PRODUCTION_INFO_URI = "/webservices/pagador/pedido.asmx/GetDadosPedido"
4
+ HOMOLOGATION_INFO_URI = "/pagador/webservice/pedido.asmx/GetDadosPedido"
5
+
6
+ def self.status(order_id)
7
+ connection = Braspag::Connection.instance
8
+
9
+ raise InvalidOrderId unless Braspag::PaymentMethod.valid_order_id?(order_id)
10
+
11
+ data = {
12
+ :loja => connection.merchant_id, :numeroPedido => order_id.to_s
13
+ }
14
+
15
+ response = Braspag::Poster.new(self.status_url).do_post(:order_status, data)
16
+
17
+ response = Utils::convert_to_map(response.body, {
18
+ :authorization => "CodigoAutorizacao",
19
+ :error_code => "CodigoErro",
20
+ :error_message => "MensagemErro",
21
+ :payment_method => "CodigoPagamento",
22
+ :payment_method_name => "FormaPagamento",
23
+ :installments => "NumeroParcelas",
24
+ :status => "Status",
25
+ :amount => "Valor",
26
+ :cancelled_at => "DataCancelamento",
27
+ :paid_at => "DataPagamento",
28
+ :order_date => "DataPedido",
29
+ :transaction_id => "TransId",
30
+ :tid => "BraspagTid"
31
+ })
32
+
33
+ raise InvalidData if response[:authorization].nil?
34
+ response
35
+ end
36
+
37
+ def self.status_url
38
+ connection = Braspag::Connection.instance
39
+ connection.braspag_url + (connection.production? ? PRODUCTION_INFO_URI : HOMOLOGATION_INFO_URI)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,72 @@
1
+ module Braspag
2
+ class PaymentMethod
3
+ PAYMENT_METHODS = {
4
+ # BRASIL
5
+ :amex_2p => 18, # American Express 2 Party
6
+ :cielo_noauth_visa => 71, # Cielo webservice captura automática sem autenticação - Visa
7
+ :cielo_preauth_visa => 73, # Cielo webservice preauth sem autenticação - Visa
8
+ :cielo_noauth_mastercard => 120, # Cielo webservice captura automática sem autenticação - Mastercard
9
+ :cielo_preauth_mastercard => 122, # Cielo webservice preauth sem autenticação - Mastercard
10
+ :cielo_noauth_elo => 126, # Cielo webservice captura automática sem autenticação - ELO
11
+ :cielo_noauth_diners => 130, # Cielo webservice captura automática sem autenticação - Diners
12
+ :redecard => 20, # Redecard Mastercard/Diners/Visa
13
+ :redecard_preauth => 42, # Redecard preauth Mastercard/Diners/Visa
14
+ :cielo_sitef => 57, # Cielo SITEF
15
+ :hipercard_sitef => 62, # Hipercard SITEF
16
+ :hipercard_moip => 90, # Hipercard MOIP
17
+ :oi_paggo => 55, # OiPaggo
18
+ :amex_sitef => 58, # Amex SITEF
19
+ :aura_dtef => 37, # Aura DTEF
20
+ :redecard_sitef => 44, # Redecard SITEF - Mastercard/Diners
21
+ # MÉXICO
22
+ :mex_amex_2p => 45, # American Express 2 Party
23
+ :mex_banorte_visa => 50, # Banorte Visa
24
+ :mex_banorte_diners => 52, # Banorte Diners
25
+ :mex_banorte_mastercard => 53, # Banorte Mastercard
26
+ # COLÔMBIA
27
+ :col_visa => 63, # Visa
28
+ :col_amex => 65, # Amex
29
+ :col_diners => 66, # Diners
30
+ # INTERNACIONAL
31
+ :paypal_express => 35, # PayPal Express Checkout
32
+ # HOMOLOGATION
33
+ :braspag => 997
34
+ }
35
+
36
+ def self.payment_method_from_id(code)
37
+ self::PAYMENT_METHODS.invert.values_at(code).first
38
+ end
39
+
40
+ def self.normalize_params(params)
41
+ if params[:amount] && !params[:amount].is_a?(BigDecimal)
42
+ params[:amount] = BigDecimal.new(params[:amount].to_s)
43
+ end
44
+
45
+ params
46
+ end
47
+
48
+ def self.check_params(params)
49
+ [:order_id, :amount, :payment_method].each do |param|
50
+ raise IncompleteParams if params[param].nil?
51
+ end
52
+
53
+ raise InvalidOrderId unless self.valid_order_id?(params[:order_id])
54
+
55
+ if params[:customer_name]
56
+ raise InvalidCustomerName unless (1..255).include?(params[:customer_name].to_s.size)
57
+ end
58
+
59
+ if params[:customer_id]
60
+ raise InvalidCustomerId unless (11..18).include?(params[:customer_id].to_s.size)
61
+ end
62
+
63
+ unless params[:payment_method].is_a?(Symbol) && self::PAYMENT_METHODS[params[:payment_method]]
64
+ raise InvalidPaymentMethod
65
+ end
66
+ end
67
+
68
+ def self.valid_order_id?(order_id)
69
+ (order_id.is_a?(String) || order_id.is_a?(Fixnum)) && (1..50).include?(order_id.to_s.size)
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,36 @@
1
+ module Braspag
2
+ class Poster
3
+ def initialize(url)
4
+ @request = ::HTTPI::Request.new(url)
5
+ end
6
+
7
+ def do_post(method, data)
8
+ @request.body = data
9
+ @request.proxy = Braspag.proxy_address if Braspag.proxy_address
10
+
11
+ with_logger(method) do
12
+ ::HTTPI.post @request
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def with_logger(method)
19
+ if Braspag::logger
20
+ Braspag::logger.info("[Braspag] ##{method}: #{@request.url}, data: #{mask_data(@request.body).inspect}")
21
+ response = yield
22
+ Braspag::logger.info("[Braspag] ##{method} returns: #{response.body.inspect}")
23
+ else
24
+ response = yield
25
+ end
26
+ response
27
+ end
28
+
29
+ def mask_data(data)
30
+ copy_data = Rack::Utils.parse_nested_query(data)
31
+ copy_data['cardNumber'] = "************%s" % copy_data['cardNumber'][-4..-1] if copy_data['cardNumber']
32
+ copy_data['securityCode'] = "***" if copy_data['securityCode']
33
+ copy_data
34
+ end
35
+ end
36
+ end