Clientes
Crea, lista, recupera y actualiza clientes de Merchants en Tokeflow — los registros canónicos de compradores que anclan transacciones, pedidos y suscripciones.
Un Cliente es el registro canónico del comprador para un único Merchant. Almacena la identidad del comprador (correo electrónico, nombre, teléfono, documento fiscal) y una dirección de facturación, y ancla las transacciones, los pedidos y las suscripciones del comprador en un único registro.
Los clientes son únicos por correo electrónico por Merchant. La creación de un cliente es idempotente por correo electrónico: si ya existe un cliente con el mismo correo electrónico para el Merchant, Tokeflow devuelve el registro existente en lugar de crear un duplicado. Esto hace que la creación de clientes sea segura para reintentar desde flujos de checkout y de servidor a servidor.
Tokeflow es una plataforma de orquestación de pagos — estandariza los registros de compradores en todos los proveedores conectados para que mantengas una única identidad de cliente, sin importar qué proveedor procese finalmente un cobro. Tokeflow no procesa ni liquida fondos; eso lo gestionan tus proveedores conectados.
El objeto cliente
| Field | Type | Description |
|---|---|---|
id | string | Identificador único, con prefijo cust_. |
merchant_id | string | Merchant propietario de este cliente, con prefijo mrc_. |
email | string | null | Correo electrónico del comprador. Se almacena en minúsculas; único por Merchant. |
name | string | null | Nombre completo del comprador. |
phone | string | null | Teléfono del comprador en formato E.164 (p. ej. +5511999990000). |
document_type | string | null | Uno de cpf, cnpj, passport, tax_id. |
metadata | object | null | Pares clave/valor arbitrarios que adjuntas. Máximo de 5 KB serializado. |
created_at | string | Marca de tiempo de creación (ISO 8601 UTC). |
updated_at | string | Marca de tiempo de la última actualización (ISO 8601 UTC). |
El número de documento fiscal (document_number) y billing_address se aceptan al escribir por motivos de cumplimiento y procesamiento, pero nunca se devuelven en las respuestas de la API. El objeto cliente expone únicamente document_type.
Autenticación y alcances
Todos los endpoints de clientes requieren una clave secreta de Merchant (sk_live_mer_…). El Merchant se infiere a partir de la clave, por lo que nunca se pasa un merchant_id. Usa el alcance customers:read para operaciones de lectura y customers:write para creación/actualización.
Authorization: Bearer sk_live_mer_xxxxxxxxxxxxxxxxxxxxxxxxLas claves secretas son solo para uso del lado del servidor. Nunca incorpores una clave sk_* en código de navegador o móvil. Consulta Autenticación para conocer la anatomía de las claves y los alcances.
POST/api/v1/customers
Auth: Merchant key (scope customers:write)
Crea un cliente para el Merchant resuelto a partir de la clave de API. Idempotente por correo electrónico: si ya existe un cliente con el mismo correo electrónico, se devuelve el registro existente con HTTP 200; un cliente nuevo devuelve HTTP 201.
Parámetros del cuerpo
| Field | Type | Required | Description |
|---|---|---|---|
email | string | Sí | Correo electrónico del comprador. Normalizado a minúsculas; único por Merchant. |
name | string | Sí | Nombre completo del comprador. |
phone | string | Sí | Teléfono en formato E.164, con al menos 10 dígitos incl. código de país/área (p. ej. +5511999990000). |
document_type | string | Sí | Uno de cpf, cnpj, passport, tax_id. |
document_number | string | Sí | Documento fiscal (máx. 40 caracteres). Se almacena cifrado en reposo; nunca se devuelve. |
billing_address | object | Sí | Dirección de facturación (ver abajo). |
metadata | object | No | Pares clave/valor arbitrarios. Máximo de 5 KB serializado. |
Objeto billing_address
| Field | Type | Required | Description |
|---|---|---|---|
line_1 | string | Sí | Calle y número (máx. 255). |
line_2 | string | No | Apartamento, oficina, etc. (máx. 255). |
zip_code | string | Sí | Código postal (máx. 20). |
city | string | Sí | Ciudad (máx. 100). |
state | string | Sí | Código de estado/provincia (máx. 100). |
country | string | Sí | Código de país ISO 3166-1 alpha-2, p. ej. BR (máx. 2). |
Envía un encabezado Idempotency-Key al crear. Combinado con la idempotencia por correo electrónico, esto garantiza que los reintentos nunca produzcan clientes duplicados y siempre devuelvan el resultado original.
Solicitud
curl -X POST https://api.tokeflow.com/api/v1/customers \
-H "Authorization: Bearer sk_live_mer_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 4f1d8c2a-9b07-4f3e-9a1c-7e2b6d0c5a11" \
-d '{
"email": "joao@example.com",
"name": "Joao da Silva",
"phone": "+5511999990000",
"document_type": "cpf",
"document_number": "123.456.789-00",
"billing_address": {
"line_1": "Av Paulista, 1000",
"line_2": "Apto 42",
"zip_code": "01310-100",
"city": "São Paulo",
"state": "SP",
"country": "BR"
},
"metadata": { "source": "checkout_web" }
}'Respuesta 201 Created
{
"success": true,
"data": {
"id": "cust_a1b2c3d4e5",
"merchant_id": "mrc_9f8e7d6c5b",
"email": "joao@example.com",
"name": "Joao da Silva",
"created_at": "2026-01-15T12:30:00.000Z"
},
"request_id": "req_8f3c1a2b4d",
"timestamp": "2026-01-15T12:30:00.000Z"
}La respuesta de creación es un payload de confirmación que contiene id, merchant_id, email, name y created_at. Para leer el objeto cliente completo, llama a GET /api/v1/customers/:id.
Cuando el correo electrónico ya existe, se devuelve el mismo cuerpo con estado 200 OK en lugar de 201.
GET/api/v1/customers
Auth: Merchant key (scope customers:read)
Lista los clientes del Merchant, del más reciente al más antiguo. Admite un filtro email y paginación.
Parámetros de consulta
| Field | Type | Required | Description |
|---|---|---|---|
email | string | No | Filtro de correo electrónico exacto, sin distinción entre mayúsculas y minúsculas. |
page | integer | No | Número de página (predeterminado 1, mínimo 1). |
limit | integer | No | Elementos por página (predeterminado 20, máx. 100). |
Solicitud
curl -X GET "https://api.tokeflow.com/api/v1/customers?page=1&limit=20&email=joao@example.com" \
-H "Authorization: Bearer sk_live_mer_xxxxxxxxxxxxxxxxxxxxxxxx"Respuesta 200 OK
{
"success": true,
"data": [
{
"id": "cust_a1b2c3d4e5",
"merchant_id": "mrc_9f8e7d6c5b",
"email": "joao@example.com",
"name": "Joao da Silva",
"phone": "+5511999990000",
"document_type": "cpf",
"metadata": { "source": "checkout_web" },
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z"
}
],
"meta": {
"pagination": {
"page": 1,
"limit": 20,
"total": 42,
"total_pages": 3,
"has_next": true,
"has_prev": false
}
},
"request_id": "req_8f3c1a2b4d",
"timestamp": "2026-01-15T12:30:00.000Z"
}Como el correo electrónico es único por Merchant, filtrar por email devuelve como máximo un cliente — una forma conveniente de consulta antes de decidir si crear uno nuevo.
GET/api/v1/customers/:customerId
Auth: Merchant key (scope customers:read)
Recupera un único cliente por ID.
Parámetros de ruta
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Sí | ID del cliente, con prefijo cust_. |
Solicitud
curl -X GET https://api.tokeflow.com/api/v1/customers/cust_a1b2c3d4e5 \
-H "Authorization: Bearer sk_live_mer_xxxxxxxxxxxxxxxxxxxxxxxx"Respuesta 200 OK
{
"success": true,
"data": {
"id": "cust_a1b2c3d4e5",
"merchant_id": "mrc_9f8e7d6c5b",
"email": "joao@example.com",
"name": "Joao da Silva",
"phone": "+5511999990000",
"document_type": "cpf",
"metadata": { "source": "checkout_web" },
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z"
},
"request_id": "req_8f3c1a2b4d",
"timestamp": "2026-01-15T12:30:00.000Z"
}Respuesta 404 Not Found
{
"error": {
"type": "not_found_error",
"code": "RESOURCE_NOT_FOUND",
"message": "Customer with ID \"cust_a1b2c3d4e5\" not found",
"details": {},
"request_id": "req_8f3c1a2b4d",
"timestamp": "2026-01-15T12:30:00.000Z"
}
}PATCH/api/v1/customers/:customerId
Auth: Merchant key (scope customers:write)
Actualiza un cliente. Todos los campos del cuerpo son opcionales; solo se modifican los campos enviados. Cambiar el email a uno ya utilizado por otro cliente del Merchant devuelve 409 Conflict.
Parámetros de ruta
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Sí | ID del cliente, con prefijo cust_. |
Parámetros del cuerpo
| Field | Type | Required | Description |
|---|---|---|---|
email | string | No | Nuevo correo electrónico. Debe ser único por Merchant. |
name | string | No | Nuevo nombre. |
phone | string | No | Nuevo teléfono en formato E.164. |
document_type | string | No | Uno de cpf, cnpj, passport, tax_id. |
document_number | string | No | Documento fiscal (máx. 40 caracteres). Nunca se devuelve. |
metadata | object | No | Reemplaza los metadatos almacenados. Máximo de 5 KB serializado. |
billing_address | object | No | Dirección de facturación (mismo formato que en la creación). |
Solicitud
curl -X PATCH https://api.tokeflow.com/api/v1/customers/cust_a1b2c3d4e5 \
-H "Authorization: Bearer sk_live_mer_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Joao P. da Silva",
"phone": "+5511988887777",
"metadata": { "source": "checkout_web", "tier": "gold" }
}'Respuesta 200 OK
{
"success": true,
"data": {
"id": "cust_a1b2c3d4e5",
"merchant_id": "mrc_9f8e7d6c5b",
"email": "joao@example.com",
"name": "Joao P. da Silva",
"phone": "+5511988887777",
"document_type": "cpf",
"metadata": { "source": "checkout_web", "tier": "gold" },
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T13:05:00.000Z"
},
"request_id": "req_8f3c1a2b4d",
"timestamp": "2026-01-15T13:05:00.000Z"
}Respuesta 409 Conflict
Se devuelve cuando el nuevo email ya pertenece a otro cliente del Merchant. El ID del cliente en conflicto se incluye en details.
{
"error": {
"type": "conflict_error",
"code": "CUSTOMER_EMAIL_EXISTS",
"message": "A customer with this email already exists for this merchant",
"details": { "existing_customer_id": "cust_f6e5d4c3b2" },
"request_id": "req_8f3c1a2b4d",
"timestamp": "2026-01-15T13:05:00.000Z"
}
}DELETE/api/v1/customers/:customerId
Auth: Organization key (with merchant_id) or Merchant key.
Elimina permanentemente un cliente sin historial. Un cliente con cualquier suscripción, pedido, transacción, método de pago guardado o registro en un proveedor de pago es rechazado con 409, porque los clientes con actividad se conservan para informes y conciliación. Espera que el rechazo sea el resultado común: esto existe para un cliente creado por error — una errata, un duplicado, datos de prueba. El correo electrónico queda disponible para crear un cliente nuevo.
Parámetros de ruta
| Field | Type | Required | Description |
|---|---|---|---|
customerId | string | Sí | ID del cliente |
Ejemplo de solicitud
curl -X DELETE https://api.tokeflow.com/api/v1/customers/cust_2f9a71d4 \
-H "Authorization: Bearer sk_live_mer_…"Ejemplo de respuesta — 204 No Content
Se devuelve un cuerpo vacío en caso de éxito.
Errores
Los endpoints de clientes usan el envoltorio de error estándar de Tokeflow. Casos comunes:
| HTTP | type | Cuándo |
|---|---|---|
| 400 | validation_error | Campo ausente/inválido, document_type inválido, teléfono malformado, o metadata que supera 5 KB. |
| 401 | authentication_error | Clave de API ausente o inválida. |
| 403 | authorization_error | La clave carece del alcance necesario, o se utilizó una clave que no es de Merchant. |
| 404 | not_found_error | No existe ningún cliente con ese ID para este Merchant. |
| 409 | conflict_error | Correo electrónico ya en uso por otro cliente (PATCH). |
| 429 | rate_limit_error | Límite de tasa excedido — reduce la frecuencia exponencialmente. |
Relacionados
- Transacciones — cobrar a un cliente.
- Pedidos — agrupar las compras de un cliente.
- Suscripciones — facturación recurrente para un cliente.
- Autenticación — claves, alcances y encabezados.