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:
// 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: unamountde0es 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_idyvisitor_idse 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_idsigue 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 nocustomer_id, indica cuál). Se atribuye como se atribuyó el primer pago. refundedbooleano- Es un reembolso de
amountcontra el pago que indicatransaction_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
amountque 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:
{"message": "Payment recorded. It's linked to its visit within a few seconds.", "transaction_id": "order_1042", "duplicate": false}| Cuándo | message | duplicate |
|---|---|---|
| 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.
| Estado | code | Cuándo |
|---|---|---|
| 400 | invalid_parameter | El cuerpo no es un pago: el mensaje indica qué campo y por qué. |
| 401 | unauthorized | Sin clave, algo que no es una clave o una clave revocada. |
| 402 | payment_required | La cuenta del sitio no tiene plan: terminó su prueba o terminó su plan. |
| 403 | forbidden | La clave solo puede leer: crea una con Record payments marcado. |
| 404 | not_found | Un reembolso indica un transaction_id que este sitio nunca registró. |
| 429 | rate_limited | El 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:
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:
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.