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.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +35 -0
- data/.github/workflows/release.yml +34 -0
- data/AGENTS.md +86 -0
- data/CHANGELOG.md +21 -0
- data/CLAUDE.md +15 -0
- data/README.md +96 -178
- data/cobro_digital.gemspec +7 -1
- data/docs/behavior/behavior.md +84 -0
- data/docs/config/configuracion.md +86 -0
- data/docs/consumed/cobrodigital.md +82 -0
- data/docs/glossary/glossary.md +101 -0
- data/docs/interface/interface.md +106 -0
- data/docs/test/testing.md +67 -0
- data/docs/topology/topology.md +42 -0
- data/lib/cobro_digital/version.rb +1 -1
- data/lib/cobro_digital.rb +38 -7
- data/skill/SKILL.md +87 -0
- data/skills.yml +17 -0
- metadata +36 -16
- data/.travis.yml +0 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1afc2d401df0ab220743405f8a5df6da4592b2b434f045b788870a3c04898e98
|
|
4
|
+
data.tar.gz: 3fc154767f9baea467ec0f12bf3243cb77222a1f4bac73cde098b2a57dd50e11
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: aca153572c2ca467b8cb3696edcaeccb989f98a5d888065bd41cf8308e9c04fe06fc8c7b947c1df843a3286e64439370557b77d990b3b1cba4839875cb0bc31c
|
|
7
|
+
data.tar.gz: b547264116c81700608a1760b556c83e7ab9001d4c8d21f7fb3db362bf4c90f84d197c4ff9df813a7638b8a8b56c2b25402d7199e0555a6ca246bc7e525936de
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Ruby
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
|
|
8
|
+
pull_request:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
test:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
name: Ruby ${{ matrix.ruby }}
|
|
17
|
+
strategy:
|
|
18
|
+
matrix:
|
|
19
|
+
ruby:
|
|
20
|
+
# savon ~> 2.12.1 corre sobre httpi 2.x, que usa URI.escape (removido
|
|
21
|
+
# en Ruby 3.0). El único consumer (wispro_cloud) corre Ruby 2.7.6.
|
|
22
|
+
# Subir a 3.x al actualizar el stack de savon.
|
|
23
|
+
- '2.7'
|
|
24
|
+
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v5
|
|
27
|
+
with:
|
|
28
|
+
persist-credentials: false
|
|
29
|
+
- name: Set up Ruby
|
|
30
|
+
uses: ruby/setup-ruby@v1
|
|
31
|
+
with:
|
|
32
|
+
ruby-version: ${{ matrix.ruby }}
|
|
33
|
+
bundler-cache: true
|
|
34
|
+
- name: Run specs
|
|
35
|
+
run: bundle exec rspec
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: Publish to RubyGems
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
name: Build + Publish
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v5
|
|
17
|
+
with:
|
|
18
|
+
persist-credentials: false
|
|
19
|
+
|
|
20
|
+
- name: Set up Ruby
|
|
21
|
+
uses: ruby/setup-ruby@v1
|
|
22
|
+
with:
|
|
23
|
+
# Igual que el target de CI: savon ~> 2.12.1 (httpi 2.x) no corre en
|
|
24
|
+
# Ruby 3.0+, y `gem build` evalúa el gemspec con el Ruby del runner.
|
|
25
|
+
ruby-version: '2.7'
|
|
26
|
+
|
|
27
|
+
- name: Build and publish to RubyGems
|
|
28
|
+
# gem push toma la credencial de GEM_HOST_API_KEY (nativo): no se escribe
|
|
29
|
+
# el secreto a disco ni queda expuesto en el process list.
|
|
30
|
+
run: |
|
|
31
|
+
gem build cobro_digital.gemspec
|
|
32
|
+
gem push *.gem
|
|
33
|
+
env:
|
|
34
|
+
GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
|
data/AGENTS.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# AGENTS.md — cobro_digital
|
|
2
|
+
|
|
3
|
+
Fuente de verdad para estructura, convenciones, entorno y arquitectura de esta gema. Leer antes de hacer cambios.
|
|
4
|
+
|
|
5
|
+
## 1. Identidad
|
|
6
|
+
|
|
7
|
+
`cobro_digital` es una gema Ruby: adaptador para comunicarse con el Web Service de [CobroDigital](http://cobrodigital.com) (versión 3.0 del WS), una pasarela de pago.
|
|
8
|
+
|
|
9
|
+
- `summary`: "Adaptador CobroDigital" (`cobro_digital.gemspec`).
|
|
10
|
+
- `description`: "Adaptador para el Web Service de CobroDigital".
|
|
11
|
+
- La gema modela las operaciones del webservice (crear/editar pagadores, generar/inhabilitar boletas, consultar transacciones y actividad de micrositios) y resuelve el transporte hacia el endpoint de CobroDigital.
|
|
12
|
+
- Requiere credenciales del comercio (`id_comercio` y `sid`) entregadas por CobroDigital para autenticarse contra el webservice (ver `README.md`).
|
|
13
|
+
- El endpoint default es `https://cobro.digital:14365/ws3/`, configurable vía la variable de entorno `ENDPOINT_COBRODIGITAL` (`lib/cobro_digital.rb`).
|
|
14
|
+
|
|
15
|
+
## 2. Convenciones del framework
|
|
16
|
+
|
|
17
|
+
Este repo consume skills del framework de agentes, declaradas en el manifiesto raíz `skills.yml`.
|
|
18
|
+
|
|
19
|
+
- Las skills vendoreadas en `.agents/skills/` traen conocimiento de las dependencias del repo.
|
|
20
|
+
- Leer la skill de una dependencia antes de responder o decidir sobre ella.
|
|
21
|
+
|
|
22
|
+
## 3. Entorno
|
|
23
|
+
|
|
24
|
+
- Ruby: `required_ruby_version = '>= 2.7', '< 3.0'` (el stack `savon ~> 2.12.1` / httpi 2.x no corre en Ruby 3.0+). El único consumer (wispro_cloud) usa Ruby 2.7.6. La CI corre sobre Ruby 2.7.
|
|
25
|
+
- Gestor de versiones: chruby (no rvm/rbenv).
|
|
26
|
+
- Dependencias: gestionadas con Bundler. El `Gemfile` toma las dependencias del gemspec (`gemspec`). No hay `Gemfile.lock` versionado (la CI resuelve con `bundler-cache`).
|
|
27
|
+
- Dependencia de runtime: `savon ~> 2.12.1` (cliente SOAP). **No depende de ActiveSupport** (solo stdlib: `net/http`, `uri`, `digest`, `json`).
|
|
28
|
+
- Dependencias de desarrollo: `rake >= 13.2.1`, `rspec ~> 3.13` (`cobro_digital.gemspec`).
|
|
29
|
+
|
|
30
|
+
## 4. YARD
|
|
31
|
+
|
|
32
|
+
Documentación incremental con la skill `yard`.
|
|
33
|
+
|
|
34
|
+
- Verificar cobertura de documentación: `bundle exec yard stats --list-undoc`.
|
|
35
|
+
|
|
36
|
+
## 5. Testing
|
|
37
|
+
|
|
38
|
+
- Framework: RSpec (`.rspec`, carpeta `spec/`, `Rakefile` registra `RSpec::Core::RakeTask`).
|
|
39
|
+
- Correr la suite: `bundle exec rspec` (o `bundle exec rake`, cuya tarea default es `:spec`).
|
|
40
|
+
- Código nuevo debe venir acompañado de tests.
|
|
41
|
+
|
|
42
|
+
## 6. Releases
|
|
43
|
+
|
|
44
|
+
- Publicar con la skill `/gem-release`.
|
|
45
|
+
- CI/release: GitHub Actions — `.github/workflows/main.yml` (rspec en PRs/push a master) y `.github/workflows/release.yml` (build + push a RubyGems al pushear un tag `v*`, vía `GEM_HOST_API_KEY`).
|
|
46
|
+
|
|
47
|
+
## 7. Arquitectura
|
|
48
|
+
|
|
49
|
+
El código vive en `lib/` bajo el módulo `CobroDigital` (`lib/cobro_digital.rb` es el require raíz).
|
|
50
|
+
|
|
51
|
+
- `CobroDigital::Client` (`lib/cobro_digital.rb`): transporte hacia el webservice. Mantiene credenciales (`id_comercio`, `sid`) y elige el cliente a usar: `soap` (vía Savon, default) o `https` (vía `Net::HTTP`, métodos `Post`/`Get`). Arma el bloque de identificación del comercio (incluye un `handshake` MD5) y ejecuta la llamada.
|
|
52
|
+
- `CobroDigital::Operador` (`lib/cobro_digital/operador.rb`): clase base de las operaciones. Define `request`, `call(id_comercio, sid, opt)` —que instancia un `Client` y ejecuta— y `parse_response`, que decodifica el JSON de salida del webservice en `{ resultado:, log:, datos: }`.
|
|
53
|
+
- `CobroDigital::Pagador` (`lib/cobro_digital/pagador.rb`): operaciones sobre pagadores (clientes a facturar): `crear`, `editar`, `verificar`, `codigo_electronico`, `estructura_de_datos`.
|
|
54
|
+
- `CobroDigital::Boleta` (`lib/cobro_digital/boleta.rb`): operaciones sobre boletas: `generar`, `inhabilitar`, `obtener_codigo_de_barras`.
|
|
55
|
+
- `CobroDigital::Transaccion` (`lib/cobro_digital/transaccion.rb`): consulta de transacciones (`consultar`) con filtros por tipo (ingresos, egresos, tarjeta de crédito, débito automático), nombre, concepto, nro de boleta e identificador.
|
|
56
|
+
- `CobroDigital::Micrositio` (`lib/cobro_digital/micrositio.rb`): consulta de actividad de micrositio (`consultar_actividad`).
|
|
57
|
+
- `CobroDigital::Meta` (`lib/cobro_digital/meta.rb`): agrupa varias operaciones en una sola llamada al webservice `meta` (batch), y expone helpers (`transaction`, `render`, `meta`).
|
|
58
|
+
- `CobroDigital::VERSION` (`lib/cobro_digital/version.rb`): versión actual de la gema.
|
|
59
|
+
|
|
60
|
+
Cada operación es una subclase de `Operador` que se construye con métodos de clase (constructores) y luego se ejecuta con `#call`.
|
|
61
|
+
|
|
62
|
+
## 8. Mapa de conocimiento (cómo leer la doc de este repo)
|
|
63
|
+
|
|
64
|
+
- **Tu conocimiento = la UNIÓN de este repo + sus asociados.** No termina en el `docs/<capa>/` local: incluye la doc de los servicios/gemas de `skills.yml`. Un flujo o pregunta que cruza repos (e2e) **no vive como doc estática** en ningún repo — se **compone on-demand recorriendo el grafo** (RFC-021): seguí las anclas (`docs/consumed/`, `**Canónico:**`) hasta los repos asociados y **unificá**.
|
|
65
|
+
- **Entrá por** [`skill/SKILL.md`](skill/SKILL.md) — índice de agente; resume el contrato y linkea el detalle.
|
|
66
|
+
- **Navegar una ancla cross-repo:** tomá la **key de servicio en `skills.yml`** (`services.<dep>.repo`) → ese repo es un **checkout hermano local** o alcanzable por **GitHub MCP**. No asumas que el hermano es inalcanzable. La dependencia externa de este repo (el WS de CobroDigital) es de proveedor, no del fleet: su contrato vive en `docs/consumed/` + el manual de CobroDigital.
|
|
67
|
+
|
|
68
|
+
### Cobertura de capas
|
|
69
|
+
|
|
70
|
+
| capa | doc | estado |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| interfaz (RFC-004) | [`docs/interface/interface.md`](docs/interface/interface.md) | **presente** |
|
|
73
|
+
| consumidas (RFC-018) | [`docs/consumed/cobrodigital.md`](docs/consumed/cobrodigital.md) | **presente** (estructural + §c/§e enriquecidos) |
|
|
74
|
+
| configuración (RFC-012) | [`docs/config/configuracion.md`](docs/config/configuracion.md) | **presente** (inventario base + §f) |
|
|
75
|
+
| topología (RFC-006) | [`docs/topology/topology.md`](docs/topology/topology.md) | **presente** |
|
|
76
|
+
| test (RFC-013) | [`docs/test/testing.md`](docs/test/testing.md) | **presente** (estructural + §e-§h) |
|
|
77
|
+
| comportamiento (RFC-007) | [`docs/behavior/behavior.md`](docs/behavior/behavior.md) | **presente** (operación simple · batch meta) |
|
|
78
|
+
| glosario (RFC-009) | [`docs/glossary/glossary.md`](docs/glossary/glossary.md) | **presente** (parcial, acreta por PR) |
|
|
79
|
+
| datos (RFC-002) | — | **n/a** — gema sin DB |
|
|
80
|
+
| api / operaciones (RFC-003) | — | **n/a** — consumer-only, sin superficie HTTP/CLI/eventos propia |
|
|
81
|
+
| errores (RFC-020) | — | **n/a** — no define excepciones propias; propaga `Savon::*`/`JSON` (ver `consumed §d`) |
|
|
82
|
+
| eventos (RFC-005) | — | **n/a** — no produce eventos |
|
|
83
|
+
| seguridad (RFC-017) | — | **n/a** — sin Pundit/Current; auth es la credencial de comercio (ver `consumed §a`) |
|
|
84
|
+
| multi-tenancy (RFC-023) | — | **n/a** — el tenant es el `id_comercio` por llamada, no hay scoping server-side |
|
|
85
|
+
| data-lifecycle (RFC-026) | — | **n/a** — sin persistencia propia |
|
|
86
|
+
| release (RFC-014) | [`.github/workflows/release.yml`](.github/workflows/release.yml) | **presente** — publicación tag-driven a RubyGems vía `/gem-release` |
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [1.9.0] — 2026-06-29
|
|
4
|
+
|
|
5
|
+
### Correcciones
|
|
6
|
+
- Reparar la rama HTTPS GET del cliente: variable `data` indefinida y colisión de la constante `CobroDigital::URI` con el módulo `::URI` de la stdlib (#9) — @gedera
|
|
7
|
+
- Agregar `require` explícitos de `net/http`, `uri`, `digest` y `json` (antes dependían de carga transitiva) (#10) — @gedera
|
|
8
|
+
- Enmascarar el `sid` y la PII del pagador en el log SOAP (`filters: [:parametros_de_entrada]`); `log_level` configurable vía `COBRODIGITAL_LOG_LEVEL` con default seguro `:error` (#12) — @gedera
|
|
9
|
+
- Validar `client_to_use` contra `CLIENTS` en `Client#initialize` → `ArgumentError` ante valor inválido (#13) — @gedera
|
|
10
|
+
|
|
11
|
+
### Mejoras internas
|
|
12
|
+
- Eliminar la dependencia de ActiveSupport: `present?` → `to_s.empty?` y `constantize` → `Net::HTTP::Post`/`Net::HTTP::Get` directos. La gema corre standalone sin Rails (#11) — @gedera
|
|
13
|
+
|
|
14
|
+
### Tests
|
|
15
|
+
- Reemplazar el spec placeholder (que fallaba a propósito) por tests reales de los constructores de operaciones y de `Operador#parse_response` (#14) — @gedera
|
|
16
|
+
|
|
17
|
+
### Otros
|
|
18
|
+
- CI/CD: GitHub Actions — `main.yml` (rspec sobre Ruby 2.7 en PRs y push a master) y `release.yml` (build + push a RubyGems tag-driven, vía `GEM_HOST_API_KEY`) — @gedera
|
|
19
|
+
- Eliminar `.travis.yml` legacy (Ruby 1.8.7) — @gedera
|
|
20
|
+
- gemspec: declarar `rspec ~> 3.13`, quitar el pin de `bundler`, `required_ruby_version = ['>= 2.7', '< 3.0']`, `documentation_uri` — @gedera
|
|
21
|
+
- Documentación: refrescar artefactos arch-* (`docs/`, `README.md`, `skill/SKILL.md`) al estado post-fix — @gedera
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Claude Code Notes
|
|
2
|
+
|
|
3
|
+
## Fuente de verdad del repositorio
|
|
4
|
+
|
|
5
|
+
Las reglas, convenciones, estructura y contexto del proyecto viven en `AGENTS.md`.
|
|
6
|
+
|
|
7
|
+
- Leer `AGENTS.md` antes de hacer cambios.
|
|
8
|
+
- Tratar `AGENTS.md` como fuente de verdad para identidad, estructura, documentación, convenciones del framework, entorno, y arquitectura.
|
|
9
|
+
|
|
10
|
+
## Propósito de este archivo
|
|
11
|
+
|
|
12
|
+
`CLAUDE.md` queda reservado para instrucciones o notas específicas de Claude Code.
|
|
13
|
+
|
|
14
|
+
- No duplicar aquí reglas generales del repositorio.
|
|
15
|
+
- Si una regla aplica a cualquier agente, moverla a `AGENTS.md`.
|
data/README.md
CHANGED
|
@@ -1,245 +1,163 @@
|
|
|
1
|
-
#
|
|
1
|
+
# cobro_digital
|
|
2
2
|
|
|
3
|
-
Adaptador para
|
|
3
|
+
Adaptador Ruby para el Web Service v3 de [CobroDigital](http://cobrodigital.com), una pasarela de pago. La gema modela las operaciones del WS (crear/editar pagadores, generar/inhabilitar boletas, consultar transacciones y actividad de micrositios) y resuelve el transporte hacia el endpoint, vía SOAP (default) o HTTPS.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* **id del comercio** (requerido para cualquier comunicación con el webservice, es la manera de identificarse con el webservice)
|
|
8
|
-
* **sid del comercio** (requerido para cualquier comunicación con el webservice, es la manera de identificarse con el webservice)
|
|
9
|
-
* **Estructura de pagador** (Esta estructura debe ser informada por cada comercio. esta estructura es del cliente a facturar)
|
|
10
|
-
* **Plantilla**, modelo de boleta para los clientes.
|
|
11
|
-
* **Manual de implementación**.
|
|
5
|
+
Requiere dar de alta el comercio con CobroDigital, que entrega: **id del comercio**, **sid del comercio**, estructura de pagador, plantilla de boleta y manual de implementación. Es posible solicitar datos de prueba.
|
|
12
6
|
|
|
13
7
|
## Instalación
|
|
14
8
|
|
|
15
|
-
|
|
9
|
+
En el `Gemfile`:
|
|
16
10
|
|
|
17
11
|
```ruby
|
|
18
12
|
gem 'cobro_digital'
|
|
19
13
|
```
|
|
20
14
|
|
|
21
|
-
Luego
|
|
22
|
-
|
|
23
|
-
$ bundle
|
|
24
|
-
|
|
25
|
-
O instala la gema a mano:
|
|
26
|
-
|
|
27
|
-
$ gem install cobro_digital
|
|
28
|
-
|
|
29
|
-
## Uso
|
|
30
|
-
|
|
31
|
-
### Pagadores
|
|
32
|
-
|
|
33
|
-
Los Pagadores son los clientes a los que se les facturará, las acciones posibles son las de `crear un pagador`, `editar un pagador`, `verificar un pagador`, `obtener codigo electronico`.
|
|
34
|
-
|
|
35
|
-
#### Crear Pagador
|
|
36
|
-
|
|
37
|
-
Consiste en crear un pagador en el webservice de CobroDigital, para ello es necesario:
|
|
15
|
+
Luego `bundle`, o instalar a mano con `gem install cobro_digital`.
|
|
38
16
|
|
|
39
|
-
|
|
40
|
-
* Es importante determinar un identificador único por pagador.
|
|
41
|
-
* El webservice de CobroDigital solo verifica que la estructura sea correcta, pero no realiza ninguna tipo de validación, por lo tanto es importante llevar el control de si un pagador ya fue dado de alta o no. Ya que es posible dar de alta eternamente el mismo pagador.
|
|
17
|
+
> **Ruby:** requiere `>= 2.7, < 3.0` (el stack `savon ~> 2.12.1` no corre en Ruby 3.0+). Desde v1.9.0 la gema usa solo stdlib — **no depende de ActiveSupport**. Los ejemplos con `Date#+`/`.days` son ilustrativos del host. Ver [`docs/topology/topology.md`](docs/topology/topology.md).
|
|
42
18
|
|
|
43
|
-
|
|
44
|
-
* Estructura de un pagador.
|
|
19
|
+
## Configuración
|
|
45
20
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
pagador = CobroDigital.Pagador.crear(estructura_pagador)
|
|
51
|
-
pagador.call(comercio_id, comercio_sid)
|
|
52
|
-
pagador.response # Obtengo el resultado.
|
|
53
|
-
```
|
|
21
|
+
| variable | default | propósito |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `ENDPOINT_COBRODIGITAL` | `https://cobro.digital:14365` | endpoint base del WS (override sandbox/prod) |
|
|
24
|
+
| `COBRODIGITAL_LOG_LEVEL` | `error` | nivel de log del cliente SOAP. **No usar `debug` en producción**: el XML formateado expone el `sid` + PII del pagador |
|
|
54
25
|
|
|
55
|
-
|
|
26
|
+
Detalle: [`docs/config/configuracion.md`](docs/config/configuracion.md).
|
|
56
27
|
|
|
57
|
-
|
|
28
|
+
## Índice de artefactos
|
|
58
29
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
30
|
+
| capa | doc | contenido |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| interfaz | [`docs/interface/interface.md`](docs/interface/interface.md) | API Ruby pública (`CobroDigital::*`) |
|
|
33
|
+
| consumidas | [`docs/consumed/cobrodigital.md`](docs/consumed/cobrodigital.md) | el WS de CobroDigital: operaciones, payloads, mapeo de error |
|
|
34
|
+
| configuración | [`docs/config/configuracion.md`](docs/config/configuracion.md) | inventario de configuración runtime |
|
|
35
|
+
| topología | [`docs/topology/topology.md`](docs/topology/topology.md) | dependencias y modos de transporte |
|
|
36
|
+
| test | [`docs/test/testing.md`](docs/test/testing.md) | suite RSpec |
|
|
37
|
+
| comportamiento | [`docs/behavior/behavior.md`](docs/behavior/behavior.md) | flujos: operación simple · batch meta |
|
|
38
|
+
| glosario | [`docs/glossary/glossary.md`](docs/glossary/glossary.md) | términos del dominio (pagador, boleta, transacción…) |
|
|
39
|
+
| datos · api · errores · eventos · seguridad · multi-tenancy · data-lifecycle | n/a | ver Mapa de conocimiento en [`AGENTS.md`](AGENTS.md) |
|
|
40
|
+
| release | [`.github/workflows/release.yml`](.github/workflows/release.yml) | publicación a RubyGems tag-driven (`v*`) vía `/gem-release` |
|
|
63
41
|
|
|
64
|
-
|
|
65
|
-
comercio_id = 'HA765587' #Brindado por cobrodigital para realizar pruebas
|
|
66
|
-
comercio_sid = 'wsZ0ya68K791phuu76gQ5L662J6F2Y4j7zqE2Jxa3Mvd22TWNn4iip6L9yq' #Brindado por cobrodigital para realizar pruebas
|
|
67
|
-
estructura_pagador = { 'Apellido y nombres' => "Probando Probando", 'Id' => 1234, 'Documento' => 33123456, 'Direccion del cliente' => "Falsa 1234", 'Telefono' => "222314", 'E-mail' => "santos.torrealba@who.com" } # Estructura brindada por cobrodigital para realizar pruebas
|
|
68
|
-
pagador = CobroDigital.Pagador.editar('id', 1234, estructura_pagador)
|
|
69
|
-
pagador.call(comercio_id, comercio_sid)
|
|
70
|
-
pagador.response # Obtengo el resultado.
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
#### Verificar Pagador
|
|
42
|
+
## Uso
|
|
74
43
|
|
|
75
|
-
|
|
44
|
+
Toda operación es una subclase de `CobroDigital::Operador`: se construye con un método de clase y se ejecuta con `#call(comercio_id, comercio_sid)`. La respuesta cruda queda en `#response`; `#parse_response` la decodifica a `{ resultado:, log:, datos: }`.
|
|
76
45
|
|
|
77
|
-
|
|
78
|
-
* Nombre del identificador.
|
|
79
|
-
* Valor del identificador.
|
|
46
|
+
> En los ejemplos, `comercio_id` y `comercio_sid` son las credenciales entregadas por CobroDigital. **No las hardcodees** — leelas de configuración/entorno (`ENV`, credentials de Rails, etc.).
|
|
80
47
|
|
|
81
48
|
```ruby
|
|
82
|
-
comercio_id
|
|
83
|
-
comercio_sid = '
|
|
84
|
-
pagador = CobroDigital.Pagador.verificar('id', 1234)
|
|
85
|
-
pagador.call(comercio_id, comercio_sid)
|
|
86
|
-
pagador.response # Obtengo el resultado.
|
|
49
|
+
comercio_id = ENV.fetch('COBRODIGITAL_ID')
|
|
50
|
+
comercio_sid = ENV.fetch('COBRODIGITAL_SID') # secreto
|
|
87
51
|
```
|
|
88
52
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
Para obtener el código electrónico con el cual le posibilitara a las personas realizar pagos por medio de pagosmiscuentas y linkpagos. Cabe que aclarar que este codigo solo sera posible obtener una vez generada la primer boleta.
|
|
92
|
-
|
|
93
|
-
Para la verificación de un pagador simplemente es necesario comunicar:
|
|
94
|
-
* Nombre del identificador.
|
|
95
|
-
* Valor del identificador.
|
|
53
|
+
### Pagadores
|
|
96
54
|
|
|
97
|
-
|
|
55
|
+
Los pagadores son los clientes a facturar.
|
|
98
56
|
|
|
99
57
|
```ruby
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
pagador = CobroDigital
|
|
58
|
+
# Crear
|
|
59
|
+
estructura = { 'Apellido y nombres' => 'Santos Torrealba', 'Id' => 1234, 'Documento' => 33123456 }
|
|
60
|
+
pagador = CobroDigital::Pagador.crear(estructura)
|
|
103
61
|
pagador.call(comercio_id, comercio_sid)
|
|
104
|
-
pagador.response
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
### Boleta
|
|
62
|
+
pagador.response
|
|
108
63
|
|
|
109
|
-
|
|
64
|
+
# Editar
|
|
65
|
+
CobroDigital::Pagador.editar('id', 1234, estructura).call(comercio_id, comercio_sid)
|
|
110
66
|
|
|
111
|
-
|
|
67
|
+
# Verificar existencia
|
|
68
|
+
CobroDigital::Pagador.verificar('id', 1234).call(comercio_id, comercio_sid)
|
|
112
69
|
|
|
113
|
-
|
|
70
|
+
# Código electrónico (solo tras generar la primera boleta)
|
|
71
|
+
CobroDigital::Pagador.codigo_electronico('id', 1234).call(comercio_id, comercio_sid)
|
|
114
72
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
* el valor del identificador.
|
|
118
|
-
* Array de vencimientos como máximo 4. Siempre la primera fecha deberá ser la fecha de emisión. ejemplo: [Date.today, Date.today+10.days, Date.today+20.days]
|
|
119
|
-
* Array de importes como máximo 4. Siempre el primer monto es el valor de la factura, los siguientes son con los recargos. [100, 110, 120]
|
|
120
|
-
* concepto, una simple leyenda.
|
|
121
|
-
* plantilla, es la plantilla de estilo de la boleta (Cada comercio debe proporcionar esta plantilla, comunicarse con CobroDigital para mas detalle)
|
|
122
|
-
|
|
123
|
-
Retorna un numero de boleta.
|
|
124
|
-
|
|
125
|
-
```ruby
|
|
126
|
-
comercio_id = 'HA765587' #Brindado por cobrodigital para realizar pruebas
|
|
127
|
-
comercio_sid = 'wsZ0ya68K791phuu76gQ5L662J6F2Y4j7zqE2Jxa3Mvd22TWNn4iip6L9yq' #Brindado por cobrodigital para realizar pruebas
|
|
128
|
-
nombre_identificador = 'id'
|
|
129
|
-
valor_identificador = 1234
|
|
130
|
-
vencimientos = [Date.today, Date.today+10.days, Date.today+20.days]
|
|
131
|
-
importes = [100,110,120]
|
|
132
|
-
concepto = "Factura A 10"
|
|
133
|
-
plantilla = 'init_273' #Proporcionado por CobroDigital para realizar pruebas.
|
|
134
|
-
boleta = CobroDigital.Boleta.generar(nombre_identificador, valor_identificador, vencimientos, importes, concepto, plantilla)
|
|
135
|
-
boleta.call(comercio_id, comercio_sid)
|
|
136
|
-
boleta.response # Obtengo el resultado.
|
|
73
|
+
# Estructura de pagadores del comercio
|
|
74
|
+
CobroDigital::Pagador.estructura_de_datos.call(comercio_id, comercio_sid)
|
|
137
75
|
```
|
|
138
76
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
Dar de baja una boleta ya generada en el webservice.
|
|
77
|
+
> El WS no controla duplicados: es posible dar de alta el mismo pagador repetidas veces. El control de unicidad es responsabilidad del consumidor.
|
|
142
78
|
|
|
143
|
-
|
|
144
|
-
* numero de boleta (obtenida en la generación)
|
|
79
|
+
### Boletas
|
|
145
80
|
|
|
146
81
|
```ruby
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
boleta = CobroDigital
|
|
82
|
+
# Generar — fechas (máx 4, la 1ª es la de emisión) e importes (máx 4, el 1º es el valor; el resto, recargos)
|
|
83
|
+
vencimientos = [Date.today, Date.today + 10, Date.today + 20]
|
|
84
|
+
importes = [100, 110, 120]
|
|
85
|
+
boleta = CobroDigital::Boleta.generar('id', 1234, vencimientos, importes, 'Factura A 10', 'init_273')
|
|
151
86
|
boleta.call(comercio_id, comercio_sid)
|
|
152
|
-
boleta.response #
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
#### Obtener codigo de barras
|
|
156
|
-
|
|
157
|
-
Obtener el string de los códigos de barras. Serán tantos como vencimientos e importes informados. En caso de querer renderizarlo a imagen deberá de hacer uso del código 128b, para ello se puede hacer uso de la gema [barby](http://toreto.re/barby/).
|
|
87
|
+
boleta.response # => numero de boleta
|
|
158
88
|
|
|
159
|
-
|
|
160
|
-
|
|
89
|
+
# Inhabilitar
|
|
90
|
+
CobroDigital::Boleta.inhabilitar(123).call(comercio_id, comercio_sid)
|
|
161
91
|
|
|
162
|
-
|
|
163
|
-
comercio_id
|
|
164
|
-
comercio_sid = 'wsZ0ya68K791phuu76gQ5L662J6F2Y4j7zqE2Jxa3Mvd22TWNn4iip6L9yq' #Brindado por cobrodigital para realizar pruebas
|
|
165
|
-
numero_boleta = 123
|
|
166
|
-
boleta = CobroDigital.Boleta.obtener_codigo_de_barras(numero_boleta)
|
|
167
|
-
boleta.call(comercio_id, comercio_sid)
|
|
168
|
-
boleta.response # Obtengo el resultado.
|
|
92
|
+
# Código de barras (uno por vencimiento/importe; render a imagen con la gema barby, código 128b)
|
|
93
|
+
CobroDigital::Boleta.obtener_codigo_de_barras(123).call(comercio_id, comercio_sid)
|
|
169
94
|
```
|
|
170
95
|
|
|
171
96
|
### Transacciones
|
|
172
97
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
Para poder realizar las consulta de las transacciones es necesario comunicar:
|
|
176
|
-
* fecha_desde: Comienzo desde donde se quiere obtener las transacciones.
|
|
177
|
-
* fecha_hasta: Fin desde donde se quiere obtener las transacciones.
|
|
178
|
-
* filtros: Los filtros nos permiten obtener transacciones mas especificas:
|
|
98
|
+
Movimientos de ingreso/egreso de la cuenta. Filtros disponibles (constantes de `CobroDigital::Transaccion`):
|
|
179
99
|
|
|
180
|
-
|
|
100
|
+
| constante | valor |
|
|
101
|
+
|---|---|
|
|
102
|
+
| `FILTRO_TIPO` | `tipo` |
|
|
103
|
+
| `FILTRO_NOMBRE` | `nombre` |
|
|
104
|
+
| `FILTRO_CONCEPTO` | `concepto` |
|
|
105
|
+
| `FILTRO_NRO_BOLETA` | `nro_boleta` |
|
|
106
|
+
| `FILTRO_IDENTIFICADOR` | `identificador` |
|
|
107
|
+
| `FILTRO_TIPO_EGRESO` | `egresos` (retiros del dinero depositado) |
|
|
108
|
+
| `FILTRO_TIPO_INGRESO` | `ingresos` (cobranzas) |
|
|
109
|
+
| `FILTRO_TIPO_TARJETA_CREDITO` | `tarjeta_credito` |
|
|
110
|
+
| `FILTRO_TIPO_DEBITO_AUTOMATICO` | `debito_automatico` (CBU) |
|
|
181
111
|
|
|
182
112
|
```ruby
|
|
183
|
-
CobroDigital
|
|
184
|
-
CobroDigital.
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
CobroDigital.Transaccion::FILTRO_IDENTIFICADOR => 'identificador'
|
|
188
|
-
|
|
189
|
-
CobroDigital.Transaccion::FILTRO_TIPO_EGRESO => 'egresos' # Transacciones de retiro del dinero depositado por los pagadores.
|
|
190
|
-
CobroDigital.Transaccion::FILTRO_TIPO_INGRESO => 'ingresos' # Todo lo que incremente el saldo de la cuenta CobroDigital. Generalmente son sólo las cobranzas.
|
|
191
|
-
CobroDigital.Transaccion::FILTRO_TIPO_TARJETA_CREDITO => 'tarjeta_credito' # Solo aquellas cobranzas abonadas con tarjeta de crédito.
|
|
192
|
-
CobroDigital.Transaccion::FILTRO_TIPO_DEBITO_AUTOMATICO => 'debito_automatico' # Está relacionado a los débitos realizados por CBU.
|
|
193
|
-
|
|
194
|
-
filtro = { CobroDigital.Transaccion::FILTRO_TIPO => CobroDigital.Transaccion::FILTRO_TIPO_INGRESO,
|
|
195
|
-
CobroDigital.Transaccion::FILTRO_NOMBRE => "Algun nombre",
|
|
196
|
-
CobroDigital.Transaccion::FILTRO_CONCEPTO => "Algun concepto"
|
|
197
|
-
CobroDigital.Transaccion::FILTRO_NRO_BOLETA => "Algun numero de boleta",
|
|
198
|
-
CobroDigital.Transaccion::FILTRO_IDENTIFICADOR => "Algun identificar" }
|
|
113
|
+
filtro = { CobroDigital::Transaccion::FILTRO_TIPO => CobroDigital::Transaccion::FILTRO_TIPO_INGRESO }
|
|
114
|
+
tx = CobroDigital::Transaccion.consultar(Date.today - 365, Date.today, filtro)
|
|
115
|
+
tx.call(comercio_id, comercio_sid)
|
|
116
|
+
tx.response
|
|
199
117
|
```
|
|
200
118
|
|
|
201
|
-
|
|
119
|
+
### Micrositios
|
|
202
120
|
|
|
203
121
|
```ruby
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
filtro = { CobroDigital.Transaccion::FILTRO_TIPO => CobroDigital.Transaccion::FILTRO_TIPO_INGRESO} # Solo consulta por transacciones de ingreso
|
|
208
|
-
transacciones = CobroDigital.Transaccion.consultar(Date.today - 1.year, Date.today)
|
|
209
|
-
transacciones.call(comercio_id, comercio_sid)
|
|
210
|
-
transacciones.response # Obtengo el resultado.
|
|
122
|
+
CobroDigital::Micrositio
|
|
123
|
+
.consultar_actividad('id', 1234, Date.today - 30, Date.today)
|
|
124
|
+
.call(comercio_id, comercio_sid)
|
|
211
125
|
```
|
|
212
126
|
|
|
213
|
-
|
|
214
|
-
La response proveniente del WS de CobroDigital siempre consiste en un JSON, donde los datos relevantes son:
|
|
215
|
-
* resultado: Si fue correcta la consulta realizada.
|
|
216
|
-
* log: En caso de no ser exitosa la consulta, mostrara los errores de la misma.
|
|
217
|
-
* datos: Resultado obtenido de la consulta (Es opcional, depende de la consulta)
|
|
127
|
+
### Respuesta y parser
|
|
218
128
|
|
|
219
|
-
El
|
|
220
|
-
|
|
221
|
-
A traves del metodo **parse_response** es posible obenter la respuesta parseada en formato hash. Este metodo debe llamarse luego de haberse ejecutado el _call_,
|
|
129
|
+
El WS responde un JSON. `#parse_response` (tras `#call`) lo decodifica:
|
|
222
130
|
|
|
223
131
|
```ruby
|
|
224
|
-
|
|
225
|
-
comercio_sid = 'wsZ0ya68K791phuu76gQ5L662J6F2Y4j7zqE2Jxa3Mvd22TWNn4iip6L9yq' #Brindado por cobrodigital para realizar pruebas
|
|
226
|
-
numero_boleta = 123
|
|
227
|
-
boleta = CobroDigital.Boleta.obtener_codigo_de_barras(numero_boleta)
|
|
132
|
+
boleta = CobroDigital::Boleta.obtener_codigo_de_barras(123)
|
|
228
133
|
boleta.call(comercio_id, comercio_sid)
|
|
229
134
|
boleta.parse_response
|
|
230
|
-
|
|
231
|
-
|
|
135
|
+
# => { resultado: true,
|
|
136
|
+
# log: ["Codigos de barra de la boleta encontrados correctamente."],
|
|
137
|
+
# datos: ["73852040502403101111600000002"] }
|
|
232
138
|
```
|
|
233
139
|
|
|
140
|
+
| clave | significado |
|
|
141
|
+
|---|---|
|
|
142
|
+
| `resultado` | `true` si la consulta fue correcta (`ejecucion_correcta == '1'`) |
|
|
143
|
+
| `log` | mensajes / errores del WS |
|
|
144
|
+
| `datos` | resultado de la consulta (opcional, según la operación) |
|
|
145
|
+
|
|
234
146
|
## SOAP vs HTTPS
|
|
235
147
|
|
|
236
|
-
|
|
148
|
+
El transporte default es SOAP (vía `savon`). El cliente HTTPS (`Net::HTTP`) es alternativo: `Cliente.new(con_client: CobroDigital::HTTPS)`. Detalle de ambos modos en [`docs/topology/topology.md`](docs/topology/topology.md).
|
|
237
149
|
|
|
238
|
-
##
|
|
150
|
+
## Desarrollo
|
|
239
151
|
|
|
240
|
-
|
|
152
|
+
```sh
|
|
153
|
+
bundle exec rspec # suite (ver docs/test/test.md)
|
|
154
|
+
bundle exec rake # task default :spec
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Contributing
|
|
241
158
|
|
|
159
|
+
Bug reports y pull requests en GitHub: <https://github.com/gedera/cobrodigital>.
|
|
242
160
|
|
|
243
161
|
## License
|
|
244
162
|
|
|
245
|
-
|
|
163
|
+
Open source bajo los términos de la [MIT License](http://opensource.org/licenses/MIT).
|
data/cobro_digital.gemspec
CHANGED
|
@@ -13,6 +13,12 @@ Gem::Specification.new do |spec|
|
|
|
13
13
|
spec.homepage = "https://github.com/gedera/cobrodigital"
|
|
14
14
|
spec.license = "MIT"
|
|
15
15
|
|
|
16
|
+
spec.metadata["documentation_uri"] = "https://github.com/gedera/cobrodigital/blob/v#{spec.version}/skill"
|
|
17
|
+
|
|
18
|
+
# savon ~> 2.12.1 (httpi 2.x) no corre en Ruby 3.0+. El único consumer
|
|
19
|
+
# (wispro_cloud) usa Ruby 2.7.6. Tope < 3.0 hasta actualizar el stack savon.
|
|
20
|
+
spec.required_ruby_version = ['>= 2.7', '< 3.0']
|
|
21
|
+
|
|
16
22
|
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
|
17
23
|
# delete this section to allow pushing this gem to any host.
|
|
18
24
|
# if spec.respond_to?(:metadata)
|
|
@@ -26,8 +32,8 @@ Gem::Specification.new do |spec|
|
|
|
26
32
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
27
33
|
spec.require_paths = ["lib"]
|
|
28
34
|
|
|
29
|
-
spec.add_development_dependency "bundler", "~> 2.6.6"
|
|
30
35
|
spec.add_development_dependency "rake", ">= 13.2.1"
|
|
36
|
+
spec.add_development_dependency "rspec", "~> 3.13"
|
|
31
37
|
|
|
32
38
|
spec.add_dependency 'savon', '~> 2.12.1'
|
|
33
39
|
end
|