Sitios

Un sitio es un punto de venta del comercio: una tienda en línea, un canal telefónico, un punto físico. Cada sitio tiene sus propias credenciales, su moneda, su idioma y su configuración de operación.

La colección sites viaja en la raíz del cuerpo, junto a los campos del propio comercio, y la aceptan tanto la creación como la actualización. Una petición puede traer varios sitios a la vez.

Crear o modificar un sitio

Lo que determina si un elemento crea un sitio nuevo o modifica uno existente es la presencia del campo id:

El elemento
Efecto
Sin id
Crea un sitio nuevo. Todos los campos que describen un sitio pasan a ser obligatorios
Con id
Modifica ese sitio. Solo cambia lo que nombras; el resto se conserva

En una creación (POST), enviar sites[].id responde 422, porque no hay sitios previos que modificar. En una actualización, el id debe pertenecer al comercio de la URL. El campo customerId responde 422 siempre: el comercio viaja en la URL.

Credenciales del sitio

Cada sitio tiene sus propias credenciales, con las que se identifica ante la plataforma de pagos:

  • Name
    login
    Type
    string
    is optional
    Description

    Identificador público del sitio. Es único en todo el registro y no distingue mayúsculas de minúsculas.

  • Name
    tranKey
    Type
    string
    is optional
    Description

    Clave secreta del sitio.

Si no las envías, Onboarding las genera. Esa es la razón por la que son opcionales incluso al crear un sitio.

Como el login no distingue mayúsculas, ACME y acme son el mismo identificador y no pueden coexistir. Sigue estando disponible en dos casos, además de cuando está libre: cuando lo tiene el propio sitio que estás modificando, y cuando pertenece a un sitio que esta misma clave de idempotencia ya creó —sin lo cual un reintento colisionaría con su propio primer intento—.

Campos del sitio

  • Name
    name
    Type
    string
    is Required
    REQUERIDO
    Description

    Nombre interno del sitio.

  • Name
    displayName
    Type
    string
    is Required
    REQUERIDO
    Description

    Nombre que ve el comprador durante el pago.

  • Name
    type
    Type
    string
    is Required
    REQUERIDO
    Description

    Canal del sitio: INT (internet), POS (punto de venta), IVR (telefónico), REC (recurrente) u ONE (pago único).

  • Name
    category
    Type
    string
    is Required
    REQUERIDO
    Description

    Categoría de operación del sitio.

  • Name
    email
    Type
    string
    is Required
    REQUERIDO
    Description

    Correo de contacto operativo del sitio.

  • Name
    currency
    Type
    string
    is Required
    REQUERIDO
    Description

    Moneda con la que opera, del catálogo de monedas.

  • Name
    language
    Type
    string
    is Required
    REQUERIDO
    Description

    Idioma del sitio, del catálogo de idiomas.

  • Name
    onTest
    Type
    boolean
    is optional
    Description

    Si el sitio opera en modo de pruebas.

  • Name
    active
    Type
    boolean
    is optional
    Description

    Si el sitio está habilitado.

A estos se suman siete bloques de configuración, descritos abajo.

sites

{
  "sites": [
    {
      "name": "Tienda principal",
      "displayName": "Acme",
      "type": "INT",
      "category": "ECOMMERCE",
      "email": "[email protected]",
      "currency": "COP",
      "language": "ES",
      "onTest": true,
      "integration": {
        "allowPartial": false,
        "checkoutVersion": "v4",
        "connectionMethod": "REDIRECT",
        "notificationUrl": "https://acme.example.com/pay/notify",
        "allowWallet": true,
        "checkoutAttemptsLimit": 5
      },
      "control": {
        "minAmount": 1000,
        "maxAmount": 5000000,
        "allowedDays": 127,
        "allowedHours": "ffffffffffffffffffffffffffffffffffffffffff",
        "filterPse": false,
        "filterByBin": false,
        "allowedBankCountries": ["CO"]
      },
      "threeDS": { "setting": "LOW", "minAmount": 0 },
      "securityFilters": { "onlyWhitelisted": false, "dayMax": 5 },
      "operation": { "taxPercentage": 19, "mailCustomer": true },
      "branding": { "buttonColor": "#1a73e8" }
    }
  ]
}

Bloque integration

