Suscriptores (Customers)


¿Qué es un suscriptor?

Un suscriptor es tu cliente dentro de nuestro sistema: guarda su identidad y sus datos de facturación, y es a quien después le asocias un plan para crear la suscripción.

Créalo una sola vez y reutilízalo: un mismo suscriptor puede tener varias suscripciones y varias tarjetas guardadas, con una marcada como predeterminada (default_payment_method).

{info} Nombre alternativo (estilo Stripe). Cada ruta de esta página existe también bajo customer, con el mismo comportamiento y la misma respuesta:

Nombre original Alias
GET /api/v1/subscriptions/subscriber GET /api/v1/subscriptions/customer
GET /api/v1/subscriptions/subscriber/{emailOrId} GET /api/v1/subscriptions/customer/{emailOrId}
POST /api/v1/subscriptions/subscriber POST /api/v1/subscriptions/customer
PUT /api/v1/subscriptions/subscriber/{id} PUT /api/v1/subscriptions/customer/{id}
DELETE /api/v1/subscriptions/subscriber/{id} DELETE /api/v1/subscriptions/customer/{id}

{warning} El correo es único por sucursal, no por comercio. El mismo cliente en dos sucursales son dos suscriptores distintos.

Listar suscriptores

Descripción: Devuelve todos los suscriptores de las sucursales a las que tienes acceso.

GET /api/v1/subscriptions/subscriber

{warning} Este listado no está paginado, no viene envuelto en data y no separa por ambiente: es el arreglo completo de suscriptores, en snake_case. Si tienes muchos clientes, la respuesta puede ser grande.

curl -X GET \
'/api/v1/subscriptions/subscriber' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Accept: application/json'

{success} Respuesta satisfactoria code: 200

[
{
"id": "9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f",
"identification_type": "CC",
"id_number": "1020304050",
"name": "Ana",
"last_name": "Gómez",
"email": "ana@ejemplo.com",
"phone_code": 57,
"cellphone_number": "3001234567",
"billing_address": "Calle 100 # 20-30",
"billing_city": "Bogotá",
"billing_country": "Colombia",
"office_id": 1,
"commerce_id": 42,
"created_at": "2026-07-31 10:15:00"
}
]

Buscar un suscriptor

Descripción: Devuelve un suscriptor por su id, su correo o su número de documento. El mismo endpoint acepta las tres cosas, así que no necesitas guardar nuestro id si ya tienes cualquiera de los otros dos.

GET /api/v1/subscriptions/subscriber/{emailOrId}

Puedes buscar por Ejemplo
Id (uuid) /subscriber/9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f
Correo /subscriber/ana@ejemplo.com
Documento /subscriber/1020304050

{info} La búsqueda queda acotada a tu comercio y a las sucursales a las que tenga acceso el usuario del token. Un documento que exista en otro comercio devuelve 404.

curl -X GET \
'/api/v1/subscriptions/subscriber/ana@ejemplo.com' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Accept: application/json'

{success} Respuesta satisfactoria code: 200

{
"id": "9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f",
"identification_type": "CC",
"id_number": "1020304050",
"name": "Ana",
"last_name": "Gómez",
"email": "ana@ejemplo.com",
"phone_code": 57,
"cellphone_number": "3001234567",
"billing_address": "Calle 100 # 20-30",
"billing_city": "Bogotá",
"billing_country": "Colombia",
"default_payment_method_id": "9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e81",
"balance": 0,
"currency": "COP",
"active": true,
"office_id": 1,
"commerce_id": 42,
"created_at": "2026-07-31 10:15:00"
}

{danger} No existe, o no pertenece a una sucursal a la que tengas acceso code: 404

Cuándo deja de servir un subscriber_id

Un id que guardaste y que funcionaba puede empezar a devolver 422 al crear una suscripción. Hay tres causas y cada una tiene su propio mensaje en errors.subscriber_id:

Mensaje Qué pasó Cómo se arregla
«El suscriptor pertenece a la sucursal N y estás enviando office=M» El suscriptor vive en otra sede Manda el office de su sede, o crea el suscriptor en la sede que estás usando
«El suscriptor fue eliminado» Alguien lo borró. La fila sigue existiendo, por eso el id "parece" válido Créalo de nuevo
«El suscriptor pertenece a otro comercio» El token es de otro comercio Revisa el token
«No existe un suscriptor con ese id» El id nunca existió Revisa el id

{danger} La causa más común es la sucursal. El suscriptor y el plan deben ser de la misma sede que el office que mandas al crear la suscripción. Los tres tienen que coincidir; si no, el 422 llega aunque el id sea correcto.

Lo que no invalida un suscriptor:

  • El paso del tiempo. Un subscriber_id no caduca.
  • Tokenizar o cambiar la tarjeta. Las tarjetas cuelgan del suscriptor; cambiarlas no lo toca.
  • El ambiente. A diferencia de planes y suscripciones, los suscriptores no tienen eje prueba/producción: el mismo suscriptor sirve para ambos.

{success} Si dudas de un id guardado, confírmalo antes de cobrar con GET /api/v1/subscriptions/subscriber/{id}. Un 200 te devuelve además su office_id, que es el que debes mandar como office.

Crear suscriptor

Descripción: Registra un cliente. Los datos de facturación son obligatorios porque viajan a la red en cada cobro recurrente.

POST /api/v1/subscriptions/subscriber

