> ## Documentation Index
> Fetch the complete documentation index at: https://docs.settlx.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Partial Payments

> Handle underpayments and multi-transaction payments

# Partial Payments

A partial payment occurs when a customer sends less than the required invoice amount. Settlx keeps the invoice active and accepts additional payments until the full amount is received or the invoice expires.

***

## How it works

1. Customer sends **30 USDT** against a \$49.99 invoice
2. Payment confirms on-chain → `invoice.underpaid` fires
3. Invoice remains active — deposit address stays valid
4. Customer sends another **20 USDT**
5. Combined total meets the invoice amount → `invoice.confirmed` fires
6. Settlement proceeds normally → `invoice.settled` fires

***

## The `invoice.underpaid` event

When the total received falls below the invoice amount, you receive an `invoice.underpaid` event:

```json theme={null}
{
  "event": "invoice.underpaid",
  "eventId": "evt_a1b2c3d4_invoice.underpaid_1744452600000",
  "timestamp": "2026-04-12T10:10:00.000Z",
  "data": {
    "invoice": {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "amount": "49.99",
      "currency": "USD",
      "settlementCurrency": "USDT",
      "settlementChain": "polygon",
      "status": "pending",
      "createdAt": "2026-04-12T10:00:00.000Z",
      "metadata": { "orderId": "order_123" }
    },
    "payment": {
      "id": "c3d4e5f6-a7b8-9012-cdef-345678901234",
      "transactionHash": "0xabc123...",
      "amount": "30.00",
      "currency": "USDT",
      "chain": "polygon",
      "confirmations": 12,
      "status": "confirmed"
    },
    "fees": {
      "platformFee": "0.45",
      "platformFeePercent": "1.5%",
      "networkFee": "0.50",
      "providerFee": "0.00",
      "totalFees": "0.95",
      "currency": "USDT"
    }
  }
}
```

***

## Handling in your webhook

```javascript theme={null}
case 'invoice.underpaid': {
  const { invoice, payment } = event.data;
  const orderId = invoice.metadata?.orderId;

  const shortfall = (parseFloat(invoice.amount) - parseFloat(payment.amount)).toFixed(2);

  // Do not cancel — invoice stays open
  await db.orders.update({
    where: { id: orderId },
    data: { paymentStatus: 'partial' },
  });

  await emailService.sendPartialPaymentEmail({
    orderId,
    received: payment.amount,
    currency: payment.currency,
    shortfall,
  });

  break;
}
```

***

## Multiple transactions

Customers can send multiple transactions to the same deposit address. Settlx automatically sums all confirmed payments against the invoice. You do not need to generate a new address or create a new invoice.

***

## Exchange rate considerations

<Warning>
  The `crypto_amount` shown at address generation reflects the exchange rate at that moment. If the customer sends a second transaction hours or days later, the exchange rate may have shifted.

  Settlx tracks the **USD value** of each confirmed payment. When the combined USD value meets or exceeds the invoice amount, the invoice is marked confirmed and settlement proceeds.
</Warning>

***

## Invoice expiry with partial payments

If an invoice expires while underpaid:

* An `invoice.expired` event fires
* No automatic settlement is triggered for the partial amount
* The deposit address becomes inactive
* Contact Settlx support to manually process any funds already received

Set a generous expiry time when you expect partial or multi-transaction payments. For B2B invoices, 24 hours to 7 days is common.

***

## Best practices

* **Do not create a new invoice** for the remaining balance — the customer's original deposit address is still valid
* **Notify customers promptly** when a partial payment is received, showing the amount still needed
* **Set a sufficient expiry** — 30–60 minutes for retail, longer for B2B
* **Show a countdown timer** on your checkout page so customers know how long they have