Define cómo se conecta el sitio con la plataforma de pagos.

  • Name
    integration.checkoutVersion
    Type
    string
    is optional
    Description

    Versión de la página de pago. Actualmente solo se admite v4.

  • Name
    integration.connectionMethod
    Type
    string
    is optional
    Description

    Modo de conexión, por ejemplo REDIRECT.

  • Name
    integration.notificationUrl
    Type
    string
    is optional
    Description

    URL donde el sitio recibe las notificaciones de sus transacciones.

  • Name
    integration.checkoutAttemptsLimit
    Type
    integer
    is optional
    Description

    Número de intentos de pago permitidos por sesión. Solo admite los valores que ofrece la configuración estándar.

  • Name
    integration.allowPartial
    Type
    boolean
    is optional
    Description

    Si se admiten pagos parciales.

  • Name
    integration.allowWallet
    Type
    boolean
    is optional
    Description

    Si se admite el uso de billetera.

Bloque control

Restringe cuándo y con qué montos puede operar el sitio.

  • Name
    control.minAmount
    Type
    number
    is optional
    Description

    Monto mínimo admitido por transacción.

  • Name
    control.maxAmount
    Type
    number
    is optional
    Description

    Monto máximo admitido por transacción.

  • Name
    control.allowedDays
    Type
    integer
    is optional
    Description

    Días de la semana habilitados, como máscara de bits. El valor 127 los habilita todos; el valor 0 responde 422, porque dejaría el sitio sin ningún día operativo.

  • Name
    control.allowedHours
    Type
    string
    is optional
    Description

    Horas habilitadas, codificadas como una cadena hexadecimal.

  • Name
    control.allowedBankCountries
    Type
    array
    is optional
    Description

    Países cuyos bancos se admiten.

  • Name
    control.filterPse
    Type
    boolean
    is optional
    Description

    Si se aplica filtrado sobre pagos bancarios.

  • Name
    control.filterByBin
    Type
    boolean
    is optional
    Description

    Si se filtra por BIN de tarjeta.

  • Name
    control.exceptionBinsList
    Type
    array
    is optional
    Description

    BINes exceptuados del filtro.

Los demás bloques

Bloque
Para qué
threeDS
Configuración de autenticación 3-D Secure: nivel de exigencia y monto a partir del cual se aplica
securityFilters
Límites antifraude por número de intentos y de tarjetas, por día, semana y mes
operation
Parámetros operativos: porcentaje de impuesto, correos al comprador, comprobantes
subscriptionValidation
Configuración de la validación al registrar un medio de pago
branding
Colores e imagen de la página de pago. Los colores se envían como #rgb o #rrggbb

Varios límites son más estrechos que lo que el registro admitiría, porque replican los que impone la configuración estándar de la plataforma. Enviar un valor fuera de esos límites responde 422 señalando el campo.

Metadatos del sitio

El bloque metadata guarda información propia del comercio, destinada a un proceso pactado con Placetopay aparte de este contrato. Es opcional y lo aceptan tanto la creación como la actualización.

Es el único bloque de un sitio sin vocabulario cerrado: los nombres los eliges tú, no el catálogo. A cambio, la forma sí es fija — un valor por nombre. Un objeto o una lista bajo un nombre responden 422.

El valor conserva el tipo con el que lo envías: un número sigue siendo número y un booleano, booleano.

metadata

{
  "sites": [
    {
      "name": "Tienda principal",
      "metadata": {
        "contractRef": "AC-2026-0042",
        "onboardingBatch": 17,
        "requiresManualReview": true
      }
    }
  ]
}

Se fusiona, y se borra nombrando la clave

El documento se fusiona: una clave que el cuerpo no nombra sobrevive con el valor que ya tenía.

Para retirar una clave, nómbrala con null o con la cadena vacía. Es la misma instrucción que ya usan los settings de un medio de pago. En una creación ambas se rechazan, porque no hay nada que borrar.

No existe forma de vaciar el documento entero de una vez: "metadata": null responde 422. Se borra clave por clave.

Retirar una clave

{
  "sites": [
    {
      "id": 412,
      "metadata": {
        "onboardingBatch": 18,
        "reviewedBy": "riesgo",
        "legacyFlag": null
      }
    }
  ]
}

contractRef sobrevive sin haberse reenviado, legacyFlag desaparece por haberse nombrado con null, y las otras dos se escriben.

