Saltar al contenido

Entornos de Prueba (Sandbox)

Aísla tu desarrollo, experimenta sin miedo y limpia tus datos con un solo clic.

¿Por qué usar Entornos de Prueba?

Al integrar APIs financieras, es crítico probar la lógica de tu aplicación sin generar transacciones reales o enviar correos a clientes verdaderos. Cord resuelve esto otorgándote un Entorno de Prueba (Sandbox) completamente aislado.

Los datos creados en el modo de prueba (cotizaciones, clientes, webhooks) jamás interactúan con tus datos en vivo.

Identificando el Modo de Prueba

  1. En el Dashboard: Cuando el Modo de Prueba está activo, verás un indicador visual naranja en la interfaz. Todas las acciones manuales que realices ocurrirán dentro del entorno aislado.
  2. En la API: Las claves de API secretas determinan automáticamente a qué entorno estás llamando. Una clave de prueba interactuará con el Sandbox, mientras que una clave en vivo tocará tus datos reales.

Importante: Jamás uses claves reales en tus flujos de pruebas unitarias o de integración.

Reinicio Rápido (Reset Sandbox)

Durante el desarrollo de una integración generarás muchos registros de prueba. Puedes devolver el entorno a un estado limpio cuando quieras, desde la app o por API.

Vaciar datos del entorno de prueba

En la app, con el modo de prueba encendido, usa Vaciar datos de prueba en la franja naranja. Desde tu código o tu CI, con una llave de prueba (sk_test_, o una restringida rk_test_ con escritura en test_helpers):

curl -X POST https://cordhq.app/api/v1/test_helpers/reset \
  -H "Authorization: Bearer sk_test_..."
{ "data": { "object": "sandbox_reset", "llaves": 2, "endpoints": 1 } }

Borra las cotizaciones, facturas, clientes, productos, eventos y todo lo demás del entorno de prueba, y conserva sus llaves y sus endpoints de webhook, también las sesiones abiertas de cord listen: tu suite sigue autenticando después del reinicio. Por API el entorno queda vacío; desde la app arranca con los datos de ejemplo. Lo que se borró no vuelve, y sus ids dejan de existir. También está en los SDK (cord.testHelpers.reset() en Node, cord.test_helpers.reset() en Python y $cord->testHelpers->reset() en PHP) y en el CLI (cord sandbox reset --yes).

Solo existe en el entorno de prueba: con una llave en vivo responde 403 con code: "test_mode_only", y la base de datos rechaza reiniciar una organización real aunque se lo pidan. Admite hasta 6 reinicios por minuto por entorno.

Simuladores (test helpers)

Con una llave sk_test_ puedes provocar lo que en producción hace un tercero: el SAT respondiendo, el tiempo pasando o el cliente abriendo el link. Cada simulador recorre el mismo código que producción, así que los webhooks, el historial y los correos salen igual que en vivo. Con una llave en vivo responden test_mode_only, y la base de datos rechaza cualquier simulación sobre una organización real.

Forzar el resultado del próximo timbrado

curl -X POST https://cordhq.app/api/v1/test_helpers/fiscal \
  -H "Authorization: Bearer sk_test_..." -H "Content-Type: application/json" \
  -d '{ "siguiente_resultado": "pac_caido" }'

Resultados: exito, pac_caido (la factura queda en borrador y se puede reintentar), receptor_invalido, certificado_vencido y timbre_duplicado. Se consume en la siguiente emisión; sin uno pendiente, la emisión simulada tiene éxito.

La emisión forzada responde como la real: pac_caido con 502 y code: "provider_error", los demás con 422 y code: "fiscal_rejected". Todas traen Cord-Should-Retry: false, para que tu SDK te muestre la falla en vez de reintentarla.

Simular al cliente y al tiempo

curl -X POST https://cordhq.app/api/v1/test_helpers/cotizaciones/8b0c6f0e-2d55-4c1e-9a43-6a2f1c7d9e10 \
  -H "Authorization: Bearer sk_test_..." -H "Content-Type: application/json" \
  -d '{ "accion": "vista" }'

vista registra la apertura del cliente (quote.viewed) y vencer la vence (quote.expired). Aprobar, rechazar y marcar pagada ya están en POST /api/v1/cotizaciones/{id}.

Disparar un webhook

curl -X POST https://cordhq.app/api/v1/test_helpers/webhooks \
  -H "Authorization: Bearer sk_test_..." -H "Content-Type: application/json" \
  -d '{ "evento": "quote.approved", "objeto_id": "8b0c6f0e-2d55-4c1e-9a43-6a2f1c7d9e10" }'

Acepta cualquiera de los eventos del catálogo. Con objeto_id de una cotización o factura de prueba usa sus datos reales; sin él, datos de ejemplo con ids test_…. El objeto_id debe ser del tipo del evento: una cotización para quote.*, payment.*, invoice.stamped e invoice.issued, y una factura para los demás invoice.*. Los eventos de clientes, productos, tareas, promesas, contracargos, reembolsos, depósitos y cuenta no aceptan objeto_id (responde 400) y van con datos de ejemplo. Un objeto_id que no existe en tu entorno de prueba responde 404. La entrega pasa por el outbox real: firma, reintentos e historial en las entregas del endpoint, en la pestaña Webhooks del Cord Workbench, y llega también a tus sesiones de cord listen. La respuesta dice a cuántos endpoints (endpoints) y sesiones (sesiones) llegó. Con o sin objeto_id, es una prueba: no queda en el historial de eventos ni dispara tus Workflows o integraciones.

Pruebas de integración en CI

Con el reinicio, los simuladores y una llave de prueba, tu suite puede correr contra Cord en cada pull request:

  1. Guarda una llave de prueba como secreto del CI. Una restringida rk_test_ con escritura en cotizaciones, clientes, productos y test_helpers alcanza para la mayoría de las suites.
  2. Reinicia el entorno antes de la suite: cada corrida empieza vacía.
  3. Crea lo que necesites por API y avanza el ciclo con los simuladores: abrir o vencer una cotización, forzar el resultado del timbrado y disparar webhooks.
  4. Corre una suite a la vez por entorno de prueba: dos corridas con el mismo entorno se borran los datos entre sí. En GitHub Actions, concurrency las pone en fila.
name: Cord
on: [pull_request]
jobs:
  integracion:
    runs-on: ubuntu-latest
    concurrency: cord-sandbox
    env:
      CORD_SECRET_KEY: ${{ secrets.CORD_TEST_KEY }}
    steps:
      - uses: actions/checkout@v4
      - run: |
          curl -fsS -X POST https://cordhq.app/api/v1/test_helpers/reset \
            -H "Authorization: Bearer $CORD_SECRET_KEY"
      - run: npm ci && npm test