> ## 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.

# invoice.confirmed

> Payment confirmed on-chain and the invoice is ready for settlement.

## When it fires

After the customer's payment has received the required number of blockchain confirmations **and** the cumulative received amount meets or exceeds the invoice total. Settlx is now processing the conversion (if needed) and transfer to your wallet.

This event fires for two outcomes — distinguished by `data.payment_quality`:

| `data.payment_quality` | Meaning                                                                                                                                                                                                                                              |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `full`                 | The customer paid exactly the required amount (within Settlx's tolerance window).                                                                                                                                                                    |
| `overpaid`             | The customer paid more than the required amount. The excess is included in the settlement transfer to your wallet. `data.excess_amount` is the excess in `data.excess_currency` (the **payment currency**, e.g. `BNB`), not the settlement currency. |

<Note>
  Partial payments (less than the required amount) do **not** fire this event — they fire [`invoice.underpaid`](/webhook-events/invoice-underpaid) instead, because the merchant action is fundamentally different.
</Note>

***

## What to do

Show the customer a "Payment received, processing..." status. **Do not fulfil the order yet** — funds are not in your wallet. Wait for [`invoice.settled`](/webhook-events/invoice-settled) before fulfilling.

If `data.payment_quality === 'overpaid'`, optionally log the excess for your records or notify the customer that they overpaid. The full received amount (including excess) lands in your wallet on `invoice.settled`.

<Info>
  This is an informational event. Its purpose is to let you update your customer-facing UI. All order fulfilment logic belongs in your `invoice.settled` handler.
</Info>

***

## Payload

**Includes:** `invoice`, `payment`, `fees` (estimated — final fees are in `invoice.settled`). The `settlement` object is not present yet.

```json theme={null}
{
  "event": "invoice.confirmed",
  "eventId": "evt_a1b2c3d4-e5f6-7890-abcd-ef1234567890_invoice.confirmed_1744455600000",
  "timestamp": "2026-04-12T11:00:00.000Z",
  "data": {
    "invoice": {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "amount": "49.99",
      "currency": "USD",
      "settlementCurrency": "USDT",
      "settlementChain": "polygon",
      "status": "confirmed",
      "createdAt": "2026-04-12T10:00:00.000Z",
      "metadata": { "orderId": "order_123", "customerId": "cust_456" }
    },
    "payment": {
      "id": "c3d4e5f6-a7b8-9012-cdef-345678901234",
      "transactionHash": "0x9f4c3a8b7e6d5f4c3a8b7e6d5f4c3a8b7e6d5f4c3a8b7e6d5f4c3a8b7e6d5f4c",
      "amount": "49.99",
      "currency": "USDT",
      "chain": "polygon",
      "confirmations": 12,
      "status": "confirmed"
    },
    "fees": {
      "platformFee": "0.75",
      "platformFeePercent": "1.5%",
      "networkFee": "0.50",
      "providerFee": "0.00",
      "totalFees": "1.25",
      "currency": "USDT"
    },

    "payment_quality": "full"
  }
}
```

When `payment_quality === 'overpaid'`, the payload also includes:

```json theme={null}
"payment_quality": "overpaid",
"excess_amount": "0.00076548",
"excess_currency": "BNB"
```

`excess_amount` is in `excess_currency` (the **payment currency**) — that's the asset the customer overpaid in. The merchant still receives the full overpaid amount in their settlement currency on `invoice.settled`; this field tells you "the customer sent X more than required, in the asset they paid with."

***

## Handler example

```javascript Node.js theme={null}
app.post('/webhooks/settlx', express.raw({ type: 'application/json' }), async (req, res) => {
  verifySignature(req);
  const event = JSON.parse(req.body);

  if (event.event === 'invoice.confirmed') {
    const { invoice, payment, payment_quality, excess_amount } = event.data;
    const orderId = invoice.metadata?.orderId;

    // Update the order status so your UI reflects the payment was seen
    await db.orders.update(orderId, { status: 'payment_confirmed' });

    if (payment_quality === 'overpaid') {
      await db.orders.update(orderId, {
        overpaymentAmount: excess_amount,
        overpaymentCurrency: invoice.settlementCurrency,
      });
    }

    // Notify the customer — do not fulfil yet
    await notifyCustomer(invoice.metadata?.customerId, {
      message: 'Your payment has been received and is being processed.',
      transactionHash: payment.transactionHash,
    });
  }

  res.status(200).json({ received: true });
});
```

***

## Typical timeline

After `invoice.confirmed` fires, expect `invoice.settled` to follow within 1–10 minutes depending on network congestion and whether a token conversion is required.

***

## Related events

* [`invoice.settled`](/webhook-events/invoice-settled) — Funds have arrived in your wallet. Fulfil the order here.
* [`invoice.underpaid`](/webhook-events/invoice-underpaid) — Customer paid less than the required amount. Different event; do **not** fulfil.
