Clientes
Los usuarios de tu sistema que pagan una suscripción, y sus medios de pago.
Registrar un cliente
POST/v1/customers
Registra al usuario de tu sistema que va a pagar, en el entorno de la
API key. external_id (tu id del usuario, 1–255 caracteres) es único
por entorno: repetido → 409 customer_external_id_taken con el id del
cliente existente en error.resource_id y error.param
external_id; en el otro entorno se puede repetir. email obligatorio (se guarda en minúsculas); phone
opcional, se normaliza a E.164 (un número de 10 dígitos se toma como
colombiano, +57); documento opcional (legal_id_type CC, CE, NIT o
PP, con su legal_id_number); metadata hasta 20 llaves (1–40
caracteres) con valores de hasta 500. Errores 422:
invalid_external_id, invalid_email, invalid_full_name,
invalid_phone, invalid_legal_id, invalid_metadata.
Los medios de pago no se crean aquí: el cliente final registra su tarjeta en la página de pago (sesiones de checkout).
Autenticación: Authorization: Bearer <API key>. Acepta Idempotency-Key.
Parámetros
| Parámetro | En | Tipo | Descripción |
|---|---|---|---|
Idempotency-Key | cabecera | string | Clave elegida por el cliente (1–255 caracteres ASCII visibles; se
recomienda un UUID v4) para reintentar un
Ejemplo: |
Cuerpo (application/json, RegisterCustomerRequest)
| Campo | Tipo | Descripción |
|---|---|---|
external_idobligatorio | string | Ejemplo: |
emailobligatorio | string (email) | |
full_name | string | |
phone | string | E.164 ( +573001234567) o número colombiano de 10 dígitos. |
legal_id_type | string | Valores: |
legal_id_number | string | |
metadata | object<string, string> |
Respuestas
201Cliente registrado (o la misma respuesta repetida, con Idempotent-Replayed).
Esquema Customer
| Campo | Tipo | Descripción |
|---|---|---|
idobligatorio | string | Ejemplo: |
environmentobligatorio | string | Valores: |
external_idobligatorio | string | Id del usuario en tu sistema (inmutable). |
emailobligatorio | string (email) | |
full_nameobligatorio | string | null | |
phoneobligatorio | string | null | E.164 Ejemplo: |
legal_id_typeobligatorio | string | null | Valores: |
legal_id_numberobligatorio | string | null | |
metadataobligatorio | object<string, string> | |
payment_methodsobligatorio | array<PaymentMethod> | |
payment_methods[].idobligatorio | string | Ejemplo: |
payment_methods[].typeobligatorio | string | Valores: |
payment_methods[].brandobligatorio | string | null | Marca de la tarjeta (VISA, MASTERCARD, …), NEQUI o el tipo de cuenta Bancolombia.Ejemplo: |
payment_methods[].last4obligatorio | string | null | Últimos 4 de la tarjeta, del celular Nequi o de la cuenta Bancolombia. Ejemplo: |
payment_methods[].exp_monthobligatorio | integer | null | |
payment_methods[].exp_yearobligatorio | integer | null | |
payment_methods[].is_defaultobligatorio | boolean | Exactamente un medio ACTIVE es el predeterminado (si hay alguno). |
payment_methods[].statusobligatorio | string | Valores: |
payment_methods[].created_atobligatorio | string (date-time) | RFC 3339 en UTC. |
created_atobligatorio | string (date-time) | RFC 3339 en UTC. |
updated_atobligatorio | string (date-time) | RFC 3339 en UTC. |
Idempotent-Replayed:truesi la respuesta es la guardada de una petición anterior con la mismaIdempotency-Key.
Errores
- 400
JSON mal formado o tipos inválidos (p. ej. decimales donde va un entero) (
codeinvalid_body).- 401
Credencial ausente, inválida, expirada o revocada (
codeunauthorized).- 409
Conflicto.
code:already_member,api_key_limit_exceeded,last_owner,invitation_expired,invitation_not_pending,webhook_endpoint_limit_exceeded,plan_name_taken(paramname),customer_external_id_taken(conresource_idyparamexternal_id; enPOST /v1/checkout-sessions,customer.external_id),last_payment_method_in_use,payment_method_not_active,idempotency_key_in_use,tenant_not_ready(el entorno no tiene credenciales de Wompi verificadas),checkout_session_completed,checkout_session_expired,checkout_session_canceled,plan_archived,subscription_exists(conresource_id),subscription_version_conflict(reintenta),payment_method_required,subscription_not_pausable,subscription_not_paused,subscription_not_changeable,subscription_cancel_at_period_end_not_allowed,subscription_cancel_not_scheduled,portal_disabled(el tenant deshabilitó el portal en el entorno).- 422
La entrada no cumple las reglas (
typeinvalid_request;paramindica el campo).- 429
Demasiadas peticiones (
typerate_limited,coderate_limited): más de 100 peticiones por segundo con la misma API key. Reintenta cuando indiqueRetry-After.- Otros
Error con el formato estándar.
Todos con el formato de error estándar.
curl -X POST https://api.paygumi.com/v1/customers \
-H "Authorization: Bearer pgm_test_..." \
-H "Idempotency-Key: 3f0c1d7e-8b1a-4f3e-9a51-6d2b7c9e0a14" \
-H "Content-Type: application/json" \
-d '{
"external_id": "user_42",
"email": "cliente@ejemplo.co"
}'{
"id": "cus_01JB86R800ABCDEFGHJKMNPQRS",
"environment": "SANDBOX",
"external_id": "string",
"email": "cliente@ejemplo.co",
"full_name": "string",
"phone": "+573001234567",
"legal_id_type": "CC",
"legal_id_number": "string",
"metadata": {},
"payment_methods": [
{
"id": "pm_01JB86R800ABCDEFGHJKMNPQRS",
"type": "CARD",
"brand": "VISA",
"last4": "4242",
"exp_month": 1,
"exp_year": 0,
"is_default": false,
"status": "ACTIVE",
"created_at": "2026-11-01T05:00:00Z"
}
],
"created_at": "2026-11-01T05:00:00Z",
"updated_at": "2026-11-01T05:00:00Z"
}Ver un cliente
GET/v1/customers/{id}
El cliente con sus medios de pago activos o inválidos (sin datos
sensibles: marca, últimos 4 y expiración; nunca el número de la
tarjeta ni el id de la fuente de Wompi) y el resumen de sus
suscripciones. De otro entorno → 404 customer_not_found.
Autenticación: Authorization: Bearer <API key>.
Parámetros
| Parámetro | En | Tipo | Descripción |
|---|---|---|---|
idobligatorio | ruta | string | Id del cliente ( cus_…). Uno mal formado responde 404.Ejemplo: |
Respuestas
200El cliente.
Esquema CustomerDetail
| Campo | Tipo | Descripción |
|---|---|---|
idobligatorio | string | Ejemplo: |
environmentobligatorio | string | Valores: |
external_idobligatorio | string | Id del usuario en tu sistema (inmutable). |
emailobligatorio | string (email) | |
full_nameobligatorio | string | null | |
phoneobligatorio | string | null | E.164 Ejemplo: |
legal_id_typeobligatorio | string | null | Valores: |
legal_id_numberobligatorio | string | null | |
metadataobligatorio | object<string, string> | |
payment_methodsobligatorio | array<PaymentMethod> | |
payment_methods[].idobligatorio | string | Ejemplo: |
payment_methods[].typeobligatorio | string | Valores: |
payment_methods[].brandobligatorio | string | null | Marca de la tarjeta (VISA, MASTERCARD, …), NEQUI o el tipo de cuenta Bancolombia.Ejemplo: |
payment_methods[].last4obligatorio | string | null | Últimos 4 de la tarjeta, del celular Nequi o de la cuenta Bancolombia. Ejemplo: |
payment_methods[].exp_monthobligatorio | integer | null | |
payment_methods[].exp_yearobligatorio | integer | null | |
payment_methods[].is_defaultobligatorio | boolean | Exactamente un medio ACTIVE es el predeterminado (si hay alguno). |
payment_methods[].statusobligatorio | string | Valores: |
payment_methods[].created_atobligatorio | string (date-time) | RFC 3339 en UTC. |
created_atobligatorio | string (date-time) | RFC 3339 en UTC. |
updated_atobligatorio | string (date-time) | RFC 3339 en UTC. |
subscriptionsobligatorio | array<SubscriptionSummary> | Resumen de las suscripciones del cliente, más recientes primero. |
subscriptions[].idobligatorio | string | Ejemplo: |
subscriptions[].statusobligatorio | string | |
subscriptions[].access_statusobligatorio | string | Valores: |
subscriptions[].plan_nameobligatorio | string |
Errores
- 401
Credencial ausente, inválida, expirada o revocada (
codeunauthorized).- 404
El recurso no existe o es de otro tenant (nunca 403, para no filtrar existencia).
- 429
Demasiadas peticiones (
typerate_limited,coderate_limited): más de 100 peticiones por segundo con la misma API key. Reintenta cuando indiqueRetry-After.- Otros
Error con el formato estándar.
Todos con el formato de error estándar.
curl https://api.paygumi.com/v1/customers/{id} \
-H "Authorization: Bearer pgm_test_..."{
"id": "cus_01JB86R800ABCDEFGHJKMNPQRS",
"environment": "SANDBOX",
"external_id": "string",
"email": "cliente@ejemplo.co",
"full_name": "string",
"phone": "+573001234567",
"legal_id_type": "CC",
"legal_id_number": "string",
"metadata": {},
"payment_methods": [
{
"id": "pm_01JB86R800ABCDEFGHJKMNPQRS",
"type": "CARD",
"brand": "VISA",
"last4": "4242",
"exp_month": 1,
"exp_year": 0,
"is_default": false,
"status": "ACTIVE",
"created_at": "2026-11-01T05:00:00Z"
}
],
"created_at": "2026-11-01T05:00:00Z",
"updated_at": "2026-11-01T05:00:00Z",
"subscriptions": [
{
"id": "sub_01JB86R800ABCDEFGHJKMNPQRS",
"status": "string",
"access_status": "GRANTED",
"plan_name": "string"
}
]
}Editar un cliente
PATCH/v1/customers/{id}
Cambia email, full_name, phone ("" lo borra) y metadata
(reemplaza el mapa completo; {} lo borra). Campos ausentes no cambian.
external_id es inmutable: enviarlo distinto → 422 external_id_immutable. Cambiar el email no cambia el de la fuente de
pago en Wompi; los cobros siguientes usan el nuevo.
Autenticación: Authorization: Bearer <API key>.
Parámetros
| Parámetro | En | Tipo | Descripción |
|---|---|---|---|
idobligatorio | ruta | string | Id del cliente ( cus_…). Uno mal formado responde 404.Ejemplo: |
Cuerpo (application/json, UpdateCustomerRequest)
Campos ausentes (o null) no cambian.
| Campo | Tipo | Descripción |
|---|---|---|
email | string (email) | |
full_name | string | |
phone | string | "" borra el teléfono. |
metadata | object<string, string> | Reemplaza el mapa completo; {} lo borra. |
external_id | string | Inmutable; solo se acepta el valor actual. |
Respuestas
200Cliente actualizado.
Esquema Customer
| Campo | Tipo | Descripción |
|---|---|---|
idobligatorio | string | Ejemplo: |
environmentobligatorio | string | Valores: |
external_idobligatorio | string | Id del usuario en tu sistema (inmutable). |
emailobligatorio | string (email) | |
full_nameobligatorio | string | null | |
phoneobligatorio | string | null | E.164 Ejemplo: |
legal_id_typeobligatorio | string | null | Valores: |
legal_id_numberobligatorio | string | null | |
metadataobligatorio | object<string, string> | |
payment_methodsobligatorio | array<PaymentMethod> | |
payment_methods[].idobligatorio | string | Ejemplo: |
payment_methods[].typeobligatorio | string | Valores: |
payment_methods[].brandobligatorio | string | null | Marca de la tarjeta (VISA, MASTERCARD, …), NEQUI o el tipo de cuenta Bancolombia.Ejemplo: |
payment_methods[].last4obligatorio | string | null | Últimos 4 de la tarjeta, del celular Nequi o de la cuenta Bancolombia. Ejemplo: |
payment_methods[].exp_monthobligatorio | integer | null | |
payment_methods[].exp_yearobligatorio | integer | null | |
payment_methods[].is_defaultobligatorio | boolean | Exactamente un medio ACTIVE es el predeterminado (si hay alguno). |
payment_methods[].statusobligatorio | string | Valores: |
payment_methods[].created_atobligatorio | string (date-time) | RFC 3339 en UTC. |
created_atobligatorio | string (date-time) | RFC 3339 en UTC. |
updated_atobligatorio | string (date-time) | RFC 3339 en UTC. |
Errores
- 400
JSON mal formado o tipos inválidos (p. ej. decimales donde va un entero) (
codeinvalid_body).- 401
Credencial ausente, inválida, expirada o revocada (
codeunauthorized).- 404
El recurso no existe o es de otro tenant (nunca 403, para no filtrar existencia).
- 422
La entrada no cumple las reglas (
typeinvalid_request;paramindica el campo).- 429
Demasiadas peticiones (
typerate_limited,coderate_limited): más de 100 peticiones por segundo con la misma API key. Reintenta cuando indiqueRetry-After.- Otros
Error con el formato estándar.
Todos con el formato de error estándar.
curl -X PATCH https://api.paygumi.com/v1/customers/{id} \
-H "Authorization: Bearer pgm_test_..."{
"id": "cus_01JB86R800ABCDEFGHJKMNPQRS",
"environment": "SANDBOX",
"external_id": "string",
"email": "cliente@ejemplo.co",
"full_name": "string",
"phone": "+573001234567",
"legal_id_type": "CC",
"legal_id_number": "string",
"metadata": {},
"payment_methods": [
{
"id": "pm_01JB86R800ABCDEFGHJKMNPQRS",
"type": "CARD",
"brand": "VISA",
"last4": "4242",
"exp_month": 1,
"exp_year": 0,
"is_default": false,
"status": "ACTIVE",
"created_at": "2026-11-01T05:00:00Z"
}
],
"created_at": "2026-11-01T05:00:00Z",
"updated_at": "2026-11-01T05:00:00Z"
}Quitar un medio de pago
DELETE/v1/customers/{id}/payment-methods/{pmId}
Borrado lógico: el medio deja de mostrarse y de cobrarse; los cobros
históricos lo siguen referenciando. Si era el predeterminado, el activo
más reciente pasa a serlo, y las suscripciones que lo usaban pasan al
predeterminado. Es el único activo y el cliente tiene suscripciones
vivas → 409 last_payment_method_in_use. Ya quitado o inexistente →
404 payment_method_not_found. Responde el cliente actualizado.
Autenticación: Authorization: Bearer <API key>.
Parámetros
| Parámetro | En | Tipo | Descripción |
|---|---|---|---|
idobligatorio | ruta | string | Id del cliente ( cus_…). Uno mal formado responde 404.Ejemplo: |
pmIdobligatorio | ruta | string | Id del medio de pago ( pm_…). Uno mal formado responde 404.Ejemplo: |
Respuestas
200Cliente actualizado (sin el medio quitado).
Esquema Customer
| Campo | Tipo | Descripción |
|---|---|---|
idobligatorio | string | Ejemplo: |
environmentobligatorio | string | Valores: |
external_idobligatorio | string | Id del usuario en tu sistema (inmutable). |
emailobligatorio | string (email) | |
full_nameobligatorio | string | null | |
phoneobligatorio | string | null | E.164 Ejemplo: |
legal_id_typeobligatorio | string | null | Valores: |
legal_id_numberobligatorio | string | null | |
metadataobligatorio | object<string, string> | |
payment_methodsobligatorio | array<PaymentMethod> | |
payment_methods[].idobligatorio | string | Ejemplo: |
payment_methods[].typeobligatorio | string | Valores: |
payment_methods[].brandobligatorio | string | null | Marca de la tarjeta (VISA, MASTERCARD, …), NEQUI o el tipo de cuenta Bancolombia.Ejemplo: |
payment_methods[].last4obligatorio | string | null | Últimos 4 de la tarjeta, del celular Nequi o de la cuenta Bancolombia. Ejemplo: |
payment_methods[].exp_monthobligatorio | integer | null | |
payment_methods[].exp_yearobligatorio | integer | null | |
payment_methods[].is_defaultobligatorio | boolean | Exactamente un medio ACTIVE es el predeterminado (si hay alguno). |
payment_methods[].statusobligatorio | string | Valores: |
payment_methods[].created_atobligatorio | string (date-time) | RFC 3339 en UTC. |
created_atobligatorio | string (date-time) | RFC 3339 en UTC. |
updated_atobligatorio | string (date-time) | RFC 3339 en UTC. |
Errores
- 401
Credencial ausente, inválida, expirada o revocada (
codeunauthorized).- 404
El recurso no existe o es de otro tenant (nunca 403, para no filtrar existencia).
- 409
Conflicto.
code:already_member,api_key_limit_exceeded,last_owner,invitation_expired,invitation_not_pending,webhook_endpoint_limit_exceeded,plan_name_taken(paramname),customer_external_id_taken(conresource_idyparamexternal_id; enPOST /v1/checkout-sessions,customer.external_id),last_payment_method_in_use,payment_method_not_active,idempotency_key_in_use,tenant_not_ready(el entorno no tiene credenciales de Wompi verificadas),checkout_session_completed,checkout_session_expired,checkout_session_canceled,plan_archived,subscription_exists(conresource_id),subscription_version_conflict(reintenta),payment_method_required,subscription_not_pausable,subscription_not_paused,subscription_not_changeable,subscription_cancel_at_period_end_not_allowed,subscription_cancel_not_scheduled,portal_disabled(el tenant deshabilitó el portal en el entorno).- 429
Demasiadas peticiones (
typerate_limited,coderate_limited): más de 100 peticiones por segundo con la misma API key. Reintenta cuando indiqueRetry-After.- Otros
Error con el formato estándar.
Todos con el formato de error estándar.
curl -X DELETE https://api.paygumi.com/v1/customers/{id}/payment-methods/{pmId} \
-H "Authorization: Bearer pgm_test_..."{
"id": "cus_01JB86R800ABCDEFGHJKMNPQRS",
"environment": "SANDBOX",
"external_id": "string",
"email": "cliente@ejemplo.co",
"full_name": "string",
"phone": "+573001234567",
"legal_id_type": "CC",
"legal_id_number": "string",
"metadata": {},
"payment_methods": [
{
"id": "pm_01JB86R800ABCDEFGHJKMNPQRS",
"type": "CARD",
"brand": "VISA",
"last4": "4242",
"exp_month": 1,
"exp_year": 0,
"is_default": false,
"status": "ACTIVE",
"created_at": "2026-11-01T05:00:00Z"
}
],
"created_at": "2026-11-01T05:00:00Z",
"updated_at": "2026-11-01T05:00:00Z"
}Marcar un medio de pago como predeterminado
POST/v1/customers/{id}/payment-methods/{pmId}/default
Los próximos cobros de las suscripciones sin medio explícito usan este.
Exactamente un medio es el predeterminado. Idempotente. Un medio
INVALID → 409 payment_method_not_active. Responde el cliente
actualizado. Acepta Idempotency-Key.
Autenticación: Authorization: Bearer <API key>. Acepta Idempotency-Key.
Parámetros
| Parámetro | En | Tipo | Descripción |
|---|---|---|---|
idobligatorio | ruta | string | Id del cliente ( cus_…). Uno mal formado responde 404.Ejemplo: |
pmIdobligatorio | ruta | string | Id del medio de pago ( pm_…). Uno mal formado responde 404.Ejemplo: |
Idempotency-Key | cabecera | string | Clave elegida por el cliente (1–255 caracteres ASCII visibles; se
recomienda un UUID v4) para reintentar un
Ejemplo: |
Respuestas
200Cliente actualizado.
Esquema Customer
| Campo | Tipo | Descripción |
|---|---|---|
idobligatorio | string | Ejemplo: |
environmentobligatorio | string | Valores: |
external_idobligatorio | string | Id del usuario en tu sistema (inmutable). |
emailobligatorio | string (email) | |
full_nameobligatorio | string | null | |
phoneobligatorio | string | null | E.164 Ejemplo: |
legal_id_typeobligatorio | string | null | Valores: |
legal_id_numberobligatorio | string | null | |
metadataobligatorio | object<string, string> | |
payment_methodsobligatorio | array<PaymentMethod> | |
payment_methods[].idobligatorio | string | Ejemplo: |
payment_methods[].typeobligatorio | string | Valores: |
payment_methods[].brandobligatorio | string | null | Marca de la tarjeta (VISA, MASTERCARD, …), NEQUI o el tipo de cuenta Bancolombia.Ejemplo: |
payment_methods[].last4obligatorio | string | null | Últimos 4 de la tarjeta, del celular Nequi o de la cuenta Bancolombia. Ejemplo: |
payment_methods[].exp_monthobligatorio | integer | null | |
payment_methods[].exp_yearobligatorio | integer | null | |
payment_methods[].is_defaultobligatorio | boolean | Exactamente un medio ACTIVE es el predeterminado (si hay alguno). |
payment_methods[].statusobligatorio | string | Valores: |
payment_methods[].created_atobligatorio | string (date-time) | RFC 3339 en UTC. |
created_atobligatorio | string (date-time) | RFC 3339 en UTC. |
updated_atobligatorio | string (date-time) | RFC 3339 en UTC. |
Idempotent-Replayed:truesi la respuesta es la guardada de una petición anterior con la mismaIdempotency-Key.
Errores
- 401
Credencial ausente, inválida, expirada o revocada (
codeunauthorized).- 404
El recurso no existe o es de otro tenant (nunca 403, para no filtrar existencia).
- 409
Conflicto.
code:already_member,api_key_limit_exceeded,last_owner,invitation_expired,invitation_not_pending,webhook_endpoint_limit_exceeded,plan_name_taken(paramname),customer_external_id_taken(conresource_idyparamexternal_id; enPOST /v1/checkout-sessions,customer.external_id),last_payment_method_in_use,payment_method_not_active,idempotency_key_in_use,tenant_not_ready(el entorno no tiene credenciales de Wompi verificadas),checkout_session_completed,checkout_session_expired,checkout_session_canceled,plan_archived,subscription_exists(conresource_id),subscription_version_conflict(reintenta),payment_method_required,subscription_not_pausable,subscription_not_paused,subscription_not_changeable,subscription_cancel_at_period_end_not_allowed,subscription_cancel_not_scheduled,portal_disabled(el tenant deshabilitó el portal en el entorno).- 422
La entrada no cumple las reglas (
typeinvalid_request;paramindica el campo).- 429
Demasiadas peticiones (
typerate_limited,coderate_limited): más de 100 peticiones por segundo con la misma API key. Reintenta cuando indiqueRetry-After.- Otros
Error con el formato estándar.
Todos con el formato de error estándar.
curl -X POST https://api.paygumi.com/v1/customers/{id}/payment-methods/{pmId}/default \
-H "Authorization: Bearer pgm_test_..." \
-H "Idempotency-Key: 3f0c1d7e-8b1a-4f3e-9a51-6d2b7c9e0a14"{
"id": "cus_01JB86R800ABCDEFGHJKMNPQRS",
"environment": "SANDBOX",
"external_id": "string",
"email": "cliente@ejemplo.co",
"full_name": "string",
"phone": "+573001234567",
"legal_id_type": "CC",
"legal_id_number": "string",
"metadata": {},
"payment_methods": [
{
"id": "pm_01JB86R800ABCDEFGHJKMNPQRS",
"type": "CARD",
"brand": "VISA",
"last4": "4242",
"exp_month": 1,
"exp_year": 0,
"is_default": false,
"status": "ACTIVE",
"created_at": "2026-11-01T05:00:00Z"
}
],
"created_at": "2026-11-01T05:00:00Z",
"updated_at": "2026-11-01T05:00:00Z"
}