Nombre del campo Descripción Reglas
identification_type Tipo de documento. Ver enumeraciones ['required', 'string', 'in:CC,CE,TI,PPT,DNI,NIT,Pasaporte,Otro']
id_number Número de documento. No puede ser un número de tarjeta: lo rechazamos a propósito ['required', 'numeric', 'digits_between:5,15']
name Nombres del cliente ['required', 'string', 'max:255']
last_name Apellidos del cliente ['required', 'string', 'max:255']
email Correo del cliente. Único dentro de la sucursal ['required', 'email', 'max:255', 'unique:subscribers,email']
phone_code Indicativo del país, sin + (Colombia: 57) ['required', 'integer', 'min_digits:1', 'max_digits:3']
cellphone_number Celular. Se valida como número real del país que resulte de phone_code ['required', 'numeric', 'phone']
billing_address Dirección de facturación ['required', 'string', 'max:255']
billing_city Ciudad de facturación ['required', 'string', 'max:255']
billing_country País de facturación. Ver lista de países ['required', 'string', 'max:255']
office Sucursal a la que pertenece el suscriptor. Debe ser una de tus sucursales ['required', 'exists:offices,id']

curl -X POST \
'/api/v1/subscriptions/subscriber' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H "Content-type: application/json" \
-d '{
    "identification_type": "CC",
    "id_number": "1020304050",
    "name": "Ana",
    "last_name": "Gómez",
    "email": "ana@ejemplo.com",
    "phone_code": "57",
    "cellphone_number": "3001234567",
    "billing_address": "Calle 100 # 20-30",
    "billing_city": "Bogotá",
    "billing_country": "Colombia",
    "office": 1
}'

{success} Suscriptor creado code: 201

{
"saved": true,
"subscriber": {
"id": "9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f",
"name": "Ana",
"lastName": "Gómez",
"email": "ana@ejemplo.com",
"phoneCode": 57,
"cellphoneNumber": "3001234567",
"billingAddress": "Calle 100 # 20-30",
"billingCity": "Bogotá",
"billingCountry": "Colombia",
"active": true,
"subscriptionsCount": 0,
"activeSubscriptionsCount": 0,
"inactiveSubscriptionsCount": 0,
"createdAt": "2026-07-31 10:15:00"
}
}

{danger} Correo repetido en la misma sucursal code: 422

{
"message": "El campo email ya está en uso.",
"errors": {
"email": ["El campo email ya está en uso."]
}
}

Actualizar suscriptor

Descripción: Cambia los datos de un suscriptor. Envía solo los campos que quieres cambiar; los que omitas se quedan como estaban. El tipo y número de documento no se modifican, ni la sucursal.

PUT /api/v1/subscriptions/subscriber/{subscriber-id}

Nombre del campo Descripción Reglas
name Nombres del cliente ['sometimes', 'required', 'string', 'max:255']
last_name Apellidos del cliente ['sometimes', 'required', 'string', 'max:255']
email Nuevo correo. Único dentro de la misma sucursal, ignorando a este suscriptor ['sometimes', 'required', 'email', 'max:255', 'unique:subscribers,email']
phone_code Indicativo del país ['sometimes', 'required', 'integer', 'min_digits:1', 'max_digits:3']
cellphone_number Celular. Aquí no se valida contra el formato del país, a diferencia de crear ['sometimes', 'required', 'numeric']
billing_address Dirección de facturación ['sometimes', 'required', 'string', 'max:255']
billing_city Ciudad de facturación ['sometimes', 'required', 'string', 'max:255']
billing_country País de facturación ['sometimes', 'required', 'string', 'max:255']

curl -X PUT \
'/api/v1/subscriptions/subscriber/9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H "Content-type: application/json" \
-d '{
    "email": "ana.gomez@ejemplo.com",
    "cellphone_number": "3009876543"
}'

{success} Respuesta satisfactoria code: 200

{
"saved": true,
"subscriber": {
"id": "9b0f2a13-2c44-4a1a-9f2e-1d3b4c5d6e7f",
"name": "Ana",
"lastName": "Gómez",
"email": "ana.gomez@ejemplo.com",
"cellphoneNumber": "3009876543",
"subscriptionsCount": 2,
"activeSubscriptionsCount": 1,
"inactiveSubscriptionsCount": 1,
"createdAt": "2026-07-31 10:15:00"
}
}

Eliminar suscriptor

Descripción: Elimina un suscriptor.

DELETE /api/v1/subscriptions/subscriber/{subscriber-id}

{warning} No podrás eliminar un suscriptor que tenga una suscripción activa. Cancélala primero, o déjala terminar.

{success} Respuesta satisfactoria code: 200

{
"deleted": true
}

{danger} El suscriptor tiene una suscripción activa code: 400

{
"message": "Este suscriptor no puede ser eliminado ya que tiene una suscripción activa"
}

Alias customer

Las mismas operaciones, con el nombre de Stripe. Comportamiento, parámetros y respuestas son idénticos a los de arriba; solo cambia el segmento de la ruta.

ListarGET /api/v1/subscriptions/customer

Buscar por correo o idGET /api/v1/subscriptions/customer/{emailOrId}

CrearPOST /api/v1/subscriptions/customer

ActualizarPUT /api/v1/subscriptions/customer/{customer-id}

EliminarDELETE /api/v1/subscriptions/customer/{customer-id}