libwebpayplus 2.0.3
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 +7 -0
- data/lib/configuration.rb +18 -0
- data/lib/libwebpay.rb +29 -0
- data/lib/utils.rb +42 -0
- data/lib/verifier.rb +60 -0
- data/lib/webpay.rb +69 -0
- data/lib/webpaycapture.rb +134 -0
- data/lib/webpaycomplete.rb +377 -0
- data/lib/webpaymallnormal.rb +312 -0
- data/lib/webpaynormal.rb +310 -0
- data/lib/webpaynullify.rb +137 -0
- data/lib/webpayoneclick.rb +440 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f5b3c05fcd844b62833e828d532b6ca33b48603a
|
4
|
+
data.tar.gz: e19679ebc32bf2c23cfbf25e63bce630168101a8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3367776fc5f8c2fafedb5a3955b28a79668c95554a572e82cf739fe4ee174add12e0a04410d615d26deb57d0c7f59e67b866a0e95c0775084f9e9805ea1efe51
|
7
|
+
data.tar.gz: 5c078ed9e0c520f654af85ca78dddf446823f06db3da55a21b07c83c7570e10b70cc01d2d86fd6c6bf3dd9ae81b22ade7a7edb862692977449cae1061f05d0a8
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
class Configuration
|
4
|
+
|
5
|
+
@environment
|
6
|
+
@commerce_code
|
7
|
+
@private_key
|
8
|
+
@public_cert
|
9
|
+
@webpay_cert
|
10
|
+
@store_codes
|
11
|
+
|
12
|
+
|
13
|
+
#getter y setter de los elementos
|
14
|
+
attr_accessor :environment,:commerce_code,:private_key,:public_cert,:webpay_cert,:store_codes
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
|
data/lib/libwebpay.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'signer'
|
2
|
+
require 'savon'
|
3
|
+
require_relative 'verifier'
|
4
|
+
require_relative 'configuration'
|
5
|
+
require_relative 'webpay'
|
6
|
+
|
7
|
+
|
8
|
+
class Libwebpay
|
9
|
+
|
10
|
+
|
11
|
+
@configuration
|
12
|
+
@webpay
|
13
|
+
|
14
|
+
|
15
|
+
def getWebpay(config)
|
16
|
+
if @webpay == nil
|
17
|
+
@webpay = Webpay.new(config)
|
18
|
+
end
|
19
|
+
return @webpay
|
20
|
+
end
|
21
|
+
|
22
|
+
def getConfiguration
|
23
|
+
if @configuration == nil
|
24
|
+
@configuration = Configuration.new
|
25
|
+
end
|
26
|
+
return @configuration
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/lib/utils.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'signer'
|
2
|
+
require 'savon'
|
3
|
+
require_relative "verifier"
|
4
|
+
|
5
|
+
class Util
|
6
|
+
|
7
|
+
def ejemplo
|
8
|
+
return true
|
9
|
+
end
|
10
|
+
|
11
|
+
def signXml (input_xml)
|
12
|
+
|
13
|
+
document = Nokogiri::XML(input_xml.body)
|
14
|
+
envelope = document.at_xpath("//env:Envelope")
|
15
|
+
envelope.prepend_child("<env:Header><wsse:Security xmlns:wsse='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' wsse:mustUnderstand='1'/></env:Header>")
|
16
|
+
xml = document.to_s
|
17
|
+
|
18
|
+
signer = Signer.new(xml)
|
19
|
+
|
20
|
+
signer.cert = OpenSSL::X509::Certificate.new(@public_cert)
|
21
|
+
signer.private_key = OpenSSL::PKey::RSA.new(@private_key)
|
22
|
+
|
23
|
+
signer.document.xpath("//soapenv:Body", { "soapenv" => "http://schemas.xmlsoap.org/soap/envelope/" }).each do |node|
|
24
|
+
signer.digest!(node)
|
25
|
+
end
|
26
|
+
|
27
|
+
signer.sign!(:issuer_serial => true)
|
28
|
+
signed_xml = signer.to_xml
|
29
|
+
|
30
|
+
document = Nokogiri::XML(signed_xml)
|
31
|
+
x509data = document.at_xpath("//*[local-name()='X509Data']")
|
32
|
+
new_data = x509data.clone()
|
33
|
+
new_data.set_attribute("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#")
|
34
|
+
|
35
|
+
n = Nokogiri::XML::Node.new('wsse:SecurityTokenReference', document)
|
36
|
+
n.add_child(new_data)
|
37
|
+
x509data.add_next_sibling(n)
|
38
|
+
|
39
|
+
return document
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
data/lib/verifier.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require "nokogiri"
|
2
|
+
require "base64"
|
3
|
+
require "digest/sha1"
|
4
|
+
require "openssl"
|
5
|
+
|
6
|
+
class Verifier
|
7
|
+
|
8
|
+
def self.verify(document, cert)
|
9
|
+
document = Nokogiri::XML(document.to_s, &:noblanks)
|
10
|
+
signed_info_node = document.at_xpath("/soap:Envelope/soap:Header/wsse:Security/ds:Signature/ds:SignedInfo", {ds: 'http://www.w3.org/2000/09/xmldsig#', wsse: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", soap:"http://schemas.xmlsoap.org/soap/envelope/"})
|
11
|
+
|
12
|
+
|
13
|
+
#revisar que digest coincida
|
14
|
+
if !check_digest(document, signed_info_node)
|
15
|
+
return false
|
16
|
+
end
|
17
|
+
|
18
|
+
if !check_signature(document, signed_info_node, cert)
|
19
|
+
return false
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def self.check_digest(doc, signed_info_node)
|
29
|
+
signed_info_node.xpath("//ds:Reference", ds: 'http://www.w3.org/2000/09/xmldsig#').each do |node|
|
30
|
+
if !process_ref_node(doc, node)
|
31
|
+
return false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.check_signature(doc, signed_info_node, cert)
|
38
|
+
signed_info_canon = canonicalize(signed_info_node, ['soap'])
|
39
|
+
signature = doc.at_xpath('//wsse:Security/ds:Signature/ds:SignatureValue', {ds: 'http://www.w3.org/2000/09/xmldsig#', wsse: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"}).text
|
40
|
+
cert.public_key.verify(OpenSSL::Digest::SHA1.new, Base64.decode64(signature), signed_info_canon)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.digest(message)
|
44
|
+
OpenSSL::Digest::SHA1.new.reset.digest(message)
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.process_ref_node(doc, node)
|
48
|
+
uri = node.attr('URI')
|
49
|
+
element = doc.at_xpath("//*[@wsu:Id='" + uri[1..-1] + "']", wsu: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd")
|
50
|
+
target = canonicalize(element, nil)
|
51
|
+
my_digest_value = Base64.encode64(digest(target)).strip
|
52
|
+
digest_value = node.at_xpath("//ds:DigestValue", ds: 'http://www.w3.org/2000/09/xmldsig#').text
|
53
|
+
return my_digest_value == digest_value
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.canonicalize(node = document, inclusive_namespaces=nil)
|
57
|
+
node.canonicalize(Nokogiri::XML::XML_C14N_EXCLUSIVE_1_0, inclusive_namespaces, nil) # The last argument should be exactly +nil+ to remove comments from result
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
data/lib/webpay.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
|
2
|
+
require_relative 'webpaymallnormal'
|
3
|
+
require_relative 'webpaynormal'
|
4
|
+
require_relative 'webpaynullify'
|
5
|
+
require_relative 'webpaycapture'
|
6
|
+
require_relative 'webpayoneclick'
|
7
|
+
require_relative 'webpaycomplete'
|
8
|
+
|
9
|
+
class Webpay
|
10
|
+
|
11
|
+
@configuration
|
12
|
+
@webpayNormal
|
13
|
+
@webpayMallNormal
|
14
|
+
@webpayNullify
|
15
|
+
@webpayCapture
|
16
|
+
@webpayOneClick
|
17
|
+
@webpayCompleteTransaction
|
18
|
+
|
19
|
+
|
20
|
+
# método inicializar clase
|
21
|
+
def initialize(params)
|
22
|
+
@configuration = params
|
23
|
+
end
|
24
|
+
|
25
|
+
def getNormalTransaction
|
26
|
+
if @webpayNormal == nil
|
27
|
+
@webpayNormal = WebpayNormal.new(@configuration)
|
28
|
+
end
|
29
|
+
return @webpayNormal
|
30
|
+
end
|
31
|
+
|
32
|
+
def getMallNormalTransaction
|
33
|
+
if @webpayMallNormal == nil
|
34
|
+
@webpayMallNormal = WebpayMallNormal.new(@configuration)
|
35
|
+
end
|
36
|
+
return @webpayMallNormal
|
37
|
+
end
|
38
|
+
|
39
|
+
def getNullifyTransaction
|
40
|
+
if @webpayNullify == nil
|
41
|
+
@webpayNullify = WebpayNullify.new(@configuration)
|
42
|
+
end
|
43
|
+
return @webpayNullify
|
44
|
+
end
|
45
|
+
|
46
|
+
def getCaptureTransaction
|
47
|
+
if @webpayCapture == nil
|
48
|
+
@webpayCapture = WebpayCapture.new(@configuration)
|
49
|
+
end
|
50
|
+
return @webpayCapture
|
51
|
+
end
|
52
|
+
|
53
|
+
def getOneClickTransaction
|
54
|
+
if @webpayOneClick == nil
|
55
|
+
@webpayOneClick = WebpayOneClick.new(@configuration)
|
56
|
+
end
|
57
|
+
return @webpayOneClick
|
58
|
+
end
|
59
|
+
|
60
|
+
def getCompleteTransaction
|
61
|
+
if @webpayCompleteTransaction == nil
|
62
|
+
@webpayCompleteTransaction = WebpayComplete.new(@configuration)
|
63
|
+
end
|
64
|
+
return @webpayCompleteTransaction
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'signer'
|
2
|
+
require 'savon'
|
3
|
+
require_relative "verifier"
|
4
|
+
|
5
|
+
|
6
|
+
class WebpayCapture
|
7
|
+
|
8
|
+
def initialize(configuration)
|
9
|
+
|
10
|
+
|
11
|
+
@wsdl_path = ''
|
12
|
+
@ambient = configuration.environment
|
13
|
+
|
14
|
+
case @ambient
|
15
|
+
when 'INTEGRACION'
|
16
|
+
@wsdl_path='https://webpay3gint.transbank.cl/WSWebpayTransaction/cxf/WSCommerceIntegrationService?wsdl'
|
17
|
+
when 'CERTIFICACION'
|
18
|
+
@wsdl_path='https://webpay3gint.transbank.cl/WSWebpayTransaction/cxf/WSCommerceIntegrationService?wsdl'
|
19
|
+
when 'PRODUCCION'
|
20
|
+
@wsdl_path='https://webpay3g.transbank.cl/WSWebpayTransaction/cxf/WSCommerceIntegrationService?wsdl'
|
21
|
+
else
|
22
|
+
#Por defecto esta el ambiente de INTEGRACION
|
23
|
+
@wsdl_path='https://webpay3gint.transbank.cl/WSWebpayTransaction/cxf/WSCommerceIntegrationService?wsdl'
|
24
|
+
end
|
25
|
+
|
26
|
+
@commerce_code = configuration.commerce_code
|
27
|
+
@private_key = OpenSSL::PKey::RSA.new(configuration.private_key)
|
28
|
+
@public_cert = OpenSSL::X509::Certificate.new(configuration.public_cert)
|
29
|
+
@webpay_cert = OpenSSL::X509::Certificate.new(configuration.webpay_cert)
|
30
|
+
@client = Savon.client(wsdl: @wsdl_path)
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
#######################################################
|
36
|
+
def capture(authorizationCode, captureAmount, buyOrder)
|
37
|
+
|
38
|
+
|
39
|
+
captureInput ={
|
40
|
+
"captureInput" => {
|
41
|
+
"captureAmount" => captureAmount,
|
42
|
+
"buyOrder" => buyOrder,
|
43
|
+
"commerceId" => @commerce_code,
|
44
|
+
"authorizationCode" => authorizationCode
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
|
49
|
+
req = @client.build_request(:capture, message: captureInput)
|
50
|
+
|
51
|
+
|
52
|
+
#Firmar documento
|
53
|
+
document = sign_xml(req)
|
54
|
+
puts document
|
55
|
+
|
56
|
+
begin
|
57
|
+
response = @client.call(:capture) do
|
58
|
+
xml document.to_xml(:save_with => 0)
|
59
|
+
end
|
60
|
+
rescue Exception, RuntimeError => e
|
61
|
+
response_array ={
|
62
|
+
"error_desc" => "Ocurrio un error en la llamada a Webpay: "+e.message
|
63
|
+
}
|
64
|
+
return response_array
|
65
|
+
end
|
66
|
+
|
67
|
+
#Verificacion de certificado respuesta
|
68
|
+
tbk_cert = OpenSSL::X509::Certificate.new(@webpay_cert)
|
69
|
+
|
70
|
+
if !Verifier.verify(response, tbk_cert)
|
71
|
+
puts "El Certificado de respuesta es Invalido."
|
72
|
+
response_array ={
|
73
|
+
"error_desc" => 'El Certificado de respuesta es Invalido'
|
74
|
+
}
|
75
|
+
return response_array
|
76
|
+
else
|
77
|
+
puts "El Certificado de respuesta es Valido."
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
response_document = Nokogiri::HTML(response.to_s)
|
82
|
+
puts 'response capture: '
|
83
|
+
puts response_document
|
84
|
+
|
85
|
+
authorizationCode = response_document.xpath("//authorizationcode").text
|
86
|
+
authorizationDate = response_document.xpath("//authorizationdate").text
|
87
|
+
capturedAmount = response_document.xpath("//capturedamount").text
|
88
|
+
token = response_document.xpath("//token").text
|
89
|
+
|
90
|
+
response_array ={
|
91
|
+
"authorizationCode" => authorizationCode.to_s,
|
92
|
+
"authorizationDate" => authorizationDate.to_s,
|
93
|
+
"capturedAmount" => capturedAmount.to_s,
|
94
|
+
"token" => token.to_s,
|
95
|
+
"error_desc" => "TRX_OK"
|
96
|
+
}
|
97
|
+
|
98
|
+
|
99
|
+
return response_array
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def sign_xml (input_xml)
|
104
|
+
|
105
|
+
document = Nokogiri::XML(input_xml.body)
|
106
|
+
envelope = document.at_xpath("//env:Envelope")
|
107
|
+
envelope.prepend_child("<env:Header><wsse:Security xmlns:wsse='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' wsse:mustUnderstand='1'/></env:Header>")
|
108
|
+
xml = document.to_s
|
109
|
+
|
110
|
+
signer = Signer.new(xml)
|
111
|
+
|
112
|
+
signer.cert = OpenSSL::X509::Certificate.new(@public_cert)
|
113
|
+
signer.private_key = OpenSSL::PKey::RSA.new(@private_key)
|
114
|
+
|
115
|
+
signer.document.xpath("//soapenv:Body", { "soapenv" => "http://schemas.xmlsoap.org/soap/envelope/" }).each do |node|
|
116
|
+
signer.digest!(node)
|
117
|
+
end
|
118
|
+
|
119
|
+
signer.sign!(:issuer_serial => true)
|
120
|
+
signed_xml = signer.to_xml
|
121
|
+
|
122
|
+
document = Nokogiri::XML(signed_xml)
|
123
|
+
x509data = document.at_xpath("//*[local-name()='X509Data']")
|
124
|
+
new_data = x509data.clone()
|
125
|
+
new_data.set_attribute("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#")
|
126
|
+
|
127
|
+
n = Nokogiri::XML::Node.new('wsse:SecurityTokenReference', document)
|
128
|
+
n.add_child(new_data)
|
129
|
+
x509data.add_next_sibling(n)
|
130
|
+
|
131
|
+
return document
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
@@ -0,0 +1,377 @@
|
|
1
|
+
require 'signer'
|
2
|
+
require 'savon'
|
3
|
+
require_relative 'verifier'
|
4
|
+
require_relative 'utils'
|
5
|
+
|
6
|
+
|
7
|
+
class WebpayComplete
|
8
|
+
|
9
|
+
def initialize(configuration)
|
10
|
+
|
11
|
+
|
12
|
+
@wsdl_path = ''
|
13
|
+
@ambient = configuration.environment
|
14
|
+
|
15
|
+
case @ambient
|
16
|
+
when 'INTEGRACION'
|
17
|
+
@wsdl_path='https://webpay3gint.transbank.cl/WSWebpayTransaction/cxf/WSCompleteWebpayService?wsdl'
|
18
|
+
when 'CERTIFICACION'
|
19
|
+
@wsdl_path='https://webpay3gint.transbank.cl/WSWebpayTransaction/cxf/WSCompleteWebpayService?wsdl'
|
20
|
+
when 'PRODUCCION'
|
21
|
+
@wsdl_path='https://webpay3g.transbank.cl/WSWebpayTransaction/cxf/WSCompleteWebpayService?wsdl'
|
22
|
+
else
|
23
|
+
#Por defecto esta el ambiente de INTEGRACION
|
24
|
+
@wsdl_path='https://webpay3gint.transbank.cl/WSWebpayTransaction/cxf/WSCompleteWebpayService?wsd'
|
25
|
+
end
|
26
|
+
|
27
|
+
@commerce_code = configuration.commerce_code
|
28
|
+
@private_key = OpenSSL::PKey::RSA.new(configuration.private_key)
|
29
|
+
@public_cert = OpenSSL::X509::Certificate.new(configuration.public_cert)
|
30
|
+
@webpay_cert = OpenSSL::X509::Certificate.new(configuration.webpay_cert)
|
31
|
+
@client = Savon.client(wsdl: @wsdl_path)
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
#######################################################
|
37
|
+
def initComplete(amount, buyOrder, sessionId, cardExpirationDate, cvv, cardNumber)
|
38
|
+
|
39
|
+
inputComplete ={
|
40
|
+
"wsCompleteInitTransactionInput" => {
|
41
|
+
"transactionType" => 'TR_COMPLETA_WS',
|
42
|
+
"sessionId" => sessionId,
|
43
|
+
"transactionDetails" => {
|
44
|
+
"amount" => amount,
|
45
|
+
"buyOrder" => buyOrder,
|
46
|
+
"commerceCode" => @commerce_code,
|
47
|
+
},
|
48
|
+
"cardDetail" => {
|
49
|
+
"cardExpirationDate" => cardExpirationDate,
|
50
|
+
"cvv" => cvv,
|
51
|
+
"cardNumber" => cardNumber
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
req = @client.build_request(:init_complete_transaction, message: inputComplete)
|
57
|
+
|
58
|
+
#Firmar documento
|
59
|
+
document = sign_xml(req)
|
60
|
+
puts document
|
61
|
+
|
62
|
+
begin
|
63
|
+
puts "Iniciando initComplete..."
|
64
|
+
response = @client.call(:init_complete_transaction) do
|
65
|
+
xml document.to_xml(:save_with => 0)
|
66
|
+
end
|
67
|
+
rescue Exception, RuntimeError => e
|
68
|
+
puts "Ocurrio un error en la llamada a Webpay: "+e.message
|
69
|
+
response_array ={
|
70
|
+
"error_desc" => "Ocurrio un error en la llamada a Webpay: "+e.message
|
71
|
+
}
|
72
|
+
return response_array
|
73
|
+
end
|
74
|
+
|
75
|
+
#Verificacion de certificado respuesta
|
76
|
+
tbk_cert = OpenSSL::X509::Certificate.new(@webpay_cert)
|
77
|
+
|
78
|
+
if !Verifier.verify(response, tbk_cert)
|
79
|
+
response_array ={
|
80
|
+
"error_desc" => 'El Certificado de respuesta es Invalido'
|
81
|
+
}
|
82
|
+
return response_array
|
83
|
+
else
|
84
|
+
puts "El Certificado de respuesta es Valido."
|
85
|
+
end
|
86
|
+
|
87
|
+
token=''
|
88
|
+
response_document = Nokogiri::HTML(response.to_s)
|
89
|
+
response_document.xpath("//token").each do |token_value|
|
90
|
+
token = token_value.text
|
91
|
+
end
|
92
|
+
url=''
|
93
|
+
response_document.xpath("//urlwebpay").each do |url_value|
|
94
|
+
url = url_value.text
|
95
|
+
end
|
96
|
+
|
97
|
+
puts 'token: '+token
|
98
|
+
puts 'url: '+url
|
99
|
+
|
100
|
+
response_array ={
|
101
|
+
"token" => token.to_s,
|
102
|
+
"error_desc" => 'TRX_OK'
|
103
|
+
}
|
104
|
+
|
105
|
+
return response_array
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
##############################################
|
110
|
+
def queryShare(token, buyOrder, shareNumber)
|
111
|
+
|
112
|
+
inputQuery ={
|
113
|
+
"token" => token,
|
114
|
+
"buyOrder" => buyOrder,
|
115
|
+
"shareNumber" => shareNumber
|
116
|
+
}
|
117
|
+
|
118
|
+
#Preparacion firma
|
119
|
+
req = @client.build_request(:query_share, message: inputQuery)
|
120
|
+
#firmar la peticion
|
121
|
+
document = sign_xml(req)
|
122
|
+
#document = Util.signXml(req)
|
123
|
+
|
124
|
+
|
125
|
+
#Se realiza el getResult
|
126
|
+
begin
|
127
|
+
puts "Iniciando queryShare..."
|
128
|
+
response = @client.call(:query_share) do
|
129
|
+
xml document.to_xml(:save_with => 0)
|
130
|
+
end
|
131
|
+
|
132
|
+
rescue Exception, RuntimeError => e
|
133
|
+
puts "Ocurrio un error en la llamada a Webpay: "+e.message
|
134
|
+
response_array ={
|
135
|
+
"error_desc" => "Ocurrio un error en la llamada a Webpay: "+e.message
|
136
|
+
}
|
137
|
+
return response_array
|
138
|
+
end
|
139
|
+
|
140
|
+
#Se revisa que respuesta no sea nula.
|
141
|
+
if response
|
142
|
+
puts 'Respuesta finishInscription: '+ response.to_s
|
143
|
+
else
|
144
|
+
puts 'Webservice Webpay responde con null'
|
145
|
+
response_array ={
|
146
|
+
"error_desc" => 'Webservice Webpay responde con null'
|
147
|
+
}
|
148
|
+
return response_array
|
149
|
+
end
|
150
|
+
|
151
|
+
puts response
|
152
|
+
|
153
|
+
#Verificacion de certificado respuesta
|
154
|
+
tbk_cert = OpenSSL::X509::Certificate.new(@webpay_cert)
|
155
|
+
|
156
|
+
if !Verifier.verify(response, tbk_cert)
|
157
|
+
response_array ={
|
158
|
+
"error_desc" => 'El Certificado de respuesta es Invalido'
|
159
|
+
}
|
160
|
+
return response_array
|
161
|
+
else
|
162
|
+
puts "El Certificado de respuesta es Valido."
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
response_document = Nokogiri::HTML(response.to_s)
|
167
|
+
puts response_document.to_s
|
168
|
+
|
169
|
+
buyOrder = response_document.xpath("//buyorder").text
|
170
|
+
queryId = response_document.xpath("//queryid").text
|
171
|
+
shareAmount = response_document.xpath("//shareamount").text
|
172
|
+
token = response_document.xpath("//token").text
|
173
|
+
|
174
|
+
response_array ={
|
175
|
+
"buyOrder" => buyOrder.to_s,
|
176
|
+
"queryId" => queryId.to_s,
|
177
|
+
"shareAmount" => shareAmount.to_s,
|
178
|
+
"token" => token.to_s,
|
179
|
+
"error_desc" => 'TRX_OK'
|
180
|
+
}
|
181
|
+
|
182
|
+
|
183
|
+
return response_array
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
##############################################
|
188
|
+
def authorize(token, buyOrder, gracePeriod, idQueryShare, deferredPeriodIndex)
|
189
|
+
|
190
|
+
input ={
|
191
|
+
"token" => token,
|
192
|
+
"paymentTypeList" => {
|
193
|
+
# "wsCompletePaymentTypeInput" => {
|
194
|
+
"commerceCode" => @commerce_code,
|
195
|
+
"buyOrder" => buyOrder,
|
196
|
+
"gracePeriod" => gracePeriod,
|
197
|
+
"wsCompleteQueryShareInput" => {
|
198
|
+
"idQueryShare" => idQueryShare,
|
199
|
+
"deferredPeriodIndex" => deferredPeriodIndex
|
200
|
+
}
|
201
|
+
# }
|
202
|
+
}
|
203
|
+
}
|
204
|
+
|
205
|
+
#Preparacion firma
|
206
|
+
req = @client.build_request(:authorize, message: input)
|
207
|
+
#firmar la peticion
|
208
|
+
document = sign_xml(req)
|
209
|
+
#document = Util.signXml(req)
|
210
|
+
|
211
|
+
#Se realiza el getResult
|
212
|
+
begin
|
213
|
+
puts "Iniciando authorize..."
|
214
|
+
puts document.to_s
|
215
|
+
response = @client.call(:authorize) do
|
216
|
+
xml document.to_xml(:save_with => 0)
|
217
|
+
end
|
218
|
+
|
219
|
+
rescue Exception, RuntimeError => e
|
220
|
+
puts "Ocurrio un error en la llamada a Webpay: "+e.message
|
221
|
+
response_array ={
|
222
|
+
"error_desc" => "Ocurrio un error en la llamada a Webpay: "+e.message
|
223
|
+
}
|
224
|
+
return response_array
|
225
|
+
end
|
226
|
+
|
227
|
+
#Se revisa que respuesta no sea nula.
|
228
|
+
if response
|
229
|
+
puts 'Respuesta authorize: '+ response.to_s
|
230
|
+
else
|
231
|
+
puts 'Webservice Webpay responde con null'
|
232
|
+
response_array ={
|
233
|
+
"error_desc" => 'Webservice Webpay responde con null'
|
234
|
+
}
|
235
|
+
return response_array
|
236
|
+
end
|
237
|
+
|
238
|
+
puts response
|
239
|
+
|
240
|
+
#Verificacion de certificado respuesta
|
241
|
+
tbk_cert = OpenSSL::X509::Certificate.new(@webpay_cert)
|
242
|
+
|
243
|
+
if !Verifier.verify(response, tbk_cert)
|
244
|
+
response_array ={
|
245
|
+
"error_desc" => 'El Certificado de respuesta es Invalido'
|
246
|
+
}
|
247
|
+
return response_array
|
248
|
+
else
|
249
|
+
puts "El Certificado de respuesta es Valido."
|
250
|
+
end
|
251
|
+
|
252
|
+
|
253
|
+
response_document = Nokogiri::HTML(response.to_s)
|
254
|
+
puts response_document.to_s
|
255
|
+
|
256
|
+
responseCode = response_document.xpath("//responsecode").text
|
257
|
+
buyOrder = response_document.xpath("//buyorder")
|
258
|
+
sharesNumber = response_document.xpath("//sharesnumber").text
|
259
|
+
amount = response_document.xpath("//amount").text
|
260
|
+
commerceCode = response_document.xpath("//commercecode").text
|
261
|
+
authorizationCode = response_document.xpath("//authorizationcode").text
|
262
|
+
paymentTypeCode = response_document.xpath("//paymenttypecode").text
|
263
|
+
sessionId = response_document.xpath("//sessionid").text
|
264
|
+
transactionDate = response_document.xpath("//transactiondate").text
|
265
|
+
|
266
|
+
|
267
|
+
response_array ={
|
268
|
+
"responseCode" => responseCode.to_s,
|
269
|
+
"buyOrder" => buyOrder.to_s,
|
270
|
+
"sharesNumber" => sharesNumber.to_s,
|
271
|
+
"amount" => amount.to_s,
|
272
|
+
"commerceCode" => commerceCode.to_s,
|
273
|
+
"authorizationCode" => authorizationCode.to_s,
|
274
|
+
"paymentTypeCode" => paymentTypeCode.to_s,
|
275
|
+
"sessionId" => sessionId.to_s,
|
276
|
+
"transactionDate" => transactionDate.to_s,
|
277
|
+
"error_desc" => 'TRX_OK'
|
278
|
+
}
|
279
|
+
|
280
|
+
acknowledgeTransaction(token)
|
281
|
+
|
282
|
+
return response_array
|
283
|
+
end
|
284
|
+
|
285
|
+
|
286
|
+
################################
|
287
|
+
def acknowledgeTransaction(token)
|
288
|
+
acknowledgeInput ={
|
289
|
+
"tokenInput" => token
|
290
|
+
}
|
291
|
+
|
292
|
+
#Preparacion firma
|
293
|
+
req = @client.build_request(:acknowledge_complete_transaction, message: acknowledgeInput)
|
294
|
+
|
295
|
+
#Se firma el body de la peticion
|
296
|
+
document = sign_xml(req)
|
297
|
+
|
298
|
+
#Se realiza el acknowledge_transaction
|
299
|
+
begin
|
300
|
+
puts "Iniciando acknowledge_transaction..."
|
301
|
+
response = @client.call(:acknowledge_complete_transaction, message: acknowledgeInput) do
|
302
|
+
xml document.to_xml(:save_with => 0)
|
303
|
+
end
|
304
|
+
|
305
|
+
rescue Exception, RuntimeError => e
|
306
|
+
puts "Ocurrio un error en la llamada a Webpay: "+e.message
|
307
|
+
response_array ={
|
308
|
+
"error_desc" => "Ocurrio un error en la llamada a Webpay: "+e.message
|
309
|
+
}
|
310
|
+
return response_array
|
311
|
+
end
|
312
|
+
|
313
|
+
#Se revisa que respuesta no sea nula.
|
314
|
+
if response
|
315
|
+
puts 'Respuesta acknowledge_transaction: '+ response.to_s
|
316
|
+
else
|
317
|
+
puts 'Webservice Webpay responde con null'
|
318
|
+
response_array ={
|
319
|
+
"error_desc" => 'Webservice Webpay responde con null'
|
320
|
+
}
|
321
|
+
return response_array
|
322
|
+
end
|
323
|
+
|
324
|
+
#Verificacion de certificado respuesta
|
325
|
+
tbk_cert = OpenSSL::X509::Certificate.new(@webpay_cert)
|
326
|
+
|
327
|
+
if !Verifier.verify(response, tbk_cert)
|
328
|
+
response_array ={
|
329
|
+
"error_desc" => 'El Certificado de respuesta es Invalido'
|
330
|
+
}
|
331
|
+
return response_array
|
332
|
+
else
|
333
|
+
puts "El Certificado de respuesta es Valido."
|
334
|
+
end
|
335
|
+
|
336
|
+
response_array ={
|
337
|
+
"error_desc" => 'TRX_OK'
|
338
|
+
}
|
339
|
+
|
340
|
+
return response_array
|
341
|
+
end
|
342
|
+
|
343
|
+
|
344
|
+
def sign_xml (input_xml)
|
345
|
+
|
346
|
+
document = Nokogiri::XML(input_xml.body)
|
347
|
+
envelope = document.at_xpath("//env:Envelope")
|
348
|
+
envelope.prepend_child("<env:Header><wsse:Security xmlns:wsse='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' wsse:mustUnderstand='1'/></env:Header>")
|
349
|
+
xml = document.to_s
|
350
|
+
|
351
|
+
signer = Signer.new(xml)
|
352
|
+
|
353
|
+
signer.cert = OpenSSL::X509::Certificate.new(@public_cert)
|
354
|
+
signer.private_key = OpenSSL::PKey::RSA.new(@private_key)
|
355
|
+
|
356
|
+
signer.document.xpath("//soapenv:Body", { "soapenv" => "http://schemas.xmlsoap.org/soap/envelope/" }).each do |node|
|
357
|
+
signer.digest!(node)
|
358
|
+
end
|
359
|
+
|
360
|
+
signer.sign!(:issuer_serial => true)
|
361
|
+
signed_xml = signer.to_xml
|
362
|
+
|
363
|
+
document = Nokogiri::XML(signed_xml)
|
364
|
+
x509data = document.at_xpath("//*[local-name()='X509Data']")
|
365
|
+
new_data = x509data.clone()
|
366
|
+
new_data.set_attribute("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#")
|
367
|
+
|
368
|
+
n = Nokogiri::XML::Node.new('wsse:SecurityTokenReference', document)
|
369
|
+
n.add_child(new_data)
|
370
|
+
x509data.add_next_sibling(n)
|
371
|
+
|
372
|
+
return document
|
373
|
+
end
|
374
|
+
|
375
|
+
|
376
|
+
|
377
|
+
end
|