{
  "info": {
    "name": "Conta360 API v1",
    "description": "API de Conta360 para integraciones externas (POS, tiendas en línea, ERP). Antes de usarla: crea la integración en Conta360 (Configuración → Integraciones), copia el client_id y el client_secret y ponlos en las variables de esta colección. Luego ejecuta «Token de acceso»: el token queda guardado en la variable access_token y lo usan las demás peticiones. Para probar sin una empresa real, pide a soporte una credencial c360_test_ del Restaurante Demo Conta360 SAS (ambiente de pruebas de la DIAN, sin validez fiscal): los ejemplos usan su catálogo P-0001 a P-0009 y la misma base_url.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "variable": [
    {
      "key": "base_url",
      "value": "https://app.conta360.co/api/v1",
      "description": "URL de la API"
    },
    {
      "key": "client_id",
      "value": "",
      "description": "client_id de la integración (c360_live_ en producción, c360_test_ en pruebas)"
    },
    {
      "key": "client_secret",
      "value": "",
      "description": "client_secret (solo se muestra al crear la integración)"
    },
    {
      "key": "access_token",
      "value": "",
      "description": "Lo llena «Token de acceso»"
    },
    {
      "key": "documento_id",
      "value": "",
      "description": "Lo llena «Emitir factura»"
    }
  ],
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{access_token}}",
        "type": "string"
      }
    ]
  },
  "item": [
    {
      "name": "Autenticación",
      "item": [
        {
          "name": "Token de acceso",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const res = pm.response.json();",
                  "pm.test('Token recibido', () => pm.expect(res.access_token).to.be.a('string'));",
                  "pm.collectionVariables.set('access_token', res.access_token);",
                  "console.log('Alcances del token:', res.scope);"
                ]
              }
            }
          ],
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/oauth/token",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "oauth",
                "token"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"grant_type\": \"client_credentials\",\n  \"client_id\": \"{{client_id}}\",\n  \"client_secret\": \"{{client_secret}}\"\n}"
            },
            "description": "Devuelve un token válido una hora. Reutilízalo: no pidas uno en cada petición."
          }
        },
        {
          "name": "Mi integración",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{base_url}}/me",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "me"
              ]
            },
            "description": "Comprueba la conexión: dice con qué empresa y alcances estás trabajando."
          }
        }
      ]
    },
    {
      "name": "Catálogo",
      "item": [
        {
          "name": "Catálogos DIAN",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{base_url}}/catalogos",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "catalogos"
              ]
            },
            "description": "Tipos de identificación, formas y métodos de pago, unidades, impuestos y municipios. Guárdalos en tu sistema."
          }
        },
        {
          "name": "Productos",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{base_url}}/productos?per_page=25",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "productos"
              ],
              "query": [
                {
                  "key": "q",
                  "value": "",
                  "disabled": true,
                  "description": "Busca por nombre o código"
                },
                {
                  "key": "activo",
                  "value": "todos",
                  "disabled": true
                },
                {
                  "key": "page",
                  "value": "1",
                  "disabled": true
                },
                {
                  "key": "per_page",
                  "value": "25"
                }
              ]
            },
            "description": "Catálogo con precios e impuestos. Es la fuente de verdad: no guardes precios propios en el POS."
          }
        },
        {
          "name": "Un producto",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{base_url}}/productos/P-0001",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "productos",
                "P-0001"
              ]
            },
            "description": "Por id de Conta360 o por código del catálogo."
          }
        },
        {
          "name": "Inventario por conteo",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{base_url}}/inventario",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "inventario"
              ]
            },
            "description": "Informativo: Conta360 no bloquea la venta por existencias."
          }
        }
      ]
    },
    {
      "name": "Clientes",
      "item": [
        {
          "name": "Buscar clientes",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{base_url}}/clientes?identificacion=1098765432",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "clientes"
              ],
              "query": [
                {
                  "key": "identificacion",
                  "value": "1098765432"
                },
                {
                  "key": "q",
                  "value": "",
                  "disabled": true
                }
              ]
            }
          }
        },
        {
          "name": "Crear cliente",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{base_url}}/clientes",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "clientes"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"tipo_documento\": \"13\",\n  \"identificacion\": \"1098765432\",\n  \"tipo_persona\": \"2\",\n  \"nombres\": \"Ana Gómez\",\n  \"correo\": \"ana@correo.com\",\n  \"telefono\": \"3001234567\",\n  \"direccion\": \"Calle 1 # 2-3\",\n  \"municipio\": \"05001\"\n}"
            },
            "description": "Si la identificación ya existe en la empresa, devuelve el cliente existente."
          }
        }
      ]
    },
    {
      "name": "Facturación",
      "item": [
        {
          "name": "Emitir factura",
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "// Una Idempotency-Key por pedido. En tu sistema, usa el número de pedido, no un valor aleatorio.",
                  "pm.collectionVariables.set('idempotency_key', 'pedido-' + Date.now());"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const res = pm.response.json();",
                  "if (res.data && res.data.id) pm.collectionVariables.set('documento_id', res.data.id);",
                  "pm.test('Documento registrado', () => pm.expect([201, 422]).to.include(pm.response.code));",
                  "if (pm.response.code === 422) console.log('La DIAN no la aceptó; consulta el estado antes de reintentar.');"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotency_key}}",
                "description": "Una clave por pedido: evita emitir dos veces"
              }
            ],
            "url": {
              "raw": "{{base_url}}/facturas",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "facturas"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"pedido\": \"Mesa 7 · 184\",\n  \"cliente\": {\n    \"tipo_documento\": \"13\",\n    \"identificacion\": \"1098765432\",\n    \"tipo_persona\": \"2\",\n    \"nombres\": \"Ana Gómez\",\n    \"correo\": \"ana@correo.com\"\n  },\n  \"items\": [\n    { \"codigo\": \"P-0001\", \"cantidad\": 2 },\n    { \"codigo\": \"P-0002\", \"cantidad\": 1, \"nota\": \"sin cebolla\" }\n  ],\n  \"pagos\": [{ \"forma\": \"1\", \"metodo\": \"49\" }],\n  \"borrador\": false\n}"
            },
            "description": "Emite la factura ante la DIAN. Si omites «pagos», se asume contado en efectivo por el total. Con «borrador»: true se guarda sin enviarla (útil para probar)."
          }
        },
        {
          "name": "Registrar venta sin factura",
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.collectionVariables.set('idempotency_key', 'venta-' + Date.now());"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotency_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/facturas",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "facturas"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"pedido\": \"Mesa 3 · 200\",\n  \"electronica\": false,\n  \"items\": [\n    { \"codigo\": \"P-0001\", \"cantidad\": 1 },\n    { \"codigo\": \"P-0002\", \"cantidad\": 2 }\n  ],\n  \"pagos\": [{ \"forma\": \"1\", \"metodo\": \"10\" }]\n}"
            },
            "description": "Venta en la que el cajero quitó «Facturar»: queda en Conta360 como documento interno (CC-…), se contabiliza y descuenta inventario, pero no va a la DIAN ni consume cupo. Sin cliente, sale a nombre de consumidor final."
          }
        },
        {
          "name": "Estado de un documento",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{base_url}}/facturas/{{documento_id}}",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "facturas",
                "{{documento_id}}"
              ]
            },
            "description": "Acepta el id, el número DIAN o el código de referencia. Haz esta consulta cuando no recibas respuesta al emitir: nunca reemitas sin consultar."
          }
        },
        {
          "name": "Documentos emitidos",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{base_url}}/facturas?tipo=factura&per_page=25",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "facturas"
              ],
              "query": [
                {
                  "key": "tipo",
                  "value": "factura"
                },
                {
                  "key": "estado",
                  "value": "validated",
                  "disabled": true
                },
                {
                  "key": "desde",
                  "value": "2026-10-01",
                  "disabled": true
                },
                {
                  "key": "hasta",
                  "value": "2026-10-31",
                  "disabled": true
                },
                {
                  "key": "per_page",
                  "value": "25"
                }
              ]
            }
          }
        },
        {
          "name": "PDF del documento",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{base_url}}/facturas/{{documento_id}}/pdf",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "facturas",
                "{{documento_id}}",
                "pdf"
              ]
            },
            "description": "También /xml. Sirve para imprimir o adjuntar el documento desde tu sistema."
          }
        },
        {
          "name": "Anular con nota crédito",
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.collectionVariables.set('idempotency_key', 'anula-' + Date.now());"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "Idempotency-Key",
                "value": "{{idempotency_key}}"
              }
            ],
            "url": {
              "raw": "{{base_url}}/notas-credito",
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "notas-credito"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"factura\": \"SETP990000001\",\n  \"concepto\": \"2\",\n  \"cliente\": {\n    \"tipo_documento\": \"13\",\n    \"identificacion\": \"1098765432\",\n    \"nombres\": \"Ana Gómez\"\n  },\n  \"items\": [\n    { \"codigo\": \"P-0001\", \"cantidad\": 2 },\n    { \"codigo\": \"P-0002\", \"cantidad\": 1 }\n  ]\n}"
            },
            "description": "Una factura validada por la DIAN no se borra: se anula con una nota crédito (concepto 2 = anulación)."
          }
        }
      ]
    },
    {
      "name": "Cupo del mes",
      "request": {
        "method": "GET",
        "url": {
          "raw": "{{base_url}}/cupo",
          "host": [
            "{{base_url}}"
          ],
          "path": [
            "cupo"
          ]
        },
        "description": "Consúltalo al abrir caja: al agotarse el cupo prepago, Conta360 no envía más facturas a la DIAN ese mes."
      }
    }
  ]
}
