cobro_digital 1.8.0 → 1.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.
data/lib/cobro_digital.rb CHANGED
@@ -7,6 +7,10 @@ require "cobro_digital/transaccion"
7
7
  require "cobro_digital/micrositio"
8
8
  require "cobro_digital/meta"
9
9
  require "savon"
10
+ require "net/http"
11
+ require "uri"
12
+ require "digest"
13
+ require "json"
10
14
 
11
15
  module CobroDigital
12
16
 
@@ -19,6 +23,18 @@ module CobroDigital
19
23
 
20
24
  TIMEOUT = 300
21
25
 
26
+ # Nivel de log del cliente SOAP. Default `:error` para no filtrar el `sid`
27
+ # ni PII del pagador a los logs de la app. Subir a `:debug` solo para
28
+ # troubleshooting explícito (vía ENV['COBRODIGITAL_LOG_LEVEL']).
29
+ # Se sanea el string vacío (`COBRODIGITAL_LOG_LEVEL=`) que produciría `:""`.
30
+ _log_level = ENV['COBRODIGITAL_LOG_LEVEL'].to_s
31
+ LOG_LEVEL = (_log_level.empty? ? 'error' : _log_level).to_sym
32
+ DEBUG_LOG = (LOG_LEVEL == :debug)
33
+
34
+ # Nodo del mensaje SOAP que transporta credenciales (`sid`) y PII del pagador.
35
+ # Savon lo enmascara como `***FILTERED***` en el log, incluso en `:debug`.
36
+ LOG_FILTERS = [:parametros_de_entrada].freeze
37
+
22
38
  module Https
23
39
  POST = 'Post'
24
40
  GET = 'Get'
@@ -26,30 +42,45 @@ module CobroDigital
26
42
 
27
43
  class Client
28
44
 
45
+ # NOTA: `sid` y `request_xml` contienen datos sensibles (credencial del
46
+ # comercio y XML con sid + PII del pagador). No loguear estos accessors.
29
47
  attr_accessor :id_comercio, :sid, :client_to_use, :http_method, :pagadores, :boletas, :transacciones, :micrositios, :requests, :request_xml
30
48
 
31
49
  def initialize(attrs={})
32
50
  @id_comercio = attrs[:id_comercio]
33
51
  @sid = attrs[:sid]
34
- @client_to_use = attrs[:con_client].present? ? attrs[:con_client] : CobroDigital::SOAP
52
+ @client_to_use = attrs[:con_client].to_s.empty? ? CobroDigital::SOAP : attrs[:con_client]
35
53
  # @with_handshake = attrs[:handshake].present? ? attrs[:handshake] : true
36
54
  @pagadores = []
37
55
  @boletas = []
38
56
  @transacciones = []
39
57
  @micrositios = []
40
58
  @request_xml = nil
59
+
60
+ unless CobroDigital::CLIENTS.include?(@client_to_use)
61
+ raise ArgumentError, "client_to_use inválido: #{@client_to_use.inspect} (esperado uno de #{CobroDigital::CLIENTS.inspect})"
62
+ end
41
63
  end
42
64
 
43
65
  def soap_client(params)
66
+ # `log: true` para que se sigan registrando errores SOAP/HTTP; la
67
+ # verbosidad la controla `log_level` (default :error → no loguea el body).
68
+ # `filters` enmascara el nodo con sid + PII como ***FILTERED*** si algo se
69
+ # llega a loguear. ADVERTENCIA: con COBRODIGITAL_LOG_LEVEL=debug el XML
70
+ # formateado incluye el sid en claro — no habilitar debug en producción.
44
71
  client = Savon.client(
45
72
  wsdl: CobroDigital::WSDL,
46
- log_level: :debug,
47
- pretty_print_xml: true,
73
+ log: true,
74
+ log_level: CobroDigital::LOG_LEVEL,
75
+ filters: CobroDigital::LOG_FILTERS,
76
+ pretty_print_xml: CobroDigital::DEBUG_LOG,
48
77
  open_timeout: CobroDigital::TIMEOUT,
49
78
  read_timeout: CobroDigital::TIMEOUT
50
79
  )
