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 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