cbraspag 0.9.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.
@@ -0,0 +1,58 @@
1
+ require "bigdecimal"
2
+
3
+ module Braspag
4
+ class Connection
5
+ def generate_billet(order, billet)
6
+ response = self.post(:generate_billet, order, billet)
7
+
8
+ status = (response[:status] == "0")
9
+
10
+ Response.new(status,
11
+ response[:message],
12
+ response,
13
+ :test => homologation?,
14
+ :authorization => response[:number])
15
+ end
16
+ end
17
+
18
+ class Billet
19
+ include ::ActiveAttr::Model
20
+
21
+ class DueDateValidator < ActiveModel::EachValidator
22
+ def validate_each(record, attribute, value)
23
+ unless (
24
+ value.kind_of?(Time) || value.kind_of?(Date)
25
+ )
26
+ record.errors.add attribute, "invalid date"
27
+ end
28
+ end
29
+ end
30
+
31
+ attr_accessor :id, :instructions, :due_date_on, :url
32
+
33
+ validates :id, :length => {:minimum => 1, :maximum => 255, :on => :generate, :allow_blank => true }
34
+ validates :instructions, :length => {:minimum => 1, :maximum => 512, :on => :generate, :allow_blank => true }
35
+ validates :due_date_on, :presence => { :on => :generate }
36
+ validates :due_date_on, :due_date => { :on => :generate }
37
+
38
+ def convert_to(method)
39
+ self.send("to_#{method}")
40
+ end
41
+
42
+ def to_generate_billet
43
+ {
44
+ :number => self.id.to_s,
45
+ :instructions => self.instructions.to_s,
46
+ :expiration_date => self.due_date_on.strftime("%d/%m/%y")
47
+ }
48
+ end
49
+
50
+ def populate!(method, response)
51
+ self.send("populate_#{method}!", response)
52
+ end
53
+
54
+ def populate_generate_billet!(response)
55
+ self.url = response[:url]
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,203 @@
1
+ module Braspag
2
+ class Connection
3
+ def purchase(order, credit_card)
4
+ resp = self.authorize(order, credit_card)
5
+ resp = self.capture(order) if resp.success?
6
+ resp
7
+ end
8
+
9
+ def authorize(order, credit_card)
10
+ response = self.post(:authorize, order, credit_card)
11
+
12
+ status = (response[:status] == "0" || response[:status] == "1")
13
+
14
+ Response.new(status,
15
+ response[:message],
16
+ response,
17
+ :test => homologation?,
18
+ :authorization => response[:number])
19
+ end
20
+
21
+ def capture(order)
22
+ response = self.post(:capture, order)
23
+
24
+ status = (response[:status] == "0")
25
+
26
+ Response.new(status,
27
+ response[:message],
28
+ response,
29
+ :test => homologation?,
30
+ :authorization => response[:number])
31
+ end
32
+
33
+ def void(order, partial=nil)
34
+ response = self.post(:void, order)
35
+
36
+ status = (response[:status] == "0")
37
+
38
+ Response.new(status,
39
+ response[:message],
40
+ response,
41
+ :test => homologation?)
42
+ end
43
+
44
+ PROTECTED_CARD_MAPPING = {
45
+ :request_id => "RequestId",
46
+ :merchant_id => "MerchantKey",
47
+ :customer_name => "CustomerName",
48
+ :holder => "CardHolder",
49
+ :card_number => "CardNumber",
50
+ :expiration => "CardExpiration"
51
+ }
52
+
53
+ JUST_CLICK_MAPPING = {
54
+ :request_id => "RequestId",
55
+ :merchant_id => "MerchantKey",
56
+ :customer_name => "CustomerName",
57
+ :order_id => "OrderId",
58
+ :amount => "Amount",
59
+ :payment_method => "PaymentMethod",
60
+ :number_installments => "NumberInstallments",
61
+ :payment_type => "PaymentType",
62
+ :just_click_key => "JustClickKey",
63
+ :security_code => "SecurityCode"
64
+ }
65
+
66
+
67
+ # saves credit card in Braspag PCI Compliant
68
+ def archive(credit_card, customer, request_id)
69
+ return ::Response
70
+
71
+ self.check_protected_card_params(params)
72
+
73
+ data = { 'saveCreditCardRequestWS' => {} }
74
+
75
+ PROTECTED_CARD_MAPPING.each do |k, v|
76
+ data['saveCreditCardRequestWS'][v] = params[k] || ""
77
+ end
78
+
79
+
80
+ client = Savon::Client.new(self.save_protected_card_url)
81
+ response = client.request(:web, :save_credit_card) do
82
+ soap.body = data
83
+ end
84
+
85
+ response.to_hash[:save_credit_card_response][:save_credit_card_result]
86
+
87
+ end
88
+
89
+ # request the credit card info in Braspag PCI Compliant
90
+ def get_recurrency(credit_card)
91
+ return ::Response
92
+
93
+ raise InvalidJustClickKey unless valid_just_click_key?(just_click_key)
94
+
95
+ data = { 'getCreditCardRequestWS' => {:loja => connection.merchant_id, :justClickKey => just_click_key} }
96
+
97
+ request = ::HTTPI::Request.new(self.get_protected_card_url)
98
+ request.body = { 'getCreditCardRequestWS' => {:loja => connection.merchant_id, :justClickKey => just_click_key} }
99
+
100
+ response = ::HTTPI.post(request)
101
+
102
+ response = Utils::convert_to_map(response.body, {
103
+ :holder => "CardHolder",
104
+ :card_number => "CardNumber",
105
+ :expiration => "CardExpiration",
106
+ :masked_card_number => "MaskedCardNumber"
107
+ })
108
+
109
+ raise UnknownError if response[:card_number].nil?
110
+ response
111
+ end
112
+
113
+ def recurrency(order, credit_card, request_id)
114
+ return ::Response
115
+
116
+ self.check_just_click_shop_params(params)
117
+
118
+ order_id = params[:order_id]
119
+ raise InvalidOrderId unless self.valid_order_id?(order_id)
120
+
121
+ data = { 'justClickShopRequestWS' => {} }
122
+
123
+ JUST_CLICK_MAPPING.each do |k, v|
124
+ case k
125
+ when :payment_method
126
+ data['justClickShopRequestWS'][v] = Braspag::Connection.instance.homologation? ? PAYMENT_METHODS[:braspag] : PAYMENT_METHODS[params[:payment_method]]
127
+ else
128
+ data['justClickShopRequestWS'][v] = params[k] || ""
129
+ end
130
+ end
131
+
132
+ client = Savon::Client.new(self.just_click_shop_url)
133
+ response = client.request(:web, :just_click_shop) do
134
+ soap.body = data
135
+ end
136
+
137
+ response.to_hash[:just_click_shop_response][:just_click_shop_result]
138
+
139
+ end
140
+
141
+
142
+ end
143
+
144
+
145
+ class CreditCard
146
+ include ::ActiveAttr::Model
147
+
148
+ attr_accessor :holder_name, :number, :month, :year, :verification_value, :alias, :id
149
+
150
+ class ExpiratorValidator < ActiveModel::EachValidator
151
+ def validate_each(record, attribute, value)
152
+ begin
153
+ year = record.year.try(:to_i)
154
+ year = "20#{year}".to_i if year && year.to_s.size == 2
155
+
156
+ month = record.month.try(:to_i)
157
+
158
+ Date.new(year, month) if year && month
159
+ rescue ArgumentError
160
+ record.errors.add attribute, "invalid date"
161
+ end
162
+ end
163
+ end
164
+
165
+
166
+ [:purchase, :authorize, :archive].each do |check_on|
167
+ validates :holder_name, :length => {:minimum => 1, :maximum => 100, :on => check_on}
168
+
169
+ validates :number, :presence => { :on => check_on }
170
+
171
+ validates :month, :presence => { :on => check_on }
172
+ validates :month, :expirator => { :on => check_on }
173
+ validates :year, :presence => { :on => check_on }
174
+ validates :year, :expirator => { :on => check_on }
175
+ end
176
+
177
+ [:purchase, :authorize, :recurrency].each do |check_on|
178
+ validates :verification_value, :length => {:minimum => 1, :maximum => 4, :on => check_on}
179
+ end
180
+
181
+ [:get_recurrency, :recurrency].each do |check_on|
182
+ validates :id, :length => {:is => 36, :on => check_on}
183
+ end
184
+
185
+ def convert_to(method)
186
+ self.send("to_#{method}")
187
+ end
188
+
189
+ def to_authorize
190
+ year_normalize = year.to_s[-2, 2]
191
+ {
192
+ :holder => self.holder_name.to_s,
193
+ :card_number => self.number.to_s,
194
+ :expiration => "#{self.month}/#{year_normalize}",
195
+ :security_code => self.verification_value.to_s,
196
+ }
197
+ end
198
+
199
+ def populate!(method, response)
200
+
201
+ end
202
+ end
203
+ end
@@ -0,0 +1,90 @@
1
+ module Braspag
2
+ class Connection
3
+
4
+ MAPPING_EFT = {
5
+ :merchant_id => "Id_Loja",
6
+ :order_id => "VENDAID",
7
+ :customer_name => "nome",
8
+ :customer_id => "CPF",
9
+ :amount => "VALOR",
10
+ :payment_method => "CODPAGAMENTO",
11
+ :installments => "PARCELAS",
12
+ :has_interest => "TIPOPARCELADO"
13
+ }
14
+
15
+
16
+ def self.generate_eft(order, eft)
17
+ return ::Response.new
18
+
19
+ connection = Braspag::Connection.instance
20
+ params[:merchant_id] = connection.merchant_id
21
+
22
+ params = self.normalize_params(params)
23
+ self.check_params(params)
24
+
25
+ data = {}
26
+
27
+ MAPPING.each do |k, v|
28
+ case k
29
+ when :payment_method
30
+ data[v] = PAYMENT_METHODS[params[:payment_method]]
31
+ when :amount
32
+ data[v] = Utils.convert_decimal_to_string(params[:amount])
33
+ else
34
+ data[v] = params[k] || ""
35
+ end
36
+ end
37
+
38
+ html = "<form id=\"form_tef_#{params[:order_id]}\" name=\"form_tef_#{params[:order_id]}\" action=\"#{self.action_url}\" method=\"post\">"
39
+
40
+ if crypto_strategy.nil?
41
+ data.each do |key, value|
42
+ html << "<input type=\"text\" name=\"#{key}\" value=\"#{value}\" />"
43
+ end
44
+ else
45
+ data.delete("Id_Loja")
46
+ html << "<input type=\"text\" name=\"Id_Loja\" value=\"#{params[:merchant_id]}\" />"
47
+ html << "<input type=\"text\" name=\"crypt\" value=\"#{crypto_strategy.encrypt(data)}\" />"
48
+ end
49
+
50
+ html << "</form><script type=\"text/javascript\" charset=\"utf-8\">document.forms[\"form_tef_#{params[:order_id]}\"].submit();</script>"
51
+
52
+ html
53
+ end
54
+
55
+ def self.normalize_params(params)
56
+ params = super
57
+
58
+ params[:installments] = params[:installments].to_i unless params[:installments].nil?
59
+ params[:installments] ||= 1
60
+
61
+ params[:has_interest] = params[:has_interest] == true ? "1" : "0"
62
+
63
+ params
64
+ end
65
+
66
+ end
67
+
68
+ class EFT
69
+ include ::ActiveAttr::Model
70
+
71
+ class CryptoValidator < ActiveModel::EachValidator
72
+ def validate_each(record, attribute, value)
73
+ unless (
74
+ value.kind_of?(Braspag::Crypto::Webservice) ||
75
+ value.kind_of?(Braspag::Crypto::NoCrypto) ||
76
+ value.kind_of?(Braspag::Crypto::JarWebservice)
77
+ )
78
+ record.errors.add attribute, "invalid crypto"
79
+ end
80
+ end
81
+ end
82
+
83
+ attr_accessor :crypto
84
+
85
+ validates :crypto, :presence => { :on => :generate }
86
+ validates :crypto, :crypto => { :on => :generate }
87
+
88
+ end
89
+
90
+ end
@@ -0,0 +1,3 @@
1
+ module Braspag
2
+ VERSION = "0.9.0"
3
+ end
@@ -0,0 +1,95 @@
1
+ # encoding: utf-8
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+
4
+ describe Braspag::Connection do
5
+ let(:merchant_id) { "{12345678-1234-1234-1234-123456789000}" }
6
+
7
+ it "should accept a valid merchant" do
8
+ expect {
9
+ Braspag::Connection.new(:merchant_id => merchant_id)
10
+ }.to_not raise_error(Braspag::Connection::InvalidMerchantId)
11
+ end
12
+
13
+ it "should raise error with invalid merchant" do
14
+ expect {
15
+ Braspag::Connection.new(:merchant_id => "INVALID")
16
+ }.to raise_error(Braspag::Connection::InvalidMerchantId)
17
+ end
18
+
19
+ [:homologation, :production].each do |env|
20
+ it "should accept #{env} environment" do
21
+ expect {
22
+ Braspag::Connection.new(:merchant_id => merchant_id, :environment => env)
23
+ }.to_not raise_error(Braspag::Connection::InvalidEnvironment)
24
+ end
25
+ end
26
+
27
+ it "should raise error with invalid environment" do
28
+ expect {
29
+ Braspag::Connection.new(:merchant_id => merchant_id, :environment => :bla)
30
+ }.to raise_error(Braspag::Connection::InvalidEnvironment)
31
+ end
32
+
33
+ describe ".production?" do
34
+ it "should return true" do
35
+ connection = Braspag::Connection.new(:merchant_id => merchant_id, :environment => :production)
36
+ connection.production?.should be(true)
37
+ end
38
+
39
+ it "should return false" do
40
+ connection = Braspag::Connection.new(:merchant_id => merchant_id, :environment => :homologation)
41
+ connection.production?.should be(false)
42
+ end
43
+ end
44
+
45
+ describe ".homologation?" do
46
+ it "should return true" do
47
+ connection = Braspag::Connection.new(:merchant_id => merchant_id, :environment => :homologation)
48
+ connection.homologation?.should be(true)
49
+ end
50
+
51
+ it "should return false" do
52
+ connection = Braspag::Connection.new(:merchant_id => merchant_id, :environment => :production)
53
+ connection.homologation?.should be(false)
54
+ end
55
+ end
56
+
57
+ describe ".url_for" do
58
+ let(:braspag_homologation_url) { "https://homologacao.pagador.com.br" }
59
+ let(:braspag_production_url) { "https://transaction.pagador.com.br" }
60
+ let(:braspag_homologation_protected_card_url) { "https://homologacao.braspag.com.br/services/testenvironment" }
61
+ let(:braspag_production_protected_card_url) { "https://cartaoprotegido.braspag.com.br/Services" }
62
+
63
+ it "should return the correct credit card creation url when connection environment is homologation" do
64
+ connection = Braspag::Connection.new(:merchant_id => merchant_id, :environment => :homologation)
65
+ connection.url_for(:authorize).should == "#{braspag_homologation_url}/webservices/pagador/Pagador.asmx/Authorize"
66
+ connection.url_for(:capture).should == "#{braspag_homologation_url}/webservices/pagador/Pagador.asmx/Capture"
67
+ connection.url_for(:void).should == "#{braspag_homologation_url}/webservices/pagador/Pagador.asmx/VoidTransaction"
68
+ connection.url_for(:generate_billet).should == "#{braspag_homologation_url}/webservices/pagador/Boleto.asmx/CreateBoleto"
69
+ connection.url_for(:generate_eft).should == "#{braspag_homologation_url}/pagador/passthru.asp"
70
+ connection.url_for(:info_billet).should == "#{braspag_homologation_url}/pagador/webservice/pedido.asmx/GetDadosBoleto"
71
+ connection.url_for(:info_card).should == "#{braspag_homologation_url}/pagador/webservice/pedido.asmx/GetDadosCartao"
72
+ connection.url_for(:info).should == "#{braspag_homologation_url}/pagador/webservice/pedido.asmx/GetDadosPedido"
73
+ connection.url_for(:encrypt).should == "#{braspag_homologation_url}/BraspagGeneralService/BraspagGeneralService.asmx"
74
+ connection.url_for(:archive_card).should == "#{braspag_homologation_protected_card_url}/CartaoProtegido.asmx?wsdl"
75
+ connection.url_for(:get_card).should == "#{braspag_homologation_protected_card_url}/CartaoProtegido.asmx/GetCreditCard"
76
+ connection.url_for(:recurrency).should == "#{braspag_homologation_protected_card_url}/CartaoProtegido.asmx?wsdl"
77
+ end
78
+
79
+ it "should return the correct credit card creation url when connection environment is production" do
80
+ connection = Braspag::Connection.new(:merchant_id => merchant_id, :environment => :production)
81
+ connection.url_for(:authorize).should == "#{braspag_production_url}/webservices/pagador/Pagador.asmx/Authorize"
82
+ connection.url_for(:capture).should == "#{braspag_production_url}/webservices/pagador/Pagador.asmx/Capture"
83
+ connection.url_for(:void).should == "#{braspag_production_url}/webservices/pagador/Pagador.asmx/VoidTransaction"
84
+ connection.url_for(:generate_billet).should == "#{braspag_production_url}/webservices/pagador/Boleto.asmx/CreateBoleto"
85
+ connection.url_for(:generate_eft).should == "#{braspag_production_url}/pagador/passthru.asp"
86
+ connection.url_for(:info_billet).should == "#{braspag_production_url}/webservices/pagador/pedido.asmx/GetDadosBoleto"
87
+ connection.url_for(:info_card).should == "#{braspag_production_url}/webservices/pagador/pedido.asmx/GetDadosCartao"
88
+ connection.url_for(:info).should == "#{braspag_production_url}/webservices/pagador/pedido.asmx/GetDadosPedido"
89
+ connection.url_for(:encrypt).should == "#{braspag_production_url}/BraspagGeneralService/BraspagGeneralService.asmx"
90
+ connection.url_for(:archive_card).should == "#{braspag_production_protected_card_url}/CartaoProtegido.asmx?wsdl"
91
+ connection.url_for(:get_card).should == "#{braspag_production_protected_card_url}/CartaoProtegido.asmx/GetCreditCard"
92
+ connection.url_for(:recurrency).should == "#{braspag_production_protected_card_url}/CartaoProtegido.asmx?wsdl"
93
+ end
94
+ end
95
+ end