pago_efectivo 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 39d4e1696f5621391ae6c184b9f361fb5a837293
4
+ data.tar.gz: dee69c3b22cb4d91cb1fcf331261d8667b5dc513
5
+ SHA512:
6
+ metadata.gz: 92b20589adb941888b28791e2c57f2b77f656d00d4734df02a57ebd7c2ada89682a1380aaf9cf6e8f6c985e2eb0ee1c5eca303e8e258b2e47daee0a80bdd5ddf
7
+ data.tar.gz: 5de31c49270265974383de9f171673d3c1662d746266d81df72c35f6cb8922ed0e65293706caf3cbf5c18708da3e992ddf3bea884639509dfaa6375a4266b090
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ settings.rb
2
+ *.1pz
3
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'gyoku', git: 'https://github.com/ccarruitero/gyoku.git', branch: 'except_convert'
6
+ gem 'savon'
7
+ gem 'nokogiri'
data/Makefile ADDED
@@ -0,0 +1,4 @@
1
+ .PHONY: test
2
+
3
+ test:
4
+ cutest test/*.rb
data/README.mkd ADDED
@@ -0,0 +1,93 @@
1
+ # Pago efectivo
2
+ Ruby SOAP Client to connect with [pago efectivo](https://pagoefectivo.pe/) api.
3
+
4
+ ## Install
5
+ You can install via
6
+ ```
7
+ gem install pago_efectivo
8
+ ```
9
+ or by adding to your Gemfile
10
+ ```
11
+ gem 'pago_efectivo'
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ To use this gem you need a service code and keys provided by pago efectivo.
17
+
18
+ The first step to use is init a client and set keys
19
+
20
+ ``` ruby
21
+ require 'pago_efectivo'
22
+
23
+ # init client
24
+ pago_client = PagoEfectivo::Client.new
25
+
26
+ # set keys
27
+ pago_client.set_key type_of_key, path_to_your_key
28
+ ```
29
+
30
+ To generate a cip
31
+
32
+ ``` ruby
33
+ # generate xml
34
+ xml = pago_client.generate_xml('RSI', PagoEfectivo::CURRENCIES[:soles], '22.00', 1, 'OR001024', 'mail@example.com', {first_name: 'Jweopan', last_name: 'Jnshska', doc_type: 'DNI', doc_num: '37283937', id: 293, email: 'nanan@mail.com'},'', '31/10/2014 17:00:00', {loc: 'San Isidro', prov: 'Lima', country: 'Peru'}, 'some order reference', '','')
35
+
36
+ # get sign with xml
37
+ sign = pago_client.signature xml
38
+
39
+ # get encrypted xml
40
+ encrypt = pago_client.encrypt_text xml
41
+
42
+ # generate cip itself
43
+ cip = pago_client.generate_cip 'RSI', sign, encrypt
44
+
45
+ # decrypt cip result
46
+ decrypted_cip = pago_client.unencrypt cip
47
+
48
+ # parse decrypted cip
49
+ cip_result = pago_client.parse_cip_result decrypted_cip
50
+ ```
51
+
52
+ To consult cip
53
+ ``` ruby
54
+ # encrypt cip number
55
+ encrypted_cip = pago_client.encrypt_text '1086648'
56
+
57
+ # sign cip number
58
+ signed_cip = pago_client.signature '1086648'
59
+
60
+ # consult cip
61
+ consulted_result = pago_client.consult_cip 'RSI', signed_cip, encrypted_cip
62
+
63
+ # decrypt result
64
+ uncrypted = pago_client.unencrypt consulted_result[:xml]
65
+
66
+ # parse cip
67
+ cip = pago_client.parse_consult_cip_result uncrypted
68
+ ```
69
+
70
+ To update expiration date
71
+ ``` ruby
72
+ # encrypt cip number
73
+ encrypted_cip = pago_client.encrypt_text '1086648'
74
+
75
+ # sign cip number
76
+ signed_cip = pago_client.signature '1086648'
77
+
78
+ # update cip
79
+ pago_client.update_cip 'RSI', signed_cip, encrypted_cip, new_date
80
+ ```
81
+ Note: new_date should be DateTime class
82
+
83
+ To delete cip
84
+ ``` ruby
85
+ # encrypt cip number
86
+ encrypted_cip = pago_client.encrypt_text '1086648'
87
+
88
+ # sign cip number
89
+ signed_cip = pago_client.signature '1086648'
90
+
91
+ # delete cip
92
+ pago_client.delete_cip 'RSI', signed_cip, encrypted_cip
93
+ ```
@@ -0,0 +1,218 @@
1
+ require 'savon'
2
+ require 'gyoku'
3
+ require 'nokogiri'
4
+
5
+ module PagoEfectivo
6
+ CURRENCIES = {soles: {id: 1, symbol: 'S/.'}, dolares: {id: 2, symbol: '$'}}
7
+ PAY_METHODS = [1,2] #[{'bancos' => 1}, {'cuenta_virtual' => 2}]
8
+
9
+ class Client
10
+ SCHEMA_TYPES = {
11
+ 'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
12
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
13
+ 'xmlns:soap' => 'http://schemas.xmlsoap.org/soap/envelope/'
14
+ }
15
+
16
+ def initialize env=nil
17
+ if env == 'production'
18
+ @api_server = 'https://pagoefectivo.pe'
19
+ else
20
+ @api_server = 'http://pre.pagoefectivo.pe'
21
+ end
22
+
23
+ if ENV['PROXY_URL'] != nil
24
+ @proxy = ENV['PROXY_URL']
25
+ end
26
+ @crypto_path = '/PagoEfectivoWSCrypto/WSCrypto.asmx?WSDL'
27
+ @cip_path = '/PagoEfectivoWSGeneralv2/service.asmx?WSDL'
28
+ end
29
+
30
+ def set_key type, path
31
+ raise 'path to your key is not valid' unless File.exists?(path)
32
+ if type == 'private'
33
+ @private_key = File.open(path, 'rb') {|f| Base64.encode64(f.read)}
34
+ elsif type == 'public'
35
+ @public_key = File.open(path, 'rb') {|f| Base64.encode64(f.read)}
36
+ end
37
+ end
38
+
39
+ def create_markup(body)
40
+ xml_markup = Nokogiri.XML(body).to_xml
41
+ end
42
+
43
+ def signature(text)
44
+ server = @api_server + @crypto_path
45
+ client = Savon.client(wsdl: server, proxy: @proxy)
46
+ response = client.call(:signer, message: {
47
+ plain_text: text, private_key: @private_key
48
+ })
49
+ response.to_hash[:signer_response][:signer_result]
50
+ end
51
+
52
+ def encrypt_text(text)
53
+ server = @api_server + @crypto_path
54
+ client = Savon.client(wsdl: server, proxy: @proxy)
55
+ response = client.call(:encrypt_text, message: {
56
+ plain_text: text, public_key: @public_key
57
+ })
58
+ response.to_hash[:encrypt_text_response][:encrypt_text_result]
59
+ end
60
+
61
+ def unencrypt enc_text
62
+ server = @api_server + @crypto_path
63
+ client = Savon.client(wsdl: server, proxy: @proxy)
64
+ response = client.call(:decrypt_text, message: {
65
+ encrypt_text: enc_text, private_key: @private_key
66
+ })
67
+ response.to_hash[:decrypt_text_response][:decrypt_text_result]
68
+ end
69
+
70
+ # after unencrypt cip result this return like string so we need parse this
71
+ # for access cip data in more easy way
72
+ def parse_cip_result uncrypt_text
73
+ parser = Nori.new
74
+ cip = parser.parse uncrypt_text
75
+ cip['ConfirSolPago']['CIP']
76
+ end
77
+
78
+ def generate_xml(cod_serv, currency, total, pay_methods, cod_trans, email,
79
+ user, additional_data, exp_date, place, pay_concept,
80
+ origin_code, origin_type)
81
+ # cod_serv => código de servicio asignado
82
+ # signer => trama firmada con llave privada
83
+ child_hash = { sol_pago: {
84
+ id_moneda: currency[:id],
85
+ total: total, # 18 enteros, 2 decimales. Separados por `,`
86
+ metodos_pago: pay_methods,
87
+ cod_servicio: cod_serv,
88
+ codtransaccion: cod_trans, # referencia al pago
89
+ email_comercio: email,
90
+ fecha_a_expirar: exp_date, # (DateTime.now + 4).to_s(:db)
91
+ usuario_id: user[:id],
92
+ data_adicional: additional_data,
93
+ usuario_nombre: user[:first_name],
94
+ usuario_apellidos: user[:last_name],
95
+ usuario_localidad: place[:loc],
96
+ usuario_provincia: place[:prov],
97
+ usuario_pais: place[:country],
98
+ usuario_alias: '',
99
+ usuario_tipo_doc: user[:doc_type], # tipo de documento DNI, LE, RUC
100
+ usuario_numero_doc: user[:doc_num],
101
+ usuario_email: user[:email],
102
+ concepto_pago: pay_concept,
103
+ detalles: {
104
+ detalle: {
105
+ cod_origen: origin_code,
106
+ tipo_origen: origin_type,
107
+ concepto_pago: pay_concept,
108
+ importe: total,
109
+ campo1: '',
110
+ campo2: '',
111
+ campo3: '',
112
+ }
113
+ },
114
+ params_url: {
115
+ param_url: {
116
+ nombre: 'IDCliente',
117
+ valor: user[:id]
118
+ },
119
+ params_email: {
120
+ param_email: {
121
+ nombre: '[UsuarioNombre]',
122
+ valor: user[:first_name]
123
+ },
124
+ param_email: {
125
+ nombre: '[Moneda]',
126
+ valor: currency[:symbol]
127
+ }
128
+ }
129
+ }
130
+ }
131
+ }
132
+ child_options = { key_converter: :camelcase}
133
+ gyoku_xml = Gyoku.xml(child_hash, child_options)
134
+ xml_child = create_markup(gyoku_xml)
135
+ end
136
+
137
+ def generate_cip(cod_serv, signer, xml)
138
+ server = @api_server + @cip_path
139
+ client = Savon.client(wsdl: server, proxy: @proxy)
140
+ response = client.call(:generar_cip_mod1, message: {
141
+ request: {
142
+ 'CodServ' => cod_serv,
143
+ 'Firma' => signer,
144
+ 'Xml' => xml
145
+ }})
146
+ response.to_hash[:generar_cip_mod1_response][:generar_cip_mod1_result]
147
+ end
148
+
149
+ # cod_serv: service code, provided by pago efectivo
150
+ # cips: string of cips separated with comma (,)
151
+ # signed_cips: cips passed by signer method
152
+ # encrypted_cips: cips passed by encrypted method
153
+ # info_request: no specified in pago efectivo documentation, send blank
154
+ # for now
155
+ def consult_cip cod_serv, signed_cips, encrypted_cips, info_request=''
156
+ server = @api_server + @cip_path
157
+ client = Savon.client(wsdl: server, proxy: @proxy)
158
+ response = client.call(:consultar_cip_mod1, message: {
159
+ 'request' => {
160
+ 'CodServ' => cod_serv,
161
+ 'Firma' => signed_cips,
162
+ 'CIPS' => encrypted_cips,
163
+ info_request: info_request
164
+ }
165
+ })
166
+ response.to_hash[:consultar_cip_mod1_response][:consultar_cip_mod1_result]
167
+ end
168
+
169
+ # after unencrypt consult cip result this return string so we need parse
170
+ # this for access cip data in more easy way
171
+ def parse_consult_cip_result uncrypt_text
172
+ parser = Nori.new
173
+ cip = parser.parse uncrypt_text
174
+ # TODO: parse response for multiple cips
175
+ cip['ConfirSolPagos']['ConfirSolPago']['CIP']
176
+ end
177
+
178
+ # cod_serv: service code, provided by pago efectivo
179
+ # signed_cip: number of cip to delete passed by signer method
180
+ # encrypted_cip: number of cip to delete passed by encrypted method
181
+ # info_request: no specified in pago efectivo documentation, send blank
182
+ # for now
183
+ def delete_cip cod_serv, signed_cip, encrypted_cip, info_request=''
184
+ server = @api_server + @cip_path
185
+ client = Savon.client(wsdl: server, proxy: @proxy)
186
+ response = client.call(:eliminar_cip_mod1, message: {
187
+ 'request' => {
188
+ 'CodServ' => cod_serv,
189
+ 'Firma' => signed_cip,
190
+ 'CIP' => encrypted_cip,
191
+ 'InfoRequest' => info_request
192
+ }
193
+ })
194
+ response.to_hash[:eliminar_cip_mod1_response][:eliminar_cip_mod1_result]
195
+ end
196
+
197
+ # cod_serv: service code, provided by pago efectivo
198
+ # signed_cip: number of cip to modify passed by signer method
199
+ # encrypted_cip: number of cip to modify passed by encrypted method
200
+ # exp_date: new expiration date, should be DateTime class
201
+ # info_request: no specified in pago efectivo documentation, send blank
202
+ # for now
203
+ def update_cip cod_serv,signed_cip,encrypted_cip,exp_date,info_request=''
204
+ server = @api_server + @cip_path
205
+ client = Savon.client(wsdl: server, proxy: @proxy)
206
+ response = client.call(:actualizar_cip_mod1, message: {
207
+ 'request' => {
208
+ 'CodServ' => cod_serv,
209
+ 'Firma' => signed_cip,
210
+ 'CIP' => encrypted_cip,
211
+ 'FechaExpira' => exp_date,
212
+ 'InfoRequest' => info_request
213
+ }
214
+ })
215
+ response.to_hash[:actualizar_cip_mod1_response][:actualizar_cip_mod1_result]
216
+ end
217
+ end
218
+ end
data/lib/vars.rb ADDED
@@ -0,0 +1,9 @@
1
+ # Pago Efectivo variables
2
+
3
+ CURRENCIES = [{soles: {id: 1, symbol: 'S/.'}}, {dólares: {id: 2, symbol: '$'}}]
4
+ PAY_METHODS = [{'bancos': 1}, {'cuenta_virtual': 2}]
5
+ ORIGIN_TYPE = [
6
+ {'orden': 'OP'},
7
+ {'boleta': 'BOL'},
8
+ {'factura': 'FAC'}
9
+ ]
@@ -0,0 +1,17 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "pago_efectivo"
3
+ s.version = "0.0.1"
4
+ s.summary = "SOAP client to use Pago Efectivo"
5
+ s.description = s.summary
6
+ s.authors = ["César Carruitero"]
7
+ s.email = ["cesar@mozilla.pe"]
8
+ s.homepage = "https://github.com/ccarruitero/pago_efectivo"
9
+ s.license = "MPL"
10
+
11
+ s.files = `git ls-files`.split("\n")
12
+
13
+ s.add_runtime_dependency "gyoku"
14
+ s.add_runtime_dependency "savon"
15
+
16
+ s.add_development_dependency "cutest"
17
+ end
data/test/app_test.rb ADDED
@@ -0,0 +1,26 @@
1
+ require_relative 'helper'
2
+ include PagoEfectivo
3
+
4
+ scope do
5
+ test 'should set dev api_server when initialize without option' do
6
+ client = PagoEfectivo::Client.new
7
+ api_server = client.instance_variable_get(:@api_server)
8
+ assert api_server == 'http://pre.pagoefectivo.pe'
9
+ end
10
+
11
+ test 'should set prod api_server when initialize if you set option' do
12
+ client = PagoEfectivo::Client.new('production')
13
+ api_server = client.instance_variable_get(:@api_server)
14
+ assert api_server == 'https://pagoefectivo.pe'
15
+ end
16
+
17
+ test 'create_markup generate valid xml' do
18
+ client = PagoEfectivo::Client.new
19
+ xml = Gyoku.xml({key: 'value'})
20
+ markup = client.create_markup(xml)
21
+ assert markup.include?('?xml')
22
+ end
23
+
24
+ test 'set_key should keep key like binary' do
25
+ end
26
+ end
data/test/fake_key ADDED
File without changes
data/test/helper.rb ADDED
@@ -0,0 +1,2 @@
1
+ require "cutest"
2
+ require_relative "../lib/pago_efectivo"
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pago_efectivo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - César Carruitero
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gyoku
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: savon
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: cutest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: SOAP client to use Pago Efectivo
56
+ email:
57
+ - cesar@mozilla.pe
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - Makefile
65
+ - README.mkd
66
+ - lib/pago_efectivo.rb
67
+ - lib/vars.rb
68
+ - pago_efectivo.gemspec
69
+ - test/app_test.rb
70
+ - test/fake_key
71
+ - test/helper.rb
72
+ homepage: https://github.com/ccarruitero/pago_efectivo
73
+ licenses:
74
+ - MPL
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 2.2.2
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: SOAP client to use Pago Efectivo
96
+ test_files: []