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

# Cambiar Estado de Transacción

> Actualiza el estado de la transacción y ejecuta reglas de actualización automáticamente — en el producto de monitoreo transaccional gu1 para fraude y AML.

## Endpoint

### Cambiar Estado de Transacción

```
PATCH http://api.gu1.ai/transactions/:id/changeStatus
```

Actualiza el estado de una transacción existente con validación automática de transiciones de estado y ejecución opcional de reglas para re-evaluación de riesgo en tiempo real.

**Características:**

* Validación automática de transiciones de estado (previene cambios de estado inválidos)
* Aplicación de máquina de estados (reglas de estados abiertos ↔ cerrados)
* Ejecución automática de reglas/matrices con trigger **`transaction_status_changed`** (no `transaction_updated`)
* Protección de integridad de transacciones
* Rastro de auditoría completo

## Autenticación

Todas las solicitudes deben incluir una clave API en el encabezado `Authorization`:

```bash theme={null}
Authorization: Bearer YOUR_API_KEY
```

## Encabezados Requeridos

```bash theme={null}
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY
```

## Parámetros de Ruta

<ParamField path="id" type="string" required>
  El UUID de la transacción a actualizar

  **Tipo**: `string` (uuid)
</ParamField>

## Cuerpo de la Solicitud

<ParamField body="status" type="string" required>
  Nuevo estado de la transacción. Debe ser un valor válido del enum de estados.

  **Estados Válidos**:

  * `CREATED` - Transacción creada (estado abierto)
  * `PROCESSING` - Transacción en proceso (estado abierto)
  * `SUSPENDED` - Transacción temporalmente suspendida (estado abierto)
  * `SENT` - Transacción enviada/transmitida (estado cerrado)
  * `EXPIRED` - Transacción expirada (estado cerrado)
  * `DECLINED` - Transacción rechazada/declinada (estado cerrado)
  * `REFUNDED` - Transacción reembolsada/reversada (estado cerrado)
  * `SUCCESSFUL` - Transacción completada exitosamente (estado cerrado)

  **Tipo**: `enum` - `'CREATED' | 'PROCESSING' | 'SUSPENDED' | 'SENT' | 'EXPIRED' | 'DECLINED' | 'REFUNDED' | 'SUCCESSFUL'`
</ParamField>

## Reglas de Transición de Estados

El endpoint aplica reglas estrictas de transición de estados para mantener la integridad de las transacciones:

### Estados Abiertos

Estados que permiten transiciones adicionales:

* `CREATED`
* `PROCESSING`
* `SUSPENDED`
* `SENT`

### Estados Cerrados

Estados finales que **no pueden** transicionar a otros estados:

* `EXPIRED`
* `DECLINED`
* `REFUNDED`
* `SUCCESSFUL`

### Matriz de Transiciones

| Estado Origen  | Estado Destino | ¿Permitido? | Nota                                        |
| -------------- | -------------- | ----------- | ------------------------------------------- |
| CREATED        | PROCESSING     | ✅ Sí        | Flujo normal                                |
| CREATED        | SUSPENDED      | ✅ Sí        | Suspender para revisión                     |
| CREATED        | SUCCESSFUL     | ✅ Sí        | Aprobación rápida                           |
| PROCESSING     | SUSPENDED      | ✅ Sí        | Suspender durante procesamiento             |
| PROCESSING     | SUCCESSFUL     | ✅ Sí        | Finalización normal                         |
| PROCESSING     | DECLINED       | ✅ Sí        | Rechazar durante procesamiento              |
| SUSPENDED      | PROCESSING     | ✅ Sí        | Reanudar procesamiento                      |
| SUSPENDED      | SUCCESSFUL     | ✅ Sí        | Aprobar transacción suspendida              |
| SUSPENDED      | DECLINED       | ✅ Sí        | Rechazar transacción suspendida             |
| **SUCCESSFUL** | PROCESSING     | ❌ No        | No se puede reabrir transacción cerrada     |
| **DECLINED**   | PROCESSING     | ❌ No        | No se puede reabrir transacción cerrada     |
| **EXPIRED**    | PROCESSING     | ❌ No        | No se puede reabrir transacción cerrada     |
| **REFUNDED**   | any            | ❌ No        | No se puede cambiar transacción reembolsada |
| **SUCCESSFUL** | DECLINED       | ❌ No        | No se puede cambiar entre estados cerrados  |

**Reglas Clave**:

