Partial Settlement
A veces un marketplace no quiere liberar todo de un solo golpe — tal vez un pedido se envía por
etapas, tal vez una política retiene una fracción para una ventana de devolución.
executeSettlement acepta un amount opcional: si se omite, Ishtaran hace el settlement de todo
lo que sigue reservado; si se pasa, Ishtaran hace el settlement de exactamente esa cantidad, tantas
veces como quede saldo.
Transaction = 200.00
Settlement #1 amount=50 → fee=0.45 remaining=150.00 PARTIALLY_SETTLED
Settlement #2 amount=70 → fee=0.63 remaining=80.00 PARTIALLY_SETTLED
Settlement #3 amount=80 → fee=0.72 remaining=0.00 SETTLED
Código
async function settlePartial(amount: string) {
const settlement = await mercatto.settlements.executeSettlement(transactionId, amount);
const full = await mercatto.settlements.get(settlement.settlementId);
const summary = await mercatto.settlements.getSummary(transactionId);
const state = await mercatto.transactions.getState(transactionId);
console.log(`amount=${amount} fee=${full.platformFeeAmount} remaining=${summary.remainingReservedAmount} status=${state.status.name}`);
}
await settlePartial('50'); // fee=0.45 remaining=150.00 PARTIALLY_SETTLED
await settlePartial('70'); // fee=0.63 remaining=80.00 PARTIALLY_SETTLED
await settlePartial('80'); // fee=0.72 remaining=0.00 SETTLED
Qué pasó por debajo
Cada llamada calcula su propio Fee, sobre su propia porción — nunca sobre el total original de la Transaction. El 0.9% de 50 es 0.45, no una parte proporcional del 1.80 eventual. Sumar los tres Fees y los tres Splits a lo largo de las tres llamadas da exactamente los mismos totales que un único Settlement de 200 habría dado (Fee 1.80, Bob 178.38, Mercatto 19.82) — el Settlement parcial solo cambia cuándo se mueve el dinero, nunca cuánto, confirmado corriendo ambos caminos y comparando.
Un gap real que este Business Case encontró y corrigió. La lógica de dominio propia de la
plataforma siempre soportó un amount parcial — pero el contrato HTTP público nunca lo enviaba
hasta que la auditoría de este Business Case detectó el gap y se activó (BL-STL-008). Pedir más
de lo que queda (amount > remaining) es rechazado directamente, nunca limitado en silencio — ver
Failure scenarios.
Un detalle real esperado que conviene conocer: disparar Settlements parciales seguidos sobre
la misma Transaction puede ocasionalmente producir un 409 CONCURRENT_MODIFICATION genuino —
concurrencia optimista estándar sobre una fila ocupada, no un bug financiero. La respuesta
correcta es la misma que en cualquier API de concurrencia optimista: reintentar una vez. Ver
Known Limitations §F.15.