# API Cloud — Cuenta maestra

Resumen de endpoints

| Método | Endpoint | Propósito |
|---|---|---|
| `POST` | [/clientes/](#crear-una-organizacion-nic) | Crear una organización/NIC. |
| `POST` | [/cuentas/](#crear-una-cuenta-de-servicios) | Crear una cuenta de servicios. |
| `POST` | [/cuentas/factudesk/confirmar/{rfc}](#confirmar-un-rfc) | Confirmar/validar un RFC. |
| `POST` | [/cuentas/create_status.dkl](#verificar-estado-de-creacion-de-cuenta-de-servicio) | Consultar el estado de una tarea de creación de cuenta. |

## Crear una organización (NIC)

Crea una nueva organización/cliente y la relaciona con una cuenta maestra distribuidora. Durante el proceso se crean los registros correspondientes en las bases de datos de Epifania, Induxsoft y del distribuidor, se vincula al usuario administrador y, opcionalmente, a otros usuarios.

La operación también permite crear una cuenta de timbrado asociada a la nueva organización.

**Endpoint**

```http
POST https://cm.api.induxsoft.net/clientes/
```

**Autorización**

```http
Authorization: bearer {idsesion}
Content-Type: application/json
```

### Carga útil

| Campo | Tipo | Requerido | Valor predeterminado | Descripción |
|---|---|---:|---|---|
| `nombre` | string | Sí | — | Nombre legal de la organización. |
| `nombre_comercial` | string | No | `nombre` | Nombre comercial. Si se omite o se envía vacío, se utiliza `nombre`. |
| `rfc` | string | Sí | — | RFC de la organización. Debe ser único. |
| `telefono` | string | No | — | Teléfono de la organización. |
| `web` | string | No | — | Sitio web. |
| `fax` | string | No | — | Fax. |
| `curp` | string | No | — | CURP asociada, cuando corresponda. |
| `giro` | string | No | — | Giro de la organización. |
| `comentarios` | string | No | — | Notas o comentarios. |
| `pais` | string | Sí | — | Código del país. |
| `domicilio` | object | Sí | — | Información del domicilio. |
| `distribuidor` | string | Sí | — | `sys_guid` de la cuenta maestra que actuará como distribuidor. Debe existir y no estar vencida. |
| `admin` | string | No | Usuario autenticado | Identificador del usuario administrador. Puede ser `sys_guid`, correo o móvil. |
| `usuarios` | array[string] | No | — | Usuarios que se vincularán a la organización. Cada elemento puede ser `sys_guid`, correo o móvil. |
| `contactos` | object | No | — | Contactos técnico, financiero y legal. |
| `ctd` | object | No | — | Datos para crear una cuenta de timbrado. |

#### `domicilio`

| Campo | Tipo | Requerido | Valor predeterminado | Descripción |
|---|---|---:|---|---|
| `edoprov` | string | Sí | — | Código del estado o provincia. |
| `ciudad` | string | Sí | — | Código de la ciudad. |
| `calle` | string | Sí | — | Calle. |
| `num_ext` | string | Sí | — | Número exterior. |
| `num_int` | string | No | — | Número interior. |
| `colonia` | string | Sí | — | Colonia. |
| `cp` | string | Sí | — | Código postal. |
| `localidad` | string | No | — | Localidad. Actualmente se recibe en la documentación, pero no es utilizada por `cm.create_organization`. |
| `referencia` | string | No | — | Referencia del domicilio. Actualmente se recibe en la documentación, pero no es utilizada por `cm.create_organization`. |

La combinación `ciudad` + `edoprov` + `pais` debe corresponder a una ciudad válida registrada.

**Consultar `pais`**:

```http
GET https://cm.api.induxsoft.net/consultas/pais/
Content-Type: application/json
```

**Consultar `edoprov`**:

```http
GET https://cm.api.induxsoft.net/consultas/edoprov/?ipais={ID_DEL_PAIS}
Content-Type: application/json
```

**Consultar `ciudad`**:

```http
GET https://cm.api.induxsoft.net/consultas/ciudad/?iestado={ID_DEL_ESTADO}
Content-Type: application/json
```

#### `contactos`

El objeto `contactos` es opcional. Cada contacto también es opcional.

Los tipos disponibles son:

- `tecnico`
- `financiero`
- `legal`

Cada contacto acepta:

| Campo | Tipo | Requerido | Valor predeterminado | Descripción |
|---|---|---:|---|---|
| `nombre` | string | No | — | Nombre del contacto. |
| `puesto` | string | No | — | Puesto del contacto. |
| `correo` | string | No | — | Correo electrónico. |
| `telefono` | string | No | — | Teléfono. |
| `telefono_alterno` | string | No | — | Teléfono alterno. |

#### `ctd`

Si se proporciona `ctd`, ambos campos siguientes son obligatorios:

| Campo | Tipo | Requerido | Valor predeterminado | Descripción |
|---|---|---:|---|---|
| `id` | string | Sí, si existe `ctd` | — | Identificador de la cuenta de timbrado. |
| `pwd` | string | Sí, si existe `ctd` | — | Contraseña de la cuenta de timbrado. |

Al crear la cuenta de timbrado, la contraseña se almacena mediante MD5 y se inicializan los valores internos de la cuenta según la configuración del servicio.

### Validaciones relevantes

La implementación verifica, entre otras, las siguientes condiciones:

- `nombre`, `rfc`, `pais` y `distribuidor` son obligatorios.
- `domicilio` es obligatorio.
- `domicilio.edoprov`, `ciudad`, `calle`, `num_ext`, `colonia` y `cp` son obligatorios.
- El RFC no debe existir previamente.
- La ciudad, estado/provincia y país deben formar una combinación válida.
- El distribuidor debe corresponder a una cuenta maestra existente y vigente.
- El usuario administrador indicado debe tener un perfil de Induxsoft.
- Existe un límite de organizaciones creadas por perfil durante una hora.
- Los usuarios de `usuarios` que no tengan perfil de Induxsoft no provocan necesariamente el aborto de la operación; se registran en `log`.

### Ejemplo de solicitud

```http
POST https://cm.api.induxsoft.net/clientes/
Authorization: bearer 9A7B...
Content-Type: application/json
```

```json
{
  "nombre": "Empresa Ejemplo S.A. de C.V.",
  "nombre_comercial": "Empresa Ejemplo",
  "rfc": "XAXX010101000",
  "telefono": "4421234567",
  "web": "https://www.ejemplo.com",
  "fax": "",
  "curp": "",
  "giro": "Comercio",
  "comentarios": "",
  "pais": "MEX",
  "domicilio": {
    "edoprov": "QUE",
    "ciudad": "001",
    "calle": "Av. Ejemplo",
    "num_ext": "100",
    "num_int": "",
    "colonia": "Centro",
    "cp": "76000",
    "localidad": "",
    "referencia": ""
  },
  "distribuidor": "715F97F2FD1B11E5B860C4E98402F4B8",
  "usuarios": [
    "correo@correo.com",
    "5556890554"
  ],
  "contactos": {
    "tecnico": {
      "nombre": "Juan Pérez",
      "puesto": "Soporte",
      "correo": "juan@ejemplo.com",
      "telefono": "4421234567",
      "telefono_alterno": ""
    },
    "financiero": {
      "nombre": "Ana López",
      "puesto": "Administración",
      "correo": "ana@ejemplo.com",
      "telefono": "4427654321",
      "telefono_alterno": ""
    },
    "legal": {
      "nombre": "Pedro García",
      "puesto": "Representante legal",
      "correo": "pedro@ejemplo.com",
      "telefono": "4421112233",
      "telefono_alterno": ""
    }
  }
}
```

#### Respuesta exitosa

Devuelve el NIC generado y un registro con los usuarios que no pudieron vincularse.

```http
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
```

```json
{
  "success": true,
  "data": {
    "nic": "123456",
    "log": []
  }
}
```

`log` contiene mensajes para los usuarios proporcionados en `usuarios` que no tengan un perfil de Induxsoft.

#### Respuesta fallida

```json
{
  "success": false,
  "message": "detalle del error..."
}
```

---

## Crear una cuenta de servicios

<span class="badge bg-warning">No Implementado - Pendiente...</span>

```
POST
cm.api.induxsoft.net/cuentas/
Authorization: bearer idsesion

{
	"tipo":"cuenta_maestra, plazamundial, serie, factudesk",
	"nic":"Requerido unicamente cuando la BD sea cuenta_maestra, serie o factudesk",
	"usuarios":["correo@correo.com","5556890554","AF454755D5E45A5441111A552",...],
	"crear_workspace": true/false (opcional para crear un Workspace únicamente cuando la BD es cuenta_maestra, serie o plazamundial),
	"crear_tienda": true/false (opcional para crear una tienda vinculada únicamente cuando la BD es cuenta_maestra, serie o plazamundial),
	"usar": {"tipo":"cuenta_maestra/serie-e", "id":"id"} (Opcional para indicar que se use una BD existente de cuenta_maestra o serie únicamente cuando la BD es plazamundial)
}
```

---

## Confirmar un RFC

Confirma/valida un RFC para un cliente y, opcionalmente, procesa los datos de un certificado de sello digital.

El endpoint recibe el RFC como parámetro de ruta. Antes de validar el RFC se comprueba que el perfil autenticado tenga autorización para realizar la operación sobre el NIC proporcionado.

**Endpoint**

```http
POST https://cm.api.induxsoft.net/cuentas/factudesk/confirmar/{rfc}
```

**Autorización**

```http
Authorization: bearer {idsesion}
Content-Type: application/json
```

### Parámetros de ruta

| Parámetro | Tipo | Requerido | Descripción |
|---|---|---:|---|
| `rfc` | string | Sí | RFC que se desea validar/confirmar. |

### Carga útil

| Campo | Tipo | Requerido | Valor predeterminado | Descripción |
|---|---|---:|---|---|
| `nic` | string | Sí | — | Identificador del cliente sobre el cual se realiza la validación. |
| `regimen_fiscal` | string | Sí | — | Código del régimen fiscal. |
| `certificado` | object | No | — | Certificado CSD. Si se proporciona, sus tres campos son obligatorios. |
| `certificado.cer` | string | Sí, si existe `certificado` | — | Base64 del arreglo de bytes del archivo `.cer`. |
| `certificado.key` | string | Sí, si existe `certificado` | — | Base64 del arreglo de bytes del archivo `.key`. |
| `certificado.kpw` | string | Sí, si existe `certificado` | — | Contraseña de la clave privada. |

### Validaciones relevantes

1. Que exista `rfc`.
2. Que exista `nic`.
3. Que el perfil autenticado esté autorizado para realizar la verificación del RFC sobre ese NIC.
4. Que el RFC sea válido.
5. Si se proporciona `certificado`, que existan `cer`, `key` y `kpw`.

### Ejemplo de solicitud

```http
POST https://cm.api.induxsoft.net/cuentas/factudesk/confirmar/XAXX010101000
Authorization: bearer 9A7B...
Content-Type: application/json
```

```json
{
  "nic": "123456",
  "regimen_fiscal": "601",
  "certificado": {
    "cer": "BASE64_DEL_ARCHIVO_CER",
    "key": "BASE64_DEL_ARCHIVO_KEY",
    "kpw": "contraseña"
  }
}
```

#### Respuesta exitosa

```http
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
```

```json
{
  "success": true,
  "data": null
}
```

#### Respuesta fallida

```json
{
  "success": false,
  "message": "detalle del error..."
}
```

---

## Verificar estado de creación de cuenta de servicio

<span class="badge bg-warning">No Implementado - Pendiente...</span>

```
POST
cm.api.induxsoft.net/cuentas/create_status.dkl
{
	"token":"Identificador de la tarea",
}
```

Response
```
Content-Type: application/json;charset=utf-8
{
    "created":"Marca de tiempo de creación",
    "updated":"Marca de tiempo de última actualización",
    "start":"Marca de tiempo de inicio",
    "end":"Marca de tiempo de finalización",
    "program":"Programa que agregó el trabajo",
    "lifetime":Entero con la cantidad de segundos de vida,
    "timeout":Entero con la cantidad de segundos de vigencia,
    "progress":Entero  o decimal con el progreso actual,
    "progress_type":Entero que indica la forma de indicar el progreso,
    "steps": (Cantidad de iteraciones si progress_type=2),
    "status":Entero que indica el estado actual del trabajo,
    "note":"Último mensaje de la bitácora"
    "sender":"Id de quien hizo la úlima actualización de estado",
    "params": Objeto con los datos de entrada al proceso,
    "result": Objeto con los datos de resultado del proceso si status es un estado final,
    "requested_status": (opcional, entero que indica si se ha solicitado una cancelación, pausa o reanudación)
    "requested_status_tm": "Marca de tiempo de la solicitud de cancelación, pausa o reanudación"
}
```