---
title: "Confirmar el pago del botón de Payphone tras el redirect y activar el plan"
method: POST
path: "/pagos/payphone/confirmar"
tags: ["pagos"]
---

# Confirmar el pago del botón de Payphone tras el redirect y activar el plan

`POST /pagos/payphone/confirmar`

## Request

- Base URL: `https://contadeo.com/api`
- URL: `https://contadeo.com/api/pagos/payphone/confirmar`
- Auth: none required

Verifica estado y monto contra `POST /api/button/V2/Confirm` de Payphone (única fuente de verdad; el botón no tiene webhook) y activa el plan en la misma transacción de BD. OJO: `V2/Confirm` es el endpoint del BOTÓN, distinto del `confirm` de la Cajita embebida, que no se usa. Payphone REVERSA la transacción si no se confirma en 5 minutos, así que el dashboard llama aquí en cuanto aterriza en `/pago/resultado`. Idempotente: una transacción ya aprobada devuelve el resultado guardado. Las pendientes de más de 24 h expiran. Responde `pendiente` sin tocar la fila (y se puede reintentar) cuando Payphone no eco-devuelve el mismo `clientTransactionId` o cuando el `transactionId` confirmado ya está asociado a otra transacción: son barreras fail-closed y no marcan `rechazado`, que es definitivo. PÚBLICO: se identifica por `id` + `clientTransactionId` del redirect (el segundo lo generó el servidor) y se valida contra el monto esperado, sin JWT. La PII del comprador que devuelve Payphone (email, teléfono, documento, titular, BIN, últimos dígitos) se redacta antes de persistir y nunca viaja al navegador.

## Request body

- object
  - `id` integer, required: Query param `id` del redirect de Payphone
  - `clientTransactionId` string, required: Query param `clientTransactionId` del redirect
  - `ctoken` string: Token de la tarjeta con el que vuelve Payphone en la query (`ctoken`). Va en el cuerpo, nunca en una URL; solo se usa si el checkout pidió la renovación automática y el pago se aprueba. Se guarda cifrado y no se registra.
  - `clavesUrl` string[]: Nombres de los parámetros de la URL de vuelta, sin valores. Se guardan con la confirmación para saber qué mandó Payphone.
  - `ctokenEnUrl` boolean: Si la URL de vuelta traía `ctoken`

## Response `201`

Resultado de la confirmación

- object
  - `estado` 'aprobado' | 'rechazado' | 'expirado' | 'pendiente'
  - `plan` string
  - `planExpiraAt` string, date, nullable
  - `ciclo` 'mensual' | 'anual'
  - `renovacionAutomatica` boolean: Lo que se pidió en el checkout
  - `tarjetaGuardada` boolean: La tarjeta quedó guardada y la renovación automática, activa
  - `complementos` string[]: Complementos que pagó este cobro
  - `tipo` 'alta' | 'renovacion' | 'mejora' | 'complemento', nullable: Qué se cobró; null en los pagos anteriores a los complementos.

## Other responses

- `404`: Recurso inexistente (o de otra cuenta — aislamiento multi-tenant)
- `502`: La pasarela no respondió; la transacción sigue pendiente y se puede reintentar

---

[API](https://skmtc.dev/contadeo/apis/api-de-contadeo.md) · [All operations](https://skmtc.dev/contadeo/apis/api-de-contadeo/llms.txt) · [OpenAPI document](https://skmtc.dev/contadeo/apis/api-de-contadeo/revisions/461bbb9a74ce?raw)