1. ✅ **Abierto → Abierto**: Permitido (ej: CREATED → PROCESSING)
2. ✅ **Abierto → Cerrado**: Permitido (ej: PROCESSING → SUCCESSFUL)
3. ❌ **Cerrado → Abierto**: **NO** Permitido (ej: SUCCESSFUL → PROCESSING)
4. ❌ **Cerrado → Cerrado**: **NO** Permitido (ej: DECLINED → REFUNDED)

## Ejecución de Reglas de Actualización

Cuando se cambia el estado de una transacción, el endpoint automáticamente:

1. **Valida la transición** - Asegura que el nuevo estado es válido y la transición está permitida
2. **Actualiza el estado** - Cambia el estado de la transacción en la base de datos
3. **Ejecuta reglas de actualización** - Ejecuta todas las reglas con `trigger: 'updated'` en su alcance
4. **Actualiza puntuación de riesgo** - Re-calcula el riesgo basado en los resultados de las reglas
5. **Devuelve transacción actualizada** - Devuelve la transacción completa con la nueva evaluación de riesgo

### Trigger de Reglas

El endpoint usa el modo `trigger_transaction_status_changed`, que ejecuta reglas con `action: "status_changed"` o matrices con `eventType: "transaction_status_changed"`. El trigger `updated` queda para `PATCH /transactions/{id}` (metadata, deviceDetails, channel, reason).

**Ejemplo de configuración de alcance de regla**:

```json theme={null}
{
  "scope": {
    "triggers": ["updated"],
    "targetEntityTypes": ["transaction"]
  }
}
```

## Ejemplos Completos de Solicitud

### Aprobar una Transacción Suspendida

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH http://api.gu1.ai/transactions/550e8400-e29b-41d4-a716-446655440000/changeStatus \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "status": "SUCCESSFUL"
    }'
  ```

  ```javascript JavaScript theme={null}
  const transactionId = '550e8400-e29b-41d4-a716-446655440000';

  const response = await fetch(`http://api.gu1.ai/transactions/${transactionId}/changeStatus`, {
    method: 'PATCH',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      status: 'SUCCESSFUL'
    })
  });

  const result = await response.json();
  console.log(result);
  ```

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

  transaction_id = "550e8400-e29b-41d4-a716-446655440000"
  url = f"http://api.gu1.ai/transactions/{transaction_id}/changeStatus"

  headers = {
      "Authorization": "Bearer YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  payload = {
      "status": "SUCCESSFUL"
  }

  response = requests.patch(url, json=payload, headers=headers)
  result = response.json()

  print(f"Estado de Transacción: {result['transaction']['status']}")
  summary = result.get("rulesExecutionSummary") or {}
  print(f"Reglas con match: {summary.get('matchedRulesCount', 0)}")
  ```
</CodeGroup>

### Rechazar una Transacción en Revisión

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH http://api.gu1.ai/transactions/550e8400-e29b-41d4-a716-446655440000/changeStatus \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "status": "DECLINED"
    }'
  ```

  ```javascript JavaScript theme={null}
  const transactionId = '550e8400-e29b-41d4-a716-446655440000';

  const response = await fetch(`http://api.gu1.ai/transactions/${transactionId}/changeStatus`, {
    method: 'PATCH',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      status: 'DECLINED'
    })
  });

  const result = await response.json();
  console.log(result);
  ```

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

  transaction_id = "550e8400-e29b-41d4-a716-446655440000"
  url = f"http://api.gu1.ai/transactions/{transaction_id}/changeStatus"

  headers = {
      "Authorization": "Bearer YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  payload = {
      "status": "DECLINED"
  }

  response = requests.patch(url, json=payload, headers=headers)
  result = response.json()

  print(f"Estado cambió de {result['statusChanged']['from']} a {result['statusChanged']['to']}")
  ```
</CodeGroup>

### Suspender una Transacción para Revisión Manual

```bash theme={null}
curl -X PATCH http://api.gu1.ai/transactions/550e8400-e29b-41d4-a716-446655440000/changeStatus \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "SUSPENDED"
  }'
```

## Respuesta

### Respuesta Exitosa (200 OK)

