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

# Crear un Pago

> Dispersa fondos desde tu saldo pre-financiado a un beneficiario

## Prerrequisitos

Antes de crear un pago necesitas:

1. **Una cuenta pre-financiada** — creada vía `POST /api/v2/customers/pre-fund/create`
2. **Saldo suficiente** — verifica vía `GET /api/v2/customers/balances`
3. **Datos del beneficiario** — cuenta bancaria, dirección de billetera o alias de pago del destinatario

<Card title="Configurar Cuentas Pre-Financiadas" icon="vault" href="/es/guides/pre-fund/pre-fund-accounts">
  ¿Aún no tienes una cuenta pre-financiada? Comienza aquí.
</Card>

## Flujo Completo de Pago

<Steps>
  <Step title="Verificar Saldo Disponible">
    Confirma que tienes fondos suficientes antes de enviar el pago.

    ```bash theme={null}
    GET /api/v2/customers/balances
    ```

    ```json Respuesta theme={null}
    [
      {
        "id": "balance-id",
        "currency": "COP",
        "amount": "10000000.00",
        "accountId": "prefund-account-id"
      }
    ]
    ```
  </Step>

  <Step title="Crear el Pago">
    Envía la solicitud de pago con tu cuenta pre-financiada, monto y beneficiario.

    ```bash theme={null}
    POST /api/v2/payouts
    ```
  </Step>

  <Step title="Seguir el Estado">
    Consulta el pago o escucha webhooks hasta que alcance un estado terminal (`COMPLETED`, `FAILED`, `REJECTED`, `ERROR` o `REFUNDED`).
  </Step>
</Steps>

## Ejemplo de Implementación

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://sandbox.killb.app/api/v2/payouts \
    -H "Authorization: Bearer TU_TOKEN" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: pago-2024-001" \
    -d '{
      "preFundAccountId": "prefund-account-id",
      "amount": 500000,
      "externalId": "pago-2024-001",
      "beneficiary": {
        "type": "BANK",
        "account": {
          "firstName": "Maria",
          "lastName": "Garcia",
          "email": "maria@ejemplo.com",
          "phone": "3001234567",
          "document": { "type": "CC", "number": "12345678" },
          "accountNumber": "123456789",
          "bankCode": "001",
          "type": "savings",
          "countryCode": "CO"
        }
      }
    }'
  ```

  ```javascript Node.js theme={null}
  const crearPago = async (preFundAccountId, amount, beneficiary) => {
    const response = await fetch(
      'https://sandbox.killb.app/api/v2/payouts',
      {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          preFundAccountId,
          amount,
          beneficiary
        })
      }
    );

    if (!response.ok) {
      const error = await response.json();
      throw new Error(`Pago fallido: ${JSON.stringify(error)}`);
    }

    return response.json();
  };

  // Ejemplo: dispersar 500,000 COP vía Bank Transfer
  const pago = await crearPago(
    'prefund-account-id',
    500000,
    {
      type: 'BANK',
      account: {
        firstName: 'Maria',
        lastName: 'Garcia',
        email: 'maria@ejemplo.com',
        phone: '3001234567',
        document: { type: 'CC', number: '12345678' },
        accountNumber: '123456789',
        bankCode: '001',
        type: 'savings',
        countryCode: 'CO'
      }
    }
  );

  console.log('ID del Pago:', pago.id);
  console.log('Estado:', pago.status);
  ```

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

  def crear_pago(pre_fund_account_id, amount, beneficiary, access_token):
      response = requests.post(
          'https://sandbox.killb.app/api/v2/payouts',
          headers={
              'Authorization': f'Bearer {access_token}',
              'Content-Type': 'application/json',
              'Idempotency-Key': f'pago-{pre_fund_account_id}-{amount}'
          },
          json={
              'preFundAccountId': pre_fund_account_id,
              'amount': amount,
              'beneficiary': beneficiary
          }
      )
      response.raise_for_status()
      return response.json()

  # Ejemplo: dispersar 500,000 COP vía Bank Transfer
  pago = crear_pago(
      pre_fund_account_id='prefund-account-id',
      amount=500000,
      beneficiary={
          'type': 'BANK',
          'account': {
              'firstName': 'Maria',
              'lastName': 'Garcia',
              'email': 'maria@ejemplo.com',
              'phone': '3001234567',
              'document': {'type': 'CC', 'number': '12345678'},
              'accountNumber': '123456789',
              'bankCode': '001',
              'type': 'savings',
              'countryCode': 'CO'
          }
      },
      access_token=token
  )

  print(f"Pago creado: {pago['id']} — {pago['status']}")
  ```
