> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zynvo.uy/llms.txt
> Use this file to discover all available pages before exploring further.

# Entorno Sandbox

> Prueba el API de Zynvo contra el entorno de prueba de DGI

## ¿Qué es el Sandbox?

El entorno sandbox de Zynvo te permite probar **endpoints específicos** del API comunicando con el entorno de prueba de DGI. Es ideal para:

* Desarrollo y pruebas de integraciones
* Experimentar con el API antes de ir a producción
* Capacitación de desarrolladores
* Validar flujos de trabajo

<Warning>
  **Importante**: No todos los endpoints soportan modo sandbox. Por defecto, todos los endpoints operan con datos reales de producción. Solo los endpoints explícitamente marcados en la documentación soportan `X-Sandbox-Mode: true`.
</Warning>

## URL del API

El API de Zynvo tiene una única URL:

```
https://api.zynvo.uy/v1
```

## Endpoints que soportan Sandbox

Por razones de seguridad y consistencia de datos, **solo algunos endpoints específicos soportan modo sandbox**. Si intentas usar `X-Sandbox-Mode: true` en un endpoint que no lo soporta, recibirás un error `400 Bad Request`.

Actualmente, los siguientes endpoints soportan `X-Sandbox-Mode: true`:

| Endpoint                  | Método |
| ------------------------- | ------ |
| `/tokens`                 | POST   |
| `/enterprises/{rut}/cfes` | POST   |

**Todos los demás endpoints operan exclusivamente con datos reales de producción** y rechazarán requests con `X-Sandbox-Mode: true`.

## Activar Modo Sandbox

El header `X-Sandbox-Mode` es **opcional** y solo debe incluirse en endpoints que soporten sandbox.

### Cómo funciona

| Header                               | Entorno                                                                                 |
| ------------------------------------ | --------------------------------------------------------------------------------------- |
| Sin header o `X-Sandbox-Mode: false` | Operaciones en **producción** (DGI entorno Producción)                                  |
| `X-Sandbox-Mode: true`               | Operaciones en **sandbox** (DGI entorno Prueba) - **Solo en endpoints que lo soporten** |

### Ejemplo Completo