```json theme={null}
{
  "success": true,
  "transaction": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "externalId": "txn_12345",
    "type": "PAYMENT",
    "status": "SUCCESSFUL",
    "amount": 1500.00,
    "currency": "USD",
    "amountInUsd": 1500.00,
    "origin": {
      "entityId": "customer_001",
      "externalId": "EXT-001",
      "name": "Juan Pérez",
      "country": "US",
      "details": {},
      "type": "person",
      "riskScore": 15.50
    },
    "destination": {
      "entityId": "merchant_002",
      "externalId": "MER-002",
      "name": "Tienda de Electrónicos",
      "country": "US",
      "details": {},
      "type": "company",
      "riskScore": 8.20
    },
    "riskScore": 22.50,
    "riskFactors": [
      {
        "factor": "status_change",
        "score": 5,
        "description": "Estado de transacción cambió a SUCCESSFUL"
      }
    ],
    "flagged": false,
    "description": "Compra de laptop",
    "category": "electronics",
    "metadata": {},
    "transactedAt": "2024-12-23T14:30:00.000Z",
    "createdAt": "2024-12-23T14:30:00.000Z",
    "updatedAt": "2024-12-23T15:45:00.000Z"
  },
  "statusChanged": {
    "from": "SUSPENDED",
    "to": "SUCCESSFUL"
  },
  "rulesExecutionSummary": {
    "rulesHit": [
      {
        "name": "Verificación de Transacciones de Alto Valor",
        "score": 5,
        "status": "active"
      }
    ],
    "rulesNoHit": [],
    "totalScore": 22.5,
    "matchedRulesCount": 3,
    "executionTimeMs": 245,
    "trigger": "status_change"
  }
}
```

### Campos de Respuesta

<ResponseField name="success" type="boolean">
  Si el cambio de estado fue exitoso
</ResponseField>

<ResponseField name="transaction" type="object">
  La transacción actualizada con todos sus datos, incluyendo:

  * **id** (string) - UUID de la transacción
  * **status** (string) - Nuevo estado de la transacción
  * **origin** (object) - Información de la parte origen (estructura anidada)
    * **entityId** (string) - UUID de la entidad origen
    * **name** (string) - Nombre de la parte origen
    * **country** (string) - País de origen
    * **details** (object) - Detalles adicionales de origen
    * **type** (string) - Tipo de entidad origen
    * **riskScore** (number) - Puntuación de riesgo de la entidad origen
  * **destination** (object) - Información de la parte destino (estructura anidada)
    * **entityId** (string) - UUID de la entidad destino
    * **name** (string) - Nombre de la parte destino
    * **country** (string) - País de destino
    * **details** (object) - Detalles adicionales de destino
    * **type** (string) - Tipo de entidad destino
    * **riskScore** (number) - Puntuación de riesgo de la entidad destino
  * **riskScore** (number) - Puntuación de riesgo actualizada después de la re-evaluación
  * **riskFactors** (array) - Factores de riesgo actualizados
  * **flagged** (boolean) - Estado de marcado actualizado
  * **updatedAt** (string) - Timestamp de la actualización
</ResponseField>

<ResponseField name="statusChanged" type="object">
  Información sobre la transición de estado:

  * **from** (string) - Estado anterior
  * **to** (string) - Nuevo estado
</ResponseField>

<ResponseField name="rulesExecutionSummary" type="object">
  **En la raíz de la respuesta** (alineado con [Crear transacción](/es/api-reference/transactions/create)). **Solo presente cuando se ejecutaron reglas.** Resumen de qué reglas hicieron match (hit) y cuáles no (no hit), acciones ejecutadas y puntuación total.

  * **rulesHit** (array) - Reglas cuyas condiciones se cumplieron. Cada elemento: **name**, **description**, **score**, **priority**, **category**, **status**, **conditions**, **actions**.
  * **rulesNoHit** (array) - Reglas evaluadas pero condiciones no cumplidas. Misma estructura que rulesHit.
  * **actionsExecuted** (object) - Acciones ejecutadas agregadas: **alerts**, **suggestion**, **status**, **assignedUser**, **customKeys** (array de strings, opcional) — claves de acciones personalizadas de las reglas que hicieron match; para integraciones/workflows.
  * **totalScore** (number) - Suma de puntuación de todas las reglas que hicieron hit (excluyendo shadow).
</ResponseField>

## Respuestas de Error

### 400 Bad Request - Estado Inválido

```json theme={null}
{
  "error": "Invalid status",
  "validStatuses": [
    "CREATED",
    "PROCESSING",
    "SUSPENDED",
    "SENT",
    "EXPIRED",
    "DECLINED",
    "REFUNDED",
    "SUCCESSFUL"
  ]
}
```

### 400 Bad Request - Transición Inválida

```json theme={null}
{
  "error": "Cannot transition from closed status to open status",
  "currentStatus": "SUCCESSFUL",
  "requestedStatus": "PROCESSING",
  "message": "Transaction is in a closed state (SUCCESSFUL) and cannot be reopened"
}
```

### 404 Not Found

