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

# Cobrar con débito directo

> Debita automáticamente tarjetas de crédito/débito o cuentas bancarias autorizadas.

## ¿Qué vas a lograr?

Al terminar esta guía podrás debitar directamente tarjetas o cuentas bancarias que tus clientes hayan autorizado previamente, sin necesidad de que el cliente interactúe con un link de pago.

<Note>
  El débito directo requiere que el cliente haya **autorizado** previamente el método de pago. Este flujo es ideal para cobros recurrentes, suscripciones o pagos donde ya tienes la autorización del cliente.
</Note>

## Prerrequisitos

* Cuenta de OnePay verificada con llaves API
* Un cliente registrado con un método de pago autorizado (tarjeta o cuenta bancaria)

## ¿Cuándo usar Charges vs Payments?

|                | Payment (Solicitud)               | Charge (Cargo)                        |
| -------------- | --------------------------------- | ------------------------------------- |
| **El cliente** | Recibe un link y elige cómo pagar | No interactúa, el cobro es automático |
| **Requiere**   | Solo monto y título               | Cliente + método de pago autorizado   |
| **Ideal para** | Cobros únicos, facturas           | Cobros recurrentes, suscripciones     |

## Flujo: Debitar una tarjeta

```mermaid theme={null}
sequenceDiagram
    participant Tu App
    participant OnePay API
    participant Banco

    Tu App->>OnePay API: POST /customers
    OnePay API-->>Tu App: customer_id
    Tu App->>OnePay API: POST /cards (con authorization: true)
    OnePay API-->>Tu App: card_id
    Tu App->>OnePay API: POST /charges
    OnePay API->>Banco: Procesa débito
    Banco-->>OnePay API: Aprobado/Rechazado
    OnePay API-->>Tu App: charge (status)
    OnePay API->>Tu App: Webhook charge.succeeded
```

<Steps>
  <Step title="Crear el cliente">
    ```bash theme={null}
    curl https://api.onepay.la/v1/customers \
      -X POST \
      -H "Authorization: Bearer sk_test_xxx" \
      -H "Content-Type: application/json" \
      -H "x-idempotency: cliente-001" \
      -d '{
        "user_type": "natural",
        "first_name": "María",
        "last_name": "López",
        "email": "maria@ejemplo.com",
        "phone": "+573201112233",
        "document_type": "CC",
        "document_number": "1060500333"
      }'
    ```

    Guarda el `id` del cliente para los siguientes pasos.
  </Step>

  <Step title="Registrar la tarjeta con autorización">
    <Warning>
      Si capturas datos de tarjeta directamente, debes cumplir con PCI DSS. Usa el [SDK Elements](/docs/elements/introduction) para capturar datos de forma segura y obtener un token.
    </Warning>

    ```bash theme={null}
    curl https://cards.onepay.la/v1/cards \
      -X POST \
      -H "Authorization: Bearer pk_test_xxx" \
      -H "Content-Type: application/json" \
      -d '{
        "card_number": "4111111111111111",
        "expiration_year": "29",
        "expiration_month": "12",
        "ccv": "123",
        "holder_name": "MARIA LOPEZ",
        "customer_id": "CUSTOMER_ID",
        "authorization": true
      }'
    ```

    <Note>
      Las tarjetas se crean en un dominio diferente (`cards.onepay.la`) por cumplimiento PCI DSS.
    </Note>
  </Step>

  <Step title="Crear el cargo">
    ```bash theme={null}
    curl https://api.onepay.la/v1/charges \
      -X POST \
      -H "Authorization: Bearer sk_test_xxx" \
      -H "Content-Type: application/json" \
      -H "x-idempotency: cargo-001" \
      -d '{
        "title": "Mensualidad Enero",
        "customer_id": "CUSTOMER_ID",
        "amount": 85000,
        "card_id": "CARD_ID"
      }'
    ```
  </Step>

  <Step title="Verificar el resultado">
    La respuesta incluye el estado del cargo:

    ```json theme={null}
    {
      "id": "9e5ccd4a-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "status": "succeeded",
      "amount": 85000,
      "title": "Mensualidad Enero",
      ...
    }
    ```

    Estados posibles: `succeeded`, `declined`, `pending`.
  </Step>
</Steps>

## Flujo: Debitar una cuenta bancaria

<Steps>
  <Step title="Crear el cliente">
    Mismo paso que el flujo de tarjeta (ver arriba).
  </Step>

  <Step title="Consultar bancos disponibles">
    ```bash theme={null}
    curl https://api.onepay.la/v1/accounts/banks \
      -H "Authorization: Bearer sk_test_xxx"
    ```
  </Step>

  <Step title="Registrar la cuenta bancaria con autorización">
    ```bash theme={null}
    curl https://api.onepay.la/v1/accounts \
      -X POST \
      -H "Authorization: Bearer sk_test_xxx" \
      -H "Content-Type: application/json" \
      -H "x-idempotency: cuenta-001" \
      -d '{
        "customer_id": "CUSTOMER_ID",
        "bank_id": "BANK_ID",
        "subtype": "SAVINGS",
        "account_number": "123456789",
        "authorization": true
      }'
    ```

    <Warning>
      El campo `authorization` debe ser `true` para poder debitar la cuenta posteriormente. Sin autorización, la cuenta se crea pero no podrás cobrar.
    </Warning>
  </Step>

  <Step title="Crear el cargo">
    ```bash theme={null}
    curl https://api.onepay.la/v1/charges \
      -X POST \
      -H "Authorization: Bearer sk_test_xxx" \
      -H "Content-Type: application/json" \
      -H "x-idempotency: cargo-cuenta-001" \
      -d '{
        "title": "Mensualidad Enero",
        "customer_id": "CUSTOMER_ID",
        "amount": 85000,
        "account_id": "ACCOUNT_ID"
      }'
    ```
  </Step>

  <Step title="Escuchar webhook">
    Implementa el [Webhook de cargos](../client/webhooks/charges) para recibir la notificación cuando el cargo se procese.
  </Step>
</Steps>

## Usar escenarios de prueba

En ambiente test, puedes simular diferentes resultados usando `test_scenario`:

```json theme={null}
{
  "test_scenario": "INSUFFICIENT_FUNDS"
}
```

Consulta todos los [escenarios de prueba](/client/charges/scenarios) disponibles.

## Errores comunes

| Error                       | Causa                                    | Solución                                     |
| --------------------------- | ---------------------------------------- | -------------------------------------------- |
| `ACCOUNT_IS_NOT_AUTHORIZED` | La cuenta no tiene `authorization: true` | Crea la cuenta con `authorization: true`     |
| `INSUFFICIENT_FUNDS`        | Fondos insuficientes                     | Notifica al cliente y reintenta más tarde    |
| `CARD_EXPIRED`              | Tarjeta expirada                         | Solicita al cliente actualizar la tarjeta    |
| `validation_error`          | Falta `customer_id` o método de pago     | Verifica que envías `card_id` o `account_id` |

## Siguiente paso

<CardGroup cols={2}>
  <Card title="Casos de uso de débitos" icon="list" href="/client/use-cases/charges">
    Flujos detallados para tarjetas, cuentas ACH, Nequi y Daviplata.
  </Card>

  <Card title="Tokenizar Nequi/Daviplata" icon="wallet" href="/client/use-cases/tokenizar-cuentas">
    Vincula billeteras digitales para débitos automáticos.
  </Card>

  <Card title="Cobros recurrentes" icon="recycle" href="/client/subscriptions/index">
    Automatiza cobros periódicos con suscripciones.
  </Card>
</CardGroup>
