> ## 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.

# Verificar OTP

> Verifica el código OTP y retorna un token de sesión para el cliente.

Verifica el código OTP enviado previamente con [POST /customers/login/request](request-otp) y retorna un token de sesión temporal con validez de **7 días**.

<Warning>
  Si el cliente acumula más de **3 intentos fallidos**, se dispara un evento de seguridad (`CustomerBanned`).
</Warning>

### Body

<ParamField body="phone" type="string" required placeholder="+573001234567">
  Número de teléfono del cliente en formato E.164.
</ParamField>

<ParamField body="otp" type="string" required placeholder="482916">
  Código OTP de 6 dígitos recibido por WhatsApp (o en la respuesta en modo test).
</ParamField>

### Respuesta exitosa

<ResponseField name="token" type="string">
  Token de sesión del cliente. Debe enviarse en el header `X-Customer-Token` en los endpoints de sesión.
</ResponseField>

<ResponseField name="expires_at" type="string">
  Fecha de expiración del token en formato ISO 8601 (7 días desde la emisión).
</ResponseField>

<ResponseField name="customer" type="object">
  Datos básicos del cliente autenticado.

  <Expandable title="Propiedades del customer">
    <ResponseField name="customer.id" type="string">
      ID único del cliente.
    </ResponseField>

    <ResponseField name="customer.first_name" type="string">
      Nombre del cliente.
    </ResponseField>

    <ResponseField name="customer.last_name" type="string">
      Apellido del cliente.
    </ResponseField>

    <ResponseField name="customer.phone" type="string">
      Teléfono del cliente.
    </ResponseField>

    <ResponseField name="customer.email" type="string">
      Email del cliente.
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl https://api.onepay.la/v1/customers/login/verify \
    -X POST \
    -H "Authorization: Bearer sk_test_xxx" \
    -H "Content-Type: application/json" \
    -d '{
      "phone": "+573001234567",
      "otp": "482916"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.onepay.la/v1/customers/login/verify', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer sk_test_xxx',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      phone: '+573001234567',
      otp: '482916'
    })
  });

  const { token, expires_at, customer } = await response.json();
  ```

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

  response = requests.post(
      'https://api.onepay.la/v1/customers/login/verify',
      headers={
          'Authorization': 'Bearer sk_test_xxx',
          'Content-Type': 'application/json'
      },
      json={
          'phone': '+573001234567',
          'otp': '482916'
      }
  )

  data = response.json()
  token = data['token']
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "token": "12|a1b2c3d4e5f6g7h8i9j0...",
    "expires_at": "2026-03-23T17:30:00+00:00",
    "customer": {
      "id": "9dd4158b-0e45-42bc-b56f-a4c1f856814d",
      "first_name": "María",
      "last_name": "López",
      "phone": "+573001234567",
      "email": "maria@ejemplo.com"
    }
  }
  ```

  ```json 422 - Credenciales inválidas theme={null}
  {
    "message": "Las credenciales proporcionadas no son válidas."
  }
  ```

  ```json 429 theme={null}
  {
    "message": "Too Many Attempts."
  }
  ```
</ResponseExample>
