Skip to content

Test Environments (Sandbox)

Isolate your development, experiment fearlessly, and clear your data with a single click.

Why use Test Environments?

When integrating financial APIs, it is critical to test your application’s logic without generating real transactions or sending emails to real customers. Cord solves this by providing you with a completely isolated Test Environment (Sandbox).

Data created in test mode (quotes, clients, webhooks) never interacts with your live data.

Identifying Test Mode

  1. In the Dashboard: When Test Mode is active, you will see a visual orange indicator in the interface. All manual actions you perform will occur within the isolated environment.
  2. In the API: Your secret API keys automatically determine which environment you are calling. A test key will interact with the Sandbox, while a live key will touch your real data.

Important: Never use real keys in your unit or integration test suites.

Quick Reset (Sandbox Reset)

During integration development, you will often generate thousands of garbage records. Cord has a radical tool to return your environment to a clean slate: the Reset Endpoint.

Clearing test environment data

You can invoke a destructive cleanup (which will cascade delete clients, quotes, products, and events from the test environment) by making a POST to the following internal endpoint (requires an active browser session in Test Mode):

POST /api/test-mode/reset

Warning: This endpoint contains strict database protections (sandbox_of is not null). Even if you call it by mistake in your live environment, the database will abort the transaction to protect your real data. It only works within Sandbox environments.

Simulators (test helpers)

With an sk_test_ key you can trigger what a third party does in production: the SAT responding, time passing, or the client opening the link. Each simulator runs the same code as production, so webhooks, history and emails come out exactly as they would live. With a live key they respond test_mode_only, and the database rejects any simulation on a real organization.

Force the next stamping result

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" }'

Results: exito, pac_caido (the invoice stays as a draft and can be retried), receptor_invalido, certificado_vencido and timbre_duplicado. It is consumed by the next issuance; with none pending, the simulated issuance succeeds.

Simulate the client and time

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 records the client opening the quote (quote.viewed) and vencer expires it (quote.expired). Approve, reject and mark as paid are already in POST /api/v1/cotizaciones/{id}.

Trigger a 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" }'

Accepts any event in the catalog. With the objeto_id of a test quote or invoice it uses its real data; without it, sample data with test_… ids. The objeto_id must match the event type: a quote for quote.*, payment.*, invoice.stamped and invoice.issued, and an invoice for the other invoice.* events. Client, product, task, promise, dispute, refund, payout and account events always use sample data. Delivery goes through the real outbox: signature, retries and history in the endpoint’s deliveries, in the Webhooks tab of the Cord Workbench. With objeto_id the event also lands in the event history and the Events tab; with sample data it doesn’t, because it isn’t an event of your business.