El tamaño se mide sobre el documento resultante

Es una consecuencia directa de la fusión: como el documento nunca se reemplaza, solo puede crecer. Acotar únicamente la petición dejaría pasar escrituras que después no se podrían almacenar.

Retirar claves es la única forma de recuperar espacio. Si un sitio se acerca al tope, nombra con null lo que ya no uses.

Ten en cuenta también que el bloque se valida en cadena y se detiene en el primer fallo: si envías a la vez un nombre inválido y un documento demasiado grande, solo verás el error del nombre.

Los límites exactos están en la referencia de la API, junto con la longitud máxima de un nombre y de un valor.

No se puede leer de vuelta

Un cuerpo que no envía metadata deja el result exactamente igual que antes de que este bloque existiera.

Qué no poner aquí

Ten en cuenta además que el back office todavía no muestra estos datos. Quedan guardados y auditados, pero verlos desde la ficha del sitio requiere un desarrollo pendiente del lado del back office.

Comportamiento en una actualización

La colección es upsert-only: un sitio que el cuerpo no nombra sobrevive intacto, y dentro de un sitio que sí nombras solo cambia lo que envías.

Los bloques branding y los ajustes internos del sitio se fusionan en lugar de reemplazarse, porque contienen claves que solo la plataforma escribe y que una actualización no podría restaurar.

Efectos de una edición posterior desde el back office

Hay tres valores que la plataforma normaliza la primera vez que una persona guarda el sitio desde el back office. No son fallos y no se pueden devolver como error, pero conviene conocerlos:

  • Un allowedHours que no habilite ninguna hora se convierte en «todas las horas».
  • Una fecha de expiración pierde su componente de hora.
  • Una comisión heredada de un medio de pago del sitio pasa a 0.00. Ver Medios de pago del sitio.

El resultado

  • Name
    id
    Type
    integer
    is Required
    REQUERIDO
    Description

    Identificador del sitio. Es el que usarás para modificarlo después.

  • Name
    login
    Type
    string
    is Required
    REQUERIDO
    Description

    Identificador público del sitio.

  • Name
    tranKey
    Type
    string
    is Required
    REQUERIDO
    Description

    Clave secreta. La clave siempre viaja; su valor es null si esta petición no la escribió.

  • Name
    active
    Type
    boolean
    is Required
    REQUERIDO
    Description

    Estado del sitio tras la operación.

  • Name
    action
    Type
    string
    is Required
    REQUERIDO
    Description

    created, updated o unchanged. Un sitio se reporta como unchanged cuando ninguno de sus campos difiere de lo almacenado, de modo que reenviar el mismo cuerpo no lo marca como editado.

La clave tranKey está siempre presente; lo que cambia es su valor, que solo llega si esta misma petición la escribió: porque la enviaste, o porque se generó al crear el sitio.

En un alta nunca es null, porque si no envías las credenciales se generan. El null aparece cuando un elemento solo modificó un sitio existente: ahí no hay nada irrecuperable que rescatar, solo un secreto que nunca enviaste.

Más concretamente, en una actualización el valor vuelve solo si cambió. Reenviar el mismo tranKey que ya está guardado devuelve null, porque no hay ningún cambio que reportar — algo que sorprende si tu sistema envía el cuerpo completo en cada actualización y espera recuperar ahí la credencial.

Si pierdes las credenciales

No hay forma de volver a leerlas: ningún endpoint las devuelve. Lo que sí puedes hacer es fijar unas nuevas. Envía un tranKey distinto en una actualización del sitio: al cambiar de valor se escribe, y viaja en el result de ese proceso.

result

{
  "result": {
    "merchantId": 18,
    "sites": [
      {
        "id": 214,
        "login": "aabbccdd1234567890aabbccdd123456",
        "tranKey": "ABC123example456trankey+789abc012def3456ABC=",
        "active": true,
        "action": "created"
      },
      {
        "id": 209,
        "login": "123example456token789abc012def345",
        "tranKey": null,
        "active": true,
        "action": "updated"
      }
    ]
  }
}

Las claves se mantienen siempre presentes para que la forma del resultado no dependa de qué cambió.

Colecciones dentro de un sitio

Un sitio puede llevar sus propias colecciones, con reglas propias:

¿Qué sigue?