Pular para o conteúdo principal

Partial Settlement

Às vezes um marketplace não quer liberar tudo de uma vez só — talvez um pedido seja enviado em etapas, talvez uma política retenha uma fração para uma janela de devolução. executeSettlement aceita um amount opcional: deixe de fora e a Ishtaran liquida tudo que ainda está reservado; passe um valor, e a Ishtaran liquida exatamente aquilo, quantas vezes houver saldo restante.

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

examples/marketplace-mercatto/scenarios/settlement-partial.ts
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

O que aconteceu por baixo dos panos

Cada chamada calcula sua própria Fee, sobre a própria fatia — nunca sobre o total original da Transaction. 0,9% de 50 é 0,45, não uma fatia proporcional do 1,80 eventual. Some as três Fees e os três Splits das três chamadas e eles batem exatamente com os mesmos totais que um único Settlement de 200 teria (Fee 1.80, Bob 178.38, Mercatto 19.82) — o Settlement parcial só muda quando o dinheiro se move, nunca quanto, confirmado rodando os dois caminhos e comparando.

Uma lacuna real que este Business Case encontrou e corrigiu. A lógica de domínio da própria plataforma sempre suportou um amount parcial — mas o contrato HTTP público nunca o enviava até a auditoria deste Business Case pegar essa lacuna e ativá-la (BL-STL-008). Pedir mais do que resta (amount > remaining) é rejeitado diretamente, nunca silenciosamente limitado — veja Failure scenarios.

Uma nuance real e esperada que vale conhecer: disparar Settlements parciais um atrás do outro na mesma Transaction pode ocasionalmente esbarrar num 409 CONCURRENT_MODIFICATION genuíno — controle de concorrência otimista padrão numa linha movimentada, não um bug financeiro. A resposta correta é a mesma de qualquer API com concorrência otimista: repetir uma vez. Veja Known Limitations §F.15.