```json theme={null}
{
  "error": "Transaction not found"
}
```

### 401 Unauthorized

```json theme={null}
{
  "error": "Unauthorized",
  "message": "Invalid or missing API key"
}
```

### 500 Internal Server Error

```json theme={null}
{
  "error": "Failed to change transaction status",
  "details": "Internal server error message"
}
```

## Casos de Uso

### 1. Flujo de Revisión Manual

```javascript theme={null}
// Paso 1: Suspender transacción sospechosa
await changeStatus(transactionId, 'SUSPENDED');

// Paso 2: Analista revisa la transacción
// ... proceso de revisión manual ...

// Paso 3: Aprobar o rechazar según la revisión
if (approved) {
  await changeStatus(transactionId, 'SUCCESSFUL');
} else {
  await changeStatus(transactionId, 'DECLINED');
}
```

### 2. Verificación Automática de Cumplimiento

```javascript theme={null}
// Transacción creada con estado CREATED
const transaction = await createTransaction({...});

// Ejecutar verificaciones de cumplimiento adicionales
const complianceResult = await runComplianceChecks(transaction.id);

if (complianceResult.passed) {
  // Mover a procesamiento
  await changeStatus(transaction.id, 'PROCESSING');

  // Completar transacción
  await changeStatus(transaction.id, 'SUCCESSFUL');
} else {
  // Rechazar por problemas de cumplimiento
  await changeStatus(transaction.id, 'DECLINED');
}
```

### 3. Respuesta a Detección de Fraude

```javascript theme={null}
// Monitorear actualizaciones de transacciones
if (fraudDetected) {
  // Suspender transacción inmediatamente
  await changeStatus(transactionId, 'SUSPENDED');

  // Crear alerta para investigación
  await createAlert({
    transactionId,
    type: 'fraud_suspected',
    severity: 'high'
  });

  // Después de la investigación, tomar acción
  if (confirmed) {
    await changeStatus(transactionId, 'DECLINED');
  } else {
    await changeStatus(transactionId, 'SUCCESSFUL');
  }
}
```

### 4. Actualizaciones Masivas de Estado

```javascript theme={null}
// Actualizar múltiples transacciones en paralelo
const suspendedTransactions = await getTransactionsByStatus('SUSPENDED');

const results = await Promise.allSettled(
  suspendedTransactions.map(async (txn) => {
    if (shouldApprove(txn)) {
      return await changeStatus(txn.id, 'SUCCESSFUL');
    } else if (shouldDecline(txn)) {
      return await changeStatus(txn.id, 'DECLINED');
    }
  })
);

console.log(`Actualizadas ${results.filter(r => r.status === 'fulfilled').length} transacciones`);
```

## Mejores Prácticas

1. **Validar antes de cambiar** - Siempre verificar el estado actual antes de intentar un cambio de estado para evitar llamadas API innecesarias

2. **Manejar errores de transición** - Implementar manejo de errores apropiado para transiciones inválidas, ya que las transacciones cerradas no pueden ser reabiertas

3. **Usar estados apropiados** - Elegir el estado correcto que refleje el estado de negocio real de la transacción

4. **Monitorear ejecución de reglas** - Prestar atención a `rulesExecutionSummary` para asegurar que las reglas de actualización se ejecuten como se espera y verificar detalles de ejecución, advertencias y metadata

5. **Implementar registro de auditoría** - Rastrear todos los cambios de estado en su sistema para cumplimiento y depuración

6. **Actualizaciones masivas** - Al actualizar múltiples transacciones, usar Promise.allSettled() para continuar procesando incluso si algunas actualizaciones fallan

7. **Integración de webhooks** - Considerar configurar webhooks para recibir notificaciones cuando los cambios de estado ejecuten reglas importantes

8. **Probar transiciones de estado** - Probar todas las posibles transiciones de estado en su entorno de desarrollo antes de desplegar a producción

## Endpoints Relacionados

<CardGroup cols={2}>
  <Card title="Crear Transacción" icon="plus" href="/es/use-cases/transaction-monitoring/api-reference">
    Crear nuevas transacciones
  </Card>

  <Card title="Obtener Transacción" icon="eye" href="/es/api-reference/transactions/get">
    Recuperar detalles de transacción
  </Card>

  <Card title="Configuración de Reglas" icon="sliders" href="/es/use-cases/transaction-monitoring/rules-configuration">
    Configurar reglas de actualización
  </Card>

  <Card title="Resumen" icon="book" href="/es/use-cases/transaction-monitoring/overview">
    Volver al resumen
  </Card>
</CardGroup>