51
80
  operation = client.operation(:webservice_cobrodigital)
52
81
  request = operation.build(message: { 'parametros_de_entrada' => params.to_json })
82
+ # Contrato público: `@request_xml` siempre disponible tras el call. Retiene
83
+ # el XML con sid + PII en memoria — el consumidor no debe loguearlo.
53
84
  @request_xml = request.pretty
54
85
 
55
86
  client.call(:webservice_cobrodigital, message: { 'parametros_de_entrada' => params.to_json })
@@ -58,12 +89,12 @@ module CobroDigital
58
89
  def https_client(params)
59
90
  case http_method
60
91
  when CobroDigital::Https::POST
61
- uri = URI(CobroDigital::URI)
62
- req = "Net::HTTP::#{http_method}".constantize.new(uri)
92
+ uri = ::URI.parse(CobroDigital::URI)
93
+ req = Net::HTTP::Post.new(uri)
63
94
  req.set_form_data(params)
64
95
  when CobroDigital::Https::GET
65
- uri = URI([CobroDigital::URI, URI.encode_www_form(data)].join('?'))
66
- req = "Net::HTTP::#{http_method}".constantize.new(uri)
96
+ uri = ::URI.parse([CobroDigital::URI, ::URI.encode_www_form(params)].join('?'))
97
+ req = Net::HTTP::Get.new(uri)
67
98
  end
68
99
 