</CodeGroup>

**Respuesta:**

```json theme={null}
{
  "id": "payout-abc123",
  "amount": 500000,
  "currency": "COP",
  "status": "PENDING",
  "externalId": "pago-2024-001",
  "beneficiary": {
    "type": "BANK",
    "account": { ... }
  },
  "createdAt": "2024-01-15T10:30:00.000Z",
  "updatedAt": "2024-01-15T10:30:00.000Z"
}
```

## Tipos de Beneficiario

<Tabs>
  <Tab title="Bank Transfer (Colombia)">
    Transferencia estándar a cuenta bancaria colombiana vía Bank Transfer.

    ```json theme={null}
    {
      "type": "BANK",
      "account": {
        "firstName": "Maria",
        "lastName": "Garcia",
        "email": "maria@ejemplo.com",
        "phone": "3001234567",
        "document": {
          "type": "CC",
          "number": "12345678"
        },
        "accountNumber": "123456789",
        "bankCode": "001",
        "type": "savings",
        "countryCode": "CO"
      }
    }
    ```

    **Campos requeridos:** `firstName` o `companyName`, `lastName`, `email`, `phone`, `document`, `accountNumber`, `bankCode`, `type`, `countryCode`

    Usa `GET /api/v2/banks` para consultar los valores válidos de `bankCode`.
  </Tab>

  <Tab title="BREB (Colombia)">
    Dispersión vía alias registrado (teléfono, email, cédula o alias BREB).

    ```json theme={null}
    {
      "type": "BREB",
      "account": {
        "firstName": "Carlos",
        "lastName": "Lopez",
        "email": "carlos@ejemplo.com",
        "phone": "3109876543",
        "document": {
          "type": "CC",
          "number": "87654321"
        },
        "aliasType": "PHONE",
        "alias": "3109876543",
        "countryCode": "CO"
      }
    }
    ```

    **Tipos de alias:** `NATIONAL_ID`, `PHONE`, `EMAIL`, `ALPHANUMERIC`, `BUSINESS_ID`
  </Tab>
</Tabs>

## Verificar Saldo Antes del Pago

Siempre verifica el saldo disponible antes de enviar pagos grandes:

```javascript theme={null}
const verificarSaldo = async (preFundAccountId, montoRequerido) => {
  const balances = await fetch('/api/v2/customers/balances', {
    headers: { 'Authorization': `Bearer ${token}` }
  }).then(r => r.json());

  const cuenta = balances.find(b => b.accountId === preFundAccountId);

  if (!cuenta || parseFloat(cuenta.amount) < montoRequerido) {
    throw new Error(
      `Saldo insuficiente. Disponible: ${cuenta?.amount ?? 0}, Requerido: ${montoRequerido}`
    );
  }

  return cuenta;
};
```

## Idempotencia

Para evitar dispersiones duplicadas en reintentos de red, envía un header único `Idempotency-Key` en cada solicitud de creación de pago. Si se recibe la misma clave dos veces, KillB devuelve el pago original en lugar de crear uno nuevo.

```bash theme={null}
Idempotency-Key: <tu-referencia-única-de-pago>
```

<Tip>
  Usa un identificador único y estable como clave — tu ID de pago interno o un UUID vinculado a la transacción funciona bien.
</Tip>

## Listar Pagos

Recupera todos los pagos con filtros opcionales:

```javascript theme={null}
const listarPagos = async ({ status, externalId, page = 1, limit = 20 } = {}) => {
  const params = new URLSearchParams({ page, limit });
  if (status) params.set('status', status);
  if (externalId) params.set('externalId', externalId);

  const response = await fetch(
    `https://sandbox.killb.app/api/v2/payouts?${params}`,
    { headers: { 'Authorization': `Bearer ${token}` } }
  );

  return response.json(); // { payouts: [...], totalPage: N }
};

// Obtener todos los pagos pendientes
const pendientes = await listarPagos({ status: 'PENDING' });
```

## Próximos Pasos

<CardGroup cols={2}>
  <Card title="Seguimiento de Estado" icon="chart-line" href="/es/guides/payouts/payout-status">
    Monitorea pagos con polling y webhooks
  </Card>

  <Card title="Configurar Webhooks" icon="bell" href="/es/guides/webhooks/setup">
    Configura notificaciones webhook para PAYOUT
  </Card>
</CardGroup>
