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

# Generar un token

> Firma una solicitud con tu clave de API y tu secreto de API para obtener el token de negocio que autentica las demás llamadas a la API de VelaFi en el header X-BH-TOKEN.

Usa este endpoint para obtener un token de negocio. Tu servidor firma la solicitud con su secreto de API y envía su clave de API en el header `X-BH-APIKEY`. La respuesta contiene un `token`, que envías en el header `X-BH-TOKEN` en las solicitudes autenticadas, y un `expireTime`.

> [!NOTE]
>
> Para que esta llamada funcione, VelaFi debe habilitar el acceso a la API en tu cuenta y la clave de API debe tener una lista blanca de IP. La solicitud debe provenir de una dirección IP incluida en esa lista blanca. Consulta [Autenticación](https://docs.velafi.com/es/api-reference/authentication.md).

## Endpoint

```text theme={null}
GET https://api.velafi.com/v2/token/generate
```

> [!NOTE]
>
> Usa `https://api-test.velafi.com/v2/token/generate` con tus credenciales de sandbox para hacer pruebas en sandbox.

## Headers de la solicitud

**X-BH-APIKEY** `string` *required*

Tu clave de API.

## Parámetros de consulta

**timestamp** `integer` *required*

La hora Unix actual en milisegundos, por ejemplo `1740568725231`.

**signature** `string` *required*

HMAC-SHA256 de la cadena `timestamp=<timestamp>`, con tu secreto de API como clave y codificado en hexadecimal en minúsculas.

> [!WARNING]
>
> Envía solo `timestamp` y `signature` como parámetros de consulta. El servidor verifica la firma contra tu query string sin el parámetro `signature`. Con solo estos dos parámetros, la cadena firmada es exactamente `timestamp=<timestamp>`.

## Cómo firmar

**1. Construye el mensaje**

Toma la hora Unix actual en milisegundos y construye la cadena `timestamp=<ms>`, por ejemplo `timestamp=1740568725231`.

**2. Calcula el HMAC**

Calcula el HMAC-SHA256 del mensaje usando tu secreto de API como clave.

**3. Codifica el resultado en hexadecimal**

Codifica el resultado de 32 bytes como una cadena hexadecimal en minúsculas de 64 caracteres. Esta es la `signature`.

## Campos de la respuesta

**code** `integer`

`200` si la solicitud es exitosa. Los errores devuelven un código negativo; consulta [Errores](#errors).

**msg** `string`

`SUCCESS` si la solicitud es exitosa; de lo contrario, un mensaje de error.

**data** `object`

**campos de data**

**token** `string`

El token de negocio. Envíalo en el header `X-BH-TOKEN` en las solicitudes autenticadas.

**expireTime** `string`

Cuándo vence el token, como marca de tiempo Unix en milisegundos. Solicita un token nuevo antes de esa hora.

## Ejemplos

```bash cURL theme={null}
API_KEY="your_api_key"
API_SECRET="your_api_secret"
TIMESTAMP=$(( $(date +%s) * 1000 ))
SIGNATURE=$(printf 'timestamp=%s' "$TIMESTAMP" | openssl dgst -sha256 -hmac "$API_SECRET" | sed 's/^.*= //')

curl --request GET \
  --url "https://api-test.velafi.com/v2/token/generate?timestamp=${TIMESTAMP}&signature=${SIGNATURE}" \
  --header "X-BH-APIKEY: ${API_KEY}"
```

```python Python theme={null}
import hashlib
import hmac
import time

import requests

BASE_URL = "https://api-test.velafi.com"
API_KEY = "your_api_key"
API_SECRET = "your_api_secret"


def generate_token():
    timestamp = str(int(time.time() * 1000))
    signature = hmac.new(
        API_SECRET.encode("utf-8"),
        f"timestamp={timestamp}".encode("utf-8"),
        hashlib.sha256,
    ).hexdigest()

    response = requests.get(
        f"{BASE_URL}/v2/token/generate",
        params={"timestamp": timestamp, "signature": signature},
        headers={"X-BH-APIKEY": API_KEY},
        timeout=10,
    )
    body = response.json()
    if body.get("code") != 200:
        raise RuntimeError(f"Token request failed: {body}")
    return body["data"]["token"], int(body["data"]["expireTime"])


token, expire_time_ms = generate_token()
print(token, expire_time_ms)
```

```javascript Node.js theme={null}
const crypto = require("crypto");

const BASE_URL = "https://api-test.velafi.com";
const API_KEY = "your_api_key";
const API_SECRET = "your_api_secret";

async function generateToken() {
  const timestamp = Date.now().toString();
  const signature = crypto
    .createHmac("sha256", API_SECRET)
    .update(`timestamp=${timestamp}`)
    .digest("hex");

  const url = `${BASE_URL}/v2/token/generate?timestamp=${timestamp}&signature=${signature}`;
  const response = await fetch(url, { headers: { "X-BH-APIKEY": API_KEY } });
  const body = await response.json();
  if (body.code !== 200) {
    throw new Error(`Token request failed: ${JSON.stringify(body)}`);
  }
  return { token: body.data.token, expireTime: Number(body.data.expireTime) };
}

generateToken().then(({ token, expireTime }) => console.log(token, expireTime));
```

```java Java theme={null}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

public class GenerateToken {
    private static final String BASE_URL = "https://api-test.velafi.com";
    private static final String API_KEY = "your_api_key";
    private static final String API_SECRET = "your_api_secret";

    public static void main(String[] args) throws Exception {
        String timestamp = String.valueOf(System.currentTimeMillis());
        String signature = hmacSha256Hex(API_SECRET, "timestamp=" + timestamp);

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(BASE_URL + "/v2/token/generate?timestamp=" + timestamp + "&signature=" + signature))
                .header("X-BH-APIKEY", API_KEY)
                .GET()
                .build();

        HttpResponse<String> response = HttpClient.newHttpClient()
                .send(request, HttpResponse.BodyHandlers.ofString());
        // Si es exitosa: {"code":200,"msg":"SUCCESS","data":{"token":"...","expireTime":"..."}}
        System.out.println(response.body());
    }

    static String hmacSha256Hex(String secret, String message) throws Exception {
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] raw = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
        StringBuilder hex = new StringBuilder();
        for (byte b : raw) {
            hex.append(String.format("%02x", b));
        }
        return hex.toString();
    }
}
```

```json Response theme={null}
{
  "code": 200,
  "msg": "SUCCESS",
  "data": {
    "token": "00000000-0000-0000-0000-000000000006",
    "expireTime": "1740568725231"
  }
}
```

## Errores

Los errores devuelven el estado HTTP `400` con un `code` negativo:

| Código | Mensaje | Causa |
| - | - | - |
| `-1002` | You are not authorized to execute this request | Falta el header `X-BH-APIKEY` o tiene un formato incorrecto. |
| `-1004` | `Missing required parameter '<name>'` | Falta el parámetro de consulta `signature`, o falta `timestamp` mientras se envían otros parámetros de consulta. El mensaje indica el parámetro faltante. |
| `-1103` | An unknown parameter was sent. | La solicitud no tiene parámetros de consulta, o `signature` es el único. |
| `-1022` | Signature for this request is not valid. | La firma no coincide, o la clave de API no existe. |
| `-1023` | Please set IP whitelist before using API | La clave de API no tiene lista blanca de IP. |
| `-2015` | Invalid API-key, IP, or permissions for action. | La clave de API o tu cuenta están deshabilitadas, o la dirección IP de la solicitud no está en la lista blanca de la clave. |
| `-5033` | You are not yet an API user. Please contact the OTC customer service manager if you have any needs. | El acceso a la API no está habilitado en tu cuenta. |

## Usar el token

Envía el token en el header `X-BH-TOKEN`:

```bash theme={null}
curl --request GET \
  --url https://api-test.velafi.com/v2/user/account \
  --header "X-BH-TOKEN: your_token"
```

Solicita un token nuevo antes de `expireTime`. Una llamada con un token vencido o desconocido falla con el código `-1022`.


## Related topics

- [Autenticación](https://docs.velafi.com/es/api-reference/authentication.md)
- [Crear una clave de API](https://docs.velafi.com/es/docs/guides/creating-api-key.md)
- [Crear un comercio](https://docs.velafi.com/es/api-reference/merchant/create-merchant.md)
- [Listar registros de fondeo](https://docs.velafi.com/es/api-reference/merchant/retrieve-funding-records.md)
- [Sandbox](https://docs.velafi.com/es/docs/sandbox.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.