Cambiar Estado de Transacción
curl --request PATCH \
--url http://api.gu1.ai/transactions/:id/changeStatus \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"status": "<string>"
}
'import requests
url = "http://api.gu1.ai/transactions/:id/changeStatus"
payload = { "status": "<string>" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({status: '<string>'})
};
fetch('http://api.gu1.ai/transactions/:id/changeStatus', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "http://api.gu1.ai/transactions/:id/changeStatus",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'status' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "http://api.gu1.ai/transactions/:id/changeStatus"
payload := strings.NewReader("{\n \"status\": \"<string>\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("http://api.gu1.ai/transactions/:id/changeStatus")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"status\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://api.gu1.ai/transactions/:id/changeStatus")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"status\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"transaction": {},
"statusChanged": {},
"rulesExecutionSummary": {}
}Referencia API
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.
PATCH
/
transactions
/
:id
/
changeStatus
Cambiar Estado de Transacción
curl --request PATCH \
--url http://api.gu1.ai/transactions/:id/changeStatus \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"status": "<string>"
}
'import requests
url = "http://api.gu1.ai/transactions/:id/changeStatus"
payload = { "status": "<string>" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({status: '<string>'})
};
fetch('http://api.gu1.ai/transactions/:id/changeStatus', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "http://api.gu1.ai/transactions/:id/changeStatus",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'status' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "http://api.gu1.ai/transactions/:id/changeStatus"
payload := strings.NewReader("{\n \"status\": \"<string>\"\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("http://api.gu1.ai/transactions/:id/changeStatus")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"status\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("http://api.gu1.ai/transactions/:id/changeStatus")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"status\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"transaction": {},
"statusChanged": {},
"rulesExecutionSummary": {}
}Endpoint
Cambiar Estado de Transacción
PATCH http://api.gu1.ai/transactions/:id/changeStatus
- 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(notransaction_updated) - Protección de integridad de transacciones
- Rastro de auditoría completo
Autenticación
Todas las solicitudes deben incluir una clave API en el encabezadoAuthorization:
Authorization: Bearer YOUR_API_KEY
Encabezados Requeridos
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY
Parámetros de Ruta
string
required
El UUID de la transacción a actualizarTipo:
string (uuid)Cuerpo de la Solicitud
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)
enum - 'CREATED' | 'PROCESSING' | 'SUSPENDED' | 'SENT' | 'EXPIRED' | 'DECLINED' | 'REFUNDED' | 'SUCCESSFUL'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:CREATEDPROCESSINGSUSPENDEDSENT
Estados Cerrados
Estados finales que no pueden transicionar a otros estados:EXPIREDDECLINEDREFUNDEDSUCCESSFUL
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 |
- ✅ Abierto → Abierto: Permitido (ej: CREATED → PROCESSING)
- ✅ Abierto → Cerrado: Permitido (ej: PROCESSING → SUCCESSFUL)
- ❌ Cerrado → Abierto: NO Permitido (ej: SUCCESSFUL → PROCESSING)
- ❌ 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:- Valida la transición - Asegura que el nuevo estado es válido y la transición está permitida
- Actualiza el estado - Cambia el estado de la transacción en la base de datos
- Ejecuta reglas de actualización - Ejecuta todas las reglas con
trigger: 'updated'en su alcance - Actualiza puntuación de riesgo - Re-calcula el riesgo basado en los resultados de las reglas
- Devuelve transacción actualizada - Devuelve la transacción completa con la nueva evaluación de riesgo
Trigger de Reglas
El endpoint usa el modotrigger_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:
{
"scope": {
"triggers": ["updated"],
"targetEntityTypes": ["transaction"]
}
}
Ejemplos Completos de Solicitud
Aprobar una Transacción Suspendida
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"
}'
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);
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)}")
Rechazar una Transacción en Revisión
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"
}'
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);
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']}")
Suspender una Transacción para Revisión Manual
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)
{
"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
boolean
Si el cambio de estado fue exitoso
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
object
Información sobre la transición de estado:
- from (string) - Estado anterior
- to (string) - Nuevo estado
object
En la raíz de la respuesta (alineado con Crear transacción). 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).
Respuestas de Error
400 Bad Request - Estado Inválido
{
"error": "Invalid status",
"validStatuses": [
"CREATED",
"PROCESSING",
"SUSPENDED",
"SENT",
"EXPIRED",
"DECLINED",
"REFUNDED",
"SUCCESSFUL"
]
}
400 Bad Request - Transición Inválida
{
"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
{
"error": "Transaction not found"
}
401 Unauthorized
{
"error": "Unauthorized",
"message": "Invalid or missing API key"
}
500 Internal Server Error
{
"error": "Failed to change transaction status",
"details": "Internal server error message"
}
Casos de Uso
1. Flujo de Revisión Manual
// 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
// 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
// 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
// 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
- Validar antes de cambiar - Siempre verificar el estado actual antes de intentar un cambio de estado para evitar llamadas API innecesarias
- Manejar errores de transición - Implementar manejo de errores apropiado para transiciones inválidas, ya que las transacciones cerradas no pueden ser reabiertas
- Usar estados apropiados - Elegir el estado correcto que refleje el estado de negocio real de la transacción
-
Monitorear ejecución de reglas - Prestar atención a
rulesExecutionSummarypara asegurar que las reglas de actualización se ejecuten como se espera y verificar detalles de ejecución, advertencias y metadata - Implementar registro de auditoría - Rastrear todos los cambios de estado en su sistema para cumplimiento y depuración
- Actualizaciones masivas - Al actualizar múltiples transacciones, usar Promise.allSettled() para continuar procesando incluso si algunas actualizaciones fallan
- Integración de webhooks - Considerar configurar webhooks para recibir notificaciones cuando los cambios de estado ejecuten reglas importantes
- Probar transiciones de estado - Probar todas las posibles transiciones de estado en su entorno de desarrollo antes de desplegar a producción
Endpoints Relacionados
Crear Transacción
Crear nuevas transacciones
Obtener Transacción
Recuperar detalles de transacción
Configuración de Reglas
Configurar reglas de actualización
Resumen
Volver al resumen
Was this page helpful?