pago_efectivo 0.0.1

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: 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: []