69
100
  Net::HTTP.start(
data/skill/SKILL.md ADDED
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: cobro-digital
3
+ description: >-
4
+ Gema adaptadora del Web Service v3 de CobroDigital (pasarela de pago).
5
+ Modela las operaciones del WS — crear/editar/verificar pagadores, generar/
6
+ inhabilitar boletas, obtener código de barras, consultar transacciones y
7
+ actividad de micrositios, y agrupar operaciones en batch (meta) — y resuelve
8
+ el transporte SOAP (default, vía savon) o HTTPS hacia el endpoint del comercio.
9
+ Activala cuando trabajes con cobranzas/boletas/pagadores contra CobroDigital,
10
+ cuando integres o depures la comunicación con su webservice, o cuando un host
11
+ consuma la gema `cobro_digital`.
12
+ triggers:
13
+ - "cobrodigital"
14
+ - "cobro digital"
15
+ - "generar boleta"
16
+ - "crear pagador"
17
+ - "consultar transacciones cobrodigital"
18
+ - "webservice de pago cobrodigital"
19
+ - "gema cobro_digital"
20
+ ---
21
+
22
+ # cobro_digital
23
+
24
+ ## Qué es / cuándo usar
25
+
26
+ Adaptador Ruby del WS v3 de CobroDigital (pasarela de pago argentina). Úsalo
27
+ para invocar las operaciones del webservice desde un host Ruby/Rails. La gema
28
+ no persiste estado ni define excepciones propias: arma el payload, lo envía y
29
+ decodifica la respuesta.
30
+
31
+ ## Contrato resumido
32
+
33
+ **Patrón de uso:** cada operación es una subclase de `CobroDigital::Operador`
34
+ construida por un método de clase y ejecutada con `#call(id_comercio, sid)`.
35
+
36
+ ```ruby
37
+ op = CobroDigital::Boleta.generar(id, buscar, vencimientos, importes, concepto, plantilla)
38
+ op.call(comercio_id, comercio_sid) # ejecuta; guarda #response
39
+ op.parse_response # => { resultado: Bool, log: [..], datos: [..] }
40
+ ```
41
+
42
+ **Superficie pública** (detalle: [`docs/interface/interface.md`](../docs/interface/interface.md)):
43
+
44
+ - `CobroDigital::Pagador` — `.crear`, `.editar`, `.verificar`, `.codigo_electronico`, `.estructura_de_datos`
45
+ - `CobroDigital::Boleta` — `.generar`, `.inhabilitar`, `.obtener_codigo_de_barras`
46
+ - `CobroDigital::Transaccion` — `.consultar(desde, hasta, filtros)` + constantes `FILTRO_*`
47
+ - `CobroDigital::Micrositio` — `.consultar_actividad`
48
+ - `CobroDigital::Meta` — `.meta(objs)` (batch de operaciones en una llamada)
49
+ - `CobroDigital::Client` — transporte; `CobroDigital::VERSION`
50
+
51
+ **Config:** `ENV['ENDPOINT_COBRODIGITAL']` (default `https://cobro.digital:14365`)
52
+ y `ENV['COBRODIGITAL_LOG_LEVEL']` (default `error`). Credenciales `id_comercio`/`sid`
53
+ se pasan por argumento en cada `#call`, no por env.
54
+
55
+ **Gotchas:**
56
+ - `parse_response` **no levanta excepción** ante `resultado: false` — el unhappy
57
+ path se inspecciona vía `resultado`/`log`. Fallos de transporte propagan
58
+ `Savon::*` / `Net::HTTP` / `JSON::ParserError` sin envolver.
59
+ - El WS **no controla duplicados** (`crear_pagador` es no-idempotente): el
60
+ control de unicidad es del consumidor.
61
+ - `client_to_use` inválido (≠ `'soap'`/`'https'`) → `ArgumentError` en `Client.new`.
62
+ - **No usar `COBRODIGITAL_LOG_LEVEL=debug` en producción**: el XML formateado del
63
+ request expone el `sid` + PII del pagador.
64
+ - Requiere Ruby `>= 2.7, < 3.0` (stack savon 2.12). Desde v1.9.0 **no** depende de
65
+ ActiveSupport (solo stdlib).
66
+
67
+ ## Índice de artefactos
68
+
69
+ | capa | doc | estado |
70
+ |---|---|---|
71
+ | interfaz | [`docs/interface/interface.md`](../docs/interface/interface.md) | API Ruby pública |
72
+ | consumidas | [`docs/consumed/cobrodigital.md`](../docs/consumed/cobrodigital.md) | WS de CobroDigital (§a/§b/§d; §c/§e pendientes de enrich) |
73
+ | configuración | [`docs/config/configuracion.md`](../docs/config/configuracion.md) | inventario base |
74
+ | topología | [`docs/topology/topology.md`](../docs/topology/topology.md) | deps + modos de transporte |
75
+ | test | [`docs/test/testing.md`](../docs/test/testing.md) | RSpec (suite mínima) |
76
+ | comportamiento | [`docs/behavior/behavior.md`](../docs/behavior/behavior.md) | operación simple · batch meta |
77
+ | glosario | [`docs/glossary/glossary.md`](../docs/glossary/glossary.md) | términos del dominio |
78
+ | datos · api · errores · eventos · seguridad · multi-tenancy · data-lifecycle | — | n/a (ver Mapa de conocimiento en `AGENTS.md`) |
79
+ | release | — | pendiente (`/gem-release`) |
80
+
81
+ ## Uso correcto / gotchas
82
+
83
+ - Para varias operaciones en una sola llamada al WS, construí cada operación y
84
+ pasalas a `CobroDigital::Meta.meta([...])`.
85
+ - Las fechas de `Boleta.generar`, `Transaccion.consultar` y `Micrositio.consultar_actividad`
86
+ se formatean internamente a `%Y%m%d` — pasá objetos `Date`/`Time`, no strings.
87
+ - El handshake (`MD5` de `Time.now`) se regenera por request automáticamente.
data/skills.yml ADDED
@@ -0,0 +1,17 @@
1
+ mcps:
2
+ - github
3
+ - clickup
4
+ skills:
5
+ multi-vendor-feedback:
6
+ yard:
7
+ quality-code:
8
+ gem-release:
9
+ arch-structure:
10
+ arch-compose:
11
+ arch-enrich:
12
+ skill-feedback:
13
+ agent-issue:
14
+ bug-report:
15
+ dev-flow:
16
+ documentation-writer:
17
+ matrix-element:
metadata CHANGED
@@ -1,42 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cobro_digital
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - g.edera
8
+ autorequire:
8
9
  bindir: exe
9
10
  cert_chain: []
10
- date: 2025-03-30 00:00:00.000000000 Z
11
+ date: 2026-06-29 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
- name: bundler
14
+ name: rake
14
15
  requirement: !ruby/object:Gem::Requirement
15
16
  requirements:
16
- - - "~>"
17
+ - - ">="
17
18
  - !ruby/object:Gem::Version
18
- version: 2.6.6
19
+ version: 13.2.1
19
20
  type: :development
20
21
  prerelease: false
21
22
  version_requirements: !ruby/object:Gem::Requirement
22
23
  requirements:
23
- - - "~>"
24
+ - - ">="
24
25
  - !ruby/object:Gem::Version
25
- version: 2.6.6
26
+ version: 13.2.1
26
27
  - !ruby/object:Gem::Dependency
27
- name: rake
28
+ name: rspec
28
29
  requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ">="
31
+ - - "~>"
31
32
  - !ruby/object:Gem::Version
32
- version: 13.2.1
33
+ version: '3.13'
33
34
  type: :development
34
35
  prerelease: false
35
36
  version_requirements: !ruby/object:Gem::Requirement
36
37
  requirements:
37
- - - ">="
38
+ - - "~>"
38
39
  - !ruby/object:Gem::Version
39
- version: 13.2.1
40
+ version: '3.13'
40
41
  - !ruby/object:Gem::Dependency
41
42
  name: savon
42
43
  requirement: !ruby/object:Gem::Requirement
@@ -58,9 +59,13 @@ executables: []
58
59
  extensions: []
59
60
  extra_rdoc_files: []
60
61
  files:
62
+ - ".github/workflows/main.yml"
63
+ - ".github/workflows/release.yml"
61
64
  - ".gitignore"
62
65
  - ".rspec"
63
- - ".travis.yml"
66
+ - AGENTS.md
67
+ - CHANGELOG.md
68
+ - CLAUDE.md
64
69
  - CODE_OF_CONDUCT.md
65
70
  - Gemfile
66
71
  - LICENSE.txt
@@ -69,6 +74,13 @@ files:
69
74
  - bin/console
70
75
  - bin/setup
71
76
  - cobro_digital.gemspec
77
+ - docs/behavior/behavior.md
78
+ - docs/config/configuracion.md
79
+ - docs/consumed/cobrodigital.md
80
+ - docs/glossary/glossary.md
81
+ - docs/interface/interface.md
82
+ - docs/test/testing.md
83
+ - docs/topology/topology.md
72
84
  - lib/cobro_digital.rb
73
85
  - lib/cobro_digital/boleta.rb
74
86
  - lib/cobro_digital/meta.rb
@@ -77,10 +89,14 @@ files:
77
89
  - lib/cobro_digital/pagador.rb
78
90
  - lib/cobro_digital/transaccion.rb
79
91
  - lib/cobro_digital/version.rb
92
+ - skill/SKILL.md
93
+ - skills.yml
80
94
  homepage: https://github.com/gedera/cobrodigital
81
95
  licenses:
82
96
  - MIT
83
- metadata: {}
97
+ metadata:
98
+ documentation_uri: https://github.com/gedera/cobrodigital/blob/v1.9.0/skill
99
+ post_install_message:
84
100
  rdoc_options: []
85
101
  require_paths:
86
102
  - lib
@@ -88,14 +104,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
88
104
  requirements:
89
105
  - - ">="
90
106
  - !ruby/object:Gem::Version
91
- version: '0'
107
+ version: '2.7'
108
+ - - "<"
109
+ - !ruby/object:Gem::Version
110
+ version: '3.0'
92
111
  required_rubygems_version: !ruby/object:Gem::Requirement
93
112
  requirements:
94
113
  - - ">="
95
114
  - !ruby/object:Gem::Version
96
115
  version: '0'
97
116
  requirements: []
98
- rubygems_version: 3.6.6
117
+ rubygems_version: 3.1.6
118
+ signing_key:
99
119
  specification_version: 4
100
120
  summary: Adaptador CobroDigital
101
121
  test_files: []
data/.travis.yml DELETED
@@ -1,4 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 1.8.7
4
- before_install: gem install bundler -v 1.10.6