Partial Settlement
Sometimes a marketplace doesn't want to release everything in one shot — maybe an order ships in
stages, maybe a policy holds a fraction back for a return window. executeSettlement takes an
optional amount: leave it out and Ishtaran settles everything still reserved; pass it, and
Ishtaran settles exactly that much, as many times as there's a balance left.
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
Code
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
What happened under the hood
Each call computes its own Fee, on its own slice — never on the Transaction's original total. 0.9% of 50 is 0.45, not a proportional share of the eventual 1.80. Sum the three Fees and the three Splits across all three calls and they land on the exact same totals as one single 200 Settlement would have (Fee 1.80, Bob 178.38, Mercatto 19.82) — partial Settlement only ever changes when money moves, never how much, confirmed by running both paths and comparing.
A real gap this Business Case found and fixed. The platform's own domain logic always supported
a partial amount — but the public HTTP contract never sent it until this Business Case's audit
caught the gap and it was activated (BL-STL-008). Requesting more than what's left
(amount > remaining) is rejected outright, never silently capped — see
Failure scenarios.
A real, expected wrinkle worth knowing: firing partial Settlements back-to-back on the same
Transaction can occasionally hit a genuine 409 CONCURRENT_MODIFICATION — standard optimistic
concurrency on a busy row, not a financial bug. The correct response is the same as any
optimistic-concurrency API: retry once. See Known Limitations §F.15.