DocumentaciónPayments API

03 · Ingresos

Registra pagos de cualquier proveedor

¿Vendes con algo a lo que Tally no se conecta? Tu servidor envía cada pago, y este se vincula con su visita como el de cualquier proveedor.

01Crea una clave que pueda registrar pagos

En la página Setup del sitio, en API keys, ponle nombre a una clave y marca Record payments. La clave se muestra una sola vez; la lista la marca como Records payments. Una clave sin ese permiso solo puede leer, y aquí se rechaza con 403.

02Envía cada pago

Cuando tu servidor cobre un pago, de cualquier proveedor, envíalo a POST https://tallybyoutpost.com/api/v1/payments con la clave como Authorization: Bearer … y un cuerpo JSON. Incluye el ID de visitante del comprador, leído de la cookie _tally_vid de su solicitud:

Mostrar el código para

// Express with cookie-parser, where your server records a payment it took.
app.post('/paid', async (req, res) => {
  await fetch('https://tallybyoutpost.com/api/v1/payments', {
    method: 'POST',
    headers: {
      Authorization: 'Bearer ' + process.env.TALLY_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      amount: 29.99,
      currency: 'USD',
      transaction_id: 'order_1042',
      tally_visitor_id: req.cookies['_tally_vid'],
      email: 'buyer@example.com',
    }),
  });
  res.sendStatus(204);
});

curl https://tallybyoutpost.com/api/v1/payments \
  -H "Authorization: Bearer $TALLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": 29.99, "currency": "USD", "transaction_id": "order_1042", "tally_visitor_id": "the _tally_vid cookie"}'

# Where your server records a payment it took (requests, Flask).
import os
import requests

requests.post(
    "https://tallybyoutpost.com/api/v1/payments",
    headers={"Authorization": "Bearer " + os.environ["TALLY_API_KEY"]},
    json={
        "amount": 29.99,
        "currency": "USD",
        "transaction_id": "order_1042",
        "tally_visitor_id": request.cookies.get("_tally_vid"),
        "email": "buyer@example.com",
    },
    timeout=10,
)

03Los campos

amountnúmeroobligatorio
Lo que se pagó, en la unidad principal de la moneda (29.99), impuestos incluidos. También sirve una cadena decimal. Mayor que 0: un amount de 0 es una prueba gratuita, que no registra nada.
currencycadenaobligatorio
Su código ISO 4217 de tres letras: USD, EUR, JPY.
transaction_idcadenaobligatorio
El ID del pago en tu sistema, de 200 caracteres como máximo (también sirve un número). Es único dentro del sitio: volver a enviarlo es un duplicado, no un segundo pago.
tally_visitor_idcadena
El valor de la cookie _tally_vid, que vincula el pago con su visita. datafast_visitor_id y visitor_id se leen igual.
emailcadena
El email del comprador, para una coincidencia de email. Se convierte en hash al llegar; solo se guarda el hash. También sirve customer_email.
namecadena
Se acepta, para que el cuerpo de DataFast funcione tal cual, y nunca se guarda. Lo mismo vale para customer_name.
customer_idcadena
Tu ID del comprador. Una renovación sin subscription_id sigue al primer pago del cliente.
subscription_idcadena
Agrupa los pagos de una suscripción, para que cada renovación siga a su primer pago.
renewalbooleano
Este pago renueva una suscripción (subscription_id, o si no customer_id, indica cuál). Se atribuye como se atribuyó el primer pago.
refundedbooleano
Es un reembolso de amount contra el pago que indica transaction_id. Se admiten reembolsos parciales.
refund_idcadena
Tu ID del reembolso, cuando un pago tiene varios reembolsos parciales. Sin él, un segundo reembolso del mismo pago es un duplicado.
is_free_trialbooleano
Una prueba sin nada pagado: no se registra nada, y la respuesta es 200.
taxnúmeropor defecto: 0
La parte de amount que corresponde a impuestos, para que los ingresos se cuenten sin ellos.
timestampcadenapor defecto: ahora
Cuándo se pagó: ISO 8601 con su zona horaria, como 2026-11-10T12:00:00Z. Como máximo, unos minutos en el futuro.

Todo lo demás del cuerpo se ignora.

04Qué responde

200 con JSON, siempre que el pago se registre o ya estuviera registrado:

200
{"message": "Payment recorded. It's linked to its visit within a few seconds.", "transaction_id": "order_1042", "duplicate": false}
Cuándomessageduplicate
Un pago«Payment recorded. It's linked to its visit within a few seconds.»false
Un reembolso«Refund recorded.»false
El mismo transaction_id otra vez«This transaction_id was recorded before; nothing new was recorded.»true
El mismo reembolso otra vez«This refund was recorded before; nothing new was recorded.»true
Una prueba gratuita«Free trials aren't revenue in Tally, so nothing was recorded.»false

Todo lo demás es un error, como en toda la API: {"error": {"code", "message"}}, donde el mensaje es una frase que puedes mostrar tal cual.

EstadocodeCuándo
400invalid_parameterEl cuerpo no es un pago: el mensaje indica qué campo y por qué.
401unauthorizedSin clave, algo que no es una clave o una clave revocada.
402payment_requiredLa cuenta del sitio no tiene plan: terminó su prueba o terminó su plan.
403forbiddenLa clave solo puede leer: crea una con Record payments marcado.
404not_foundUn reembolso indica un transaction_id que este sitio nunca registró.
429rate_limitedEl límite de solicitudes de la clave, con Retry-After en segundos.

05Renovaciones y reembolsos

Una renovación indica su suscripción (o su cliente) y activa renewal; se atribuye como se atribuyó el primer pago de la suscripción:

Renovación
curl https://tallybyoutpost.com/api/v1/payments \
  -H "Authorization: Bearer $TALLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": 29.99, "currency": "USD", "transaction_id": "inv_2207", "subscription_id": "sub_88", "renewal": true}'

Un reembolso activa refunded, indica por su transaction_id el pago que revierte y da el importe reembolsado. Dale a cada reembolso parcial de un pago su propio refund_id:

Reembolso
curl https://tallybyoutpost.com/api/v1/payments \
  -H "Authorization: Bearer $TALLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": 10, "currency": "USD", "transaction_id": "order_1042", "refunded": true, "refund_id": "rf_1"}'

06Cómo se vincula cada pago

Con las mismas reglas que cualquier proveedor, después de la respuesta: un ID de visitante vincula con confianza alta (como los metadatos del checkout), un email con confianza media (cuando el navegador del comprador llamó a identify con él), y las renovaciones y los reembolsos siguen al pago al que pertenecen. Cómo funciona la vinculación.

07Comprueba que funciona

¿Falta algo o no coincide con lo que ves? Escribe a support@tallybyoutpost.com y dinos qué página.