<CodeGroup>
  ```bash cURL theme={null}
  # 1. Obtener token (sin X-Sandbox-Mode)
  curl -X POST https://api.zynvo.uy/v1/tokens \
    -H "X-API-Key: zynvo_live_tu_api_key"

  # 2. Emitir CFE en sandbox (CON X-Sandbox-Mode: true)
  curl -X POST https://api.zynvo.uy/v1/enterprises/210000000018/cfes \
    -H "X-API-Key: zynvo_live_tu_api_key" \
    -H "Authorization: Bearer tu_jwt_token" \
    -H "X-Sandbox-Mode: true" \
    -H "Content-Type: application/json" \
    -d '{
      "cfe_type_code": 101,
      "emission_date": "2024-03-15T14:30:00",
      "receiver": {...},
      "items": [...],
      "payment_methods": [...]
    }'

  # 3. Emitir CFE en producción (SIN X-Sandbox-Mode)
  curl -X POST https://api.zynvo.uy/v1/enterprises/210000000018/cfes \
    -H "X-API-Key: zynvo_live_tu_api_key" \
    -H "Authorization: Bearer tu_jwt_token" \
    -H "Content-Type: application/json" \
    -d '{
      "cfe_type_code": 101,
      "emission_date": "2024-03-15T14:30:00",
      "receiver": {...},
      "items": [...],
      "payment_methods": [...]
    }'
  ```

  ```javascript JavaScript/TypeScript theme={null}
  // 1. Obtener token
  const tokenResponse = await fetch('https://api.zynvo.uy/v1/tokens', {
    method: 'POST',
    headers: {
      'X-API-Key': 'zynvo_live_tu_api_key'
    }
  });
  const { data: { access_token } } = await tokenResponse.json();

  // 2. Emitir CFE en sandbox
  const responseSandbox = await fetch(
    'https://api.zynvo.uy/v1/enterprises/210000000018/cfes',
    {
      method: 'POST',
      headers: {
        'X-API-Key': 'zynvo_live_tu_api_key',
        'Authorization': `Bearer ${access_token}`,
        'X-Sandbox-Mode': 'true',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        cfe_type_code: 101,
        emission_date: new Date().toISOString(),
        // ... resto de campos CFE
      })
    }
  );

  // 3. Emitir CFE en producción
  const responseProd = await fetch(
    'https://api.zynvo.uy/v1/enterprises/210000000018/cfes',
    {
      method: 'POST',
      headers: {
        'X-API-Key': 'zynvo_live_tu_api_key',
        'Authorization': `Bearer ${access_token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        cfe_type_code: 101,
        emission_date: new Date().toISOString(),
        // ... resto de campos CFE
      })
    }
  );
  ```

  ```python Python theme={null}
  import requests

  # 1. Obtener token
  token_response = requests.post(
      'https://api.zynvo.uy/v1/tokens',
      headers={'X-API-Key': 'zynvo_live_tu_api_key'}
  )
  access_token = token_response.json()['data']['access_token']

  # 2. Emitir CFE en sandbox
  response_sandbox = requests.post(
      'https://api.zynvo.uy/v1/enterprises/210000000018/cfes',
      headers={
          'X-API-Key': 'zynvo_live_tu_api_key',
          'Authorization': f'Bearer {access_token}',
          'X-Sandbox-Mode': 'true',
          'Content-Type': 'application/json'
      },
      json={
          'cfe_type_code': 101,
          'emission_date': '2024-03-15T14:30:00',
          # ... resto de campos CFE
      }
  )

  # 3. Emitir CFE en producción
  response_prod = requests.post(
      'https://api.zynvo.uy/v1/enterprises/210000000018/cfes',
      headers={
          'X-API-Key': 'zynvo_live_tu_api_key',
          'Authorization': f'Bearer {access_token}',
          'Content-Type': 'application/json'
      },
      json={
          'cfe_type_code': 101,
          'emission_date': '2024-03-15T14:30:00',
          # ... resto de campos CFE
      }
  )
  ```
</CodeGroup>

## Cambiar entre Entornos

Usa siempre la misma URL (`https://api.zynvo.uy/v1`) y controla el ambiente con el valor del header:

| Modo           | Header                  | Comportamiento         |
| -------------- | ----------------------- | ---------------------- |
| **Producción** | `X-Sandbox-Mode: false` | DGI entorno Producción |
| **Sandbox**    | `X-Sandbox-Mode: true`  | DGI entorno Prueba     |

## Diferencias con Producción

### En Sandbox

* Todos los endpoints disponibles
* Los CFEs se envían a DGI entorno Prueba
* Usa datos reales de tu cuenta
* Sin límites de volumen

### Limitaciones

* Los CFEs no son válidos fiscalmente
* No se comunica con DGI entorno Producción

## Rate Limits

| Límite           | Producción | Sandbox |
| ---------------- | ---------- | ------- |
| Solicitudes/hora | 1,000      | 5,000   |

## Mejores Prácticas

<AccordionGroup>
  <Accordion title="Probar escenarios de error">
    El sandbox es el lugar perfecto para probar manejo de errores y casos límite.
  </Accordion>

  <Accordion title="Validar antes de producción">
    Prueba todo el flujo completo en sandbox antes de mover a producción.
  </Accordion>
</AccordionGroup>

## Migrar a Producción

Para pasar de sandbox a producción:

<Steps>
  <Step title="Cambia el header X-Sandbox-Mode">
    Modifica el valor del header de `X-Sandbox-Mode: true` a `X-Sandbox-Mode: false`.
  </Step>

  <Step title="Configura certificados reales">
    Carga los certificados digitales y CAEs reales de la empresa.
  </Step>

  <Step title="Prueba gradualmente">
    Comienza con volúmenes bajos y monitorea los resultados.
  </Step>
</Steps>

## Soporte

¿Problemas con el sandbox? Contáctanos en [soporte@zynvo.uy](mailto:soporte@zynvo.uy)
