Product) sirve para agrupar y categorizar tus cobros (deudas, suscripciones y ligas de pago). Su uso es completamente opcional: puedes cobrar sin asociar ningún producto.
Lo usas cuando quieres reportar tus cobros por línea de producto o servicio, por ejemplo “Plan Premium”, “Cuota mensual gimnasio” o “Internet 100MB”.
Llave natural: name
El name es la llave natural del producto y es único por company. Si ya existe un producto activo con ese name, POST /products responde 201 con el producto existente, sin modificarlo: no genera un duplicado ni un error.
Por eso
POST /products es idempotente por diseño: repetir el mismo name te devuelve el mismo producto, tal como está guardado (si mandas otros valores en el body, se ignoran). La excepción es el externalProductId: si el producto existente ya tiene otro externalProductId, la API responde 409 RESOURCE_CONFLICT.Crear un producto
externalProductId y active), no el request.
El
productId es el ID público del producto, con prefijo prd_ (ej. prd_12985). En el path de GET, PATCH y DELETE /products/{id} también se acepta el número sin prefijo (12985); otros prefijos o valores no numéricos devuelven 404 RESOURCE_NOT_FOUND.string
Tu propio identificador del producto (opcional). Es el que después usas para referenciarlo al crear deudas, sin tener que guardar el
productId de Tapi. No admite los caracteres ', ", \ ni ; (devuelve 400).Validaciones
nameyexternalProductIdse recortan (trim) antes de guardarse.- Los campos no declarados en el body se ignoran.
- Si el
externalProductIdya lo usa otro producto, o si elnameya existe con otroexternalProductId, la API responde409 RESOURCE_CONFLICT(con el mismo mensaje en los dos casos).
Clientes con varias companies
Si tu cliente de TapiPay tiene una sola company, no tienes que indicar nada: todo lo que creas queda asociado a ella. Si tu cliente administra varias companies (por ejemplo, una red de escuelas donde cada escuela es una company de Tapi), indica en el body para cuál de ellas es el producto concompanyCode:
name y externalProductId son únicos por company, así que el mismo nombre puede existir en cada una de tus companies sin chocar. Para listar los productos de una company en particular usa GET /products?companyCode=MX-S-04937.
string
Company de Tapi (
MX-S-…) en la que se crea el producto. Opcional si tu cliente tiene una sola company. Debe pertenecer a tu cliente.Esta regla aplica a toda la API, no solo a productos: un cliente con varias companies indica
companyCode en cada request (en el body en POST/PATCH, o como ?companyCode= en GET). En un PATCH, el companyCode del body se toma como contexto y no como un campo a modificar. Ver Convenciones de la API. Al crear deudas con POST /v2/debts, el producto se busca dentro de la company del request: un producto de una company no puede usarse en una deuda de otra.Referenciar un producto en una deuda
Al crear una deuda conPOST /v2/debts, el producto debe existir de antemano y se referencia por productId (formato prd_<número>; otro formato devuelve 400 INVALID_REQUEST) o por externalProductId (uno solo; enviar los dos devuelve 400). El endpoint de deudas no crea productos: enviar productName devuelve 400 INVALID_REQUEST, y referenciar un producto inexistente devuelve 404 RESOURCE_NOT_FOUND sin crear la deuda.
Creación en línea (productName)
En suscripciones y ligas de pago puedes enviar el producto en línea con el campo productName: si el nombre no existe, se crea; si ya existe, se reutiliza sin duplicarlo.
createdInline es true si el producto se creó en esa misma petición, y false si ya existía y se reutilizó. En deudas es siempre false.
Listar productos
GET /products devuelve solo productos activos, ordenados por productId descendente.
La paginación usa
page (default 1) y limit (default 50, máximo 500). Ver Convenciones de la API.
Actualizar
PATCH /products/{id} acepta solo dos campos:
string
Nuevo nombre, string no vacío. Si ya lo usa otro producto, incluso uno inactivo, devuelve
409 RESOURCE_CONFLICT.boolean
Solo
true o false. active: false desactiva el producto igual que DELETE. active: true no cambia nada: un producto que puedes leer ya está activo, y uno inactivo devuelve 404. Se acepta para que puedas enviar el objeto completo.400 INVALID_REQUEST. Los tipos inválidos (por ejemplo "active": "no") devuelven 400 con el detalle en details[]. El companyCode del body se toma como contexto, no como campo a modificar.
Desactivar
boolean
predeterminado:"true"
Estado del producto.
DELETE /products/{id} hace un soft-delete: pone active: false sin eliminar el producto, de modo que el historial se conserva. Hacer DELETE sobre un producto ya eliminado devuelve 404 RESOURCE_NOT_FOUND.
Endpoints
Pruébalo en el API Reference
Explora cada endpoint con su playground interactivo.

